MDL-65082 core_course: Update frontpage view to use new forum API
[moodle.git] / mod / forum / deprecatedlib.php
CommitLineData
39de876c
AN
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 * @package mod_forum
19 * @copyright 2014 Andrew Robert Nicols <andrew@nicols.co.uk>
20 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
21 */
22
23defined('MOODLE_INTERNAL') || die();
24
25// Deprecated a very long time ago.
26
27/**
39de876c
AN
28 * @deprecated since Moodle 1.1 - please do not use this function any more.
29 */
d16185fd
AN
30function forum_count_unrated_posts() {
31 throw new coding_exception(__FUNCTION__ . '() can not be used any more.');
39de876c
AN
32}
33
34
35// Since Moodle 1.5.
36
37/**
39de876c
AN
38 * @deprecated since Moodle 1.5 - please do not use this function any more.
39 */
d16185fd
AN
40function forum_tp_count_discussion_read_records() {
41 throw new coding_exception(__FUNCTION__ . '() can not be used any more.');
39de876c
AN
42}
43
44/**
39de876c
AN
45 * @deprecated since Moodle 1.5 - please do not use this function any more.
46 */
d16185fd
AN
47function forum_get_user_discussions() {
48 throw new coding_exception(__FUNCTION__ . '() can not be used any more.');
39de876c
AN
49}
50
51
52// Since Moodle 1.6.
53
54/**
39de876c
AN
55 * @deprecated since Moodle 1.6 - please do not use this function any more.
56 */
d16185fd
AN
57function forum_tp_count_forum_posts() {
58 throw new coding_exception(__FUNCTION__ . '() can not be used any more.');
39de876c
AN
59}
60
61/**
39de876c
AN
62 * @deprecated since Moodle 1.6 - please do not use this function any more.
63 */
d16185fd
AN
64function forum_tp_count_forum_read_records() {
65 throw new coding_exception(__FUNCTION__ . '() can not be used any more.');
39de876c
AN
66}
67
68
69// Since Moodle 1.7.
70
71/**
39de876c
AN
72 * @deprecated since Moodle 1.7 - please do not use this function any more.
73 */
74function forum_get_open_modes() {
d16185fd 75 throw new coding_exception(__FUNCTION__ . '() can not be used any more.');
39de876c
AN
76}
77
78
79// Since Moodle 1.9.
80
81/**
39de876c
AN
82 * @deprecated since Moodle 1.9 MDL-13303 - please do not use this function any more.
83 */
d16185fd
AN
84function forum_get_child_posts() {
85 throw new coding_exception(__FUNCTION__ . '() can not be used any more.');
39de876c
AN
86}
87
88/**
39de876c
AN
89 * @deprecated since Moodle 1.9 MDL-13303 - please do not use this function any more.
90 */
d16185fd
AN
91function forum_get_discussion_posts() {
92 throw new coding_exception(__FUNCTION__ . '() can not be used any more.');
39de876c
AN
93}
94
95
96// Since Moodle 2.0.
97
98/**
39de876c
AN
99 * @deprecated since Moodle 2.0 MDL-21657 - please do not use this function any more.
100 */
d16185fd
AN
101function forum_get_ratings() {
102 throw new coding_exception(__FUNCTION__ . '() can not be used any more.');
39de876c
AN
103}
104
105/**
39de876c
AN
106 * @deprecated since Moodle 2.0 MDL-14632 - please do not use this function any more.
107 */
d16185fd
AN
108function forum_get_tracking_link() {
109 throw new coding_exception(__FUNCTION__ . '() can not be used any more.');
39de876c
AN
110}
111
112/**
39de876c
AN
113 * @deprecated since Moodle 2.0 MDL-14113 - please do not use this function any more.
114 */
d16185fd
AN
115function forum_tp_count_discussion_unread_posts() {
116 throw new coding_exception(__FUNCTION__ . '() can not be used any more.');
39de876c
AN
117}
118
119/**
39de876c
AN
120 * @deprecated since Moodle 2.0 MDL-23479 - please do not use this function any more.
121 */
122function forum_convert_to_roles() {
d16185fd 123 throw new coding_exception(__FUNCTION__ . '() can not be used any more.');
39de876c
AN
124}
125
126/**
39de876c
AN
127 * @deprecated since Moodle 2.0 MDL-14113 - please do not use this function any more.
128 */
d16185fd
AN
129function forum_tp_get_read_records() {
130 throw new coding_exception(__FUNCTION__ . '() can not be used any more.');
39de876c
AN
131}
132
133/**
39de876c
AN
134 * @deprecated since Moodle 2.0 MDL-14113 - please do not use this function any more.
135 */
d16185fd
AN
136function forum_tp_get_discussion_read_records() {
137 throw new coding_exception(__FUNCTION__ . '() can not be used any more.');
39de876c
AN
138}
139
140// Deprecated in 2.3.
141
142/**
39de876c 143 * @deprecated since Moodle 2.3 MDL-33166 - please do not use this function any more.
39de876c 144 */
d16185fd
AN
145function forum_user_enrolled() {
146 throw new coding_exception(__FUNCTION__ . '() can not be used any more.');
39de876c
AN
147}
148
149
150// Deprecated in 2.4.
151
152/**
39de876c 153 * @deprecated since Moodle 2.4 use forum_user_can_see_post() instead
39de876c 154 */
d16185fd
AN
155function forum_user_can_view_post() {
156 throw new coding_exception(__FUNCTION__ . '() can not be used any more.');
39de876c
AN
157}
158
159
160// Deprecated in 2.6.
161
162/**
163 * FORUM_TRACKING_ON - deprecated alias for FORUM_TRACKING_FORCED.
164 * @deprecated since 2.6
165 */
166define('FORUM_TRACKING_ON', 2);
167
168/**
39de876c
AN
169 * @deprecated since Moodle 2.6
170 * @see shorten_text()
39de876c
AN
171 */
172function forum_shorten_post($message) {
d16185fd
AN
173 throw new coding_exception(__FUNCTION__ . '() can not be used any more. '
174 . 'Please use shorten_text($message, $CFG->forum_shortpost) instead.');
39de876c 175}
59075a43
AN
176
177// Deprecated in 2.8.
178
179/**
59075a43
AN
180 * @deprecated since Moodle 2.8 use \mod_forum\subscriptions::is_subscribed() instead
181 */
d16185fd
AN
182function forum_is_subscribed() {
183 throw new coding_exception(__FUNCTION__ . '() can not be used any more.');
59075a43
AN
184}
185
186/**
59075a43
AN
187 * @deprecated since Moodle 2.8 use \mod_forum\subscriptions::subscribe_user() instead
188 */
d16185fd
AN
189function forum_subscribe() {
190 throw new coding_exception(__FUNCTION__ . '() can not be used any more. Please use '
191 . \mod_forum\subscriptions::class . '::subscribe_user() instead');
59075a43
AN
192}
193
194/**
59075a43
AN
195 * @deprecated since Moodle 2.8 use \mod_forum\subscriptions::unsubscribe_user() instead
196 */
d16185fd
AN
197function forum_unsubscribe() {
198 throw new coding_exception(__FUNCTION__ . '() can not be used any more. Please use '
199 . \mod_forum\subscriptions::class . '::unsubscribe_user() instead');
59075a43
AN
200}
201
202/**
59075a43
AN
203 * @deprecated since Moodle 2.8 use \mod_forum\subscriptions::fetch_subscribed_users() instead
204 */
d16185fd
AN
205function forum_subscribed_users() {
206 throw new coding_exception(__FUNCTION__ . '() can not be used any more. Please use '
207 . \mod_forum\subscriptions::class . '::fetch_subscribed_users() instead');
59075a43
AN
208}
209
210/**
211 * Determine whether the forum is force subscribed.
212 *
59075a43
AN
213 * @deprecated since Moodle 2.8 use \mod_forum\subscriptions::is_forcesubscribed() instead
214 */
215function forum_is_forcesubscribed($forum) {
d16185fd
AN
216 throw new coding_exception(__FUNCTION__ . '() can not be used any more. Please use '
217 . \mod_forum\subscriptions::class . '::is_forcesubscribed() instead');
59075a43
AN
218}
219
220/**
59075a43
AN
221 * @deprecated since Moodle 2.8 use \mod_forum\subscriptions::set_subscription_mode() instead
222 */
223function forum_forcesubscribe($forumid, $value = 1) {
d16185fd
AN
224 throw new coding_exception(__FUNCTION__ . '() can not be used any more. Please use '
225 . \mod_forum\subscriptions::class . '::set_subscription_mode() instead');
59075a43
AN
226}
227
228/**
59075a43
AN
229 * @deprecated since Moodle 2.8 use \mod_forum\subscriptions::get_subscription_mode() instead
230 */
231function forum_get_forcesubscribed($forum) {
d16185fd
AN
232 throw new coding_exception(__FUNCTION__ . '() can not be used any more. Please use '
233 . \mod_forum\subscriptions::class . '::set_subscription_mode() instead');
59075a43
AN
234}
235
236/**
59075a43
AN
237 * @deprecated since Moodle 2.8 use \mod_forum\subscriptions::is_subscribed in combination wtih
238 * \mod_forum\subscriptions::fill_subscription_cache_for_course instead.
239 */
d16185fd
AN
240function forum_get_subscribed_forums() {
241 throw new coding_exception(__FUNCTION__ . '() can not be used any more. Please use '
242 . \mod_forum\subscriptions::class . '::is_subscribed(), and '
243 . \mod_forum\subscriptions::class . '::fill_subscription_cache_for_course() instead');
59075a43
AN
244}
245
246/**
59075a43
AN
247 * @deprecated since Moodle 2.8 use \mod_forum\subscriptions::get_unsubscribable_forums() instead
248 */
249function forum_get_optional_subscribed_forums() {
d16185fd
AN
250 throw new coding_exception(__FUNCTION__ . '() can not be used any more. Please use '
251 . \mod_forum\subscriptions::class . '::get_unsubscribable_forums() instead');
59075a43
AN
252}
253
254/**
59075a43
AN
255 * @deprecated since Moodle 2.8 use \mod_forum\subscriptions::get_potential_subscribers() instead
256 */
d16185fd
AN
257function forum_get_potential_subscribers() {
258 throw new coding_exception(__FUNCTION__ . '() can not be used any more. Please use '
259 . \mod_forum\subscriptions::class . '::get_potential_subscribers() instead');
59075a43 260}
31793839
AN
261
262/**
263 * Builds and returns the body of the email notification in plain text.
264 *
265 * @uses CONTEXT_MODULE
266 * @param object $course
267 * @param object $cm
268 * @param object $forum
269 * @param object $discussion
270 * @param object $post
271 * @param object $userfrom
272 * @param object $userto
273 * @param boolean $bare
274 * @param string $replyaddress The inbound address that a user can reply to the generated e-mail with. [Since 2.8].
275 * @return string The email body in plain text format.
276 * @deprecated since Moodle 3.0 use \mod_forum\output\forum_post_email instead
277 */
278function forum_make_mail_text($course, $cm, $forum, $discussion, $post, $userfrom, $userto, $bare = false, $replyaddress = null) {
279 global $PAGE;
280 $renderable = new \mod_forum\output\forum_post_email(
281 $course,
282 $cm,
283 $forum,
284 $discussion,
285 $post,
286 $userfrom,
287 $userto,
288 forum_user_can_post($forum, $discussion, $userto, $cm, $course)
289 );
290
291 $modcontext = context_module::instance($cm->id);
292 $renderable->viewfullnames = has_capability('moodle/site:viewfullnames', $modcontext, $userto->id);
293
294 if ($bare) {
295 $renderer = $PAGE->get_renderer('mod_forum', 'emaildigestfull', 'textemail');
296 } else {
297 $renderer = $PAGE->get_renderer('mod_forum', 'email', 'textemail');
298 }
299
300 debugging("forum_make_mail_text() has been deprecated, please use the \mod_forum\output\forum_post_email renderable instead.",
301 DEBUG_DEVELOPER);
302
303 return $renderer->render($renderable);
304}
305
306/**
307 * Builds and returns the body of the email notification in html format.
308 *
309 * @param object $course
310 * @param object $cm
311 * @param object $forum
312 * @param object $discussion
313 * @param object $post
314 * @param object $userfrom
315 * @param object $userto
316 * @param string $replyaddress The inbound address that a user can reply to the generated e-mail with. [Since 2.8].
317 * @return string The email text in HTML format
318 * @deprecated since Moodle 3.0 use \mod_forum\output\forum_post_email instead
319 */
320function forum_make_mail_html($course, $cm, $forum, $discussion, $post, $userfrom, $userto, $replyaddress = null) {
321 return forum_make_mail_post($course,
322 $cm,
323 $forum,
324 $discussion,
325 $post,
326 $userfrom,
327 $userto,
328 forum_user_can_post($forum, $discussion, $userto, $cm, $course)
329 );
330}
331
332/**
333 * Given the data about a posting, builds up the HTML to display it and
334 * returns the HTML in a string. This is designed for sending via HTML email.
335 *
336 * @param object $course
337 * @param object $cm
338 * @param object $forum
339 * @param object $discussion
340 * @param object $post
341 * @param object $userfrom
342 * @param object $userto
343 * @param bool $ownpost
344 * @param bool $reply
345 * @param bool $link
346 * @param bool $rate
347 * @param string $footer
348 * @return string
349 * @deprecated since Moodle 3.0 use \mod_forum\output\forum_post_email instead
350 */
351function forum_make_mail_post($course, $cm, $forum, $discussion, $post, $userfrom, $userto,
352 $ownpost=false, $reply=false, $link=false, $rate=false, $footer="") {
353 global $PAGE;
354 $renderable = new \mod_forum\output\forum_post_email(
355 $course,
356 $cm,
357 $forum,
358 $discussion,
359 $post,
360 $userfrom,
361 $userto,
362 $reply);
363
364 $modcontext = context_module::instance($cm->id);
365 $renderable->viewfullnames = has_capability('moodle/site:viewfullnames', $modcontext, $userto->id);
366
367 // Assume that this is being used as a standard forum email.
368 $renderer = $PAGE->get_renderer('mod_forum', 'email', 'htmlemail');
369
370 debugging("forum_make_mail_post() has been deprecated, please use the \mod_forum\output\forum_post_email renderable instead.",
371 DEBUG_DEVELOPER);
372
373 return $renderer->render($renderable);
374}
4459ad29
AN
375
376/**
377 * Removes properties from user record that are not necessary for sending post notifications.
378 *
379 * @param stdClass $user
380 * @return void, $user parameter is modified
381 * @deprecated since Moodle 3.7
382 */
383function forum_cron_minimise_user_record(stdClass $user) {
384 debugging("forum_cron_minimise_user_record() has been deprecated and has not been replaced.",
385 DEBUG_DEVELOPER);
386
387 // We store large amount of users in one huge array,
388 // make sure we do not store info there we do not actually need
389 // in mail generation code or messaging.
390
391 unset($user->institution);
392 unset($user->department);
393 unset($user->address);
394 unset($user->city);
395 unset($user->url);
396 unset($user->currentlogin);
397 unset($user->description);
398 unset($user->descriptionformat);
399}
400
401/**
402 * Function to be run periodically according to the scheduled task.
403 *
404 * Finds all posts that have yet to be mailed out, and mails them out to all subscribers as well as other maintance
405 * tasks.
406 *
407 * @deprecated since Moodle 3.7
408 */
409function forum_cron() {
410 debugging("forum_cron() has been deprecated and replaced with new tasks. Please uses these instead.",
411 DEBUG_DEVELOPER);
412}
2e19ca18
RW
413
414/**
415 * Prints a forum discussion
416 *
417 * @uses CONTEXT_MODULE
418 * @uses FORUM_MODE_FLATNEWEST
419 * @uses FORUM_MODE_FLATOLDEST
420 * @uses FORUM_MODE_THREADED
421 * @uses FORUM_MODE_NESTED
422 * @param stdClass $course
423 * @param stdClass $cm
424 * @param stdClass $forum
425 * @param stdClass $discussion
426 * @param stdClass $post
427 * @param int $mode
428 * @param mixed $canreply
429 * @param bool $canrate
430 * @deprecated since Moodle 3.7
431 */
432function forum_print_discussion($course, $cm, $forum, $discussion, $post, $mode, $canreply=NULL, $canrate=false) {
f30f46db
RW
433 debugging('forum_print_discussion() has been deprecated, ' .
434 'please use \mod_forum\local\renderers\discussion instead.', DEBUG_DEVELOPER);
2e19ca18
RW
435
436 global $USER, $CFG;
437
438 require_once($CFG->dirroot.'/rating/lib.php');
439
440 $ownpost = (isloggedin() && $USER->id == $post->userid);
441
442 $modcontext = context_module::instance($cm->id);
443 if ($canreply === NULL) {
444 $reply = forum_user_can_post($forum, $discussion, $USER, $cm, $course, $modcontext);
445 } else {
446 $reply = $canreply;
447 }
448
449 // $cm holds general cache for forum functions
450 $cm->cache = new stdClass;
451 $cm->cache->groups = groups_get_all_groups($course->id, 0, $cm->groupingid);
452 $cm->cache->usersgroups = array();
453
454 $posters = array();
455
456 // preload all posts - TODO: improve...
457 if ($mode == FORUM_MODE_FLATNEWEST) {
458 $sort = "p.created DESC";
459 } else {
460 $sort = "p.created ASC";
461 }
462
463 $forumtracked = forum_tp_is_tracked($forum);
464 $posts = forum_get_all_discussion_posts($discussion->id, $sort, $forumtracked);
465 $post = $posts[$post->id];
466
467 foreach ($posts as $pid=>$p) {
468 $posters[$p->userid] = $p->userid;
469 }
470
471 // preload all groups of ppl that posted in this discussion
472 if ($postersgroups = groups_get_all_groups($course->id, $posters, $cm->groupingid, 'gm.id, gm.groupid, gm.userid')) {
473 foreach($postersgroups as $pg) {
474 if (!isset($cm->cache->usersgroups[$pg->userid])) {
475 $cm->cache->usersgroups[$pg->userid] = array();
476 }
477 $cm->cache->usersgroups[$pg->userid][$pg->groupid] = $pg->groupid;
478 }
479 unset($postersgroups);
480 }
481
482 //load ratings
483 if ($forum->assessed != RATING_AGGREGATE_NONE) {
484 $ratingoptions = new stdClass;
485 $ratingoptions->context = $modcontext;
486 $ratingoptions->component = 'mod_forum';
487 $ratingoptions->ratingarea = 'post';
488 $ratingoptions->items = $posts;
489 $ratingoptions->aggregate = $forum->assessed;//the aggregation method
490 $ratingoptions->scaleid = $forum->scale;
491 $ratingoptions->userid = $USER->id;
492 if ($forum->type == 'single' or !$discussion->id) {
493 $ratingoptions->returnurl = "$CFG->wwwroot/mod/forum/view.php?id=$cm->id";
494 } else {
495 $ratingoptions->returnurl = "$CFG->wwwroot/mod/forum/discuss.php?d=$discussion->id";
496 }
497 $ratingoptions->assesstimestart = $forum->assesstimestart;
498 $ratingoptions->assesstimefinish = $forum->assesstimefinish;
499
500 $rm = new rating_manager();
501 $posts = $rm->get_ratings($ratingoptions);
502 }
503
504
505 $post->forum = $forum->id; // Add the forum id to the post object, later used by forum_print_post
506 $post->forumtype = $forum->type;
507
508 $post->subject = format_string($post->subject);
509
510 $postread = !empty($post->postread);
511
512 forum_print_post_start($post);
513 forum_print_post($post, $discussion, $forum, $cm, $course, $ownpost, $reply, false,
514 '', '', $postread, true, $forumtracked);
515
516 switch ($mode) {
517 case FORUM_MODE_FLATOLDEST :
518 case FORUM_MODE_FLATNEWEST :
519 default:
520 forum_print_posts_flat($course, $cm, $forum, $discussion, $post, $mode, $reply, $forumtracked, $posts);
521 break;
522
523 case FORUM_MODE_THREADED :
524 forum_print_posts_threaded($course, $cm, $forum, $discussion, $post, 0, $reply, $forumtracked, $posts);
525 break;
526
527 case FORUM_MODE_NESTED :
528 forum_print_posts_nested($course, $cm, $forum, $discussion, $post, $reply, $forumtracked, $posts);
529 break;
530 }
531 forum_print_post_end($post);
532}
533
534
535/**
536 * Return a static array of posts that are open.
537 *
538 * @return array
539 * @deprecated since Moodle 3.7
540 */
541function forum_post_nesting_cache() {
f30f46db
RW
542 debugging('forum_post_nesting_cache() has been deprecated, ' .
543 'please use \mod_forum\local\renderers\posts instead.', DEBUG_DEVELOPER);
2e19ca18
RW
544 static $nesting = array();
545 return $nesting;
546}
547
548/**
549 * Return true for the first time this post was started
550 *
551 * @param int $id The id of the post to start
552 * @return bool
553 * @deprecated since Moodle 3.7
554 */
555function forum_should_start_post_nesting($id) {
f30f46db
RW
556 debugging('forum_should_start_post_nesting() has been deprecated, ' .
557 'please use \mod_forum\local\renderers\posts instead.', DEBUG_DEVELOPER);
2e19ca18
RW
558 $cache = forum_post_nesting_cache();
559 if (!array_key_exists($id, $cache)) {
560 $cache[$id] = 1;
561 return true;
562 } else {
563 $cache[$id]++;
564 return false;
565 }
566}
567
568/**
569 * Return true when all the opens are nested with a close.
570 *
571 * @param int $id The id of the post to end
572 * @return bool
573 * @deprecated since Moodle 3.7
574 */
575function forum_should_end_post_nesting($id) {
f30f46db
RW
576 debugging('forum_should_end_post_nesting() has been deprecated, ' .
577 'please use \mod_forum\local\renderers\posts instead.', DEBUG_DEVELOPER);
2e19ca18
RW
578 $cache = forum_post_nesting_cache();
579 if (!array_key_exists($id, $cache)) {
580 return true;
581 } else {
582 $cache[$id]--;
583 if ($cache[$id] == 0) {
584 unset($cache[$id]);
585 return true;
586 }
587 }
588 return false;
589}
590
591/**
592 * Start a forum post container
593 *
594 * @param object $post The post to print.
595 * @param bool $return Return the string or print it
596 * @return string
597 * @deprecated since Moodle 3.7
598 */
599function forum_print_post_start($post, $return = false) {
f30f46db
RW
600 debugging('forum_print_post_start() has been deprecated, ' .
601 'please use \mod_forum\local\renderers\posts instead.', DEBUG_DEVELOPER);
2e19ca18
RW
602 $output = '';
603
604 if (forum_should_start_post_nesting($post->id)) {
605 $attributes = [
606 'id' => 'p'.$post->id,
607 'tabindex' => -1,
608 'class' => 'relativelink'
609 ];
610 $output .= html_writer::start_tag('article', $attributes);
611 }
612 if ($return) {
613 return $output;
614 }
615 echo $output;
616 return;
617}
618
619/**
620 * End a forum post container
621 *
622 * @param object $post The post to print.
623 * @param bool $return Return the string or print it
624 * @return string
625 * @deprecated since Moodle 3.7
626 */
627function forum_print_post_end($post, $return = false) {
f30f46db
RW
628 debugging('forum_print_post_end() has been deprecated, ' .
629 'please use \mod_forum\local\renderers\posts instead.', DEBUG_DEVELOPER);
2e19ca18
RW
630 $output = '';
631
632 if (forum_should_end_post_nesting($post->id)) {
633 $output .= html_writer::end_tag('article');
634 }
635 if ($return) {
636 return $output;
637 }
638 echo $output;
639 return;
640}
641
642/**
643 * Print a forum post
644 * This function should always be surrounded with calls to forum_print_post_start
645 * and forum_print_post_end to create the surrounding container for the post.
646 * Replies can be nested before forum_print_post_end and should reflect the structure of
647 * thread.
648 *
649 * @global object
650 * @global object
651 * @uses FORUM_MODE_THREADED
652 * @uses PORTFOLIO_FORMAT_PLAINHTML
653 * @uses PORTFOLIO_FORMAT_FILE
654 * @uses PORTFOLIO_FORMAT_RICHHTML
655 * @uses PORTFOLIO_ADD_TEXT_LINK
656 * @uses CONTEXT_MODULE
657 * @param object $post The post to print.
658 * @param object $discussion
659 * @param object $forum
660 * @param object $cm
661 * @param object $course
662 * @param boolean $ownpost Whether this post belongs to the current user.
663 * @param boolean $reply Whether to print a 'reply' link at the bottom of the message.
664 * @param boolean $link Just print a shortened version of the post as a link to the full post.
665 * @param string $footer Extra stuff to print after the message.
666 * @param string $highlight Space-separated list of terms to highlight.
667 * @param int $post_read true, false or -99. If we already know whether this user
668 * has read this post, pass that in, otherwise, pass in -99, and this
669 * function will work it out.
670 * @param boolean $dummyifcantsee When forum_user_can_see_post says that
671 * the current user can't see this post, if this argument is true
672 * (the default) then print a dummy 'you can't see this post' post.
673 * If false, don't output anything at all.
674 * @param bool|null $istracked
675 * @return void
676 * @deprecated since Moodle 3.7
677 */
678function forum_print_post($post, $discussion, $forum, &$cm, $course, $ownpost=false, $reply=false, $link=false,
679 $footer="", $highlight="", $postisread=null, $dummyifcantsee=true, $istracked=null, $return=false) {
f30f46db
RW
680 debugging('forum_print_post() has been deprecated, ' .
681 'please use \mod_forum\local\renderers\posts instead.', DEBUG_DEVELOPER);
2e19ca18
RW
682 global $USER, $CFG, $OUTPUT;
683
684 require_once($CFG->libdir . '/filelib.php');
685
686 // String cache
687 static $str;
688 // This is an extremely hacky way to ensure we only print the 'unread' anchor
689 // the first time we encounter an unread post on a page. Ideally this would
690 // be moved into the caller somehow, and be better testable. But at the time
691 // of dealing with this bug, this static workaround was the most surgical and
692 // it fits together with only printing th unread anchor id once on a given page.
693 static $firstunreadanchorprinted = false;
694
695 $modcontext = context_module::instance($cm->id);
696
697 $post->course = $course->id;
698 $post->forum = $forum->id;
699 $post->message = file_rewrite_pluginfile_urls($post->message, 'pluginfile.php', $modcontext->id, 'mod_forum', 'post', $post->id);
700 if (!empty($CFG->enableplagiarism)) {
701 require_once($CFG->libdir.'/plagiarismlib.php');
702 $post->message .= plagiarism_get_links(array('userid' => $post->userid,
703 'content' => $post->message,
704 'cmid' => $cm->id,
705 'course' => $post->course,
706 'forum' => $post->forum));
707 }
708
709 // caching
710 if (!isset($cm->cache)) {
711 $cm->cache = new stdClass;
712 }
713
714 if (!isset($cm->cache->caps)) {
715 $cm->cache->caps = array();
716 $cm->cache->caps['mod/forum:viewdiscussion'] = has_capability('mod/forum:viewdiscussion', $modcontext);
717 $cm->cache->caps['moodle/site:viewfullnames'] = has_capability('moodle/site:viewfullnames', $modcontext);
718 $cm->cache->caps['mod/forum:editanypost'] = has_capability('mod/forum:editanypost', $modcontext);
719 $cm->cache->caps['mod/forum:splitdiscussions'] = has_capability('mod/forum:splitdiscussions', $modcontext);
720 $cm->cache->caps['mod/forum:deleteownpost'] = has_capability('mod/forum:deleteownpost', $modcontext);
721 $cm->cache->caps['mod/forum:deleteanypost'] = has_capability('mod/forum:deleteanypost', $modcontext);
722 $cm->cache->caps['mod/forum:viewanyrating'] = has_capability('mod/forum:viewanyrating', $modcontext);
723 $cm->cache->caps['mod/forum:exportpost'] = has_capability('mod/forum:exportpost', $modcontext);
724 $cm->cache->caps['mod/forum:exportownpost'] = has_capability('mod/forum:exportownpost', $modcontext);
725 }
726
727 if (!isset($cm->uservisible)) {
728 $cm->uservisible = \core_availability\info_module::is_user_visible($cm, 0, false);
729 }
730
731 if ($istracked && is_null($postisread)) {
732 $postisread = forum_tp_is_post_read($USER->id, $post);
733 }
734
735 if (!forum_user_can_see_post($forum, $discussion, $post, null, $cm, false)) {
736 // Do _not_ check the deleted flag - we need to display a different UI.
737 $output = '';
738 if (!$dummyifcantsee) {
739 if ($return) {
740 return $output;
741 }
742 echo $output;
743 return;
744 }
745
746 $output .= html_writer::start_tag('div', array('class' => 'forumpost clearfix',
747 'aria-label' => get_string('hiddenforumpost', 'forum')));
748 $output .= html_writer::start_tag('header', array('class' => 'row header'));
749 $output .= html_writer::tag('div', '', array('class' => 'left picture', 'role' => 'presentation')); // Picture.
750 if ($post->parent) {
751 $output .= html_writer::start_tag('div', array('class' => 'topic'));
752 } else {
753 $output .= html_writer::start_tag('div', array('class' => 'topic starter'));
754 }
755 $output .= html_writer::tag('div', get_string('forumsubjecthidden','forum'), array('class' => 'subject',
756 'role' => 'header',
757 'id' => ('headp' . $post->id))); // Subject.
758 $authorclasses = array('class' => 'author');
759 $output .= html_writer::tag('address', get_string('forumauthorhidden', 'forum'), $authorclasses); // Author.
760 $output .= html_writer::end_tag('div');
761 $output .= html_writer::end_tag('header'); // Header.
762 $output .= html_writer::start_tag('div', array('class'=>'row'));
763 $output .= html_writer::tag('div', '&nbsp;', array('class'=>'left side')); // Groups
764 $output .= html_writer::tag('div', get_string('forumbodyhidden','forum'), array('class'=>'content')); // Content
765 $output .= html_writer::end_tag('div'); // row
766 $output .= html_writer::end_tag('div'); // forumpost
767
768 if ($return) {
769 return $output;
770 }
771 echo $output;
772 return;
773 }
774
775 if (!empty($post->deleted)) {
776 // Note: Posts marked as deleted are still returned by the above forum_user_can_post because it is required for
777 // nesting of posts.
778 $output = '';
779 if (!$dummyifcantsee) {
780 if ($return) {
781 return $output;
782 }
783 echo $output;
784 return;
785 }
786 $output .= html_writer::start_tag('div', [
787 'class' => 'forumpost clearfix',
788 'aria-label' => get_string('forumbodydeleted', 'forum'),
789 ]);
790
791 $output .= html_writer::start_tag('header', array('class' => 'row header'));
792 $output .= html_writer::tag('div', '', array('class' => 'left picture', 'role' => 'presentation'));
793
794 $classes = ['topic'];
795 if (!empty($post->parent)) {
796 $classes[] = 'starter';
797 }
798 $output .= html_writer::start_tag('div', ['class' => implode(' ', $classes)]);
799
800 // Subject.
801 $output .= html_writer::tag('div', get_string('forumsubjectdeleted', 'forum'), [
802 'class' => 'subject',
803 'role' => 'header',
804 'id' => ('headp' . $post->id)
805 ]);
806
807 // Author.
808 $output .= html_writer::tag('address', '', ['class' => 'author']);
809
810 $output .= html_writer::end_tag('div');
811 $output .= html_writer::end_tag('header'); // End header.
812 $output .= html_writer::start_tag('div', ['class' => 'row']);
813 $output .= html_writer::tag('div', '&nbsp;', ['class' => 'left side']); // Groups.
814 $output .= html_writer::tag('div', get_string('forumbodydeleted', 'forum'), ['class' => 'content']); // Content.
815 $output .= html_writer::end_tag('div'); // End row.
816 $output .= html_writer::end_tag('div'); // End forumpost.
817
818 if ($return) {
819 return $output;
820 }
821 echo $output;
822 return;
823 }
824
825 if (empty($str)) {
826 $str = new stdClass;
827 $str->edit = get_string('edit', 'forum');
828 $str->delete = get_string('delete', 'forum');
829 $str->reply = get_string('reply', 'forum');
830 $str->parent = get_string('parent', 'forum');
831 $str->pruneheading = get_string('pruneheading', 'forum');
832 $str->prune = get_string('prune', 'forum');
833 $str->displaymode = get_user_preferences('forum_displaymode', $CFG->forum_displaymode);
834 $str->markread = get_string('markread', 'forum');
835 $str->markunread = get_string('markunread', 'forum');
836 }
837
838 $discussionlink = new moodle_url('/mod/forum/discuss.php', array('d'=>$post->discussion));
839
840 // Build an object that represents the posting user
841 $postuser = new stdClass;
842 $postuserfields = explode(',', user_picture::fields());
843 $postuser = username_load_fields_from_object($postuser, $post, null, $postuserfields);
844 $postuser->id = $post->userid;
845 $postuser->fullname = fullname($postuser, $cm->cache->caps['moodle/site:viewfullnames']);
846 $postuser->profilelink = new moodle_url('/user/view.php', array('id'=>$post->userid, 'course'=>$course->id));
847
848 // Prepare the groups the posting user belongs to
849 if (isset($cm->cache->usersgroups)) {
850 $groups = array();
851 if (isset($cm->cache->usersgroups[$post->userid])) {
852 foreach ($cm->cache->usersgroups[$post->userid] as $gid) {
853 $groups[$gid] = $cm->cache->groups[$gid];
854 }
855 }
856 } else {
857 $groups = groups_get_all_groups($course->id, $post->userid, $cm->groupingid);
858 }
859
860 // Prepare the attachements for the post, files then images
861 list($attachments, $attachedimages) = forum_print_attachments($post, $cm, 'separateimages');
862
863 // Determine if we need to shorten this post
864 $shortenpost = ($link && (strlen(strip_tags($post->message)) > $CFG->forum_longpost));
865
866 // Prepare an array of commands
867 $commands = array();
868
869 // Add a permalink.
870 $permalink = new moodle_url($discussionlink);
871 $permalink->set_anchor('p' . $post->id);
872 $commands[] = array('url' => $permalink, 'text' => get_string('permalink', 'forum'), 'attributes' => ['rel' => 'bookmark']);
873
874 // SPECIAL CASE: The front page can display a news item post to non-logged in users.
875 // Don't display the mark read / unread controls in this case.
876 if ($istracked && $CFG->forum_usermarksread && isloggedin()) {
877 $url = new moodle_url($discussionlink, array('postid'=>$post->id, 'mark'=>'unread'));
878 $text = $str->markunread;
879 if (!$postisread) {
880 $url->param('mark', 'read');
881 $text = $str->markread;
882 }
883 if ($str->displaymode == FORUM_MODE_THREADED) {
884 $url->param('parent', $post->parent);
885 } else {
886 $url->set_anchor('p'.$post->id);
887 }
888 $commands[] = array('url'=>$url, 'text'=>$text, 'attributes' => ['rel' => 'bookmark']);
889 }
890
891 // Zoom in to the parent specifically
892 if ($post->parent) {
893 $url = new moodle_url($discussionlink);
894 if ($str->displaymode == FORUM_MODE_THREADED) {
895 $url->param('parent', $post->parent);
896 } else {
897 $url->set_anchor('p'.$post->parent);
898 }
899 $commands[] = array('url'=>$url, 'text'=>$str->parent, 'attributes' => ['rel' => 'bookmark']);
900 }
901
902 // Hack for allow to edit news posts those are not displayed yet until they are displayed
903 $age = time() - $post->created;
904 if (!$post->parent && $forum->type == 'news' && $discussion->timestart > time()) {
905 $age = 0;
906 }
907
908 if ($forum->type == 'single' and $discussion->firstpost == $post->id) {
909 if (has_capability('moodle/course:manageactivities', $modcontext)) {
910 // The first post in single simple is the forum description.
911 $commands[] = array('url'=>new moodle_url('/course/modedit.php', array('update'=>$cm->id, 'sesskey'=>sesskey(), 'return'=>1)), 'text'=>$str->edit);
912 }
913 } else if (($ownpost && $age < $CFG->maxeditingtime) || $cm->cache->caps['mod/forum:editanypost']) {
914 $commands[] = array('url'=>new moodle_url('/mod/forum/post.php', array('edit'=>$post->id)), 'text'=>$str->edit);
915 }
916
917 if ($cm->cache->caps['mod/forum:splitdiscussions'] && $post->parent && $forum->type != 'single') {
918 $commands[] = array('url'=>new moodle_url('/mod/forum/post.php', array('prune'=>$post->id)), 'text'=>$str->prune, 'title'=>$str->pruneheading);
919 }
920
921 if ($forum->type == 'single' and $discussion->firstpost == $post->id) {
922 // Do not allow deleting of first post in single simple type.
923 } else if (($ownpost && $age < $CFG->maxeditingtime && $cm->cache->caps['mod/forum:deleteownpost']) || $cm->cache->caps['mod/forum:deleteanypost']) {
924 $commands[] = array('url'=>new moodle_url('/mod/forum/post.php', array('delete'=>$post->id)), 'text'=>$str->delete);
925 }
926
927 if ($reply) {
928 $commands[] = array('url'=>new moodle_url('/mod/forum/post.php#mformforum', array('reply'=>$post->id)), 'text'=>$str->reply);
929 }
930
931 if ($CFG->enableportfolios && ($cm->cache->caps['mod/forum:exportpost'] || ($ownpost && $cm->cache->caps['mod/forum:exportownpost']))) {
932 $p = array('postid' => $post->id);
933 require_once($CFG->libdir.'/portfoliolib.php');
934 $button = new portfolio_add_button();
935 $button->set_callback_options('forum_portfolio_caller', array('postid' => $post->id), 'mod_forum');
936 if (empty($attachments)) {
937 $button->set_formats(PORTFOLIO_FORMAT_PLAINHTML);
938 } else {
939 $button->set_formats(PORTFOLIO_FORMAT_RICHHTML);
940 }
941
942 $porfoliohtml = $button->to_html(PORTFOLIO_ADD_TEXT_LINK);
943 if (!empty($porfoliohtml)) {
944 $commands[] = $porfoliohtml;
945 }
946 }
947 // Finished building commands
948
949
950 // Begin output
951
952 $output = '';
953
954 if ($istracked) {
955 if ($postisread) {
956 $forumpostclass = ' read';
957 } else {
958 $forumpostclass = ' unread';
959 // If this is the first unread post printed then give it an anchor and id of unread.
960 if (!$firstunreadanchorprinted) {
961 $output .= html_writer::tag('a', '', array('id' => 'unread'));
962 $firstunreadanchorprinted = true;
963 }
964 }
965 } else {
966 // ignore trackign status if not tracked or tracked param missing
967 $forumpostclass = '';
968 }
969
970 $topicclass = '';
971 if (empty($post->parent)) {
972 $topicclass = ' firstpost starter';
973 }
974
975 if (!empty($post->lastpost)) {
976 $forumpostclass .= ' lastpost';
977 }
978
979 // Flag to indicate whether we should hide the author or not.
980 $authorhidden = forum_is_author_hidden($post, $forum);
981 $postbyuser = new stdClass;
982 $postbyuser->post = $post->subject;
983 $postbyuser->user = $postuser->fullname;
984 $discussionbyuser = get_string('postbyuser', 'forum', $postbyuser);
985 // Begin forum post.
986 $output .= html_writer::start_div('forumpost clearfix' . $forumpostclass . $topicclass,
987 ['aria-label' => $discussionbyuser]);
988 // Begin header row.
989 $output .= html_writer::start_tag('header', ['class' => 'row header clearfix']);
990
991 // User picture.
992 if (!$authorhidden) {
993 $picture = $OUTPUT->user_picture($postuser, ['courseid' => $course->id]);
994 $output .= html_writer::div($picture, 'left picture', ['role' => 'presentation']);
995 $topicclass = 'topic' . $topicclass;
996 }
997
998 // Begin topic column.
999 $output .= html_writer::start_div($topicclass);
1000 $postsubject = $post->subject;
1001 if (empty($post->subjectnoformat)) {
1002 $postsubject = format_string($postsubject);
1003 }
1004 $output .= html_writer::div($postsubject, 'subject', ['role' => 'heading', 'aria-level' => '1', 'id' => ('headp' . $post->id)]);
1005
1006 if ($authorhidden) {
1007 $bytext = userdate_htmltime($post->created);
1008 } else {
1009 $by = new stdClass();
1010 $by->date = userdate_htmltime($post->created);
1011 $by->name = html_writer::link($postuser->profilelink, $postuser->fullname);
1012 $bytext = get_string('bynameondate', 'forum', $by);
1013 }
1014 $bytextoptions = [
1015 'class' => 'author'
1016 ];
1017 $output .= html_writer::tag('address', $bytext, $bytextoptions);
1018 // End topic column.
1019 $output .= html_writer::end_div();
1020
1021 // End header row.
1022 $output .= html_writer::end_tag('header');
1023
1024 // Row with the forum post content.
1025 $output .= html_writer::start_div('row maincontent clearfix');
1026 // Show if author is not hidden or we have groups.
1027 if (!$authorhidden || $groups) {
1028 $output .= html_writer::start_div('left');
1029 $groupoutput = '';
1030 if ($groups) {
1031 $groupoutput = print_group_picture($groups, $course->id, false, true, true);
1032 }
1033 if (empty($groupoutput)) {
1034 $groupoutput = '&nbsp;';
1035 }
1036 $output .= html_writer::div($groupoutput, 'grouppictures');
1037 $output .= html_writer::end_div(); // Left side.
1038 }
1039
1040 $output .= html_writer::start_tag('div', array('class'=>'no-overflow'));
1041 $output .= html_writer::start_tag('div', array('class'=>'content'));
1042
1043 $options = new stdClass;
1044 $options->para = false;
1045 $options->trusted = $post->messagetrust;
1046 $options->context = $modcontext;
1047 if ($shortenpost) {
1048 // Prepare shortened version by filtering the text then shortening it.
1049 $postclass = 'shortenedpost';
1050 $postcontent = format_text($post->message, $post->messageformat, $options);
1051 $postcontent = shorten_text($postcontent, $CFG->forum_shortpost);
1052 $postcontent .= html_writer::link($discussionlink, get_string('readtherest', 'forum'));
1053 $postcontent .= html_writer::tag('div', '('.get_string('numwords', 'moodle', count_words($post->message)).')',
1054 array('class'=>'post-word-count'));
1055 } else {
1056 // Prepare whole post
1057 $postclass = 'fullpost';
1058 $postcontent = format_text($post->message, $post->messageformat, $options, $course->id);
1059 if (!empty($highlight)) {
1060 $postcontent = highlight($highlight, $postcontent);
1061 }
1062 if (!empty($forum->displaywordcount)) {
1063 $postcontent .= html_writer::tag('div', get_string('numwords', 'moodle', count_words($postcontent)),
1064 array('class'=>'post-word-count'));
1065 }
1066 $postcontent .= html_writer::tag('div', $attachedimages, array('class'=>'attachedimages'));
1067 }
1068
1069 if (\core_tag_tag::is_enabled('mod_forum', 'forum_posts')) {
1070 $postcontent .= $OUTPUT->tag_list(core_tag_tag::get_item_tags('mod_forum', 'forum_posts', $post->id), null, 'forum-tags');
1071 }
1072
1073 // Output the post content
1074 $output .= html_writer::tag('div', $postcontent, array('class'=>'posting '.$postclass));
1075 $output .= html_writer::end_tag('div'); // Content
1076 $output .= html_writer::end_tag('div'); // Content mask
1077 $output .= html_writer::end_tag('div'); // Row
1078
1079 $output .= html_writer::start_tag('nav', array('class' => 'row side'));
1080 $output .= html_writer::tag('div','&nbsp;', array('class'=>'left'));
1081 $output .= html_writer::start_tag('div', array('class'=>'options clearfix'));
1082
1083 if (!empty($attachments)) {
1084 $output .= html_writer::tag('div', $attachments, array('class' => 'attachments'));
1085 }
1086
1087 // Output ratings
1088 if (!empty($post->rating)) {
1089 $output .= html_writer::tag('div', $OUTPUT->render($post->rating), array('class'=>'forum-post-rating'));
1090 }
1091
1092 // Output the commands
1093 $commandhtml = array();
1094 foreach ($commands as $command) {
1095 if (is_array($command)) {
1096 $attributes = ['class' => 'nav-item nav-link'];
1097 if (isset($command['attributes'])) {
1098 $attributes = array_merge($attributes, $command['attributes']);
1099 }
1100 $commandhtml[] = html_writer::link($command['url'], $command['text'], $attributes);
1101 } else {
1102 $commandhtml[] = $command;
1103 }
1104 }
1105 $output .= html_writer::tag('div', implode(' ', $commandhtml), array('class' => 'commands nav'));
1106
1107 // Output link to post if required
1108 if ($link) {
1109 if (forum_user_can_post($forum, $discussion, $USER, $cm, $course, $modcontext)) {
1110 $langstring = 'discussthistopic';
1111 } else {
1112 $langstring = 'viewthediscussion';
1113 }
1114 if ($post->replies == 1) {
1115 $replystring = get_string('repliesone', 'forum', $post->replies);
1116 } else {
1117 $replystring = get_string('repliesmany', 'forum', $post->replies);
1118 }
1119 if (!empty($discussion->unread) && $discussion->unread !== '-') {
1120 $replystring .= ' <span class="sep">/</span> <span class="unread">';
1121 $unreadlink = new moodle_url($discussionlink, null, 'unread');
1122 if ($discussion->unread == 1) {
1123 $replystring .= html_writer::link($unreadlink, get_string('unreadpostsone', 'forum'));
1124 } else {
1125 $replystring .= html_writer::link($unreadlink, get_string('unreadpostsnumber', 'forum', $discussion->unread));
1126 }
1127 $replystring .= '</span>';
1128 }
1129
1130 $output .= html_writer::start_tag('div', array('class'=>'link'));
1131 $output .= html_writer::link($discussionlink, get_string($langstring, 'forum'));
1132 $output .= '&nbsp;('.$replystring.')';
1133 $output .= html_writer::end_tag('div'); // link
1134 }
1135
1136 // Output footer if required
1137 if ($footer) {
1138 $output .= html_writer::tag('div', $footer, array('class'=>'footer'));
1139 }
1140
1141 // Close remaining open divs
1142 $output .= html_writer::end_tag('div'); // content
1143 $output .= html_writer::end_tag('nav'); // row
1144 $output .= html_writer::end_tag('div'); // forumpost
1145
1146 // Mark the forum post as read if required
1147 if ($istracked && !$CFG->forum_usermarksread && !$postisread) {
1148 forum_tp_mark_post_read($USER->id, $post);
1149 }
1150
1151 if ($return) {
1152 return $output;
1153 }
1154 echo $output;
1155 return;
1156}
1157
1158/**
1159 * @global object
1160 * @global object
1161 * @uses FORUM_MODE_FLATNEWEST
1162 * @param object $course
1163 * @param object $cm
1164 * @param object $forum
1165 * @param object $discussion
1166 * @param object $post
1167 * @param object $mode
1168 * @param bool $reply
1169 * @param bool $forumtracked
1170 * @param array $posts
1171 * @return void
1172 * @deprecated since Moodle 3.7
1173 */
1174function forum_print_posts_flat($course, &$cm, $forum, $discussion, $post, $mode, $reply, $forumtracked, $posts) {
f30f46db
RW
1175 debugging('forum_print_posts_flat() has been deprecated, ' .
1176 'please use \mod_forum\local\renderers\posts instead.', DEBUG_DEVELOPER);
2e19ca18
RW
1177 global $USER, $CFG;
1178
1179 $link = false;
1180
1181 foreach ($posts as $post) {
1182 if (!$post->parent) {
1183 continue;
1184 }
1185 $post->subject = format_string($post->subject);
1186 $ownpost = ($USER->id == $post->userid);
1187
1188 $postread = !empty($post->postread);
1189
1190 forum_print_post_start($post);
1191 forum_print_post($post, $discussion, $forum, $cm, $course, $ownpost, $reply, $link,
1192 '', '', $postread, true, $forumtracked);
1193 forum_print_post_end($post);
1194 }
1195}
1196
1197/**
1198 * @todo Document this function
1199 *
1200 * @global object
1201 * @global object
1202 * @uses CONTEXT_MODULE
1203 * @return void
1204 * @deprecated since Moodle 3.7
1205 */
1206function forum_print_posts_threaded($course, &$cm, $forum, $discussion, $parent, $depth, $reply, $forumtracked, $posts) {
f30f46db
RW
1207 debugging('forum_print_posts_threaded() has been deprecated, ' .
1208 'please use \mod_forum\local\renderers\posts instead.', DEBUG_DEVELOPER);
2e19ca18
RW
1209 global $USER, $CFG;
1210
1211 $link = false;
1212
1213 if (!empty($posts[$parent->id]->children)) {
1214 $posts = $posts[$parent->id]->children;
1215
1216 $modcontext = context_module::instance($cm->id);
1217 $canviewfullnames = has_capability('moodle/site:viewfullnames', $modcontext);
1218
1219 foreach ($posts as $post) {
1220
1221 echo '<div class="indent">';
1222 if ($depth > 0) {
1223 $ownpost = ($USER->id == $post->userid);
1224 $post->subject = format_string($post->subject);
1225
1226 $postread = !empty($post->postread);
1227
1228 forum_print_post_start($post);
1229 forum_print_post($post, $discussion, $forum, $cm, $course, $ownpost, $reply, $link,
1230 '', '', $postread, true, $forumtracked);
1231 forum_print_post_end($post);
1232 } else {
1233 if (!forum_user_can_see_post($forum, $discussion, $post, null, $cm, true)) {
1234 if (forum_user_can_see_post($forum, $discussion, $post, null, $cm, false)) {
1235 // This post has been deleted but still exists and may have children.
1236 $subject = get_string('privacy:request:delete:post:subject', 'mod_forum');
1237 $byline = '';
1238 } else {
1239 // The user can't see this post at all.
1240 echo "</div>\n";
1241 continue;
1242 }
1243 } else {
1244 $by = new stdClass();
1245 $by->name = fullname($post, $canviewfullnames);
1246 $by->date = userdate_htmltime($post->modified);
1247 $byline = ' ' . get_string("bynameondate", "forum", $by);
1248 $subject = format_string($post->subject, true);
1249 }
1250
1251 if ($forumtracked) {
1252 if (!empty($post->postread)) {
1253 $style = '<span class="forumthread read">';
1254 } else {
1255 $style = '<span class="forumthread unread">';
1256 }
1257 } else {
1258 $style = '<span class="forumthread">';
1259 }
1260
1261 echo $style;
1262 echo "<a name='{$post->id}'></a>";
1263 echo html_writer::link(new moodle_url('/mod/forum/discuss.php', [
1264 'd' => $post->discussion,
1265 'parent' => $post->id,
1266 ]), $subject);
1267 echo $byline;
1268 echo "</span>";
1269 }
1270
1271 forum_print_posts_threaded($course, $cm, $forum, $discussion, $post, $depth-1, $reply, $forumtracked, $posts);
1272 echo "</div>\n";
1273 }
1274 }
1275}
1276
1277/**
1278 * @todo Document this function
1279 * @global object
1280 * @global object
1281 * @return void
1282 * @deprecated since Moodle 3.7
1283 */
1284function forum_print_posts_nested($course, &$cm, $forum, $discussion, $parent, $reply, $forumtracked, $posts) {
f30f46db
RW
1285 debugging('forum_print_posts_nested() has been deprecated, ' .
1286 'please use \mod_forum\local\renderers\posts instead.', DEBUG_DEVELOPER);
2e19ca18
RW
1287 global $USER, $CFG;
1288
1289 $link = false;
1290
1291 if (!empty($posts[$parent->id]->children)) {
1292 $posts = $posts[$parent->id]->children;
1293
1294 foreach ($posts as $post) {
1295
1296 echo '<div class="indent">';
1297 if (!isloggedin()) {
1298 $ownpost = false;
1299 } else {
1300 $ownpost = ($USER->id == $post->userid);
1301 }
1302
1303 $post->subject = format_string($post->subject);
1304 $postread = !empty($post->postread);
1305
1306 forum_print_post_start($post);
1307 forum_print_post($post, $discussion, $forum, $cm, $course, $ownpost, $reply, $link,
1308 '', '', $postread, true, $forumtracked);
1309 forum_print_posts_nested($course, $cm, $forum, $discussion, $post, $reply, $forumtracked, $posts);
1310 forum_print_post_end($post);
1311 echo "</div>\n";
1312 }
1313 }
1314}