Merge branch 'MDL-26562-23' of git://github.com/vadimonus/moodle
authorSam Hemelryk <sam@moodle.com>
Wed, 23 May 2012 23:00:09 +0000 (11:00 +1200)
committerSam Hemelryk <sam@moodle.com>
Wed, 23 May 2012 23:00:09 +0000 (11:00 +1200)
1  2 
mod/forum/lib.php

diff --combined mod/forum/lib.php
@@@ -44,11 -44,6 +44,11 @@@ define('FORUM_TRACKING_OFF', 0)
  define('FORUM_TRACKING_OPTIONAL', 1);
  define('FORUM_TRACKING_ON', 2);
  
 +if (!defined('FORUM_CRON_USER_CACHE')) {
 +    /** Defines how many full user records are cached in forum cron. */
 +    define('FORUM_CRON_USER_CACHE', 5000);
 +}
 +
  /// STANDARD FUNCTIONS ///////////////////////////////////////////////////////////
  
  /**
@@@ -383,28 -378,6 +383,28 @@@ function forum_get_email_message_id($po
      return '<'.hash('sha256',$postid.'to'.$usertoid.'@'.$hostname).'>';
  }
  
 +/**
 + * Removes properties from user record that are not necessary
 + * for sending post notifications.
 + * @param stdClass $user
 + * @return void, $user parameter is modified
 + */
 +function forum_cron_minimise_user_record(stdClass $user) {
 +
 +    // We store large amount of users in one huge array,
 +    // make sure we do not store info there we do not actually need
 +    // in mail generation code or messaging.
 +
 +    unset($user->institution);
 +    unset($user->department);
 +    unset($user->address);
 +    unset($user->city);
 +    unset($user->url);
 +    unset($user->currentlogin);
 +    unset($user->description);
 +    unset($user->descriptionformat);
 +}
 +
  /**
   * Function to be run periodically according to the moodle cron
   * Finds all posts that have yet to be mailed out, and mails them
@@@ -424,11 -397,8 +424,11 @@@ function forum_cron() 
  
      $site = get_site();
  
 -    // all users that are subscribed to any post that needs sending
 +    // All users that are subscribed to any post that needs sending,
 +    // please increase $CFG->extramemorylimit on large sites that
 +    // send notifications to a large number of users.
      $users = array();
 +    $userscount = 0; // Cached user counter - count($users) in PHP is horribly slow!!!
  
      // status arrays
      $mailcount  = array();
                  $modcontext = get_context_instance(CONTEXT_MODULE, $coursemodules[$forumid]->id);
                  if ($subusers = forum_subscribed_users($courses[$courseid], $forums[$forumid], 0, $modcontext, "u.*")) {
                      foreach ($subusers as $postuser) {
 -                        unset($postuser->description); // not necessary
                          // this user is subscribed to this forum
                          $subscribedusers[$forumid][$postuser->id] = $postuser->id;
 -                        // this user is a user we have to process later
 -                        $users[$postuser->id] = $postuser;
 +                        $userscount++;
 +                        if ($userscount > FORUM_CRON_USER_CACHE) {
 +                            // Store minimal user info.
 +                            $minuser = new stdClass();
 +                            $minuser->id = $postuser->id;
 +                            $users[$postuser->id] = $minuser;
 +                        } else {
 +                            // Cache full user record.
 +                            forum_cron_minimise_user_record($postuser);
 +                            $users[$postuser->id] = $postuser;
 +                        }
                      }
 -                    unset($subusers); // release memory
 +                    // Release memory.
 +                    unset($subusers);
 +                    unset($postuser);
                  }
              }
  
  
              @set_time_limit(120); // terminate if processing of any account takes longer than 2 minutes
  
 -            // set this so that the capabilities are cached, and environment matches receiving user
 -            cron_setup_user($userto);
 -
              mtrace('Processing user '.$userto->id);
  
 -            // init caches
 +            // Init user caches - we keep the cache for one cycle only,
 +            // otherwise it could consume too much memory.
 +            if (isset($userto->username)) {
 +                $userto = clone($userto);
 +            } else {
 +                $userto = $DB->get_record('user', array('id' => $userto->id));
 +                forum_cron_minimise_user_record($userto);
 +            }
              $userto->viewfullnames = array();
              $userto->canpost       = array();
              $userto->markposts     = array();
  
 +            // set this so that the capabilities are cached, and environment matches receiving user
 +            cron_setup_user($userto);
 +
              // reset the caches
              foreach ($coursemodules as $forumid=>$unused) {
                  $coursemodules[$forumid]->cache       = new stdClass();
                  // Get info about the sending user
                  if (array_key_exists($post->userid, $users)) { // we might know him/her already
                      $userfrom = $users[$post->userid];
 +                    if (!isset($userfrom->idnumber)) {
 +                        // Minimalised user info, fetch full record.
 +                        $userfrom = $DB->get_record('user', array('id' => $userfrom->id));
 +                        forum_cron_minimise_user_record($userfrom);
 +                    }
 +
                  } else if ($userfrom = $DB->get_record('user', array('id' => $post->userid))) {
 -                    unset($userfrom->description); // not necessary
 -                    $users[$userfrom->id] = $userfrom; // fetch only once, we can add it to user list, it will be skipped anyway
 +                    forum_cron_minimise_user_record($userfrom);
 +                    // Fetch only once if possible, we can add it to user list, it will be skipped anyway.
 +                    if ($userscount <= FORUM_CRON_USER_CACHE) {
 +                        $userscount++;
 +                        $users[$userfrom->id] = $userfrom;
 +                    }
 +
                  } else {
                      mtrace('Could not find user '.$post->userid);
                      continue;
                  if (!isset($userfrom->groups[$forum->id])) {
                      if (!isset($userfrom->groups)) {
                          $userfrom->groups = array();
 -                        $users[$userfrom->id]->groups = array();
 +                        if (isset($users[$userfrom->id])) {
 +                            $users[$userfrom->id]->groups = array();
 +                        }
                      }
                      $userfrom->groups[$forum->id] = groups_get_all_groups($course->id, $userfrom->id, $cm->groupingid);
 -                    $users[$userfrom->id]->groups[$forum->id] = $userfrom->groups[$forum->id];
 +                    if (isset($users[$userfrom->id])) {
 +                        $users[$userfrom->id]->groups[$forum->id] = $userfrom->groups[$forum->id];
 +                    }
                  }
  
                  // Make sure groups allow this user to see this email
  
              // mark processed posts as read
              forum_tp_mark_posts_read($userto, $userto->markposts);
 +            unset($userto);
          }
      }
  
              $userdiscussions = array();
  
              foreach ($digestposts_rs as $digestpost) {
 -                if (!isset($users[$digestpost->userid])) {
 -                    if ($user = $DB->get_record('user', array('id' => $digestpost->userid))) {
 -                        $users[$digestpost->userid] = $user;
 -                    } else {
 -                        continue;
 -                    }
 -                }
 -                $postuser = $users[$digestpost->userid];
 -
                  if (!isset($posts[$digestpost->postid])) {
                      if ($post = $DB->get_record('forum_posts', array('id' => $digestpost->postid))) {
                          $posts[$digestpost->postid] = $post;
  
                  // First of all delete all the queue entries for this user
                  $DB->delete_records_select('forum_queue', "userid = ? AND timemodified < ?", array($userid, $digesttime));
 -                $userto = $users[$userid];
  
 -                // Override the language and timezone of the "current" user, so that
 -                // mail is customised for the receiver.
 -                cron_setup_user($userto);
 -
 -                // init caches
 +                // Init user caches - we keep the cache for one cycle only,
 +                // otherwise it would unnecessarily consume memory.
 +                if (array_key_exists($userid, $users) and isset($users[$userid]->username)) {
 +                    $userto = clone($users[$userid]);
 +                } else {
 +                    $userto = $DB->get_record('user', array('id' => $userid));
 +                    forum_cron_minimise_user_record($userto);
 +                }
                  $userto->viewfullnames = array();
                  $userto->canpost       = array();
                  $userto->markposts     = array();
  
 +                // Override the language and timezone of the "current" user, so that
 +                // mail is customised for the receiver.
 +                cron_setup_user($userto);
 +
                  $postsubject = get_string('digestmailsubject', 'forum', format_string($site->shortname, true));
  
                  $headerdata = new stdClass();
  
                          if (array_key_exists($post->userid, $users)) { // we might know him/her already
                              $userfrom = $users[$post->userid];
 +                            if (!isset($userfrom->idnumber)) {
 +                                $userfrom = $DB->get_record('user', array('id' => $userfrom->id));
 +                                forum_cron_minimise_user_record($userfrom);
 +                            }
 +
                          } else if ($userfrom = $DB->get_record('user', array('id' => $post->userid))) {
 -                            $users[$userfrom->id] = $userfrom; // fetch only once, we can add it to user list, it will be skipped anyway
 +                            forum_cron_minimise_user_record($userfrom);
 +                            if ($userscount <= FORUM_CRON_USER_CACHE) {
 +                                $userscount++;
 +                                $users[$userfrom->id] = $userfrom;
 +                            }
 +
                          } else {
                              mtrace('Could not find user '.$post->userid);
                              continue;
                          if (!isset($userfrom->groups[$forum->id])) {
                              if (!isset($userfrom->groups)) {
                                  $userfrom->groups = array();
 -                                $users[$userfrom->id]->groups = array();
 +                                if (isset($users[$userfrom->id])) {
 +                                    $users[$userfrom->id]->groups = array();
 +                                }
                              }
                              $userfrom->groups[$forum->id] = groups_get_all_groups($course->id, $userfrom->id, $cm->groupingid);
 -                            $users[$userfrom->id]->groups[$forum->id] = $userfrom->groups[$forum->id];
 +                            if (isset($users[$userfrom->id])) {
 +                                $users[$userfrom->id]->groups[$forum->id] = $userfrom->groups[$forum->id];
 +                            }
                          }
  
                          $userfrom->customheaders = array ("Precedence: Bulk");
@@@ -1380,8 -1306,6 +1380,6 @@@ function forum_print_overview($courses,
      }
  
      $strforum = get_string('modulename','forum');
-     $strnumunread = get_string('overviewnumunread','forum');
-     $strnumpostssince = get_string('overviewnumpostssince','forum');
  
      foreach ($forums as $forum) {
          $str = '';
              $str .= '<div class="overview forum"><div class="name">'.$strforum.': <a title="'.$strforum.'" href="'.$CFG->wwwroot.'/mod/forum/view.php?f='.$forum->id.'">'.
                  $forum->name.'</a></div>';
              $str .= '<div class="info"><span class="postsincelogin">';
-             $str .= $count.' '.$strnumpostssince."</span>";
+             $str .= get_string('overviewnumpostssince', 'forum', $count)."</span>";
              if (!empty($showunread)) {
-                 $str .= '<div class="unreadposts">'.$thisunread .' '.$strnumunread.'</div>';
+                 $str .= '<div class="unreadposts">'.get_string('overviewnumunread', 'forum', $thisunread).'</div>';
              }
              $str .= '</div></div>';
          }
@@@ -3985,7 -3909,7 +3983,7 @@@ function forum_print_attachments($post
          foreach ($files as $file) {
              $filename = $file->get_filename();
              $mimetype = $file->get_mimetype();
 -            $iconimage = '<img src="'.$OUTPUT->pix_url(file_mimetype_icon($mimetype)).'" class="icon" alt="'.$mimetype.'" />';
 +            $iconimage = $OUTPUT->pix_icon(file_file_icon($file), get_mimetype_description($file), 'moodle', array('class' => 'icon'));
              $path = file_encode_url($CFG->wwwroot.'/pluginfile.php', '/'.$context->id.'/mod_forum/attachment/'.$post->id.'/'.$filename);
  
              if ($type == 'html') {