[ Index ] |
PHP Cross Reference of Unnamed Project |
[Summary view] [Print] [Text view]
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 <petr.skoda@totaralms.com> 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 <petr.skoda@totaralms.com> 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|\core\message\message $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($eventdata, \stdClass $savemessage, array $processorlist) { 59 global $CFG; 60 61 if (!($eventdata instanceof \stdClass) && !($eventdata instanceof message)) { 62 // Not a valid object. 63 throw new \coding_exception('Message should be of type stdClass or \core\message\message'); 64 } 65 66 require_once($CFG->dirroot.'/message/lib.php'); // This is most probably already included from messagelib.php file. 67 68 if (empty($processorlist)) { 69 // Trigger event for sending a message - we need to do this before marking as read! 70 \core\event\message_sent::create_from_ids($eventdata->userfrom->id, $eventdata->userto->id, $savemessage->id)->trigger(); 71 72 if ($savemessage->notification or empty($CFG->messaging)) { 73 // If they have deselected all processors and its a notification mark it read. The user doesn't want to be bothered. 74 // The same goes if the messaging is completely disabled. 75 // We cannot insert directly to the message_read table because we want to get all events in proper order! 76 $messageid = message_mark_message_read($savemessage, time(), true); 77 78 } else { 79 // Just add it to the list of unread messages, there is no way it could be delivered to them, 80 // but they can read it via the messaging UI later. 81 $messageid = $savemessage->id; 82 } 83 84 return $messageid; 85 } 86 87 // Let the manager do the sending or buffering when db transaction in progress. 88 return self::send_message_to_processors($eventdata, $savemessage, $processorlist); 89 } 90 91 /** 92 * Send message to message processors. 93 * 94 * @param \stdClass|\core\message\message $eventdata 95 * @param \stdClass $savemessage 96 * @param array $processorlist 97 * @return int $messageid 98 */ 99 protected static function send_message_to_processors($eventdata, \stdClass $savemessage, array 100 $processorlist) { 101 global $CFG, $DB; 102 103 // We cannot communicate with external systems in DB transactions, 104 // buffer the messages if necessary. 105 106 if ($DB->is_transaction_started()) { 107 // We need to clone all objects so that devs may not modify it from outside later. 108 $eventdata = clone($eventdata); 109 $eventdata->userto = clone($eventdata->userto); 110 $eventdata->userfrom = clone($eventdata->userfrom); 111 112 // Conserve some memory the same was as $USER setup does. 113 unset($eventdata->userto->description); 114 unset($eventdata->userfrom->description); 115 116 self::$buffer[] = array($eventdata, $savemessage, $processorlist); 117 return $savemessage->id; 118 } 119 120 $processors = get_message_processors(true); 121 122 $failed = false; 123 foreach ($processorlist as $procname) { 124 // Let new messaging class add custom content based on the processor. 125 $proceventdata = ($eventdata instanceof message) ? $eventdata->get_eventobject_for_processor($procname) : $eventdata; 126 if (!$processors[$procname]->object->send_message($proceventdata)) { 127 debugging('Error calling message processor ' . $procname); 128 $failed = true; 129 // Previously the $messageid = false here was overridden 130 // by other processors and message_mark_message_read() below. 131 } 132 } 133 134 // Trigger event for sending a message - must be done before marking as read. 135 \core\event\message_sent::create_from_ids($eventdata->userfrom->id, $eventdata->userto->id, $savemessage->id)->trigger(); 136 137 if (empty($CFG->messaging)) { 138 // If messaging is disabled and they previously had forum notifications handled by the popup processor 139 // or any processor that puts a row in message_working then the notification will remain forever 140 // unread. To prevent this mark the message read if messaging is disabled. 141 $messageid = message_mark_message_read($savemessage, time()); 142 143 } else if ($failed) { 144 // Something failed, better keep it as unread then. 145 $messageid = $savemessage->id; 146 147 } else if ($DB->count_records('message_working', array('unreadmessageid' => $savemessage->id)) == 0) { 148 // If there is no more processors that want to process this we can move message to message_read. 149 $messageid = message_mark_message_read($savemessage, time(), true); 150 151 } else { 152 // Some processor is still working on the data, let's keep it unread. 153 $messageid = $savemessage->id; 154 } 155 156 return $messageid; 157 } 158 159 /** 160 * Notification from DML layer. 161 * 162 * Note: to be used from DML layer only. 163 */ 164 public static function database_transaction_commited() { 165 if (!self::$buffer) { 166 return; 167 } 168 self::process_buffer(); 169 } 170 171 /** 172 * Notification from DML layer. 173 * 174 * Note: to be used from DML layer only. 175 */ 176 public static function database_transaction_rolledback() { 177 self::$buffer = array(); 178 } 179 180 /** 181 * Sent out any buffered messages if necessary. 182 */ 183 protected static function process_buffer() { 184 // Reset the buffer first in case we get exception from processor. 185 $messages = self::$buffer; 186 self::$buffer = array(); 187 188 foreach ($messages as $message) { 189 list($eventdata, $savemessage, $processorlist) = $message; 190 self::send_message_to_processors($eventdata, $savemessage, $processorlist); 191 } 192 } 193 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Thu Aug 11 10:00:09 2016 | Cross-referenced by PHPXref 0.7.1 |