I'm about to create a new competition site, where users can upload pictures/vote.
I want to add some achievement bonuses/badges based on some very easy "achievements".
Achievement examples:
Login for 5 consecutive days --
Login for 10 consecutive days --
Login for 20 consecutive days
Vote 5 pictures (not yours) --
Vote 5 pictures for 5 consecutive days
I want to be able to add more achievements without adding too much code later on. A basic rule engine will be created.
Now.. I am having some troubles trying to think out how to do it. Anyone did something similar and wants to share database structure/coding examples, or someone with a good idea for this?
Read about 50 different threads on the topic here on SO, but couldn't find anything usable.
Make a new field in the table that will contain the date of the last activity (probably name it like lastactivity), and then create another one and name it something like consecutive. After that, each time the user login (or vote), check the last activity date and if it's yesterday, increment the value of the field consecutive by one and update the lastactivity field. Otherwise, reset it to 1.
Related
CURRENT FUNCTIONALITY:
In my financial/budgeting app, the current functionality allows a user to add a recurring budget category that will appear in each month's budget. It does this by allowing a user to select a "recurring" option from a dropdown, which makes 2 additional dropdowns appear, one with a beginning month and one with an ending month. When the category is recurring, it writes the beginning month and the ending month to the database (diagram below).
DESIRED FUNCTIONALITY:
The problem with the current design is that I want the user to be able to delete one (or more) month from the recurring months. So lets say I set up a recurring category in January for the entire year. Then I get to May and I want that category not to appear for that month. If I delete the category, it currently deletes it for all months, past and present. I need it to have the option to only delete only the desired month(s).
I'm not sure how to accomplish this, and I thought maybe someone has a good idea. Maybe my database structure is off? In the interest of normalization, I didn't want to just add a column for each month or anything like that.
Rather than storing the recurrence formula, IMHO it would be best to store the actual months in a many-to-many relationship:
categories
----------
id
name
months
------
id
category_months
---------------
cat_id
month_id
When a user enters a recurrence formula, it will create the relationships. Then they will be freely able to remove months one at a time if necessary.
In the website im working on i need to add user points. Every user will have it's own points and maximum amount of points will be 200. And upon registration user gets 100 points. With various tasks user points will be deducted.
But main problem im struggling is how to add points to the user, since every user need to gets 1 point every hour unless he have 200 or more points.
My first thought was to do a cronjob where it will run every hour a script which will check if user is verified and if user have less than 200 points and add 1 point to every user.
But after some reading im thinking of different approach which i don't understand quite exactly. The better approach, less server resource consuming would be to run a function which will check every time when user login how many points he have and add appropriate number of points to him. Problem is i don't know how to set it, how to calculate how many points to add to user if he was offline like 8 hours and how to time it? Or even maybe use ajax with timer?
What would be your suggestion and approach to this ?
Edit: Just to add since you ask, users doesn't see each other points.
When a user does something, check the last time you gave them points. If it was 5 hours ago, give them 5 points. If it was 10 hours ago, give them 10 points. Etc. Implement caching so if a user visits your site 50 times in one hour, you don't have to check against the DB every time.
Anyway, short answer is, do the check when loading the user data, rather than automatically every hour for all users whether they are active or not.
UPDATE users
SET points = MIN(points + 1, 200)
I don't really see the problem with this script running as a cron. Would be more problem if you handled each event as transaction points, since you'd have to run something like:
# Generates a row each hour per uncapped user, which may become a lot
INSERT INTO transcations (points, type, created)
SELECT 1, 'HOURLY_INCOME', NOW()
FROM users
WHERE points < 200
Is it relevant for other users, or official/inofficial statistics to check what their current point is? This is quite relevant, since it won't work fully if it only updates upon login.
user_table
---------------
id | reg_date
1 | 2013-10-10 21:10:15
2 | 2013-10-11 05:56:32
Just look how many hours left after user registration, add 100 points:
SELECT
TIMESTAMPDIFF(HOUR, `reg_date`, NOW())+100 AS `p`
FROM
user_table
WHERE
id = 1
And then check in PHP if result more than 200 just show 200.
Hmm, from mysql 5.1 there is neat feature which is basically mysql cron called MySQL Event Scheduler, and i think ill go with that for now since cron script will be very easy to write, small and not time consuming.
All i need to do is to write
UPDATE users SET points = (points +1) WHERE points<200
And add it to mysql event recurring every hour.
I know, the title does not sound good however I will explain it clearly. In mySQL table there is a column named expires. It will hold a date in the future that will be checked against current time of the server every time a user logs in.
So, when that day is passed and the user logs in, he will get a message. There are two user roles, number 2 and number 3. Number 3 will never have an ending period. Number 2 have "trial" accounts.
I know how to set the value for users with role 2 and make the check against time() on logging, but what is the value I should place in column expires on users with role 3 and how can I make the check against time for them when logging? Maybe a time at 2020 does the trick but isn't it kind of silly ?
I would probably just store NULL for the non-expiring accounts. When validating them, first test if the column value is null, in which case you have a type 3, then check if the date has passed, wherein you have an expired type 2.
You can save some programming on the application side if you stored it as a date far far in the future, but a NULL makes more logical sense to me.
I have some games I have programmed for members to play. I usually allow members to play games every day, and I have a cronjob resetting the value at midnight to allow access to the games again the next day.
I constructed a new game, and I wanted it to allow members to play every 2 hours. I realize I cannot do this with a cronjob, because members will play the game at different times.
I know this probably sounds bad, but I'm not very familiar with timestamps, so I really don't know where to start. I haven't really had any reason to look into it until now. I'm guessing that the time or now function will accomplish this when compared, but again I cannot find the relevant situation in the manual about doing this with mysql and successfully submitting that data in the same format.
I've seen examples of other programmers doing this in a certain way, but it seemed they went to unnecessary lengths to make it work. The example I've seen would add a lot of lines to my code.
If this is a repeat question, I apologize, but I don't know what keywords to search for in this situation. All I have gotten is javascript countdowns.
Well the first thing that you're going to need is a way to determine when each member has played the game. So you will need to create a table with the following information:
MemberID
GameID (In case you want to support more than just 1 game in the future using this model)
DateTimePlayed
So now the first problem you have to solve is "Has player X played game Y in the last 2 hours?" That can be solved with a simple query:
SELECT * FROM MemberGameHistory WHERE MemberID = X and GameID = Y and DateTimePlayed > DATE_SUB(NOW(), INTERVAL 2 HOURS)
If you're happy that they haven't played it and decide to let them in, then you need to insert a row so that the next time you run the query you'll see that they've done it:
INSERT INTO MemberGameHistory (MemberID, GameID, DateTimePlayed) VALUES (X, Y, NOW())
Does that solve your problem?
I want to display the number of new(unseen) guest entries in the guest book of a user. I was thinking to count it so that, total number of entries in guestbook minus entries in guestbook at time of last login. However, I think that is not a good approach, because if the user logs in but does not go to his guestbook, in that case, the entries should be still "new", also if some new entry is posted in the user while he is online, it does not work in that case too. Any suggested please?
You could save the time when the user last entered the guestbook, and display the number of new entries since that time.
You can have a column which indicates when entry is marked as seen/unseen and group the total number of entries on this column.
Edit after reading the comments: if your messages have an autoincrement id column you may save the max id of the unseen entries in the guestbook when the user visits the book. Initially it would be zero. Further a "new" entry will have an id > of the saved max id. If this is not the case you may consider using timestamps - the last time the user entered the guest-book compared to the message timestamp. I believe that the messages should have at least timestamp.
The question sounds too general to me. but you probably need to have a flag per entry; it gives the client the opportunity to set some entries to unseen, if he wants.