f7141b3534b20b89c67d0cf9cd408c4141c5ed24
[moodle.git] / mod / forum / classes / local / factories / url.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  * A URL factory for the forum.
19  *
20  * @package    mod_forum
21  * @copyright  2019 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\local\factories;
27 defined('MOODLE_INTERNAL') || die();
29 use mod_forum\local\entities\author as author_entity;
30 use mod_forum\local\entities\forum as forum_entity;
31 use mod_forum\local\entities\discussion as discussion_entity;
32 use mod_forum\local\entities\post as post_entity;
33 use mod_forum\local\factories\legacy_data_mapper as legacy_data_mapper_factory;
34 use moodle_url;
35 use stored_file;
36 use user_picture;
38 require_once($CFG->dirroot . '/mod/forum/lib.php');
40 /**
41  * A URL factory for the forum.
42  *
43  * @copyright  2019 Andrew Nicols <andrew@nicols.co.uk>
44  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
45  */
46 class url {
47     /** @var legacy_data_mapper_factory $legacydatamapperfactory Legacy data mapper factory */
48     private $legacydatamapperfactory;
50     /**
51      * Constructor.
52      *
53      * @param legacy_data_mapper_factory $legacydatamapperfactory Legacy data mapper factory
54      */
55     public function __construct(legacy_data_mapper_factory $legacydatamapperfactory) {
56         $this->legacydatamapperfactory = $legacydatamapperfactory;
57     }
59     /**
60      * Get the course url from the given course id.
61      *
62      * @param int $courseid The course id
63      * @return moodle_url
64      */
65     public function get_course_url_from_courseid(int $courseid) : moodle_url {
66         return new moodle_url('/course/view.php', [
67             'id' => $courseid,
68         ]);
69     }
71     /**
72      * Get the course url from the given forum entity.
73      *
74      * @param forum_entity $forum The forum entity
75      * @return moodle_url
76      */
77     public function get_course_url_from_forum(forum_entity $forum) : moodle_url {
78         return $this->get_course_url_from_courseid($forum->get_course_id());
79     }
81     /**
82      * Get the create discussion url for the given forum.
83      *
84      * @param forum_entity $forum The forum entity
85      * @return moodle_url
86      */
87     public function get_discussion_create_url(forum_entity $forum) : moodle_url {
88         return new moodle_url('/mod/forum/post.php', [
89             'forum' => $forum->get_id(),
90         ]);
91     }
93     /**
94      * Get the view forum url for the given forum and optionally a page number.
95      *
96      * @param forum_entity $forum The forum entity
97      * @param int|null $pageno The page number
98      * @param int|null $sortorder The sorting order
99      * @return moodle_url
100      */
101     public function get_forum_view_url_from_forum(forum_entity $forum, ?int $pageno = null,
102             ?int $sortorder = null) : moodle_url {
104         return $this->get_forum_view_url_from_course_module_id($forum->get_course_module_record()->id, $pageno, $sortorder);
105     }
107     /**
108      * Get the view forum url for the given course module id and optionally a page number.
109      *
110      * @param int $coursemoduleid The course module id
111      * @param int|null $pageno The page number
112      * @param int|null $sortorder The sorting order
113      * @return moodle_url
114      */
115     public function get_forum_view_url_from_course_module_id(int $coursemoduleid, ?int $pageno = null,
116             ?int $sortorder = null) : moodle_url {
118         $url = new moodle_url('/mod/forum/view.php', [
119             'id' => $coursemoduleid,
120         ]);
122         if (null !== $pageno) {
123             $url->param('p', $pageno);
124         }
126         if (null !== $sortorder) {
127             $url->param('o', $sortorder);
128         }
130         return $url;
131     }
133     /**
134      * Get the view discussion url from the given discussion id.
135      *
136      * @param int $discussionid The discussion id
137      * @return moodle_url
138      */
139     public function get_discussion_view_url_from_discussion_id(int $discussionid) : moodle_url {
140         return new moodle_url('/mod/forum/discuss.php', [
141             'd' => $discussionid
142         ]);
143     }
145     /**
146      * Get the view discussion url from the given discussion.
147      *
148      * @param discussion_entity $discussion The discussion
149      * @return moodle_url
150      */
151     public function get_discussion_view_url_from_discussion(discussion_entity $discussion) : moodle_url {
152         return $this->get_discussion_view_url_from_discussion_id($discussion->get_id());
153     }
155     /**
156      * Get the url to view the first unread post in a discussion.
157      *
158      * @param discussion_entity $discussion The discussion
159      * @return moodle_url
160      */
161     public function get_discussion_view_first_unread_post_url_from_discussion(discussion_entity $discussion) {
162         $viewurl = $this->get_discussion_view_url_from_discussion_id($discussion->get_id());
163         $viewurl->set_anchor('unread');
165         return $viewurl;
166     }
168     /**
169      * Get the url to view the latest post in a discussion.
170      *
171      * @param discussion_entity $discussion The discussion
172      * @param int|null $latestpost The id of the latest post
173      * @return moodle_url
174      */
175     public function get_discussion_view_latest_post_url_from_discussion(discussion_entity $discussion, ?int $latestpost) {
176         $viewurl = $this->get_discussion_view_url_from_discussion_id($discussion->get_id());
177         if (null === $latestpost) {
178             return $viewurl;
179         } else {
180             return new moodle_url($viewurl, ['parent' => $latestpost]);
181         }
182     }
184     /**
185      * Get the url to view a discussion from a post.
186      *
187      * @param post_entity $post The post
188      * @return moodle_url
189      */
190     public function get_discussion_view_url_from_post(post_entity $post) : moodle_url {
191         return $this->get_discussion_view_url_from_discussion_id($post->get_discussion_id());
192     }
194     /**
195      * Get the url to view a discussion from a discussion id and post id.
196      *
197      * @param int $discussionid The discussion id
198      * @param int $postid The post id
199      * @return moodle_url
200      */
201     public function get_view_post_url_from_post_id(int $discussionid, int $postid) : moodle_url {
202         $url = $this->get_discussion_view_url_from_discussion_id($discussionid);
203         $url->set_anchor('p' . $postid);
204         return $url;
205     }
207     /**
208      * Get the url to view a post in the context of the rest of the discussion.
209      *
210      * @param post_entity $post The post
211      * @return moodle_url
212      */
213     public function get_view_post_url_from_post(post_entity $post) : moodle_url {
214         return $this->get_view_post_url_from_post_id($post->get_discussion_id(), $post->get_id());
215     }
217     /**
218      * Get the url to view a post and it's replies in isolation without the rest of the
219      * discussion.
220      *
221      * @param int $discussionid The discussion id
222      * @param int $postid The post id
223      * @return moodle_url
224      */
225     public function get_view_isolated_post_url_from_post_id(int $discussionid, int $postid) : moodle_url {
226         $url = $this->get_discussion_view_url_from_discussion_id($discussionid);
227         $url->params(['parent' => $postid]);
228         return $url;
229     }
231     /**
232      * Get the url to view a post and it's replies in isolation without the rest of the
233      * discussion.
234      *
235      * @param post_entity $post The post
236      * @return moodle_url
237      */
238     public function get_view_isolated_post_url_from_post(post_entity $post) : moodle_url {
239         return $this->get_view_isolated_post_url_from_post_id($post->get_discussion_id(), $post->get_id());
240     }
242     /**
243      * Get the url to edit a post.
244      *
245      * @param forum_entity $forum The forum the post belongs to
246      * @param post_entity $post The post
247      * @return moodle_url
248      */
249     public function get_edit_post_url_from_post(forum_entity $forum, post_entity $post) : moodle_url {
250         if ($forum->get_type() == 'single') {
251             return new moodle_url('/course/modedit.php', [
252                 'update' => $forum->get_course_module_record()->id,
253                 'sesskey' => sesskey(),
254                 'return' => 1
255             ]);
256         } else {
257             return new moodle_url('/mod/forum/post.php', [
258                 'edit' => $post->get_id()
259             ]);
260         }
261     }
263     /**
264      * Get the url to split a discussion at a post.
265      *
266      * @param post_entity $post The post
267      * @return moodle_url
268      */
269     public function get_split_discussion_at_post_url_from_post(post_entity $post) : moodle_url {
270         return new moodle_url('/mod/forum/post.php', [
271             'prune' => $post->get_id()
272         ]);
273     }
275     /**
276      * Get the url to delete a post.
277      *
278      * @param post_entity $post The post
279      * @return moodle_url
280      */
281     public function get_delete_post_url_from_post(post_entity $post) : moodle_url {
282         return new moodle_url('/mod/forum/post.php', [
283             'delete' => $post->get_id()
284         ]);
285     }
287     /**
288      * Get the url to reply to a post.
289      *
290      * @param post_entity $post The post
291      * @return moodle_url
292      */
293     public function get_reply_to_post_url_from_post(post_entity $post) : moodle_url {
294         return new moodle_url('/mod/forum/post.php#mformforum', [
295             'reply' => $post->get_id()
296         ]);
297     }
299     /**
300      * Get the url to export (see portfolios) a post.
301      *
302      * @param post_entity $post The post
303      * @return moodle_url
304      */
305     public function get_export_post_url_from_post(post_entity $post) : ?moodle_url {
306         global $CFG;
308         require_once($CFG->libdir . '/portfoliolib.php');
309         $button = new \portfolio_add_button();
310         $button->set_callback_options('forum_portfolio_caller', ['postid' => $post->get_id()], 'mod_forum');
311         if ($post->has_attachments()) {
312             $button->set_formats(PORTFOLIO_FORMAT_RICHHTML);
313         } else {
314             $button->set_formats(PORTFOLIO_FORMAT_PLAINHTML);
315         }
317         $url = $button->to_html(PORTFOLIO_ADD_MOODLE_URL);
318         return $url ?: null;
319     }
321     /**
322      * Get the url to mark a post as read.
323      *
324      * @param post_entity $post The post
325      * @param int $displaymode The display mode to show the forum in after marking as read
326      * @return moodle_url
327      */
328     public function get_mark_post_as_read_url_from_post(post_entity $post, int $displaymode = FORUM_MODE_THREADED) : moodle_url {
329         $params = [
330             'd' => $post->get_discussion_id(),
331             'postid' => $post->get_id(),
332             'mark' => 'read'
333         ];
335         $url = new moodle_url('/mod/forum/discuss.php', $params);
337         if ($displaymode == FORUM_MODE_THREADED) {
338             $url->param('parent', $post->get_parent_id());
339         } else {
340             $url->set_anchor('p' . $post->get_id());
341         }
343         return $url;
344     }
346     /**
347      * Get the url to mark a post as unread.
348      *
349      * @param post_entity $post The post
350      * @param int $displaymode The display mode to show the forum in after marking as unread
351      * @return moodle_url
352      */
353     public function get_mark_post_as_unread_url_from_post(post_entity $post, int $displaymode = FORUM_MODE_THREADED) : moodle_url {
354         $params = [
355             'd' => $post->get_discussion_id(),
356             'postid' => $post->get_id(),
357             'mark' => 'unread'
358         ];
360         $url = new moodle_url('/mod/forum/discuss.php', $params);
362         if ($displaymode == FORUM_MODE_THREADED) {
363             $url->param('parent', $post->get_parent_id());
364         } else {
365             $url->set_anchor('p' . $post->get_id());
366         }
368         return $url;
369     }
371     /**
372      * Get the url to export attachments for a post.
373      *
374      * @param post_entity $post The post
375      * @param stored_file $attachment
376      * @return moodle_url|null
377      */
378     public function get_export_attachment_url_from_post_and_attachment(post_entity $post, stored_file $attachment) : ?moodle_url {
379         global $CFG;
381         require_once($CFG->libdir . '/portfoliolib.php');
382         $button = new \portfolio_add_button();
383         $button->set_callback_options(
384             'forum_portfolio_caller',
385             ['postid' => $post->get_id(), 'attachment' => $attachment->get_id()],
386             'mod_forum'
387         );
388         $button->set_format_by_file($attachment);
389         $url = $button->to_html(PORTFOLIO_ADD_MOODLE_URL);
390         return $url ?: null;
391     }
393     /**
394      * Get the url to view an author's profile.
395      *
396      * @param author_entity $author The author
397      * @return moodle_url
398      */
399     public function get_author_profile_url(author_entity $author) : moodle_url {
400         return new moodle_url('/user/view.php', [
401             'id' => $author->get_id()
402         ]);
403     }
405     /**
406      * Get the url to view the author's profile image. The author's context id should be
407      * provided to prevent the code from needing to load it.
408      *
409      * @param author_entity $author The author
410      * @param int|null $authorcontextid The author context id
411      * @return moodle_url
412      */
413     public function get_author_profile_image_url(author_entity $author, int $authorcontextid = null) : moodle_url {
414         global $PAGE;
416         $datamapper = $this->legacydatamapperfactory->get_author_data_mapper();
417         $record = $datamapper->to_legacy_object($author);
418         $record->contextid = $authorcontextid;
419         $userpicture = new user_picture($record);
420         $userpicture->size = 2;
422         return $userpicture->get_url($PAGE);
423     }
425     /**
426      * Get the url to mark a discussion as read.
427      *
428      * @param forum_entity $forum The forum that the discussion belongs to
429      * @param discussion_entity $discussion The discussion
430      * @return moodle_url
431      */
432     public function get_mark_discussion_as_read_url_from_discussion(
433         forum_entity $forum,
434         discussion_entity $discussion
435     ) : moodle_url {
436         return new moodle_url('/mod/forum/markposts.php', [
437             'f' => $discussion->get_forum_id(),
438             'd' => $discussion->get_id(),
439             'mark' => 'read',
440             'sesskey' => sesskey(),
441             'return' => $this->get_forum_view_url_from_forum($forum)->out(),
442         ]);
443     }
445     /**
446      * Get the url to mark all discussions as read.
447      *
448      * @param forum_entity $forum The forum that the discussions belong to
449      * @return moodle_url
450      */
451     public function get_mark_all_discussions_as_read_url(forum_entity $forum) : moodle_url {
452         return new moodle_url('/mod/forum/markposts.php', [
453             'f' => $forum->get_id(),
454             'mark' => 'read',
455             'sesskey' => sesskey(),
456             'return' => $this->get_forum_view_url_from_forum($forum)->out(),
457         ]);
458     }
460     /**
461      * Get the url to subscribe to a discussion.
462      *
463      * @param discussion_entity $discussion The discussion
464      * @return moodle_url
465      */
466     public function get_discussion_subscribe_url(discussion_entity $discussion) : moodle_url {
467         return new moodle_url('/mod/forum/subscribe.php', [
468             'sesskey' => sesskey(),
469             'id' => $discussion->get_forum_id(),
470             'd' => $discussion->get_id()
471         ]);
472     }
474     /**
475      * Generate the pinned discussion link
476      *
477      * @param discussion_entity $discussion
478      * @return moodle_url
479      * @throws \moodle_exception
480      */
481     public function get_pin_discussion_url_from_discussion(discussion_entity $discussion) : moodle_url {
482         return new moodle_url('discuss.php', [
483             'sesskey' => sesskey(),
484             'd' => $discussion->get_id(),
485             'pin' => $discussion->is_pinned() ? FORUM_DISCUSSION_UNPINNED : FORUM_DISCUSSION_PINNED
486         ]);
487     }