[ Index ]

PHP Cross Reference of moodle-2.8

title

Body

[close]

/lib/classes/message/ -> manager.php (source)

   1  <?php
   2  // This file is part of Moodle - http://moodle.org/
   3  //
   4  // Moodle is free software: you can redistribute it and/or modify
   5  // it under the terms of the GNU General Public License as published by
   6  // the Free Software Foundation, either version 3 of the License, or
   7  // (at your option) any later version.
   8  //
   9  // Moodle is distributed in the hope that it will be useful,
  10  // but WITHOUT ANY WARRANTY; without even the implied warranty of
  11  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12  // GNU General Public License for more details.
  13  //
  14  // You should have received a copy of the GNU General Public License
  15  // along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
  16  
  17  /**
  18   * New messaging manager class.
  19   *
  20   * @package   core_message
  21   * @since     Moodle 2.8
  22   * @copyright 2014 Totara Learning Solutions Ltd {@link http://www.totaralms.com/}
  23   * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  24   * @author    Petr Skoda <[email protected]>
  25   */
  26  
  27  namespace core\message;
  28  
  29  defined('MOODLE_INTERNAL') || die();
  30  
  31  /**
  32   * Class used for various messaging related stuff.
  33   *
  34   * Note: Do NOT use directly in your code, it is intended to be used from core code only.
  35   *
  36   * @access private
  37   *
  38   * @package   core_message
  39   * @since     Moodle 2.8
  40   * @copyright 2014 Totara Learning Solutions Ltd {@link http://www.totaralms.com/}
  41   * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  42   * @author    Petr Skoda <[email protected]>
  43   */
  44  class manager {
  45      /** @var array buffer of pending messages */
  46      protected static $buffer = array();
  47  
  48      /**
  49       * Do the message sending.
  50       *
  51       * NOTE: to be used from message_send() only.
  52       *
  53       * @param \stdClass $eventdata fully prepared event data for processors
  54       * @param \stdClass $savemessage the message saved in 'message' table
  55       * @param array $processorlist list of processors for target user
  56       * @return int $messageid the id from 'message' or 'message_read' table (false is not returned)
  57       */
  58      public static function send_message(\stdClass $eventdata, \stdClass $savemessage, array $processorlist) {
  59          global $CFG;
  60          require_once($CFG->dirroot.'/message/lib.php'); // This is most probably already included from messagelib.php file.
  61  
  62          if (empty($processorlist)) {
  63              // Trigger event for sending a message - we need to do this before marking as read!
  64              \core\event\message_sent::create_from_ids($eventdata->userfrom->id, $eventdata->userto->id, $savemessage->id)->trigger();
  65  
  66              if ($savemessage->notification or empty($CFG->messaging)) {
  67                  // If they have deselected all processors and its a notification mark it read. The user doesn't want to be bothered.
  68                  // The same goes if the messaging is completely disabled.
  69                  // We cannot insert directly to the message_read table because we want to get all events in proper order!
  70                  $messageid = message_mark_message_read($savemessage, time(), true);
  71  
  72              } else {
  73                  // Just add it to the list of unread messages, there is no way it could be delivered to them,
  74                  // but they can read it via the messaging UI later.
  75                  $messageid = $savemessage->id;
  76              }
  77  
  78              return $messageid;
  79          }
  80  
  81          // Let the manager do the sending or buffering when db transaction in progress.
  82          return self::send_message_to_processors($eventdata, $savemessage, $processorlist);
  83      }
  84  
  85      /**
  86       * Send message to message processors.
  87       *
  88       * @param \stdClass $eventdata
  89       * @param \stdClass $savemessage
  90       * @param array $processorlist
  91       * @return int $messageid
  92       */
  93      protected static function send_message_to_processors(\stdClass $eventdata, \stdClass $savemessage, array $processorlist) {
  94          global $CFG, $DB;
  95  
  96          // We cannot communicate with external systems in DB transactions,
  97          // buffer the messages if necessary.
  98  
  99          if ($DB->is_transaction_started()) {
 100              // We need to clone all objects so that devs may not modify it from outside later.
 101              $eventdata = clone($eventdata);
 102              $eventdata->userto = clone($eventdata->userto);
 103              $eventdata->userfrom = clone($eventdata->userfrom);
 104  
 105              // Conserve some memory the same was as $USER setup does.
 106              unset($eventdata->userto->description);
 107              unset($eventdata->userfrom->description);
 108  
 109              self::$buffer[] = array($eventdata, $savemessage, $processorlist);
 110              return $savemessage->id;
 111          }
 112  
 113          $processors = get_message_processors(true);
 114  
 115          $failed = false;
 116          foreach ($processorlist as $procname) {
 117              if (!$processors[$procname]->object->send_message($eventdata)) {
 118                  debugging('Error calling message processor ' . $procname);
 119                  $failed = true;
 120                  // Previously the $messageid = false here was overridden
 121                  // by other processors and message_mark_message_read() below.
 122              }
 123          }
 124  
 125          // Trigger event for sending a message - must be done before marking as read.
 126          \core\event\message_sent::create_from_ids($eventdata->userfrom->id, $eventdata->userto->id, $savemessage->id)->trigger();
 127  
 128          if (empty($CFG->messaging)) {
 129              // If messaging is disabled and they previously had forum notifications handled by the popup processor
 130              // or any processor that puts a row in message_working then the notification will remain forever
 131              // unread. To prevent this mark the message read if messaging is disabled.
 132              $messageid = message_mark_message_read($savemessage, time());
 133  
 134          } else if ($failed) {
 135              // Something failed, better keep it as unread then.
 136              $messageid = $savemessage->id;
 137  
 138          } else if ($DB->count_records('message_working', array('unreadmessageid' => $savemessage->id)) == 0) {
 139              // If there is no more processors that want to process this we can move message to message_read.
 140              $messageid = message_mark_message_read($savemessage, time(), true);
 141  
 142          } else {
 143              // Some processor is still working on the data, let's keep it unread.
 144              $messageid = $savemessage->id;
 145          }
 146  
 147          return $messageid;
 148      }
 149  
 150      /**
 151       * Notification from DML layer.
 152       *
 153       * Note: to be used from DML layer only.
 154       */
 155      public static function database_transaction_commited() {
 156          if (!self::$buffer) {
 157              return;
 158          }
 159          self::process_buffer();
 160      }
 161  
 162      /**
 163       * Notification from DML layer.
 164       *
 165       * Note: to be used from DML layer only.
 166       */
 167      public static function database_transaction_rolledback() {
 168          self::$buffer = array();
 169      }
 170  
 171      /**
 172       * Sent out any buffered messages if necessary.
 173       */
 174      protected static function process_buffer() {
 175          // Reset the buffer first in case we get exception from processor.
 176          $messages = self::$buffer;
 177          self::$buffer = array();
 178  
 179          foreach ($messages as $message) {
 180              list($eventdata, $savemessage, $processorlist) = $message;
 181              self::send_message_to_processors($eventdata, $savemessage, $processorlist);
 182          }
 183      }
 184  }


Generated: Fri Nov 28 20:29:05 2014 Cross-referenced by PHPXref 0.7.1