Differences Between: [Versions 310 and 402] [Versions 311 and 402] [Versions 39 and 402] [Versions 400 and 402] [Versions 401 and 402]
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 * 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 */ 24 25 namespace mod_forum\output; 26 27 defined('MOODLE_INTERNAL') || die(); 28 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, \templatable { 38 39 /** 40 * The course that the forum post is in. 41 * 42 * @var object $course 43 */ 44 protected $course = null; 45 46 /** 47 * The course module for the forum. 48 * 49 * @var object $cm 50 */ 51 protected $cm = null; 52 53 /** 54 * The forum that the post is in. 55 * 56 * @var object $forum 57 */ 58 protected $forum = null; 59 60 /** 61 * The discussion that the forum post is in. 62 * 63 * @var object $discussion 64 */ 65 protected $discussion = null; 66 67 /** 68 * The forum post being displayed. 69 * 70 * @var object $post 71 */ 72 protected $post = null; 73 74 /** 75 * Whether the user can reply to this post. 76 * 77 * @var boolean $canreply 78 */ 79 protected $canreply = false; 80 81 /** 82 * Whether to override forum display when displaying usernames. 83 * @var boolean $viewfullnames 84 */ 85 protected $viewfullnames = false; 86 87 /** 88 * The user that is reading the post. 89 * 90 * @var object $userto 91 */ 92 protected $userto = null; 93 94 /** 95 * The user that wrote the post. 96 * 97 * @var object $author 98 */ 99 protected $author = null; 100 101 /** 102 * An associative array indicating which keys on this object should be writeable. 103 * 104 * @var array $writablekeys 105 */ 106 protected $writablekeys = array( 107 'viewfullnames' => true, 108 ); 109 110 /** @var \stdClass user record. */ 111 protected $userfrom; 112 113 /** 114 * Builds a renderable forum post 115 * 116 * @param object $course Course of the forum 117 * @param object $cm Course Module of the forum 118 * @param object $forum The forum of the post 119 * @param object $discussion Discussion thread in which the post appears 120 * @param object $post The post 121 * @param object $author Author of the post 122 * @param object $recipient Recipient of the email 123 * @param bool $canreply True if the user can reply to the post 124 */ 125 public function __construct($course, $cm, $forum, $discussion, $post, $author, $recipient, $canreply) { 126 $this->course = $course; 127 $this->cm = $cm; 128 $this->forum = $forum; 129 $this->discussion = $discussion; 130 $this->post = $post; 131 $this->author = $author; 132 $this->userto = $recipient; 133 $this->canreply = $canreply; 134 } 135 136 /** 137 * Export this data so it can be used as the context for a mustache template. 138 * 139 * @param \mod_forum_renderer $renderer The render to be used for formatting the message and attachments 140 * @param bool $plaintext Whethe the target is a plaintext target 141 * @return array Data ready for use in a mustache template 142 */ 143 public function export_for_template(\renderer_base $renderer, $plaintext = false) { 144 if ($plaintext) { 145 return $this->export_for_template_text($renderer); 146 } else { 147 return $this->export_for_template_html($renderer); 148 } 149 } 150 151 /** 152 * Export this data so it can be used as the context for a mustache template. 153 * 154 * @param \mod_forum_renderer $renderer The render to be used for formatting the message and attachments 155 * @return array Data ready for use in a mustache template 156 */ 157 protected function export_for_template_text(\mod_forum_renderer $renderer) { 158 $data = $this->export_for_template_shared($renderer); 159 return $data + array( 160 'id' => html_entity_decode($this->post->id, ENT_COMPAT), 161 'coursename' => html_entity_decode($this->get_coursename(), ENT_COMPAT), 162 'courselink' => html_entity_decode($this->get_courselink(), ENT_COMPAT), 163 'forumname' => html_entity_decode($this->get_forumname(), ENT_COMPAT), 164 'showdiscussionname' => html_entity_decode($this->get_showdiscussionname(), ENT_COMPAT), 165 'discussionname' => html_entity_decode($this->get_discussionname(), ENT_COMPAT), 166 'subject' => html_entity_decode($this->get_subject(), ENT_COMPAT), 167 'authorfullname' => html_entity_decode($this->get_author_fullname(), ENT_COMPAT), 168 'postdate' => html_entity_decode($this->get_postdate(), ENT_COMPAT), 169 170 // Format some components according to the renderer. 171 'message' => html_entity_decode($renderer->format_message_text($this->cm, $this->post), ENT_COMPAT), 172 'attachments' => html_entity_decode($renderer->format_message_attachments($this->cm, $this->post), ENT_COMPAT), 173 174 'canreply' => $this->canreply, 175 'permalink' => $this->get_permalink(), 176 'firstpost' => $this->get_is_firstpost(), 177 'replylink' => $this->get_replylink(), 178 'unsubscribediscussionlink' => $this->get_unsubscribediscussionlink(), 179 'unsubscribeforumlink' => $this->get_unsubscribeforumlink(), 180 'parentpostlink' => $this->get_parentpostlink(), 181 182 'forumindexlink' => $this->get_forumindexlink(), 183 'forumviewlink' => $this->get_forumviewlink(), 184 'discussionlink' => $this->get_discussionlink(), 185 186 'authorlink' => $this->get_authorlink(), 187 'authorpicture' => $this->get_author_picture($renderer), 188 189 'grouppicture' => $this->get_group_picture($renderer), 190 ); 191 } 192 193 /** 194 * Export this data so it can be used as the context for a mustache template. 195 * 196 * @param \mod_forum_renderer $renderer The render to be used for formatting the message and attachments 197 * @return array Data ready for use in a mustache template 198 */ 199 protected function export_for_template_html(\mod_forum_renderer $renderer) { 200 $data = $this->export_for_template_shared($renderer); 201 return $data + array( 202 'id' => $this->post->id, 203 'coursename' => $this->get_coursename(), 204 'courselink' => $this->get_courselink(), 205 'forumname' => $this->get_forumname(), 206 'showdiscussionname' => $this->get_showdiscussionname(), 207 'discussionname' => $this->get_discussionname(), 208 'subject' => $this->get_subject(), 209 'authorfullname' => $this->get_author_fullname(), 210 'postdate' => $this->get_postdate(), 211 212 // Format some components according to the renderer. 213 'message' => $renderer->format_message_text($this->cm, $this->post), 214 'attachments' => $renderer->format_message_attachments($this->cm, $this->post), 215 ); 216 } 217 218 /** 219 * Export this data so it can be used as the context for a mustache template. 220 * 221 * @param \mod_forum_renderer $renderer The render to be used for formatting the message and attachments 222 * @return stdClass Data ready for use in a mustache template 223 */ 224 protected function export_for_template_shared(\mod_forum_renderer $renderer) { 225 return array( 226 'canreply' => $this->canreply, 227 'permalink' => $this->get_permalink(), 228 'firstpost' => $this->get_is_firstpost(), 229 'replylink' => $this->get_replylink(), 230 'unsubscribediscussionlink' => $this->get_unsubscribediscussionlink(), 231 'unsubscribeforumlink' => $this->get_unsubscribeforumlink(), 232 'parentpostlink' => $this->get_parentpostlink(), 233 234 'forumindexlink' => $this->get_forumindexlink(), 235 'forumviewlink' => $this->get_forumviewlink(), 236 'discussionlink' => $this->get_discussionlink(), 237 238 'authorlink' => $this->get_authorlink(), 239 'authorpicture' => $this->get_author_picture($renderer), 240 241 'grouppicture' => $this->get_group_picture($renderer), 242 243 'isprivatereply' => !empty($this->post->privatereplyto), 244 ); 245 } 246 247 /** 248 * Magically sets a property against this object. 249 * 250 * @param string $key 251 * @param mixed $value 252 */ 253 public function __set($key, $value) { 254 // First attempt to use the setter function. 255 $methodname = 'set_' . $key; 256 if (method_exists($this, $methodname)) { 257 return $this->{$methodname}($value); 258 } 259 260 // Fall back to the writable keys list. 261 if (isset($this->writablekeys[$key]) && $this->writablekeys[$key]) { 262 return $this->{$key} = $value; 263 } 264 265 // Throw an error rather than fail silently. 266 throw new \coding_exception('Tried to set unknown property "' . $key . '"'); 267 } 268 269 /** 270 * Whether this is the first post. 271 * 272 * @return boolean 273 */ 274 public function get_is_firstpost() { 275 return empty($this->post->parent); 276 } 277 278 /** 279 * Get the link to the course. 280 * 281 * @return string 282 */ 283 public function get_courselink() { 284 $link = new \moodle_url( 285 // Posts are viewed on the topic. 286 '/course/view.php', array( 287 'id' => $this->course->id, 288 ) 289 ); 290 291 return $link->out(false); 292 } 293 294 /** 295 * Get the link to the forum index for this course. 296 * 297 * @return string 298 */ 299 public function get_forumindexlink() { 300 $link = new \moodle_url( 301 // Posts are viewed on the topic. 302 '/mod/forum/index.php', array( 303 'id' => $this->course->id, 304 ) 305 ); 306 307 return $link->out(false); 308 } 309 310 /** 311 * Get the link to the view page for this forum. 312 * 313 * @return string 314 */ 315 public function get_forumviewlink() { 316 $link = new \moodle_url( 317 // Posts are viewed on the topic. 318 '/mod/forum/view.php', array( 319 'f' => $this->forum->id, 320 ) 321 ); 322 323 return $link->out(false); 324 } 325 326 /** 327 * Get the link to the current discussion. 328 * 329 * @return string 330 */ 331 protected function _get_discussionlink() { 332 return new \moodle_url( 333 // Posts are viewed on the topic. 334 '/mod/forum/discuss.php', array( 335 // Within a discussion. 336 'd' => $this->discussion->id, 337 ) 338 ); 339 } 340 341 /** 342 * Get the link to the current discussion. 343 * 344 * @return string 345 */ 346 public function get_discussionlink() { 347 $link = $this->_get_discussionlink(); 348 349 return $link->out(false); 350 } 351 352 /** 353 * Get the link to the current post, including post anchor. 354 * 355 * @return string 356 */ 357 public function get_permalink() { 358 $link = $this->_get_discussionlink(); 359 $link->set_anchor($this->get_postanchor()); 360 361 return $link->out(false); 362 } 363 364 /** 365 * Get the link to the parent post. 366 * 367 * @return string 368 */ 369 public function get_parentpostlink() { 370 $link = $this->_get_discussionlink(); 371 $link->param('parent', $this->post->parent); 372 373 return $link->out(false); 374 } 375 376 /** 377 * Get the link to the author's profile page. 378 * 379 * @return string 380 */ 381 public function get_authorlink() { 382 $link = new \moodle_url( 383 '/user/view.php', array( 384 'id' => $this->post->userid, 385 'course' => $this->course->id, 386 ) 387 ); 388 389 return $link->out(false); 390 } 391 392 /** 393 * Get the link to unsubscribe from the forum. 394 * 395 * @return string 396 */ 397 public function get_unsubscribeforumlink() { 398 if (!\mod_forum\subscriptions::is_subscribable($this->forum)) { 399 return null; 400 } 401 $link = new \moodle_url( 402 '/mod/forum/subscribe.php', array( 403 'id' => $this->forum->id, 404 ) 405 ); 406 407 return $link->out(false); 408 } 409 410 /** 411 * Get the link to unsubscribe from the discussion. 412 * 413 * @return string 414 */ 415 public function get_unsubscribediscussionlink() { 416 if (!\mod_forum\subscriptions::is_subscribable($this->forum)) { 417 return null; 418 } 419 $link = new \moodle_url( 420 '/mod/forum/subscribe.php', array( 421 'id' => $this->forum->id, 422 'd' => $this->discussion->id, 423 ) 424 ); 425 426 return $link->out(false); 427 } 428 429 /** 430 * Get the link to reply to the current post. 431 * 432 * @return string 433 */ 434 public function get_replylink() { 435 return new \moodle_url( 436 '/mod/forum/post.php', array( 437 'reply' => $this->post->id, 438 ) 439 ); 440 } 441 442 /** 443 * The formatted subject for the current post. 444 * 445 * @return string 446 */ 447 public function get_subject() { 448 return format_string($this->post->subject, true); 449 } 450 451 /** 452 * The plaintext anchor id for the current post. 453 * 454 * @return string 455 */ 456 public function get_postanchor() { 457 return 'p' . $this->post->id; 458 } 459 460 /** 461 * ID number of the course that the forum is in. 462 * 463 * @return string 464 */ 465 public function get_courseidnumber() { 466 return s($this->course->idnumber); 467 } 468 469 /** 470 * The full name of the course that the forum is in. 471 * 472 * @return string 473 */ 474 public function get_coursefullname() { 475 return format_string($this->course->fullname, true, array( 476 'context' => \context_course::instance($this->course->id), 477 )); 478 } 479 480 /** 481 * The name of the course that the forum is in. 482 * 483 * @return string 484 */ 485 public function get_coursename() { 486 return format_string($this->course->shortname, true, array( 487 'context' => \context_course::instance($this->course->id), 488 )); 489 } 490 491 /** 492 * The name of the forum. 493 * 494 * @return string 495 */ 496 public function get_forumname() { 497 return format_string($this->forum->name, true); 498 } 499 500 /** 501 * The name of the current discussion. 502 * 503 * @return string 504 */ 505 public function get_discussionname() { 506 return format_string($this->discussion->name, true); 507 } 508 509 /** 510 * Whether to show the discussion name. 511 * If the forum name matches the discussion name, the discussion name 512 * is not typically displayed. 513 * 514 * @return boolean 515 */ 516 public function get_showdiscussionname() { 517 return ($this->forum->name !== $this->discussion->name); 518 } 519 520 /** 521 * The fullname of the post author. 522 * 523 * @return string 524 */ 525 public function get_author_fullname() { 526 return fullname($this->author, $this->viewfullnames); 527 } 528 529 /** 530 * The recipient of the post. 531 * 532 * @return string 533 */ 534 protected function get_postto() { 535 global $USER; 536 if (null === $this->userto) { 537 return $USER; 538 } 539 540 return $this->userto; 541 } 542 543 /** 544 * The date of the post, formatted according to the postto user's 545 * preferences. 546 * 547 * @return string 548 */ 549 public function get_postdate() { 550 global $CFG; 551 552 $postmodified = $this->post->modified; 553 if (!empty($CFG->forum_enabletimedposts) && ($this->discussion->timestart > $postmodified)) { 554 $postmodified = $this->discussion->timestart; 555 } 556 557 return userdate($postmodified, "", \core_date::get_user_timezone($this->get_postto())); 558 } 559 560 /** 561 * The HTML for the author's user picture. 562 * 563 * @param \renderer_base $renderer 564 * @return string 565 */ 566 public function get_author_picture(\renderer_base $renderer) { 567 return $renderer->user_picture($this->author, array('courseid' => $this->course->id)); 568 } 569 570 /** 571 * The HTML for a group picture. 572 * 573 * @param \renderer_base $renderer 574 * @return string 575 */ 576 public function get_group_picture(\renderer_base $renderer) { 577 if (isset($this->userfrom->groups)) { 578 $groups = $this->userfrom->groups[$this->forum->id]; 579 } else { 580 $groups = groups_get_all_groups($this->course->id, $this->author->id, $this->cm->groupingid); 581 } 582 583 if ($this->get_is_firstpost()) { 584 return print_group_picture($groups, $this->course->id, false, true, true, true); 585 } 586 } 587 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body