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 * 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 */ 24 25 namespace mod_forum\local\factories; 26 27 defined('MOODLE_INTERNAL') || die(); 28 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; 37 38 require_once($CFG->dirroot . '/mod/forum/lib.php'); 39 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; 49 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 } 58 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 } 70 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 } 80 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 } 92 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 { 103 104 return $this->get_forum_view_url_from_course_module_id($forum->get_course_module_record()->id, $pageno, $sortorder); 105 } 106 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 { 117 118 $url = new moodle_url('/mod/forum/view.php', [ 119 'id' => $coursemoduleid, 120 ]); 121 122 if (null !== $pageno) { 123 $url->param('p', $pageno); 124 } 125 126 if (null !== $sortorder) { 127 $url->param('o', $sortorder); 128 } 129 130 return $url; 131 } 132 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 } 144 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 } 154 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'); 164 165 return $viewurl; 166 } 167 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 } 183 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 } 193 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 } 206 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 } 216 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 } 230 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 } 241 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' && !$post->has_parent()) { 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 } 262 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 } 274 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 } 286 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 } 298 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; 307 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 } 316 317 $url = $button->to_html(PORTFOLIO_ADD_MOODLE_URL); 318 return $url ?: null; 319 } 320 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 ]; 334 335 $url = new moodle_url('/mod/forum/discuss.php', $params); 336 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 } 342 343 return $url; 344 } 345 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 ]; 359 360 $url = new moodle_url('/mod/forum/discuss.php', $params); 361 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 } 367 368 return $url; 369 } 370 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; 380 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 } 392 393 /** 394 * Get the url to view an author's profile. 395 * 396 * @param author_entity $author The author 397 * @param int $courseid The course id 398 * @return moodle_url 399 */ 400 public function get_author_profile_url(author_entity $author, int $courseid) : moodle_url { 401 return new moodle_url('/user/view.php', [ 402 'id' => $author->get_id(), 403 'course' => $courseid 404 ]); 405 } 406 407 /** 408 * Get the url to view the author's profile image. The author's context id should be 409 * provided to prevent the code from needing to load it. 410 * 411 * @param author_entity $author The author 412 * @param int|null $authorcontextid The author context id 413 * @param int $size The size of the image to return 414 * @return moodle_url 415 */ 416 public function get_author_profile_image_url( 417 author_entity $author, 418 int $authorcontextid = null, 419 int $size = 100 420 ) : moodle_url { 421 global $PAGE; 422 423 $datamapper = $this->legacydatamapperfactory->get_author_data_mapper(); 424 $record = $datamapper->to_legacy_object($author); 425 $record->contextid = $authorcontextid; 426 $userpicture = new user_picture($record); 427 $userpicture->size = $size; 428 429 return $userpicture->get_url($PAGE); 430 } 431 432 /** 433 * Get the url to view an author's group. 434 * 435 * @param \stdClass $group The group 436 * @return moodle_url 437 */ 438 public function get_author_group_url(\stdClass $group) : moodle_url { 439 return new moodle_url('/user/index.php', [ 440 'id' => $group->courseid, 441 'group' => $group->id 442 ]); 443 } 444 /** 445 * Get the url to mark a discussion as read. 446 * 447 * @param forum_entity $forum The forum that the discussion belongs to 448 * @param discussion_entity $discussion The discussion 449 * @return moodle_url 450 */ 451 public function get_mark_discussion_as_read_url_from_discussion( 452 forum_entity $forum, 453 discussion_entity $discussion 454 ) : moodle_url { 455 return new moodle_url('/mod/forum/markposts.php', [ 456 'f' => $discussion->get_forum_id(), 457 'd' => $discussion->get_id(), 458 'mark' => 'read', 459 'sesskey' => sesskey(), 460 'return' => $this->get_forum_view_url_from_forum($forum)->out(), 461 ]); 462 } 463 464 /** 465 * Get the url to mark all discussions as read. 466 * 467 * @param forum_entity $forum The forum that the discussions belong to 468 * @return moodle_url 469 */ 470 public function get_mark_all_discussions_as_read_url(forum_entity $forum) : moodle_url { 471 return new moodle_url('/mod/forum/markposts.php', [ 472 'f' => $forum->get_id(), 473 'mark' => 'read', 474 'sesskey' => sesskey(), 475 'return' => $this->get_forum_view_url_from_forum($forum)->out(), 476 ]); 477 } 478 479 /** 480 * Get the url to subscribe to a discussion. 481 * 482 * @param discussion_entity $discussion The discussion 483 * @return moodle_url 484 */ 485 public function get_discussion_subscribe_url(discussion_entity $discussion) : moodle_url { 486 return new moodle_url('/mod/forum/subscribe.php', [ 487 'sesskey' => sesskey(), 488 'id' => $discussion->get_forum_id(), 489 'd' => $discussion->get_id() 490 ]); 491 } 492 493 /** 494 * Generate the pinned discussion link 495 * 496 * @param discussion_entity $discussion 497 * @return moodle_url 498 * @throws \moodle_exception 499 */ 500 public function get_pin_discussion_url_from_discussion(discussion_entity $discussion) : moodle_url { 501 return new moodle_url('discuss.php', [ 502 'sesskey' => sesskey(), 503 'd' => $discussion->get_id(), 504 'pin' => $discussion->is_pinned() ? FORUM_DISCUSSION_UNPINNED : FORUM_DISCUSSION_PINNED 505 ]); 506 } 507 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body