MDL-49682 mod_forum: Build forum email templates
[moodle.git] / mod / forum / classes / output / forum_post.php
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/>.
17 /**
18  * Forum post renderable.
19  *
20  * @package    mod_forum
21  * @copyright  2015 Andrew Nicols <andrew@nicols.co.uk>
22  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
23  */
25 namespace mod_forum\output;
27 defined('MOODLE_INTERNAL') || die();
29 /**
30  * Forum post renderable.
31  *
32  * @copyright  2015 Andrew Nicols <andrew@nicols.co.uk>
33  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
34  *
35  * @property boolean $viewfullnames Whether to override fullname()
36  */
37 class forum_post implements \renderable {
39     /**
40      * The course that the forum post is in.
41      *
42      * @var object $course
43      */
44     private $course = null;
46     /**
47      * The course module for the forum.
48      *
49      * @var object $cm
50      */
51     private $cm = null;
53     /**
54      * The forum that the post is in.
55      *
56      * @var object $forum
57      */
58     private $forum = null;
60     /**
61      * The discussion that the forum post is in.
62      *
63      * @var object $discussion
64      */
65     private $discussion = null;
67     /**
68      * The forum post being displayed.
69      *
70      * @var object $post
71      */
72     private $post = null;
74     /**
75      * Whether the user can reply to this post.
76      *
77      * @var boolean $canreply
78      */
79     private $canreply = false;
81     /**
82      * Whether to override forum display when displaying usernames.
83      * @var boolean $viewfullnames
84      */
85     private $viewfullnames = false;
87     /**
88      * The user that is reading the post.
89      *
90      * @var object $userto
91      */
92     private $userto = null;
94     /**
95      * The user that wrote the post.
96      *
97      * @var object $author
98      */
99     private $author = null;
101     /**
102      * An associative array indicating which keys on this object should be writeable.
103      *
104      * @var array $writablekeys
105      */
106     private $writablekeys = array(
107         'viewfullnames'    => true,
108     );
110     /**
111      * Builds a renderable forum post
112      *
113      * @param object $course Course of the forum
114      * @param object $cm Course Module of the forum
115      * @param object $forum The forum of the post
116      * @param object $discussion Discussion thread in which the post appears
117      * @param object $post The post
118      * @param object $author Author of the post
119      * @param object $recipient Recipient of the email
120      * @param bool $canreply True if the user can reply to the post
121      */
122     public function __construct($course, $cm, $forum, $discussion, $post, $author, $recipient, $canreply) {
123         $this->course = $course;
124         $this->cm = $cm;
125         $this->forum = $forum;
126         $this->discussion = $discussion;
127         $this->post = $post;
128         $this->author = $author;
129         $this->userto = $recipient;
130         $this->canreply = $canreply;
131     }
133     /**
134      * Export this data so it can be used as the context for a mustache template.
135      *
136      * @param \mod_forum_renderer $renderer The render to be used for formatting the message and attachments
137      * @return stdClass Data ready for use in a mustache template
138      */
139     public function export_for_template(\mod_forum_renderer $renderer) {
140         return array(
141             'id'                            => $this->post->id,
142             'coursename'                    => $this->get_coursename(),
143             'courselink'                    => $this->get_courselink(),
144             'forumname'                     => $this->get_forumname(),
145             'showdiscussionname'            => $this->get_showdiscussionname(),
146             'discussionname'                => $this->get_discussionname(),
147             'subject'                       => $this->get_subject(),
148             'authorfullname'                => $this->get_author_fullname(),
149             'postdate'                      => $this->get_postdate(),
151             // Format some components according to the renderer.
152             'message'                       => $renderer->format_message_text($this->forum, $this->post),
153             'attachments'                   => $renderer->format_message_attachments($this->cm, $this->post),
155             'canreply'                      => $this->canreply,
156             'permalink'                     => $this->get_permalink(),
157             'firstpost'                     => $this->get_is_firstpost(),
158             'replylink'                     => $this->get_replylink(),
159             'unsubscribediscussionlink'     => $this->get_unsubscribediscussionlink(),
160             'unsubscribeforumlink'          => $this->get_unsubscribeforumlink(),
161             'parentpostlink'                => $this->get_parentpostlink(),
163             'forumindexlink'                => $this->get_forumindexlink(),
164             'forumviewlink'                 => $this->get_forumviewlink(),
165             'discussionlink'                => $this->get_discussionlink(),
167             'authorlink'                    => $this->get_authorlink(),
168             'authorpicture'                 => $this->get_author_picture(),
170             'grouppicture'                  => $this->get_group_picture(),
171         );
172     }
174     /**
175      * Magically sets a property against this object.
176      *
177      * @param string $key
178      * @param mixed $value
179      */
180     public function __set($key, $value) {
181         // First attempt to use the setter function.
182         $methodname = 'set_' . $key;
183         if (method_exists($this, $methodname)) {
184             return $this->{$methodname}($value);
185         }
187         // Fall back to the writable keys list.
188         if (isset($this->writablekeys[$key]) && $this->writablekeys[$key]) {
189             return $this->{$key} = $value;
190         }
192         // Throw an error rather than fail silently.
193         throw new \coding_exception('Tried to set unknown property "' . $key . '"');
194     }
196     /**
197      * Whether this is the first post.
198      *
199      * @return boolean
200      */
201     public function get_is_firstpost() {
202         return empty($this->post->parent);
203     }
205     /**
206      * Get the link to the course.
207      *
208      * @return string
209      */
210     public function get_courselink() {
211         $link = new \moodle_url(
212             // Posts are viewed on the topic.
213             '/course/view.php', array(
214                 'id'    => $this->course->id,
215             )
216         );
218         return $link->out(false);
219     }
221     /**
222      * Get the link to the forum index for this course.
223      *
224      * @return string
225      */
226     public function get_forumindexlink() {
227         $link = new \moodle_url(
228             // Posts are viewed on the topic.
229             '/mod/forum/index.php', array(
230                 'id'    => $this->course->id,
231             )
232         );
234         return $link->out(false);
235     }
237     /**
238      * Get the link to the view page for this forum.
239      *
240      * @return string
241      */
242     public function get_forumviewlink() {
243         $link = new \moodle_url(
244             // Posts are viewed on the topic.
245             '/mod/forum/view.php', array(
246                 'f' => $this->forum->id,
247             )
248         );
250         return $link->out(false);
251     }
253     /**
254      * Get the link to the current discussion.
255      *
256      * @return string
257      */
258     protected function _get_discussionlink() {
259         return new \moodle_url(
260             // Posts are viewed on the topic.
261             '/mod/forum/discuss.php', array(
262                 // Within a discussion.
263                 'd' => $this->discussion->id,
264             )
265         );
266     }
268     /**
269      * Get the link to the current discussion.
270      *
271      * @return string
272      */
273     public function get_discussionlink() {
274         $link = $this->_get_discussionlink();
276         return $link->out(false);
277     }
279     /**
280      * Get the link to the current post, including post anchor.
281      *
282      * @return string
283      */
284     public function get_permalink() {
285         $link = $this->_get_discussionlink();
286         $link->set_anchor($this->get_postanchor());
288         return $link->out(false);
289     }
291     /**
292      * Get the link to the parent post.
293      *
294      * @return string
295      */
296     public function get_parentpostlink() {
297         $link = $this->_get_discussionlink();
298         $link->param('parent', $this->post->parent);
300         return $link->out(false);
301     }
303     /**
304      * Get the link to the author's profile page.
305      *
306      * @return string
307      */
308     public function get_authorlink() {
309         $link = new \moodle_url(
310             '/user/view.php', array(
311                 'id' => $this->post->userid,
312                 'course' => $this->course->id,
313             )
314         );
316         return $link->out(false);
317     }
319     /**
320      * Get the link to unsubscribe from the forum.
321      *
322      * @return string
323      */
324     public function get_unsubscribeforumlink() {
325         $link = new \moodle_url(
326             '/mod/forum/subscribe.php', array(
327                 'id' => $this->forum->id,
328             )
329         );
331         return $link->out(false);
332     }
334     /**
335      * Get the link to unsubscribe from the discussion.
336      *
337      * @return string
338      */
339     public function get_unsubscribediscussionlink() {
340         $link = new \moodle_url(
341             '/mod/discussion/subscribe.php', array(
342                 'id'  => $this->forum->id,
343                 'd'   => $this->discussion->id,
344             )
345         );
347         return $link->out(false);
348     }
350     /**
351      * Get the link to reply to the current post.
352      *
353      * @return string
354      */
355     public function get_replylink() {
356         return new \moodle_url(
357             '/mod/forum/post.php', array(
358                 'reply' => $this->post->id,
359             )
360         );
361     }
363     /**
364      * The formatted subject for the current post.
365      *
366      * @return string
367      */
368     public function get_subject() {
369         return format_string($this->post->subject, true);
370     }
372     /**
373      * The plaintext anchor id for the current post.
374      *
375      * @return string
376      */
377     public function get_postanchor() {
378         return 'p' . $this->post->id;
379     }
381     /**
382      * The name of the course that the forum is in.
383      *
384      * @return string
385      */
386     public function get_coursename() {
387         return format_string($this->course->shortname, true, array(
388             'context' => \context_course::instance($this->course->id),
389         ));
390     }
392     /**
393      * The name of the forum.
394      *
395      * @return string
396      */
397     public function get_forumname() {
398         return format_string($this->forum->name, true);
399     }
401     /**
402      * The name of the current discussion.
403      *
404      * @return string
405      */
406     public function get_discussionname() {
407         return format_string($this->discussion->name, true);
408     }
410     /**
411      * Whether to show the discussion name.
412      * If the forum name matches the discussion name, the discussion name
413      * is not typically displayed.
414      *
415      * @return boolean
416      */
417     public function get_showdiscussionname() {
418         return ($this->forum->name !== $this->discussion->name);
419     }
421     /**
422      * The fullname of the post author.
423      *
424      * @return string
425      */
426     public function get_author_fullname() {
427         return fullname($this->author, $this->viewfullnames);
428     }
430     /**
431      * The recipient of the post.
432      *
433      * @return string
434      */
435     protected function get_postto() {
436         global $USER;
437         if (null === $this->userto) {
438             return $USER;
439         }
441         return $this->userto;
442     }
444     /**
445      * The date of the post, formatted according to the postto user's
446      * preferences.
447      *
448      * @return string.
449      */
450     public function get_postdate() {
451         return userdate($this->post->modified, "", \core_date::get_user_timezone($this->get_postto()));
452     }
454     /**
455      * The HTML for the author's user picture.
456      *
457      * @return string
458      */
459     public function get_author_picture() {
460         global $OUTPUT;
462         return $OUTPUT->user_picture($this->author, array('courseid' => $this->course->id));
463     }
465     /**
466      * The HTML for a group picture.
467      *
468      * @return string
469      */
470     public function get_group_picture() {
471         if (isset($this->userfrom->groups)) {
472             $groups = $this->userfrom->groups[$this->forum->id];
473         } else {
474             $groups = groups_get_all_groups($this->course->id, $this->author->id, $this->cm->groupingid);
475         }
477         if ($this->get_is_firstpost()) {
478             return print_group_picture($groups, $this->course->id, false, true, true);
479         }
480     }