Commit | Line | Data |
---|---|---|
349f98ad PS |
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 | ||
b30f4d6d JD |
48 | /** @var array buffer of pending messages to conversations */ |
49 | protected static $convmessagebuffer = array(); | |
50 | ||
9581bc3c JD |
51 | /** |
52 | * Used for calling processors, and generating event data when sending a message to a conversation. | |
53 | * | |
54 | * This is ONLY used for messages of type 'message' (notification=0), and is responsible for: | |
55 | * | |
56 | * 1. generation of per-user event data (to pass to processors) | |
57 | * 2. generation of the processors for each recipient member of the conversation | |
58 | * 3. calling said processors for each member, passing in the per-user (local) eventdata. | |
59 | * 4. generation of an appropriate event for the message send, depending on the conversation type | |
60 | * - messages to individual conversations generate a 'message_sent' event (as per legacy send_message()) | |
61 | * - messages to group conversations generate a 'group_message_sent' event. | |
62 | * | |
63 | * @param message $eventdata | |
64 | * @param \stdClass $savemessage | |
65 | * @return int | |
66 | */ | |
67 | public static function send_message_to_conversation(message $eventdata, \stdClass $savemessage) : int { | |
68 | global $DB, $CFG, $SITE; | |
69 | ||
70 | if (empty($eventdata->convid)) { | |
71 | throw new \moodle_exception("Message is not being sent to a conversation. Please check event data."); | |
72 | } | |
73 | ||
74 | // Fetch default (site) preferences. | |
75 | $defaultpreferences = get_message_output_default_preferences(); | |
76 | $preferencebase = $eventdata->component.'_'.$eventdata->name; | |
77 | ||
78 | // Because we're dealing with multiple recipients, we need to send a localised (per-user) version of the eventdata to each | |
79 | // processor, because of things like the language-specific subject. We're going to modify this, for each recipient member. | |
80 | // Any time we're modifying the event data here, we should be using the localised version. | |
81 | // This localised version is based on the generic event data, but we should keep that object intact, so we clone it. | |
82 | $localisedeventdata = clone $eventdata; | |
83 | ||
84 | // Get user records for all members of the conversation. | |
ad5de40c JD |
85 | // We must fetch distinct users, because it's possible for a user to message themselves via bulk user actions. |
86 | // In such cases, there will be 2 records referring to the same user. | |
5e600f7c | 87 | $sql = "SELECT u.*, mca.id as ismuted |
ad5de40c | 88 | FROM {user} u |
5e600f7c MN |
89 | LEFT JOIN {message_conversation_actions} mca |
90 | ON mca.userid = u.id AND mca.conversationid = ? AND mca.action = ? | |
ad5de40c JD |
91 | WHERE u.id IN ( |
92 | SELECT mcm.userid FROM {message_conversation_members} mcm | |
5e600f7c | 93 | WHERE mcm.conversationid = ? |
ad5de40c | 94 | )"; |
5e600f7c MN |
95 | $members = $DB->get_records_sql($sql, [$eventdata->convid, \core_message\api::CONVERSATION_ACTION_MUTED, |
96 | $eventdata->convid]); | |
9581bc3c JD |
97 | if (empty($members)) { |
98 | throw new \moodle_exception("Conversation has no members or does not exist."); | |
99 | } | |
100 | ||
101 | if (!is_object($localisedeventdata->userfrom)) { | |
102 | $localisedeventdata->userfrom = $members[$localisedeventdata->userfrom]; | |
103 | } | |
104 | ||
105 | // This should now hold only the other users (recipients). | |
106 | unset($members[$localisedeventdata->userfrom->id]); | |
107 | $otherusers = $members; | |
108 | ||
109 | // Get conversation type and name. We'll use this to determine which message subject to generate, depending on type. | |
110 | $conv = $DB->get_record('message_conversations', ['id' => $eventdata->convid], 'id, type, name'); | |
111 | ||
734b198f SA |
112 | // For now Self conversations are not processed because users are aware of the messages sent by themselves, so we |
113 | // can return early. | |
114 | if ($conv->type == \core_message\api::MESSAGE_CONVERSATION_TYPE_SELF) { | |
115 | return $savemessage->id; | |
116 | } | |
ca754fc8 | 117 | $localisedeventdata->conversationtype = $conv->type; |
734b198f | 118 | |
9581bc3c JD |
119 | // We treat individual conversations the same as any direct message with 'userfrom' and 'userto' specified. |
120 | // We know the other user, so set the 'userto' field so that the event code will get access to this field. | |
121 | // If this was a legacy caller (eventdata->userto is set), then use that instead, as we want to use the fields specified | |
122 | // in that object instead of using one fetched from the DB. | |
123 | $legacymessage = false; | |
124 | if ($conv->type == \core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL) { | |
125 | if (isset($eventdata->userto)) { | |
126 | $legacymessage = true; | |
127 | } else { | |
128 | $otheruser = reset($otherusers); | |
129 | $eventdata->userto = $otheruser; | |
130 | } | |
131 | } | |
132 | ||
133 | // Fetch enabled processors. | |
134 | // If we are dealing with a message some processors may want to handle it regardless of user and site settings. | |
135 | $processors = array_filter(get_message_processors(false), function($processor) { | |
136 | if ($processor->object->force_process_messages()) { | |
137 | return true; | |
138 | } | |
139 | ||
140 | return ($processor->enabled && $processor->configured); | |
141 | }); | |
142 | ||
143 | // For each member of the conversation, other than the sender: | |
144 | // 1. Set recipient specific event data (language specific, user prefs, etc) | |
145 | // 2. Generate recipient specific processor list | |
146 | // 3. Call send_message() to pass the message to processors and generate the relevant per-user events. | |
147 | $eventprocmaps = []; // Init the event/processors buffer. | |
148 | foreach ($otherusers as $recipient) { | |
149 | // If this message was a legacy (1:1) message, then we use the userto. | |
150 | if ($legacymessage) { | |
5e600f7c MN |
151 | $ismuted = $recipient->ismuted; |
152 | ||
9581bc3c | 153 | $recipient = $eventdata->userto; |
5e600f7c | 154 | $recipient->ismuted = $ismuted; |
9581bc3c JD |
155 | } |
156 | ||
157 | $usertoisrealuser = (\core_user::is_real_user($recipient->id) != false); | |
158 | ||
159 | // Using string manager directly so that strings in the message will be in the message recipients language rather than | |
160 | // the sender's. | |
161 | if ($conv->type == \core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL) { | |
162 | $localisedeventdata->subject = get_string_manager()->get_string('unreadnewmessage', 'message', | |
163 | fullname($localisedeventdata->userfrom), $recipient->lang); | |
164 | } else if ($conv->type == \core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP) { | |
165 | $stringdata = (object) ['name' => fullname($localisedeventdata->userfrom), 'conversationname' => $conv->name]; | |
166 | $localisedeventdata->subject = get_string_manager()->get_string('unreadnewgroupconversationmessage', 'message', | |
167 | $stringdata, $recipient->lang); | |
168 | } | |
169 | ||
170 | // Spoof the userto based on the current member id. | |
171 | $localisedeventdata->userto = $recipient; | |
36fa0ec9 JL |
172 | // Check if the notification is including images that will need a user token to be displayed outside Moodle. |
173 | if (!empty($localisedeventdata->customdata)) { | |
174 | $customdata = json_decode($localisedeventdata->customdata); | |
175 | if (is_object($customdata) && !empty($customdata->notificationiconurl)) { | |
176 | $customdata->tokenpluginfile = get_user_key('core_files', $localisedeventdata->userto->id); | |
177 | $localisedeventdata->customdata = $customdata; // Message class will JSON encode again. | |
178 | } | |
179 | } | |
9581bc3c JD |
180 | |
181 | $s = new \stdClass(); | |
182 | $s->sitename = format_string($SITE->shortname, true, array('context' => \context_course::instance(SITEID))); | |
e84312f7 | 183 | $s->url = $CFG->wwwroot.'/message/index.php?id='.$eventdata->userfrom->id; |
9581bc3c JD |
184 | $emailtagline = get_string_manager()->get_string('emailtagline', 'message', $s, $recipient->lang); |
185 | ||
186 | $localisedeventdata->fullmessage = $eventdata->fullmessage; | |
187 | $localisedeventdata->fullmessagehtml = $eventdata->fullmessagehtml; | |
188 | if (!empty($localisedeventdata->fullmessage)) { | |
9aa5f7fe | 189 | // Prevent unclosed HTML elements. |
190 | $localisedeventdata->fullmessage = | |
191 | \core_message\helper::prevent_unclosed_html_tags($localisedeventdata->fullmessage, true); | |
192 | ||
9581bc3c JD |
193 | $localisedeventdata->fullmessage .= "\n\n---------------------------------------------------------------------\n" |
194 | . $emailtagline; | |
195 | } | |
196 | if (!empty($localisedeventdata->fullmessagehtml)) { | |
9aa5f7fe | 197 | // Prevent unclosed HTML elements. |
198 | $localisedeventdata->fullmessagehtml = | |
199 | \core_message\helper::prevent_unclosed_html_tags($localisedeventdata->fullmessagehtml, true); | |
200 | ||
9581bc3c JD |
201 | $localisedeventdata->fullmessagehtml .= |
202 | "<br><br>---------------------------------------------------------------------<br>" . $emailtagline; | |
203 | } | |
204 | ||
205 | // If recipient is internal user (noreply user), and emailstop is set then don't send any msg. | |
206 | if (!$usertoisrealuser && !empty($recipient->emailstop)) { | |
207 | debugging('Attempt to send msg to internal (noreply) user', DEBUG_NORMAL); | |
208 | return false; | |
209 | } | |
210 | ||
9581bc3c | 211 | // Fill in the array of processors to be used based on default and user preferences. |
5e600f7c | 212 | // Do not process muted conversations. |
9581bc3c | 213 | $processorlist = []; |
c210455a | 214 | if (!$recipient->ismuted) { |
267b4f03 JD |
215 | foreach ($processors as $processor) { |
216 | // Skip adding processors for internal user, if processor doesn't support sending message to internal user. | |
217 | if (!$usertoisrealuser && !$processor->object->can_send_to_any_users()) { | |
218 | continue; | |
219 | } | |
9581bc3c | 220 | |
267b4f03 | 221 | // First find out permissions. |
d74bd798 PFO |
222 | $defaultlockedpreference = $processor->name . '_provider_' . $preferencebase . '_locked'; |
223 | $locked = false; | |
224 | if (isset($defaultpreferences->{$defaultlockedpreference})) { | |
225 | $locked = $defaultpreferences->{$defaultlockedpreference}; | |
267b4f03 JD |
226 | } else { |
227 | // MDL-25114 They supplied an $eventdata->component $eventdata->name combination which doesn't | |
228 | // exist in the message_provider table (thus there is no default settings for them). | |
d74bd798 PFO |
229 | $preferrormsg = "Could not load preference $defaultlockedpreference. |
230 | Make sure the component and name you supplied to message_send() are valid."; | |
3a352b40 | 231 | throw new \coding_exception($preferrormsg); |
267b4f03 | 232 | } |
9581bc3c | 233 | |
d74bd798 PFO |
234 | $enabledpreference = 'message_provider_'.$preferencebase . '_enabled'; |
235 | $forced = false; | |
236 | if ($locked && isset($defaultpreferences->{$enabledpreference})) { | |
237 | $forced = $defaultpreferences->{$enabledpreference}; | |
238 | } | |
239 | ||
267b4f03 JD |
240 | // Find out if user has configured this output. |
241 | // Some processors cannot function without settings from the user. | |
242 | $userisconfigured = $processor->object->is_user_configured($recipient); | |
9581bc3c | 243 | |
267b4f03 | 244 | // DEBUG: notify if we are forcing unconfigured output. |
d74bd798 | 245 | if ($forced && !$userisconfigured) { |
267b4f03 JD |
246 | debugging('Attempt to force message delivery to user who has "' . $processor->name . |
247 | '" output unconfigured', DEBUG_NORMAL); | |
248 | } | |
9581bc3c | 249 | |
267b4f03 JD |
250 | // Populate the list of processors we will be using. |
251 | if (!$eventdata->notification && $processor->object->force_process_messages()) { | |
252 | $processorlist[] = $processor->name; | |
d74bd798 | 253 | } else if ($forced && $userisconfigured) { |
267b4f03 JD |
254 | // An admin is forcing users to use this message processor. Use this processor unconditionally. |
255 | $processorlist[] = $processor->name; | |
d74bd798 | 256 | } else if (!$locked && $userisconfigured && !$recipient->emailstop) { |
267b4f03 JD |
257 | // User has not disabled notifications. |
258 | // See if user set any notification preferences, otherwise use site default ones. | |
d74bd798 | 259 | $userpreferencename = 'message_provider_' . $preferencebase . '_enabled'; |
267b4f03 JD |
260 | if ($userpreference = get_user_preferences($userpreferencename, null, $recipient)) { |
261 | if (in_array($processor->name, explode(',', $userpreference))) { | |
262 | $processorlist[] = $processor->name; | |
263 | } | |
264 | } else if (isset($defaultpreferences->{$userpreferencename})) { | |
265 | if (in_array($processor->name, explode(',', $defaultpreferences->{$userpreferencename}))) { | |
266 | $processorlist[] = $processor->name; | |
267 | } | |
9581bc3c JD |
268 | } |
269 | } | |
270 | } | |
271 | } | |
b30f4d6d JD |
272 | // Batch up the localised event data and processor list for all users into a local buffer. |
273 | $eventprocmaps[] = [clone($localisedeventdata), $processorlist]; | |
9581bc3c | 274 | } |
b30f4d6d JD |
275 | // Then pass it off as one item of work, to be processed by send_conversation_message_to_processors(), which will |
276 | // handle all transaction buffering logic. | |
277 | self::send_conversation_message_to_processors($eventprocmaps, $eventdata, $savemessage); | |
9581bc3c JD |
278 | |
279 | return $savemessage->id; | |
280 | } | |
281 | ||
b30f4d6d JD |
282 | /** |
283 | * Takes a list of localised event data, and tries to send them to their respective member's message processors. | |
284 | * | |
285 | * Input format: | |
286 | * [CONVID => [$localisedeventdata, $savemessage, $processorlist], ]. | |
287 | * | |
288 | * @param array $eventprocmaps the array of localised event data and processors for each member of the conversation. | |
289 | * @param message $eventdata the original conversation message eventdata | |
290 | * @param \stdClass $savemessage the saved message record. | |
291 | * @throws \coding_exception | |
292 | */ | |
293 | protected static function send_conversation_message_to_processors(array $eventprocmaps, message $eventdata, | |
294 | \stdClass $savemessage) { | |
295 | global $DB; | |
296 | ||
297 | // We cannot communicate with external systems in DB transactions, | |
298 | // buffer the messages if necessary. | |
299 | if ($DB->is_transaction_started()) { | |
300 | // Buffer this group conversation message and it's record. | |
301 | self::$convmessagebuffer[] = [$eventprocmaps, $eventdata, $savemessage]; | |
302 | return; | |
303 | } | |
304 | ||
305 | // Send each localised version of the event data to each member's respective processors. | |
306 | foreach ($eventprocmaps as $eventprocmap) { | |
307 | $eventdata = $eventprocmap[0]; | |
308 | $processorlist = $eventprocmap[1]; | |
309 | self::call_processors($eventdata, $processorlist); | |
310 | } | |
311 | ||
312 | // Trigger event for sending a message or notification - we need to do this before marking as read! | |
313 | self::trigger_message_events($eventdata, $savemessage); | |
314 | } | |
315 | ||
349f98ad PS |
316 | /** |
317 | * Do the message sending. | |
318 | * | |
319 | * NOTE: to be used from message_send() only. | |
320 | * | |
cc350fd9 | 321 | * @param \core\message\message $eventdata fully prepared event data for processors |
349f98ad PS |
322 | * @param \stdClass $savemessage the message saved in 'message' table |
323 | * @param array $processorlist list of processors for target user | |
883ce421 | 324 | * @return int $messageid the id from 'messages' (false is not returned) |
349f98ad | 325 | */ |
cc4952e9 | 326 | public static function send_message(message $eventdata, \stdClass $savemessage, array $processorlist) { |
349f98ad | 327 | global $CFG; |
c6f45ef8 | 328 | |
349f98ad PS |
329 | require_once($CFG->dirroot.'/message/lib.php'); // This is most probably already included from messagelib.php file. |
330 | ||
331 | if (empty($processorlist)) { | |
376a79c2 | 332 | // Trigger event for sending a message or notification - we need to do this before marking as read! |
947d3289 | 333 | self::trigger_message_events($eventdata, $savemessage); |
349f98ad | 334 | |
1ccc7e66 TS |
335 | if ($eventdata->notification) { |
336 | // If they have deselected all processors and it's a notification mark it read. The user doesn't want to be | |
337 | // bothered. | |
338 | $savemessage->timeread = null; | |
339 | \core_message\api::mark_notification_as_read($savemessage); | |
340 | } else if (empty($CFG->messaging)) { | |
341 | // If it's a message and messaging is disabled mark it read. | |
342 | \core_message\api::mark_message_as_read($eventdata->userto->id, $savemessage); | |
349f98ad PS |
343 | } |
344 | ||
883ce421 | 345 | return $savemessage->id; |
349f98ad PS |
346 | } |
347 | ||
348 | // Let the manager do the sending or buffering when db transaction in progress. | |
349 | return self::send_message_to_processors($eventdata, $savemessage, $processorlist); | |
350 | } | |
351 | ||
352 | /** | |
353 | * Send message to message processors. | |
354 | * | |
c6f45ef8 | 355 | * @param \stdClass|\core\message\message $eventdata |
349f98ad PS |
356 | * @param \stdClass $savemessage |
357 | * @param array $processorlist | |
c66c2999 | 358 | * @throws \moodle_exception |
349f98ad PS |
359 | * @return int $messageid |
360 | */ | |
c6f45ef8 AA |
361 | protected static function send_message_to_processors($eventdata, \stdClass $savemessage, array |
362 | $processorlist) { | |
349f98ad PS |
363 | global $CFG, $DB; |
364 | ||
365 | // We cannot communicate with external systems in DB transactions, | |
366 | // buffer the messages if necessary. | |
349f98ad PS |
367 | if ($DB->is_transaction_started()) { |
368 | // We need to clone all objects so that devs may not modify it from outside later. | |
369 | $eventdata = clone($eventdata); | |
370 | $eventdata->userto = clone($eventdata->userto); | |
371 | $eventdata->userfrom = clone($eventdata->userfrom); | |
372 | ||
373 | // Conserve some memory the same was as $USER setup does. | |
374 | unset($eventdata->userto->description); | |
375 | unset($eventdata->userfrom->description); | |
376 | ||
377 | self::$buffer[] = array($eventdata, $savemessage, $processorlist); | |
378 | return $savemessage->id; | |
379 | } | |
380 | ||
947d3289 | 381 | // Send the message to processors. |
c66c2999 JB |
382 | if (!self::call_processors($eventdata, $processorlist)) { |
383 | throw new \moodle_exception("Message was not sent."); | |
384 | } | |
349f98ad | 385 | |
376a79c2 | 386 | // Trigger event for sending a message or notification - we need to do this before marking as read! |
947d3289 | 387 | self::trigger_message_events($eventdata, $savemessage); |
349f98ad | 388 | |
1ccc7e66 TS |
389 | if (!$eventdata->notification && empty($CFG->messaging)) { |
390 | // If it's a message and messaging is disabled mark it read. | |
391 | \core_message\api::mark_message_as_read($eventdata->userto->id, $savemessage); | |
349f98ad PS |
392 | } |
393 | ||
883ce421 | 394 | return $savemessage->id; |
349f98ad PS |
395 | } |
396 | ||
397 | /** | |
398 | * Notification from DML layer. | |
399 | * | |
400 | * Note: to be used from DML layer only. | |
401 | */ | |
402 | public static function database_transaction_commited() { | |
b30f4d6d | 403 | if (!self::$buffer && !self::$convmessagebuffer) { |
349f98ad PS |
404 | return; |
405 | } | |
406 | self::process_buffer(); | |
407 | } | |
408 | ||
409 | /** | |
410 | * Notification from DML layer. | |
411 | * | |
412 | * Note: to be used from DML layer only. | |
413 | */ | |
414 | public static function database_transaction_rolledback() { | |
415 | self::$buffer = array(); | |
9581bc3c | 416 | self::$convmessagebuffer = array(); |
349f98ad PS |
417 | } |
418 | ||
419 | /** | |
420 | * Sent out any buffered messages if necessary. | |
421 | */ | |
422 | protected static function process_buffer() { | |
b30f4d6d | 423 | // Reset the buffers first in case we get exception from processor. |
349f98ad PS |
424 | $messages = self::$buffer; |
425 | self::$buffer = array(); | |
b30f4d6d JD |
426 | $convmessages = self::$convmessagebuffer; |
427 | self::$convmessagebuffer = array(); | |
349f98ad PS |
428 | |
429 | foreach ($messages as $message) { | |
430 | list($eventdata, $savemessage, $processorlist) = $message; | |
431 | self::send_message_to_processors($eventdata, $savemessage, $processorlist); | |
432 | } | |
b30f4d6d JD |
433 | |
434 | foreach ($convmessages as $convmessage) { | |
435 | list($eventprocmap, $eventdata, $savemessage) = $convmessage; | |
436 | self::send_conversation_message_to_processors($eventprocmap, $eventdata, $savemessage); | |
437 | } | |
349f98ad | 438 | } |
947d3289 JD |
439 | |
440 | /** | |
441 | * Trigger an appropriate message creation event, based on the supplied $eventdata and $savemessage. | |
442 | * | |
443 | * @param message $eventdata the eventdata for the message. | |
444 | * @param \stdClass $savemessage the message record. | |
445 | * @throws \coding_exception | |
446 | */ | |
447 | protected static function trigger_message_events(message $eventdata, \stdClass $savemessage) { | |
9581bc3c | 448 | global $DB; |
947d3289 JD |
449 | if ($eventdata->notification) { |
450 | \core\event\notification_sent::create_from_ids( | |
451 | $eventdata->userfrom->id, | |
452 | $eventdata->userto->id, | |
453 | $savemessage->id, | |
454 | $eventdata->courseid | |
455 | )->trigger(); | |
456 | } else { // Must be a message. | |
9581bc3c JD |
457 | // If the message is a group conversation, then trigger the 'group_message_sent' event. |
458 | if ($eventdata->convid) { | |
459 | $conv = $DB->get_record('message_conversations', ['id' => $eventdata->convid], 'id, type'); | |
460 | if ($conv->type == \core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP) { | |
461 | \core\event\group_message_sent::create_from_ids( | |
462 | $eventdata->userfrom->id, | |
463 | $eventdata->convid, | |
464 | $savemessage->id, | |
465 | $eventdata->courseid | |
466 | )->trigger(); | |
467 | return; | |
468 | } | |
469 | // Individual type conversations fall through to the default 'message_sent' event. | |
470 | } | |
947d3289 JD |
471 | \core\event\message_sent::create_from_ids( |
472 | $eventdata->userfrom->id, | |
473 | $eventdata->userto->id, | |
474 | $savemessage->id, | |
475 | $eventdata->courseid | |
476 | )->trigger(); | |
477 | } | |
478 | } | |
479 | ||
480 | /** | |
481 | * For each processor, call it's send_message() method. | |
482 | * | |
483 | * @param message $eventdata the message object. | |
484 | * @param array $processorlist the list of processors for a single user. | |
c66c2999 | 485 | * @return bool false if error calling message processor |
947d3289 JD |
486 | */ |
487 | protected static function call_processors(message $eventdata, array $processorlist) { | |
5ba12283 JL |
488 | // Allow plugins to change the message/notification data before sending it. |
489 | $pluginsfunction = get_plugins_with_function('pre_processor_message_send'); | |
c66c2999 | 490 | $sendmsgsuccessful = true; |
947d3289 JD |
491 | foreach ($processorlist as $procname) { |
492 | // Let new messaging class add custom content based on the processor. | |
493 | $proceventdata = ($eventdata instanceof message) ? $eventdata->get_eventobject_for_processor($procname) : $eventdata; | |
5ba12283 JL |
494 | |
495 | if ($pluginsfunction) { | |
496 | foreach ($pluginsfunction as $plugintype => $plugins) { | |
497 | foreach ($plugins as $pluginfunction) { | |
498 | $pluginfunction($procname, $proceventdata); | |
499 | } | |
500 | } | |
501 | } | |
502 | ||
947d3289 JD |
503 | $stdproc = new \stdClass(); |
504 | $stdproc->name = $procname; | |
505 | $processor = \core_message\api::get_processed_processor_object($stdproc); | |
506 | if (!$processor->object->send_message($proceventdata)) { | |
507 | debugging('Error calling message processor ' . $procname); | |
c66c2999 | 508 | $sendmsgsuccessful = false; |
947d3289 JD |
509 | } |
510 | } | |
c66c2999 | 511 | return $sendmsgsuccessful; |
947d3289 | 512 | } |
349f98ad | 513 | } |