Proyectos de Subversion Moodle

Rev

| Ultima modificación | Ver Log |

Rev Autor Línea Nro. Línea
1 efrain 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
 * Renderer factory.
19
 *
20
 * @package    mod_forum
21
 * @copyright  2019 Ryan Wyllie <ryan@moodle.com>
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\grades\forum_gradeitem;
30
use mod_forum\local\entities\discussion as discussion_entity;
31
use mod_forum\local\entities\forum as forum_entity;
32
use mod_forum\local\factories\vault as vault_factory;
33
use mod_forum\local\factories\legacy_data_mapper as legacy_data_mapper_factory;
34
use mod_forum\local\factories\entity as entity_factory;
35
use mod_forum\local\factories\exporter as exporter_factory;
36
use mod_forum\local\factories\manager as manager_factory;
37
use mod_forum\local\factories\builder as builder_factory;
38
use mod_forum\local\factories\url as url_factory;
39
use mod_forum\local\renderers\discussion as discussion_renderer;
40
use mod_forum\local\renderers\discussion_list as discussion_list_renderer;
41
use mod_forum\local\renderers\posts as posts_renderer;
42
use moodle_page;
43
use core\output\notification;
44
 
45
/**
46
 * Renderer factory.
47
 *
48
 * See:
49
 * https://designpatternsphp.readthedocs.io/en/latest/Creational/SimpleFactory/README.html
50
 *
51
 * @copyright  2019 Ryan Wyllie <ryan@moodle.com>
52
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
53
 */
