MDL-25057 mod_forum: Stop duplicating forum_read posts from cron

This also includes an upgrade script to delete the existing duplicates.
This commit is contained in:
Andrew Nicols
2014-10-30 14:03:53 +08:00
parent 8699d48e7d
commit deb5eed574
3 changed files with 70 additions and 45 deletions
+24
View File
@@ -130,5 +130,29 @@ function xmldb_forum_upgrade($oldversion) {
upgrade_mod_savepoint(true, 2013110501, 'forum');
}
if ($oldversion < 2013110502) {
// Find records with multiple userid/postid combinations and find the lowest ID.
// Later we will remove all those which don't match this ID.
$sql = "
SELECT MIN(id) as lowid, userid, postid
FROM {forum_read}
GROUP BY userid, postid
HAVING COUNT(id) > 1";
if ($duplicatedrows = $DB->get_recordset_sql($sql)) {
foreach ($duplicatedrows as $row) {
$DB->delete_records_select('forum_read', 'userid = ? AND postid = ? AND id <> ?', array(
$row->userid,
$row->postid,
$row->lowid,
));
}
}
$duplicatedrows->close();
// Forum savepoint reached.
upgrade_mod_savepoint(true, 2013110502, 'forum');
}
return true;
}
+45 -44
View File
@@ -6330,57 +6330,58 @@ function forum_tp_mark_posts_read($user, $postids) {
return $status;
}
list($usql, $params) = $DB->get_in_or_equal($postids);
$params[] = $user->id;
list($usql, $postidparams) = $DB->get_in_or_equal($postids, SQL_PARAMS_NAMED, 'postid');
$sql = "SELECT id
FROM {forum_read}
WHERE postid $usql AND userid = ?";
if ($existing = $DB->get_records_sql($sql, $params)) {
$existing = array_keys($existing);
$insertparams = array(
'userid1' => $user->id,
'userid2' => $user->id,
'userid3' => $user->id,
'firstread' => $now,
'lastread' => $now,
'cutoffdate' => $cutoffdate,
);
$params = array_merge($postidparams, $insertparams);
if ($CFG->forum_allowforcedreadtracking) {
$trackingsql = "AND (f.trackingtype = ".FORUM_TRACKING_FORCED."
OR (f.trackingtype = ".FORUM_TRACKING_OPTIONAL." AND tf.id IS NULL))";
} else {
$existing = array();
$trackingsql = "AND ((f.trackingtype = ".FORUM_TRACKING_OPTIONAL." OR f.trackingtype = ".FORUM_TRACKING_FORCED.")
AND tf.id IS NULL)";
}
$new = array_diff($postids, $existing);
// First insert any new entries.
$sql = "INSERT INTO {forum_read} (userid, postid, discussionid, forumid, firstread, lastread)
if ($new) {
list($usql, $new_params) = $DB->get_in_or_equal($new);
$params = array($user->id, $now, $now, $user->id);
$params = array_merge($params, $new_params);
$params[] = $cutoffdate;
SELECT :userid1, p.id, p.discussion, d.forum, :firstread, :lastread
FROM {forum_posts} p
JOIN {forum_discussions} d ON d.id = p.discussion
JOIN {forum} f ON f.id = d.forum
LEFT JOIN {forum_track_prefs} tf ON (tf.userid = :userid2 AND tf.forumid = f.id)
LEFT JOIN {forum_read} fr ON (
fr.userid = :userid3
AND fr.postid = p.id
AND fr.discussionid = d.id
AND fr.forumid = f.id
)
WHERE p.id $usql
AND p.modified >= :cutoffdate
$trackingsql
AND fr.id IS NULL";
if ($CFG->forum_allowforcedreadtracking) {
$trackingsql = "AND (f.trackingtype = ".FORUM_TRACKING_FORCED."
OR (f.trackingtype = ".FORUM_TRACKING_OPTIONAL." AND tf.id IS NULL))";
} else {
$trackingsql = "AND ((f.trackingtype = ".FORUM_TRACKING_OPTIONAL." OR f.trackingtype = ".FORUM_TRACKING_FORCED.")
AND tf.id IS NULL)";
}
$status = $DB->execute($sql, $params) && $status;
$sql = "INSERT INTO {forum_read} (userid, postid, discussionid, forumid, firstread, lastread)
SELECT ?, p.id, p.discussion, d.forum, ?, ?
FROM {forum_posts} p
JOIN {forum_discussions} d ON d.id = p.discussion
JOIN {forum} f ON f.id = d.forum
LEFT JOIN {forum_track_prefs} tf ON (tf.userid = ? AND tf.forumid = f.id)
WHERE p.id $usql
AND p.modified >= ?
$trackingsql";
$status = $DB->execute($sql, $params) && $status;
}
if ($existing) {
list($usql, $new_params) = $DB->get_in_or_equal($existing);
$params = array($now, $user->id);
$params = array_merge($params, $new_params);
$sql = "UPDATE {forum_read}
SET lastread = ?
WHERE userid = ? AND postid $usql";
$status = $DB->execute($sql, $params) && $status;
}
// Then update all records.
$updateparams = array(
'userid' => $user->id,
'lastread' => $now,
);
$params = array_merge($postidparams, $updateparams);
$status = $DB->set_field_select('forum_read', 'lastread', $now, '
userid = :userid
AND lastread <> :lastread
AND postid ' . $usql,
$params) && $status;
return $status;
}
+1 -1
View File
@@ -25,7 +25,7 @@
defined('MOODLE_INTERNAL') || die();
$module->version = 2013110501; // The current module version (Date: YYYYMMDDXX)
$module->version = 2013110502; // The current module version (Date: YYYYMMDDXX)
$module->requires = 2013110500; // Requires this Moodle version
$module->component = 'mod_forum'; // Full name of the plugin (used for diagnostics)
$module->cron = 60;