Here's a (crap) function that resets the points to zero, then counts up all existing nodes and comments on the site to generate the points. I don't know where (or if) you want to include this, so there's no patch yet.
It's probably trivial to rewrite this into a single SQL query, but I just wanted a quick way to give people points for their old posts after enabling this module on an existing site. I think it creates an accurate count, but I haven't really tested it.
function _userpoints_recount_points() {
// reset the points
db_query("UPDATE {userpoints} SET points = 0");
// count how many nodes of each type users have posted.
foreach (node_list() as $type) {
$points = variable_get('userpoints_post_' . $type, '1');
$sql = "SELECT COUNT(*) contribs, n.uid
FROM {node} n
LEFT JOIN {users} u ON n.uid = u.uid
WHERE n.uid >0
AND u.name != ''
AND n.type = '$type'
AND n.status =1
GROUP BY u.uid
LIMIT 1000";
$node_result = db_query($sql);
while ($row = db_fetch_array($node_result)) {
$current_points = db_result(db_query('SELECT points FROM {userpoints} WHERE uid = %d', $row[uid]));
$new_points = $current_points + ($points * $row[contribs]);
db_query("UPDATE {userpoints} SET points = '%d', last_update = '%d' WHERE uid = %d", $new_points, time(), $row[uid]);
}
}
// count how many comments users have posted
$comment_sql = "SELECT COUNT(*) contribs, u.uid
FROM {comments} c
LEFT JOIN {users} u ON c.uid = u.uid
WHERE u.name != ''
GROUP BY u.uid
LIMIT 1000";
$comment_result = db_query($comment_sql);
$points = variable_get('userpoints_post_comment', '1');
while ($row = db_fetch_array($comment_result)) {
$current_points = db_result(db_query('SELECT points FROM {userpoints} WHERE uid = %d', $row[uid]));
$comment_points = $current_points + ($points * $row[contribs]);
db_query("UPDATE {userpoints} SET points = '%d', last_update = '%d' WHERE uid = %d", $comment_points, time(), $row[uid]);
}
print theme('page', $output);
}
Comments
Comment #1
kbahey commentedActually, this is a good idea in some cases.
In other cases, it is not needed. It is like money they earned, and any change in "prices" does not affect what they have in the bank.
Also, it will not cater for every situation, like when someone uses the invite.module. Some extra code is needed to see who referred whom, and who registered.
Going back to your idea, I see when it would be useful:
a. To retroactively give users credit for what they posted.
b. To recalculate the points for each user after you change the points for each event.
A variation can be used to wipe clean the points every month and have users start fresh and compete again.
Regarding your code, it would not work as is. The reason is, you assume that an update will do it, but not all users will have a row in the userpoints table.
A better approach is something like this
Wipe the table using DELETE FROM {userpoints};
For each user, create a row for each user in the userpoints table with 0 points
Then run your code.
The LIMIT 1000 thing can be problematic to some sites. It is a case where if you do not put it, PHP may time out on you, but if you put it, not all nodes/comments would be processed.
More code is needed to handle cases where you have extra modules (nodevote, invite, ...etc).
If you get this working, and submit a patch, we can have an option in the settings page for that module to "recalculate user points" with appropriate warnings. Just like the option in pathauto to redo all paths.
Comment #2
ixis.dylan commentedI'll work on it, and submit a patch.
The "LIMIT 1000" was left in accidentally. I just hacked that function in because after enabling this module on a site the users were complaining that all of their old content was being ignored in the point totals, and thought the code might be a useful starting point for others.
As you say, this function isn't suitable for running on other sites yet, but it can help to synch the table with an existing set of nodes.
Comment #3
kbahey commentedDuplicate of http://drupal.org/node/84161
Comment #4
RikiB commentedThis is very old but I was just wondering how we could do this with the current version in D6. I'm surprised more people aren't posting about this feature.