2 // This file is part of Moodle - http://moodle.org/
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.
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.
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/>.
18 * New messaging class.
20 * @package core_message
22 * @copyright 2015 onwards Ankit Agarwal
23 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
26 namespace core\message;
28 defined('MOODLE_INTERNAL') || die();
31 * New messaging class.
33 * Required parameters of the $eventdata object:
34 * component string Component name. must exist in message_providers
35 * name string Message type name. must exist in message_providers
36 * userfrom object|int The user sending the message
37 * userto object|int The message recipient. This is mandatory for NOTIFICACIONS and 1:1 personal messages.
38 * subject string The message subject
39 * fullmessage string The full message in a given format
40 * fullmessageformat int The format if the full message (FORMAT_MOODLE, FORMAT_HTML, ..)
41 * fullmessagehtml string The full version (the message processor will choose with one to use)
42 * smallmessage string The small version of the message
44 * Required parameters of the $eventdata object for PERSONAL MESSAGES:
45 * convid int The conversation identifier where this message will be sent
47 * Optional parameters of the $eventdata object:
48 * notification bool Should the message be considered as a notification rather than a personal message
49 * contexturl string If this is a notification then you can specify a url to view the event.
50 * For example the forum post the user is being notified of.
51 * contexturlname string The display text for contexturl.
52 * replyto string An email address which can be used to send an reply.
53 * attachment stored_file File instance that needs to be sent as attachment.
54 * attachname string Name of the attachment.
55 * customdata mixed Custom data to be passed to the message processor. Must be serialisable using json_encode().
57 * @package core_message
59 * @copyright 2015 onwards Ankit Agarwal
60 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
63 /** @var int Course id. */
66 /** @var string Module name. */
69 /** @var string Component name. */
72 /** @var string Name. */
75 /** @var object|int The user who is sending this message. */
78 /** @var int The conversation id where userfrom is sending this message. */
81 /** @var int The conversation type, eg. \core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL */
82 private $conversationtype;
84 /** @var object|int The user who is receiving from which is sending this message. */
87 /** @var string Subject of the message. */
90 /** @var string Complete message. */
93 /** @var int Message format. */
94 private $fullmessageformat;
96 /** @var string Complete message in html format. */
97 private $fullmessagehtml;
99 /** @var string Smaller version of the message. */
100 private $smallmessage;
102 /** @var int Is it a notification? */
103 private $notification;
105 /** @var string context url. */
108 /** @var string context name. */
109 private $contexturlname;
111 /** @var string An email address which can be used to send an reply. */
114 /** @var string A name which can be used with replyto. */
115 private $replytoname;
117 /** @var int Used internally to store the id of the row representing this message in DB. */
118 private $savedmessageid;
120 /** @var \stored_file File to be attached to the message. Note:- not all processors support this.*/
123 /** @var string Name of the attachment. Note:- not all processors support this.*/
126 /** @var int The time the message was created.*/
127 private $timecreated;
129 /** @var boolean Mark trust content. */
130 private $fullmessagetrust;
132 /** @var mixed Custom data to be passed to the message processor. Must be serialisable using json_encode(). */
135 /** @var boolean If message is anonymous. */
138 /** @var array a list of properties that is allowed for each message. */
139 private $properties = array(
167 /** @var array property to store any additional message processor specific content */
168 private $additionalcontent = array();
171 * Fullmessagehtml content including any processor specific content.
173 * @param string $processorname Name of the processor.
175 * @return mixed|string
177 protected function get_fullmessagehtml($processorname = '') {
178 if (!empty($processorname) && isset($this->additionalcontent[$processorname])) {
179 return $this->get_message_with_additional_content($processorname, 'fullmessagehtml');
181 return $this->fullmessagehtml;
186 * Fullmessage content including any processor specific content.
188 * @param string $processorname Name of the processor.
190 * @return mixed|string
192 protected function get_fullmessage($processorname = '') {
193 if (!empty($processorname) && isset($this->additionalcontent[$processorname])) {
194 return $this->get_message_with_additional_content($processorname, 'fullmessage');
196 return $this->fullmessage;
201 * Smallmessage content including any processor specific content.
203 * @param string $processorname Name of the processor.
205 * @return mixed|string
207 protected function get_smallmessage($processorname = '') {
208 if (!empty($processorname) && isset($this->additionalcontent[$processorname])) {
209 return $this->get_message_with_additional_content($processorname, 'smallmessage');
211 return $this->smallmessage;
216 * Always JSON encode customdata.
218 * @param mixed $customdata a data structure that must be serialisable using json_encode().
220 protected function set_customdata($customdata) {
221 // Always include the courseid (because is not stored in the notifications or messages table).
222 if (!empty($this->courseid) && (is_object($customdata) || is_array($customdata))) {
223 $customdata = (array) $customdata;
224 $customdata['courseid'] = $this->courseid;
226 $this->customdata = json_encode($customdata);
230 * Helper method used to get message content added with processor specific content.
232 * @param string $processorname Name of the processor.
233 * @param string $messagetype one of 'fullmessagehtml', 'fullmessage', 'smallmessage'.
235 * @return mixed|string
237 protected function get_message_with_additional_content($processorname, $messagetype) {
238 $message = $this->$messagetype;
239 if (isset($this->additionalcontent[$processorname]['*'])) {
240 // Content that needs to be added to all format.
241 $pattern = $this->additionalcontent[$processorname]['*'];
242 $message = empty($pattern['header']) ? $message : $pattern['header'] . $message;
243 $message = empty($pattern['footer']) ? $message : $message . $pattern['footer'];
246 if (isset($this->additionalcontent[$processorname][$messagetype])) {
247 // Content that needs to be added to the specific given format.
248 $pattern = $this->additionalcontent[$processorname][$messagetype];
249 $message = empty($pattern['header']) ? $message : $pattern['header'] . $message;
250 $message = empty($pattern['footer']) ? $message : $message . $pattern['footer'];
257 * Magic getter method.
259 * @param string $prop name of property to get.
262 * @throws \coding_exception
264 public function __get($prop) {
265 if (in_array($prop, $this->properties)) {
268 throw new \coding_exception("Invalid property $prop specified");
272 * Magic setter method.
274 * @param string $prop name of property to set.
275 * @param mixed $value value to assign to the property.
278 * @throws \coding_exception
280 public function __set($prop, $value) {
282 // Custom data must be JSON encoded always.
283 if ($prop == 'customdata') {
284 return $this->set_customdata($value);
287 if (in_array($prop, $this->properties)) {
288 return $this->$prop = $value;
290 throw new \coding_exception("Invalid property $prop specified");
294 * Magic method to check if property is set.
296 * @param string $prop name of property to check.
298 * @throws \coding_exception
300 public function __isset($prop) {
301 if (in_array($prop, $this->properties)) {
302 return isset($this->$prop);
304 throw new \coding_exception("Invalid property $prop specified");
308 * This method lets you define content that would be added to the message only for specific message processors.
310 * Example of $content:-
311 * array('fullmessagehtml' => array('header' => 'header content', 'footer' => 'footer content'),
312 * 'smallmessage' => array('header' => 'header content for small message', 'footer' => 'footer content'),
313 * '*' => array('header' => 'header content for all types', 'footer' => 'footer content')
316 * @param string $processorname name of the processor.
317 * @param array $content content to add in the above defined format.
319 public function set_additional_content($processorname, $content) {
320 $this->additionalcontent[$processorname] = $content;
324 * Get a event object for a specific processor in stdClass format.
326 * @param string $processorname Name of the processor.
328 * @return \stdClass event object in stdClass format.
330 public function get_eventobject_for_processor($processorname) {
331 // This is done for Backwards compatibility. We should consider throwing notices here in future versions and requesting
332 // them to use proper api.
334 $eventdata = new \stdClass();
335 foreach ($this->properties as $prop) {
337 $eventdata->$prop = method_exists($this, $func) ? $this->$func($processorname) : $this->$prop;