Permalink
Browse files

Merged and updated Yu's forum_cron optimising from head

  • Loading branch information...
moodler
moodler committed Mar 8, 2007
1 parent 9b4c44e commit fa730d469f3bc32a1db8feb83251a57c7f668d4e
Showing with 121 additions and 62 deletions.
  1. +121 −62 mod/forum/lib.php
View
@@ -217,6 +217,7 @@ function forum_delete_instance($id) {
function forum_cron() {
+
/// Function to be run periodically according to the moodle cron
/// Finds all posts that have yet to be mailed out, and mails them
/// out to all subscribers
@@ -241,9 +242,17 @@ function forum_cron() {
$starttime = $endtime - 48 * 3600; /// Two days earlier
$CFG->enablerecordcache = true; // We want all the caching we can get
-
- if ($posts = forum_get_unmailed_posts($starttime, $endtime)) {
-
+
+ // all users that are subscribed to any post that needs sending
+ $users = array();
+
+ $mailcount=array();
+ $errorcount=array();
+
+ $postsinfo = array();
+ $subscribedusers = array();
+
+ if ($posts = forum_get_unmailed_posts($starttime, $endtime)) {
/// Mark them all now as being mailed. It's unlikely but possible there
/// might be an error later so that a post is NOT actually mailed out,
/// but since mail isn't crucial, we can accept this risk. Doing it now
@@ -254,34 +263,70 @@ function forum_cron() {
return false; // Don't continue trying to mail them, in case we are in a cron loop
}
- @set_time_limit(0); /// so that script does not get timed out when posting to many users
-
- $urlinfo = parse_url($CFG->wwwroot);
- $hostname = $urlinfo['host'];
-
- foreach ($posts as $post) {
-
- mtrace(get_string('processingpost', 'forum', $post->id), '');
-
- /// Check the consistency of the data first
-
- if (! $userfrom = get_record('user', 'id', $post->userid)) {
- mtrace('Could not find user '.$post->userid);
- continue;
- }
+ // checking post validity, and adding users to loop through later
+ foreach ($posts as $pid => $post) {
if (! $discussion = get_record('forum_discussions', 'id', $post->discussion)) {
mtrace('Could not find discussion '.$post->discussion);
+ unset($posts[$pid]);
continue;
}
-
+
if (! $forum = get_record('forum', 'id', $discussion->forum)) {
mtrace('Could not find forum '.$discussion->forum);
+ unset($posts[$pid]);
continue;
}
if (! $course = get_record('course', 'id', $forum->course)) {
mtrace('Could not find course '.$forum->course);
+ unset($posts[$pid]);
+ continue;
+ }
+
+ // caching this so we don't need sqls later
+ unset($pinfo);
+ $pinfo -> discussion = $discussion;
+ $pinfo -> forum = $forum;
+ $pinfo -> course = $course;
+
+ $postinfo[$pid] = $pinfo;
+
+ // caching subscribed users of each forum
+ if (!isset($subscribedusers[$forum->id])) {
+ if ($subusers = forum_subscribed_users($course, $forum, 0, true)) {
+ foreach ($subusers as $postuser) {
+ // this user is subscribed to this forum
+ $subscribedusers[$forum->id][] = $postuser->id;
+ // this user is a user we have to process later
+ $users[$postuser->id] = $postuser;
+ }
+ }
+ }
+
+ $mailcount[$pid] = 0;
+ $errorcount[$pid] = 0;
+ }
+ }
+
+ if ($users) {
+
+ @set_time_limit(0); /// so that script does not get timed out when posting to many users
+
+ $urlinfo = parse_url($CFG->wwwroot);
+ $hostname = $urlinfo['host'];
+
+ foreach ($users as $userto) {
+
+ // set this so that the capabilities are cached
+ $USER = $userto;
+
+ mtrace('Processing user '.$userto->id);
+
+ /// Check the consistency of the data first
+
+ if (! $userfrom = get_record('user', 'id', $post->userid)) {
+ mtrace('Could not find user '.$post->userid);
continue;
}
@@ -299,52 +344,60 @@ function forum_cron() {
);
- // Get coursemodule record (and cache these)
-
- if (!empty($cachecm[$forum->id])) {
- $cm = $cachecm[$forum->id];
+ if ($posts) {
- } else if ($cm = get_coursemodule_from_instance('forum', $forum->id, $course->id)) {
- $cachecm[$forum->id] = $cm;
+ /// we might want to add another layer - forums here (by checking array_keys($subscribedusers))
+ /// so that we can skip many posts
- } else {
- $cm = new object;
- $cm->id = 0;
- $cachecm[$forum->id] = $cm;
- }
-
- $groupmode = false;
- if (!empty($cm->id)) {
- if ($groupmode = groupmode($course, $cm) and $discussion->groupid > 0) { // Groups are being used
- if (! groups_group_exists($discussion->groupid)) { // Can't find group //TODO:
- continue; // Be safe and don't send it to anyone
+ foreach ($posts as $pid=>$post) {
+
+ $discussion = $postinfo[$pid]->discussion;
+ $forum = $postinfo[$pid]->forum;
+ $course = $postinfo[$pid]->course;
+
+ if (empty($subscribedusers[$forum->id]) || !in_array($userto->id, $subscribedusers[$forum->id])) {
+ continue; // user does not subscribe to this forum
}
- }
- }
-
- $modcontext = get_context_instance(CONTEXT_MODULE, $cm->id); // Cached already
+
+ if (!empty($cachecm[$forum->id])) {
+ $cm = $cachecm[$forum->id];
+ } else if ($cm = get_coursemodule_from_instance('forum', $forum->id, $course->id)) {
+ $cachecm[$forum->id] = $cm;
- if ($users = forum_subscribed_users($course, $forum, 0, true)) {
-
- mtrace('Found '.count($users).' subscribed users for forum '.$forum->id);
-
- $mailcount=0;
- $errorcount=0;
+ } else {
+ $cm = new object;
+ $cm->id = 0;
+ $cachecm[$forum->id] = $cm;
+ }
+
+ $modcontext = get_context_instance(CONTEXT_MODULE, $cm->id); // Cached already
+ // Get coursemodule record (and cache these)
+
+ $groupmode = false;
+ if (!empty($cm->id)) {
+ if ($groupmode = groupmode($course, $cm) and $discussion->groupid > 0) { // Groups are being used
+ if (! groups_group_exists($discussion->groupid)) { // Can't find group //TODO:
+ continue; // Be safe and don't send it to anyone
+ }
+ }
+ }
- foreach ($users as $userto) {
if ($groupmode) { // Look for a reason not to send this email
if (!empty($group->id)) {
if (!ismember($group->id, $userto->id)) {
- if (!has_capability('moodle/site:accessallgroups', $modcontext, false, $userto->id)) {
+ // no need because $USER = $userto?
+ if (!has_capability('moodle/site:accessallgroups', $modcontext)) {
+ //if (!has_capability('moodle/site:accessallgroups', $modcontext, false, $userto->id)) {
continue;
}
}
}
}
// make sure we're allowed to see it...
- if (!forum_user_can_see_post($forum, $discussion, $post, $userto)) {
+ //if (!forum_user_can_see_post($forum, $discussion, $post, $userto)) {
+ if (!forum_user_can_see_post($forum, $discussion, $post)) {
mtrace('user '.$userto->id. ' can not see '.$post->id);
continue;
}
@@ -363,27 +416,28 @@ function forum_cron() {
/// Override the language and timezone of the "current" user, so that
/// mail is customised for the receiver.
- $USER = $userto;
+
course_setup($course);
- mtrace('Sending post '.$post->id. ' to user '.$userto->id. '...', '');
$postsubject = "$course->shortname: ".format_string($post->subject,true);
$posttext = forum_make_mail_text($course, $forum, $discussion, $post, $userfrom, $userto);
$posthtml = forum_make_mail_html($course, $forum, $discussion, $post, $userfrom, $userto);
+ mtrace('Sending ', '');
+
if (!$mailresult = email_to_user($userto, $userfrom, $postsubject, $posttext,
$posthtml, '', '', $CFG->forum_replytouser)) {
mtrace("Error: mod/forum/cron.php: Could not send out mail for id $post->id to user $userto->id".
" ($userto->email) .. not trying again.");
add_to_log($course->id, 'forum', 'mail error', "discuss.php?d=$discussion->id#p$post->id",
substr(format_string($post->subject,true),0,30), $cm->id, $userto->id);
- $errorcount++;
+ $errorcount[$post->id]++;
} else if ($mailresult === 'emailstop') {
add_to_log($course->id, 'forum', 'mail blocked', "discuss.php?d=$discussion->id#p$post->id",
substr(format_string($post->subject,true),0,30), $cm->id, $userto->id);
} else {
- $mailcount++;
+ $mailcount[$post->id]++;
/// Mark post as read if forum_usermarksread is set off
if (!$CFG->forum_usermarksread && forum_tp_can_track_forums($forum, $userto) &&
@@ -395,17 +449,22 @@ function forum_cron() {
}
}
- mtrace(' sent.');
- }
-
- mtrace(".... mailed to $mailcount users.");
- if ($errorcount) {
- set_field("forum_posts", "mailed", "2", "id", "$post->id");
+ mtrace('post '.$post->id. ': '.$post->subject);
}
}
}
}
+ if ($posts) {
+ foreach ($posts as $post) {
+ // this needs fixing, needs to be done after all posts are mailed
+ mtrace($mailcount[$post->id]." users were sent post $post->id, '$post->subject'");
+ if ($errorcount[$post->id]) {
+ set_field("forum_posts", "mailed", "2", "id", "$post->id");
+ }
+ }
+ }
+
$sitetimezone = $CFG->timezone;
/// Now see if there are any digest mails waiting to be sent, and if we should send them
@@ -632,7 +691,7 @@ function forum_cron() {
}
function forum_make_mail_text($course, $forum, $discussion, $post, $userfrom, $userto, $bare = false) {
- global $CFG;
+ global $CFG, $USER;
if (!$cm = get_coursemodule_from_instance('forum', $forum->id, $course->id)) {
error('Course Module ID was incorrect');
@@ -1767,7 +1826,7 @@ function forum_make_mail_post(&$post, $user, $touser, $course,
// Given the data about a posting, builds up the HTML to display it and
// returns the HTML in a string. This is designed for sending via HTML email.
- global $CFG;
+ global $CFG, $USER;
static $formattedtext; // Cached version of formatted text for a post
static $formattedtextid; // The ID number of the post
@@ -1800,7 +1859,7 @@ function forum_make_mail_post(&$post, $user, $touser, $course,
}
$output .= '<div class="subject">'.format_string($post->subject).'</div>';
- $fullname = fullname($user, has_capability('moodle/site:viewfullnames', $modcontext, $touser->id));
+ $fullname = fullname($user, has_capability('moodle/site:viewfullnames', $modcontext));
$by->name = '<a href="'.$CFG->wwwroot.'/user/view.php?id='.$user->id.'&amp;course='.$course->id.'">'.$fullname.'</a>';
$by->date = userdate($post->modified, '', $touser->timezone);
$output .= '<div class="author">'.get_string('bynameondate', 'forum', $by).'</div>';

0 comments on commit fa730d4

Please sign in to comment.