54
class renderer {
55
    /** @var legacy_data_mapper_factory $legacydatamapperfactory Legacy data mapper factory */
56
    private $legacydatamapperfactory;
57
    /** @var exporter_factory $exporterfactory Exporter factory */
58
    private $exporterfactory;
59
    /** @var vault_factory $vaultfactory Vault factory */
60
    private $vaultfactory;
61
    /** @var manager_factory $managerfactory Manager factory */
62
    private $managerfactory;
63
    /** @var entity_factory $entityfactory Entity factory */
64
    private $entityfactory;
65
    /** @var builder_factory $builderfactory Builder factory */
66
    private $builderfactory;
67
    /** @var url_factory $urlfactory URL factory */
68
    private $urlfactory;
69
    /** @var renderer_base $rendererbase Renderer base */
70
    private $rendererbase;
71
    /** @var moodle_page $page Moodle page */
72
    private $page;
73
 
74
    /**
75
     * Constructor.
76
     *
77
     * @param legacy_data_mapper_factory $legacydatamapperfactory Legacy data mapper factory
78
     * @param exporter_factory $exporterfactory Exporter factory
79
     * @param vault_factory $vaultfactory Vault factory
80
     * @param manager_factory $managerfactory Manager factory
81
     * @param entity_factory $entityfactory Entity factory
82
     * @param builder_factory $builderfactory Builder factory
83
     * @param url_factory $urlfactory URL factory
84
     * @param moodle_page $page Moodle page
85
     */
86
    public function __construct(
87
        legacy_data_mapper_factory $legacydatamapperfactory,
88
        exporter_factory $exporterfactory,
89
        vault_factory $vaultfactory,
90
        manager_factory $managerfactory,
91
        entity_factory $entityfactory,
92
        builder_factory $builderfactory,
93
        url_factory $urlfactory,
94
        moodle_page $page
95
    ) {
96
        $this->legacydatamapperfactory = $legacydatamapperfactory;
97
        $this->exporterfactory = $exporterfactory;
98
        $this->vaultfactory = $vaultfactory;
99
        $this->managerfactory = $managerfactory;
100
        $this->entityfactory = $entityfactory;
101
        $this->builderfactory = $builderfactory;
102
        $this->urlfactory = $urlfactory;
103
        $this->page = $page;
104
        $this->rendererbase = $page->get_renderer('mod_forum');
105
    }
106
 
107
    /**
108
     * Create a discussion renderer for the given forum and discussion.
109
     *
110
     * @param forum_entity $forum Forum the discussion belongs to
111
     * @param discussion_entity $discussion Discussion to render
112
     * @param int $displaymode How should the posts be formatted?
113
     * @return discussion_renderer
114
     */
115
    public function get_discussion_renderer(
116
        forum_entity $forum,
117
        discussion_entity $discussion,
118
        int $displaymode
119
    ): discussion_renderer {
120
 
121
        $capabilitymanager = $this->managerfactory->get_capability_manager($forum);
122
        $ratingmanager = $this->managerfactory->get_rating_manager();
123
        $rendererbase = $this->rendererbase;
124
 
125
        $baseurl = $this->urlfactory->get_discussion_view_url_from_discussion($discussion);
126
        $notifications = [];
127
 
128
        return new discussion_renderer(
129
            $forum,
130
            $discussion,
131
            $displaymode,
132
            $rendererbase,
133
            $this->get_single_discussion_posts_renderer($displaymode, false),
134
            $this->page,
135
            $this->legacydatamapperfactory,
136
            $this->exporterfactory,
137
            $this->vaultfactory,
138
            $this->urlfactory,
139
            $this->entityfactory,
140
            $capabilitymanager,
141
            $ratingmanager,
142
            $this->entityfactory->get_exported_posts_sorter(),
143
            $baseurl,
144
            $notifications,
145
            function($discussion, $user, $forum) {
146
                $exportbuilder = $this->builderfactory->get_exported_discussion_builder();
147
                return $exportbuilder->build(
148
                    $user,
149
                    $forum,
150
                    $discussion
151
                );
152
            }
153
        );
154
    }
155
 
156
    /**
157
     * Create a posts renderer to render posts without defined parent/reply relationships.
158
     *
159
     * @return posts_renderer
160
     */
161
    public function get_posts_renderer(): posts_renderer {
162
        return new posts_renderer(
163
            $this->rendererbase,
164
            $this->builderfactory->get_exported_posts_builder(),
165
            'mod_forum/forum_discussion_posts'
166
        );
167
    }
168
 
169
    /**
170
     * Create a posts renderer to render a list of posts in a single discussion.
171
     *
172
     * @param int|null $displaymode How should the posts be formatted?
173
     * @param bool $readonly Should the posts include the actions to reply, delete, etc?
174
     * @return posts_renderer
175
     */
176
    public function get_single_discussion_posts_renderer(int $displaymode = null, bool $readonly = false): posts_renderer {
177
        $exportedpostssorter = $this->entityfactory->get_exported_posts_sorter();
178
 
179
        switch ($displaymode) {
180
            case FORUM_MODE_THREADED:
181
                $template = 'mod_forum/forum_discussion_threaded_posts';
182
                break;
183
            case FORUM_MODE_NESTED:
184
                $template = 'mod_forum/forum_discussion_nested_posts';
185
                break;
186
            case FORUM_MODE_NESTED_V2:
187
                $template = 'mod_forum/forum_discussion_nested_v2_posts';
188
                break;
189
            default;
190
                $template = 'mod_forum/forum_discussion_posts';
191
                break;
192
        }
193
 
194
        return new posts_renderer(
195
            $this->rendererbase,
196
            $this->builderfactory->get_exported_posts_builder(),
197
            $template,
198
            // Post process the exported posts for our template. This function will add the "replies"
199
            // and "hasreplies" properties to the exported posts. It will also sort them into the
200
            // reply tree structure if the display mode requires it.
201
            function($exportedposts, $forums, $discussions) use ($displaymode, $readonly, $exportedpostssorter) {
202
                $forum = array_shift($forums);
203
                $seenfirstunread = false;
204
                $postcount = count($exportedposts);
205
                $discussionsbyid = array_reduce($discussions, function($carry, $discussion) {
206
                    $carry[$discussion->get_id()] = $discussion;
207
                    return $carry;
208
                }, []);
209
                $exportedposts = array_map(
210
                    function($exportedpost) use ($forum, $discussionsbyid, $readonly, $seenfirstunread, $displaymode) {
211
                        $discussion = $discussionsbyid[$exportedpost->discussionid] ?? null;
212
                        if ($forum->get_type() == 'single' && !$exportedpost->hasparent) {
213
                            // Remove the author from any posts that don't have a parent.
214
                            unset($exportedpost->author);
215
                            unset($exportedpost->html['authorsubheading']);
216
                        }
217
 
218
                        $exportedpost->firstpost = false;
219
                        $exportedpost->readonly = $readonly;
220
                        $exportedpost->hasreplycount = false;
221
                        $exportedpost->hasreplies = false;
222
                        $exportedpost->replies = [];
223
                        $exportedpost->discussionlocked = $discussion ? $discussion->is_locked() : null;
224
 
225
                        $exportedpost->isfirstunread = false;
226
                        if (!$seenfirstunread && $exportedpost->unread) {
227
                            $exportedpost->isfirstunread = true;
228
                            $seenfirstunread = true;
229
                        }
230
 
231
                        if ($displaymode === FORUM_MODE_NESTED_V2) {
232
                            $exportedpost->showactionmenu = $exportedpost->capabilities['view'] ||
233
                                                            $exportedpost->capabilities['controlreadstatus'] ||
234
                                                            $exportedpost->capabilities['edit'] ||
235
                                                            $exportedpost->capabilities['split'] ||
236
                                                            $exportedpost->capabilities['delete'] ||
237
                                                            $exportedpost->capabilities['export'] ||
238
                                                            !empty($exportedpost->urls['viewparent']);
239
                        }
240
 
241
                        return $exportedpost;
242
                    },
243
                    $exportedposts
244
                );
245
 
246
                if (
247
                    $displaymode === FORUM_MODE_NESTED ||
248
                    $displaymode === FORUM_MODE_THREADED ||
249
                    $displaymode === FORUM_MODE_NESTED_V2
250
                ) {
251
                    $sortedposts = $exportedpostssorter->sort_into_children($exportedposts);
252
                    $sortintoreplies = function($nestedposts) use (&$sortintoreplies) {
253
                        return array_map(function($postdata) use (&$sortintoreplies) {
254
                            [$post, $replies] = $postdata;
255
                            $totalreplycount = 0;
256
 
257
                            if (empty($replies)) {
258
                                $post->replies = [];
259
                                $post->hasreplies = false;
260
                            } else {
261
                                $sortedreplies = $sortintoreplies($replies);
262
                                // Set the parent author name on the replies. This is used for screen
263
                                // readers to help them identify the structure of the discussion.
264
                                $sortedreplies = array_map(function($reply) use ($post) {
265
                                    if (isset($post->author)) {
266
                                        $reply->parentauthorname = $post->author->fullname;
267
                                    } else {
268
                                        // The only time the author won't be set is for a single discussion
269
                                        // forum. See above for where it gets unset.
270
                                        $reply->parentauthorname = get_string('firstpost', 'mod_forum');
271
                                    }
272
                                    return $reply;
273
                                }, $sortedreplies);
274
 
275
                                $totalreplycount = array_reduce($sortedreplies, function($carry, $reply) {
276
                                    return $carry + 1 + $reply->totalreplycount;
277
                                }, $totalreplycount);
278
 
279
                                $post->replies = $sortedreplies;
280
                                $post->hasreplies = true;
281
                            }
282
 
283
                            $post->totalreplycount = $totalreplycount;
284
 
285
                            return $post;
286
                        }, $nestedposts);
287
                    };
288
                    // Set the "replies" property on the exported posts.
289
                    $exportedposts = $sortintoreplies($sortedposts);
290
                } else if ($displaymode === FORUM_MODE_FLATNEWEST || $displaymode === FORUM_MODE_FLATOLDEST) {
291
                    $exportedfirstpost = array_shift($exportedposts);
292
                    $exportedfirstpost->replies = $exportedposts;
293
                    $exportedfirstpost->hasreplies = true;
294
                    $exportedposts = [$exportedfirstpost];
295
                }
296
 
297
                if (!empty($exportedposts)) {
298
                    // Need to identify the first post so that we can use it in behat tests.
299
                    $exportedposts[0]->firstpost = true;
300
                    $exportedposts[0]->hasreplycount = true;
301
                    $exportedposts[0]->replycount = $postcount - 1;
302
                }
303
 
304
                return $exportedposts;
305
            }
306
        );
307
    }
308
 
309
    /**
310
     * Create a posts renderer to render posts in the forum search results.
311
     *
312
     * @param string[] $searchterms The search terms to be highlighted in the posts
313
     * @return posts_renderer
314
     */
315
    public function get_posts_search_results_renderer(array $searchterms): posts_renderer {
316
        $urlfactory = $this->urlfactory;
317
 
318
        return new posts_renderer(
319
            $this->rendererbase,
320
            $this->builderfactory->get_exported_posts_builder(),
321
            'mod_forum/forum_search_results',
322
            // Post process the exported posts to add the highlighting of the search terms to the post
323
            // and also the additional context links in the subject.
324
            function($exportedposts, $forumsbyid, $discussionsbyid) use ($searchterms, $urlfactory) {
325
                $highlightwords = implode(' ', $searchterms);
326
 
327
                return array_map(
328
                    function($exportedpost) use (
329
                        $forumsbyid,
330
                        $discussionsbyid,
331
                        $searchterms,
332
                        $highlightwords,
333
                        $urlfactory
334
                    ) {
335
                        $discussion = $discussionsbyid[$exportedpost->discussionid];
336
                        $forum = $forumsbyid[$discussion->get_forum_id()];
337
 
338
                        $viewdiscussionurl = $urlfactory->get_discussion_view_url_from_discussion($discussion);
339
                        $exportedpost->urls['viewforum'] = $urlfactory->get_forum_view_url_from_forum($forum)->out(false);
340
                        $exportedpost->urls['viewdiscussion'] = $viewdiscussionurl->out(false);
341
                        $exportedpost->subject = highlight($highlightwords, $exportedpost->subject);
342
                        $exportedpost->forumname = format_string($forum->get_name(), true);
343
                        $exportedpost->discussionname = highlight($highlightwords, format_string($discussion->get_name(), true));
344
                        $exportedpost->showdiscussionname = $forum->get_type() != 'single';
345
 
346
                        // Identify search terms only found in HTML markup, and add a warning about them to
347
                        // the start of the message text. This logic was copied exactly as is from the previous
348
                        // implementation.
349
                        $missingterms = '';
350
                        $exportedpost->message = highlight(
351
                            $highlightwords,
352
                            $exportedpost->message,
353
                            0,
354
                            '<fgw9sdpq4>',
355
                            '</fgw9sdpq4>'
356
                        );
357
 
358
                        foreach ($searchterms as $searchterm) {
359
                            if (
360
                                preg_match("/$searchterm/i", $exportedpost->message) &&
361
                                !preg_match('/<fgw9sdpq4>' . $searchterm . '<\/fgw9sdpq4>/i', $exportedpost->message)
362
                            ) {
363
                                $missingterms .= " $searchterm";
364
                            }
365
                        }
366
 
367
                        $exportedpost->message = str_replace('<fgw9sdpq4>', '<span class="highlight">', $exportedpost->message);
368
                        $exportedpost->message = str_replace('</fgw9sdpq4>', '</span>', $exportedpost->message);
369
 
370
                        if ($missingterms) {
371
                            $strmissingsearchterms = get_string('missingsearchterms', 'forum');
372
                            $exportedpost->message = '<p class="highlight2">' . $strmissingsearchterms . ' '
373
                                . $missingterms . '</p>' . $exportedpost->message;
374
                        }
375
 
376
                        return $exportedpost;
377
                    },
378
                    $exportedposts
379
                );
380
            }
381
        );
382
    }
383
 
384
    /**
385
     * Create a posts renderer to render posts in mod/forum/user.php.
386
     *
387
     * @param bool $addlinkstocontext Should links to the course, forum, and discussion be included?
388
     * @return posts_renderer
389
     */
390
    public function get_user_forum_posts_report_renderer(bool $addlinkstocontext): posts_renderer {
391
        $urlfactory = $this->urlfactory;
392
 
393
        return new posts_renderer(
394
            $this->rendererbase,
395
            $this->builderfactory->get_exported_posts_builder(),
396
            'mod_forum/forum_posts_with_context_links',
397
            function($exportedposts, $forumsbyid, $discussionsbyid) use ($urlfactory, $addlinkstocontext) {
398
 
399
                return array_map(function($exportedpost) use ($forumsbyid, $discussionsbyid, $addlinkstocontext, $urlfactory) {
400
                    $discussion = $discussionsbyid[$exportedpost->discussionid];
401
                    $forum = $forumsbyid[$discussion->get_forum_id()];
402
                    $courserecord = $forum->get_course_record();
403
 
404
                    if ($addlinkstocontext) {
405
                        $viewdiscussionurl = $urlfactory->get_discussion_view_url_from_discussion($discussion);
406
                        $exportedpost->urls['viewforum'] = $urlfactory->get_forum_view_url_from_forum($forum)->out(false);
407
                        $exportedpost->urls['viewdiscussion'] = $viewdiscussionurl->out(false);
408
                        $exportedpost->urls['viewcourse'] = $urlfactory->get_course_url_from_forum($forum)->out(false);
409
                    }
410
 
411
                    $exportedpost->forumname = format_string($forum->get_name(), true);
412
                    $exportedpost->discussionname = format_string($discussion->get_name(), true);
413
                    $exportedpost->coursename = format_string($courserecord->shortname, true);
414
                    $exportedpost->showdiscussionname = $forum->get_type() != 'single';
415
 
416
                    return $exportedpost;
417
                }, $exportedposts);
418
            }
419
        );
420
    }
421
 
422
    /**
423
     * Create a standard type discussion list renderer.
424
     *
425
     * @param forum_entity $forum The forum that the discussions belong to
426
     * @return discussion_list_renderer
427
     */
428
    public function get_discussion_list_renderer(
429
        forum_entity $forum
430
    ): discussion_list_renderer {
431
 
432
        $capabilitymanager = $this->managerfactory->get_capability_manager($forum);
433
        $rendererbase = $this->rendererbase;
434
        $notifications = [];
435
 
436
        switch ($forum->get_type()) {
437
            case 'news':
438
                if (SITEID == $forum->get_course_id()) {
439
                    $template = 'mod_forum/frontpage_news_discussion_list';
440
                } else {
441
                    $template = 'mod_forum/news_discussion_list';
442
                }
443
                break;
444
            case 'qanda':
445
                $template = 'mod_forum/qanda_discussion_list';
446
                break;
447
            default:
448
                $template = 'mod_forum/discussion_list';
449
        }
450
 
451
        return new discussion_list_renderer(
452
            $forum,
453
            $rendererbase,
454
            $this->legacydatamapperfactory,
455
            $this->exporterfactory,
456
            $this->vaultfactory,
457
            $this->builderfactory,
458
            $capabilitymanager,
459
            $this->urlfactory,
460
            forum_gradeitem::load_from_forum_entity($forum),
461
            $template,
462
            $notifications,
463
            function($discussions, $user, $forum) {
464
 
465
                $exporteddiscussionsummarybuilder = $this->builderfactory->get_exported_discussion_summaries_builder();
466
                return $exporteddiscussionsummarybuilder->build(
467
                    $user,
468
                    $forum,
469
                    $discussions
470
                );
471
            }
472
        );
473
    }
474
 
475
    /**
476
     * Create a discussion list renderer which shows more information about the first post.
477
     *
478
     * @param forum_entity $forum The forum that the discussions belong to
479
     * @param string $template The template to use
480
     * @return discussion_list_renderer
481
     */
482
    private function get_detailed_discussion_list_renderer(
483
        forum_entity $forum,
484
        string $template
485
    ): discussion_list_renderer {
486
 
487
        $capabilitymanager = $this->managerfactory->get_capability_manager($forum);
488
        $rendererbase = $this->rendererbase;
489
        $notifications = [];
490
 
491
        return new discussion_list_renderer(
492
            $forum,
493
            $rendererbase,
494
            $this->legacydatamapperfactory,
495
            $this->exporterfactory,
496
            $this->vaultfactory,
497
            $this->builderfactory,
498
            $capabilitymanager,
499
            $this->urlfactory,
500
            forum_gradeitem::load_from_forum_entity($forum),
501
            $template,
502
            $notifications,
503
            function($discussions, $user, $forum) use ($capabilitymanager) {
504
                $exportedpostsbuilder = $this->builderfactory->get_exported_posts_builder();
505
                $discussionentries = [];
506
                $postentries = [];
507
                foreach ($discussions as $discussion) {
508
                    $discussionentries[] = $discussion->get_discussion();
509
                    $discussionentriesids[] = $discussion->get_discussion()->get_id();
510
                    $postentries[] = $discussion->get_first_post();
511
                }
512
 
513
                $exportedposts['posts'] = $exportedpostsbuilder->build(
514
                    $user,
515
                    [$forum],
516
                    $discussionentries,
517
                    $postentries
518
                );
519
 
520
                $postvault = $this->vaultfactory->get_post_vault();
521
                $canseeanyprivatereply = $capabilitymanager->can_view_any_private_reply($user);
522
                $discussionrepliescount = $postvault->get_reply_count_for_discussion_ids(
523
                        $user,
524
                        $discussionentriesids,
525
                        $canseeanyprivatereply
526
                    );
527
                $forumdatamapper = $this->legacydatamapperfactory->get_forum_data_mapper();
528
                $forumrecord = $forumdatamapper->to_legacy_object($forum);
529
                if (forum_tp_is_tracked($forumrecord, $user)) {
530
                    $discussionunreadscount = $postvault->get_unread_count_for_discussion_ids(
531
                            $user,
532
                            $discussionentriesids,
533
                            $canseeanyprivatereply
534
                    );
535
                } else {
536
                    $discussionunreadscount = [];
537
                }
538
 
539
                array_walk($exportedposts['posts'], function($post) use ($discussionrepliescount, $discussionunreadscount) {
540
                    $post->discussionrepliescount = $discussionrepliescount[$post->discussionid] ?? 0;
541
                    $post->discussionunreadscount = $discussionunreadscount[$post->discussionid] ?? 0;
542
                    // TODO: Find a better solution due to language differences when defining the singular and plural form.
543
                    $post->isreplyplural = $post->discussionrepliescount != 1 ? true : false;
544
                    $post->isunreadplural = $post->discussionunreadscount != 1 ? true : false;
545
                });
546
 
547
                $exportedposts['state']['hasdiscussions'] = $exportedposts['posts'] ? true : false;
548
 
549
                return $exportedposts;
550
            }
551
        );
552
    }
553
 
554
    /**
555
     * Create a blog type discussion list renderer.
556
     *
557
     * @param forum_entity $forum The forum that the discussions belong to
558
     * @return discussion_list_renderer
559
     */
560
    public function get_blog_discussion_list_renderer(
561
        forum_entity $forum
562
    ): discussion_list_renderer {
563
        return $this->get_detailed_discussion_list_renderer($forum, 'mod_forum/blog_discussion_list');
564
    }
565
 
566
    /**
567
     * Create a discussion list renderer for the social course format.
568
     *
569
     * @param forum_entity $forum The forum that the discussions belong to
570
     * @return discussion_list_renderer
571
     */
572
    public function get_social_discussion_list_renderer(
573
        forum_entity $forum
574
    ): discussion_list_renderer {
575
        return $this->get_detailed_discussion_list_renderer($forum, 'mod_forum/social_discussion_list');
576
    }
577
 
578
    /**
579
     * Create a discussion list renderer for the social course format.
580
     *
581
     * @param forum_entity $forum The forum that the discussions belong to
582
     * @return discussion_list_renderer
583
     */
584
    public function get_frontpage_news_discussion_list_renderer(
585
        forum_entity $forum
586
    ): discussion_list_renderer {
587
        return $this->get_detailed_discussion_list_renderer($forum, 'mod_forum/frontpage_social_discussion_list');
588
    }
589
 
590
    /**
591
     * Create a single type discussion list renderer.
592
     *
593
     * @param forum_entity $forum Forum the discussion belongs to
594
     * @param discussion_entity $discussion The discussion entity
595
     * @param bool $hasmultiplediscussions Whether the forum has multiple discussions (more than one)
596
     * @param int $displaymode How should the posts be formatted?
597
     * @return discussion_renderer
598
     */
599
    public function get_single_discussion_list_renderer(
600
        forum_entity $forum,
601
        discussion_entity $discussion,
602
        bool $hasmultiplediscussions,
603
        int $displaymode
604
    ): discussion_renderer {
605
 
606
        $capabilitymanager = $this->managerfactory->get_capability_manager($forum);
607
        $ratingmanager = $this->managerfactory->get_rating_manager();
608
        $rendererbase = $this->rendererbase;
609
 
610
        $cmid = $forum->get_course_module_record()->id;
611
        $baseurl = $this->urlfactory->get_forum_view_url_from_course_module_id($cmid);
612
        $notifications = array();
613
 
614
        if ($hasmultiplediscussions) {
615
            $notifications[] = (new notification(get_string('warnformorepost', 'forum')))
616
                ->set_show_closebutton(true);
617
        }
618
 
619
        return new discussion_renderer(
620
            $forum,
621
            $discussion,
622
            $displaymode,
623
            $rendererbase,
624
            $this->get_single_discussion_posts_renderer($displaymode, false),
625
            $this->page,
626
            $this->legacydatamapperfactory,
627
            $this->exporterfactory,
628
            $this->vaultfactory,
629
            $this->urlfactory,
630
            $this->entityfactory,
631
            $capabilitymanager,
632
            $ratingmanager,
633
            $this->entityfactory->get_exported_posts_sorter(),
634
            $baseurl,
635
            $notifications
636
        );
637
    }
638
}