Proyectos de Subversion Moodle

Rev

Ir a la última revisión | | 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
 * Edit and save a new post to a discussion
19
 *
20
 * @package   mod_forum
21
 * @copyright 1999 onwards Martin Dougiamas  {@link http://moodle.com}
22
 * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
23
 */
24
 
25
require_once('../../config.php');
26
require_once('lib.php');
27
require_once($CFG->libdir.'/completionlib.php');
28
 
29
$reply   = optional_param('reply', 0, PARAM_INT);
30
$forum   = optional_param('forum', 0, PARAM_INT);
31
$edit    = optional_param('edit', 0, PARAM_INT);
32
$delete  = optional_param('delete', 0, PARAM_INT);
33
$prune   = optional_param('prune', 0, PARAM_INT);
34
$name    = optional_param('name', '', PARAM_CLEAN);
35
$confirm = optional_param('confirm', 0, PARAM_INT);
36
$groupid = optional_param('groupid', null, PARAM_INT);
37
$subject = optional_param('subject', '', PARAM_TEXT);
38
 
39
// Values posted via the inpage reply form.
40
$prefilledpost = optional_param('post', '', PARAM_TEXT);
41
$prefilledpostformat = optional_param('postformat', FORMAT_MOODLE, PARAM_INT);
42
$prefilledprivatereply = optional_param('privatereply', false, PARAM_BOOL);
43
 
44
$PAGE->set_url('/mod/forum/post.php', array(
45
    'reply' => $reply,
46
    'forum' => $forum,
47
    'edit'  => $edit,
48
    'delete' => $delete,
49
    'prune' => $prune,
50
    'name'  => $name,
51
    'confirm' => $confirm,
52
    'groupid' => $groupid,
53
));
54
// These page_params will be passed as hidden variables later in the form.
55
$pageparams = array('reply' => $reply, 'forum' => $forum, 'edit' => $edit);
56
 
57
$sitecontext = context_system::instance();
58
 
59
$entityfactory = mod_forum\local\container::get_entity_factory();
60
$vaultfactory = mod_forum\local\container::get_vault_factory();
61
$managerfactory = mod_forum\local\container::get_manager_factory();
62
$legacydatamapperfactory = mod_forum\local\container::get_legacy_data_mapper_factory();
63
$urlfactory = mod_forum\local\container::get_url_factory();
64
 
65
$forumvault = $vaultfactory->get_forum_vault();
66
$forumdatamapper = $legacydatamapperfactory->get_forum_data_mapper();
67
 
68
$discussionvault = $vaultfactory->get_discussion_vault();
69
$discussiondatamapper = $legacydatamapperfactory->get_discussion_data_mapper();
70
 
71
$postvault = $vaultfactory->get_post_vault();
72
$postdatamapper = $legacydatamapperfactory->get_post_data_mapper();
73
 
74
if (!isloggedin() or isguestuser()) {
75
    if (!isloggedin() and !get_local_referer()) {
76
        // No referer+not logged in - probably coming in via email  See MDL-9052.
77
        require_login();
78
    }
79
 
80
    if (!empty($forum)) {
81
        // User is starting a new discussion in a forum.
82
        $forumentity = $forumvault->get_from_id($forum);
83
        if (empty($forumentity)) {
84
            throw new \moodle_exception('invalidforumid', 'forum');
85
        }
86
    } else if (!empty($reply)) {
87
        // User is writing a new reply.
88
        $forumentity = $forumvault->get_from_post_id($reply);
89
        if (empty($forumentity)) {
90
            throw new \moodle_exception('invalidparentpostid', 'forum');
91
        }
92
    }
93
 
94
    $forum = $forumdatamapper->to_legacy_object($forumentity);
95
    $modcontext = $forumentity->get_context();
96
    $course = $forumentity->get_course_record();
97
    if (!$cm = get_coursemodule_from_instance("forum", $forum->id, $course->id)) {
98
        throw new \moodle_exception("invalidcoursemodule");
99
    }
100
 
101
    $PAGE->set_cm($cm, $course, $forum);
102
    $PAGE->set_context($modcontext);
103
    $PAGE->set_title($course->shortname);
104
    $PAGE->set_heading($course->fullname);
105
    $referer = get_local_referer(false);
106
 
107
    echo $OUTPUT->header();
108
    echo $OUTPUT->confirm(get_string('noguestpost', 'forum'), get_login_url(), $referer, [
109
        'confirmtitle' => get_string('noguestpost:title', 'forum'),
110
        'continuestr' => get_string('login')
111
    ]);
112
    echo $OUTPUT->footer();
113
    exit;
114
}
115
 
116
require_login(0, false);   // Script is useless unless they're logged in.
117
 
118
$canreplyprivately = false;
119
 
120
if (!empty($forum)) {
121
    // User is starting a new discussion in a forum.
122
    $forumentity = $forumvault->get_from_id($forum);
123
    if (empty($forumentity)) {
124
        throw new \moodle_exception('invalidforumid', 'forum');
125
    }
126
 
127
    $capabilitymanager = $managerfactory->get_capability_manager($forumentity);
128
    $forum = $forumdatamapper->to_legacy_object($forumentity);
129
    $course = $forumentity->get_course_record();
130
    if (!$cm = get_coursemodule_from_instance("forum", $forum->id, $course->id)) {
131
        throw new \moodle_exception("invalidcoursemodule");
132
    }
133
 
134
    // Retrieve the contexts.
135
    $modcontext = $forumentity->get_context();
136
    $coursecontext = context_course::instance($course->id);
137
 
138
    if ($forumentity->is_in_group_mode() && null === $groupid) {
139
        $groupid = groups_get_activity_group($cm);
140
    }
141
 
142
    if (!$capabilitymanager->can_create_discussions($USER, $groupid)) {
143
        if (!isguestuser()) {
144
            if (!is_enrolled($coursecontext)) {
145
                if (enrol_selfenrol_available($course->id)) {
146
                    $SESSION->wantsurl = qualified_me();
147
                    $SESSION->enrolcancel = get_local_referer(false);
148
                    redirect(new moodle_url('/enrol/index.php', array('id' => $course->id,
149
                        'returnurl' => '/mod/forum/view.php?f=' . $forum->id)),
150
                        get_string('youneedtoenrol'));
151
                }
152
            }
153
        }
154
        throw new \moodle_exception('nopostforum', 'forum');
155
    }
156
 
157
    if (!$cm->visible and !has_capability('moodle/course:viewhiddenactivities', $modcontext)) {
158
        redirect(
159
                $urlfactory->get_course_url_from_forum($forumentity),
160
                get_string('activityiscurrentlyhidden'),
161
                null,
162
                \core\output\notification::NOTIFY_ERROR
163
            );
164
    }
165
 
166
    // Load up the $post variable.
167
 
168
    $post = new stdClass();
169
    $post->course        = $course->id;
170
    $post->forum         = $forum->id;
171
    $post->discussion    = 0;           // Ie discussion # not defined yet.
172
    $post->parent        = 0;
173
    $post->subject       = $subject;
174
    $post->userid        = $USER->id;
175
    $post->message       = $prefilledpost;
176
    $post->messageformat = editors_get_preferred_format();
177
    $post->messagetrust  = 0;
178
    $post->groupid = $groupid;
179
 
180
    // Unsetting this will allow the correct return URL to be calculated later.
181
    unset($SESSION->fromdiscussion);
182
 
183
} else if (!empty($reply)) {
184
    // User is writing a new reply.
185
 
186
    $parententity = $postvault->get_from_id($reply);
187
    if (empty($parententity)) {
188
        throw new \moodle_exception('invalidparentpostid', 'forum');
189
    }
190
 
191
    $discussionentity = $discussionvault->get_from_id($parententity->get_discussion_id());
192
    if (empty($discussionentity)) {
193
        throw new \moodle_exception('notpartofdiscussion', 'forum');
194
    }
195
 
196
    $forumentity = $forumvault->get_from_id($discussionentity->get_forum_id());
197
    if (empty($forumentity)) {
198
        throw new \moodle_exception('invalidforumid', 'forum');
199
    }
200
 
201
    $capabilitymanager = $managerfactory->get_capability_manager($forumentity);
202
    $parent = $postdatamapper->to_legacy_object($parententity);
203
    $discussion = $discussiondatamapper->to_legacy_object($discussionentity);
204
    $forum = $forumdatamapper->to_legacy_object($forumentity);
205
    $course = $forumentity->get_course_record();
206
    $modcontext = $forumentity->get_context();
207
    $coursecontext = context_course::instance($course->id);
208
 
209
    if (!$cm = get_coursemodule_from_instance("forum", $forum->id, $course->id)) {
210
        throw new \moodle_exception('invalidcoursemodule');
211
    }
212
 
213
    // Ensure lang, theme, etc. is set up properly. MDL-6926.
214
    $PAGE->set_cm($cm, $course, $forum);
215
 
216
    if (!$capabilitymanager->can_reply_to_post($USER, $discussionentity, $parententity)) {
217
        if (!isguestuser()) {
218
            if (!is_enrolled($coursecontext)) {  // User is a guest here!
219
                $SESSION->wantsurl = qualified_me();
220
                $SESSION->enrolcancel = get_local_referer(false);
221
                redirect(new moodle_url('/enrol/index.php', array('id' => $course->id,
222
                    'returnurl' => '/mod/forum/view.php?f=' . $forum->id)),
223
                    get_string('youneedtoenrol'));
224
            }
225
 
226
            // The forum has been locked. Just redirect back to the discussion page.
227
            if (forum_discussion_is_locked($forum, $discussion)) {
228
                redirect(new moodle_url('/mod/forum/discuss.php', array('d' => $discussion->id)));
229
            }
230
        }
231
        throw new \moodle_exception('nopostforum', 'forum');
232
    }
233
 
234
    // Make sure user can post here.
235
    if (isset($cm->groupmode) && empty($course->groupmodeforce)) {
236
        $groupmode = $cm->groupmode;
237
    } else {
238
        $groupmode = $course->groupmode;
239
    }
240
    if ($groupmode == SEPARATEGROUPS and !has_capability('moodle/site:accessallgroups', $modcontext)) {
241
        if ($discussion->groupid == -1) {
242
            throw new \moodle_exception('nopostforum', 'forum');
243
        } else {
244
            if (!groups_is_member($discussion->groupid)) {
245
                throw new \moodle_exception('nopostforum', 'forum');
246
            }
247
        }
248
    }
249
 
250
    if (!$cm->visible and !has_capability('moodle/course:viewhiddenactivities', $modcontext)) {
251
        throw new \moodle_exception("activityiscurrentlyhidden");
252
    }
253
 
254
    if ($parententity->is_private_reply()) {
255
        throw new \moodle_exception('cannotreplytoprivatereply', 'forum');
256
    }
257
 
258
    // We always are going to honor the preferred format. We are creating a new post.
259
    $preferredformat = editors_get_preferred_format();
260
 
261
    // Only if there are prefilled contents coming.
262
    if (!empty($prefilledpost)) {
263
        // If the prefilled post is not HTML and the preferred format is HTML, convert to it.
264
        if ($prefilledpostformat != FORMAT_HTML and $preferredformat == FORMAT_HTML) {
265
            $prefilledpost = format_text($prefilledpost, $prefilledpostformat, ['context' => $modcontext]);
266
        }
267
    }
268
 
269
    // Load up the $post variable.
270
    $post = new stdClass();
271
    $post->course      = $course->id;
272
    $post->forum       = $forum->id;
273
    $post->discussion  = $parent->discussion;
274
    $post->parent      = $parent->id;
275
    $post->subject     = $subject ? $subject : $parent->subject;
276
    $post->userid      = $USER->id;
277
    $post->parentpostauthor = $parent->userid;
278
    $post->message     = $prefilledpost;
279
    $post->messageformat  = $preferredformat;
280
    $post->isprivatereply = $prefilledprivatereply;
281
    $canreplyprivately = $capabilitymanager->can_reply_privately_to_post($USER, $parententity);
282
 
283
    $post->groupid = ($discussion->groupid == -1) ? 0 : $discussion->groupid;
284
 
285
    $strre = get_string('re', 'forum');
286
    if (!(substr($post->subject, 0, strlen($strre)) == $strre)) {
287
        $post->subject = $strre.' '.$post->subject;
288
    }
289
 
290
    // Unsetting this will allow the correct return URL to be calculated later.
291
    unset($SESSION->fromdiscussion);
292
 
293
} else if (!empty($edit)) {
294
    // User is editing their own post.
295
 
296
    $postentity = $postvault->get_from_id($edit);
297
    if (empty($postentity)) {
298
        throw new \moodle_exception('invalidpostid', 'forum');
299
    }
300
    if ($postentity->has_parent()) {
301
        $parententity = $postvault->get_from_id($postentity->get_parent_id());
302
        $parent = $postdatamapper->to_legacy_object($parententity);
303
    }
304
 
305
    $discussionentity = $discussionvault->get_from_id($postentity->get_discussion_id());
306
    if (empty($discussionentity)) {
307
        throw new \moodle_exception('notpartofdiscussion', 'forum');
308
    }
309
 
310
    $forumentity = $forumvault->get_from_id($discussionentity->get_forum_id());
311
    if (empty($forumentity)) {
312
        throw new \moodle_exception('invalidforumid', 'forum');
313
    }
314
 
315
    $capabilitymanager = $managerfactory->get_capability_manager($forumentity);
316
    $post = $postdatamapper->to_legacy_object($postentity);
317
    $discussion = $discussiondatamapper->to_legacy_object($discussionentity);
318
    $forum = $forumdatamapper->to_legacy_object($forumentity);
319
    $course = $forumentity->get_course_record();
320
    $modcontext = $forumentity->get_context();
321
    $coursecontext = context_course::instance($course->id);
322
 
323
    if (!$cm = get_coursemodule_from_instance("forum", $forum->id, $course->id)) {
324
        throw new \moodle_exception('invalidcoursemodule');
325
    }
326
 
327
    $PAGE->set_cm($cm, $course, $forum);
328
 
329
    if (!($forum->type == 'news' && !$post->parent && $discussion->timestart > time())) {
330
        if (((time() - $post->created) > $CFG->maxeditingtime) and
331
            !has_capability('mod/forum:editanypost', $modcontext)) {
332
            throw new \moodle_exception('maxtimehaspassed', 'forum', '', format_time($CFG->maxeditingtime));
333
        }
334
    }
335
    if (($post->userid <> $USER->id) and
336
        !has_capability('mod/forum:editanypost', $modcontext)) {
337
        throw new \moodle_exception('cannoteditposts', 'forum');
338
    }
339
 
340
    // Load up the $post variable.
341
    $post->edit   = $edit;
342
    $post->course = $course->id;
343
    $post->forum  = $forum->id;
344
    $post->groupid = ($discussion->groupid == -1) ? 0 : $discussion->groupid;
345
    if ($postentity->has_parent()) {
346
        $canreplyprivately = forum_user_can_reply_privately($modcontext, $parent);
347
    }
348
 
349
    $post = trusttext_pre_edit($post, 'message', $modcontext);
350
 
351
    // Unsetting this will allow the correct return URL to be calculated later.
352
    unset($SESSION->fromdiscussion);
353
 
354
} else if (!empty($delete)) {
355
    // User is deleting a post.
356
 
357
    $postentity = $postvault->get_from_id($delete);
358
    if (empty($postentity)) {
359
        throw new \moodle_exception('invalidpostid', 'forum');
360
    }
361
 
362
    $discussionentity = $discussionvault->get_from_id($postentity->get_discussion_id());
363
    if (empty($discussionentity)) {
364
        throw new \moodle_exception('notpartofdiscussion', 'forum');
365
    }
366
 
367
    $forumentity = $forumvault->get_from_id($discussionentity->get_forum_id());
368
    if (empty($forumentity)) {
369
        throw new \moodle_exception('invalidforumid', 'forum');
370
    }
371
 
372
    $capabilitymanager = $managerfactory->get_capability_manager($forumentity);
373
    $course = $forumentity->get_course_record();
374
    $cm = $forumentity->get_course_module_record();
375
    $modcontext = $forumentity->get_context();
376
 
377
    require_login($course, false, $cm);
378
 
379
    $replycount = $postvault->get_reply_count_for_post_id_in_discussion_id(
380
        $USER, $postentity->get_id(), $discussionentity->get_id(), true);
381
 
382
    if (!empty($confirm) && confirm_sesskey()) {
383
        // Do further checks and delete the post.
384
        $hasreplies = $replycount > 0;
385
 
386
        try {
387
            $capabilitymanager->validate_delete_post($USER, $discussionentity, $postentity, $hasreplies);
388
 
389
            if (!$postentity->has_parent()) {
390
                forum_delete_discussion(
391
                    $discussiondatamapper->to_legacy_object($discussionentity),
392
                    false,
393
                    $forumentity->get_course_record(),
394
                    $forumentity->get_course_module_record(),
395
                    $forumdatamapper->to_legacy_object($forumentity)
396
                );
397
 
398
                redirect(
399
                    $urlfactory->get_forum_view_url_from_forum($forumentity),
400
                    get_string('eventdiscussiondeleted', 'forum'),
401
                    null,
402
                    \core\output\notification::NOTIFY_SUCCESS
403
                );
404
            } else {
405
                forum_delete_post(
406
                    $postdatamapper->to_legacy_object($postentity),
407
                    has_capability('mod/forum:deleteanypost', $modcontext),
408
                    $forumentity->get_course_record(),
409
                    $forumentity->get_course_module_record(),
410
                    $forumdatamapper->to_legacy_object($forumentity)
411
                );
412
 
413
                if ($forumentity->get_type() == 'single') {
414
                    // Single discussion forums are an exception.
415
                    // We show the forum itself since it only has one discussion thread.
416
                    $discussionurl = $urlfactory->get_forum_view_url_from_forum($forumentity);
417
                } else {
418
                    $discussionurl = $urlfactory->get_discussion_view_url_from_discussion($discussionentity);
419
                }
420
 
421
                redirect(
422
                    forum_go_back_to($discussionurl),
423
                    get_string('eventpostdeleted', 'forum'),
424
                    null,
425
                    \core\output\notification::NOTIFY_SUCCESS
426
                );
427
            }
428
        } catch (Exception $e) {
429
            redirect(
430
                $urlfactory->get_discussion_view_url_from_discussion($discussionentity),
431
                $e->getMessage(),
432
                null,
433
                \core\output\notification::NOTIFY_ERROR
434
            );
435
        }
436
 
437
    } else {
438
 
439
        if (!$capabilitymanager->can_delete_post($USER, $discussionentity, $postentity)) {
440
            redirect(
441
                    $urlfactory->get_discussion_view_url_from_discussion($discussionentity),
442
                    get_string('cannotdeletepost', 'forum'),
443
                    null,
444
                    \core\output\notification::NOTIFY_ERROR
445
                );
446
        }
447
 
448
        $post = $postdatamapper->to_legacy_object($postentity);
449
        $forum = $forumdatamapper->to_legacy_object($forumentity);
450
 
451
        // User just asked to delete something.
452
        forum_set_return();
453
        $PAGE->navbar->add(get_string('delete', 'forum'));
454
        $PAGE->set_title($course->shortname);
455
        $PAGE->set_heading($course->fullname);
456
        $PAGE->set_secondary_active_tab('modulepage');
457
        $PAGE->activityheader->disable();
458
 
459
        if ($replycount) {
460
            if (!has_capability('mod/forum:deleteanypost', $modcontext)) {
461
                redirect(
462
                        forum_go_back_to($urlfactory->get_view_post_url_from_post($postentity)),
463
                        get_string('couldnotdeletereplies', 'forum'),
464
                        null,
465
                        \core\output\notification::NOTIFY_ERROR
466
                    );
467
            }
468
 
469
            echo $OUTPUT->header();
470
            if (!$PAGE->has_secondary_navigation()) {
471
                echo $OUTPUT->heading(format_string($forum->name), 2);
472
            }
473
            echo $OUTPUT->confirm(get_string("deletesureplural", "forum", $replycount + 1),
474
                "post.php?delete=$delete&confirm=$delete",
475
                $CFG->wwwroot.'/mod/forum/discuss.php?d='.$post->discussion.'#p'.$post->id);
476
 
477
            $postentities = [$postentity];
478
            if (empty($post->edit)) {
479
                $postvault = $vaultfactory->get_post_vault();
480
                $replies = $postvault->get_replies_to_post(
481
                        $USER,
482
                        $postentity,
483
                        // Note: All replies are fetched here as the user has deleteanypost.
484
                        true,
485
                        'created ASC'
486
                    );
487
                $postentities = array_merge($postentities, $replies);
488
            }
489
 
490
            $rendererfactory = mod_forum\local\container::get_renderer_factory();
491
            $postsrenderer = $rendererfactory->get_single_discussion_posts_renderer(FORUM_MODE_NESTED, true);
492
            echo $postsrenderer->render($USER, [$forumentity], [$discussionentity], $postentities);
493
        } else {
494
            echo $OUTPUT->header();
495
            if (!$PAGE->has_secondary_navigation()) {
496
                echo $OUTPUT->heading(format_string($forum->name), 2);
497
            }
498
            echo $OUTPUT->confirm(get_string("deletesure", "forum", $replycount),
499
                "post.php?delete=$delete&confirm=$delete",
500
                $CFG->wwwroot.'/mod/forum/discuss.php?d='.$post->discussion.'#p'.$post->id);
501
 
502
            $rendererfactory = mod_forum\local\container::get_renderer_factory();
503
            $postsrenderer = $rendererfactory->get_single_discussion_posts_renderer(null, true);
504
            echo $postsrenderer->render($USER, [$forumentity], [$discussionentity], [$postentity]);
505
        }
506
 
507
    }
508
    echo $OUTPUT->footer();
509
    die;
510
 
511
} else if (!empty($prune)) {
512
    // Pruning.
513
 
514
    $postentity = $postvault->get_from_id($prune);
515
    if (empty($postentity)) {
516
        throw new \moodle_exception('invalidpostid', 'forum');
517
    }
518
 
519
    $discussionentity = $discussionvault->get_from_id($postentity->get_discussion_id());
520
    if (empty($discussionentity)) {
521
        throw new \moodle_exception('notpartofdiscussion', 'forum');
522
    }
523
 
524
    $forumentity = $forumvault->get_from_id($discussionentity->get_forum_id());
525
    if (empty($forumentity)) {
526
        throw new \moodle_exception('invalidforumid', 'forum');
527
    }
528
 
529
    $capabilitymanager = $managerfactory->get_capability_manager($forumentity);
530
    $post = $postdatamapper->to_legacy_object($postentity);
531
    $discussion = $discussiondatamapper->to_legacy_object($discussionentity);
532
    $forum = $forumdatamapper->to_legacy_object($forumentity);
533
    $course = $forumentity->get_course_record();
534
    $modcontext = $forumentity->get_context();
535
    $coursecontext = context_course::instance($course->id);
536
 
537
    if (!$cm = get_coursemodule_from_instance("forum", $forum->id, $course->id)) {
538
        throw new \moodle_exception('invalidcoursemodule');
539
    }
540
 
541
    if (!$postentity->has_parent()) {
542
        redirect(
543
                $urlfactory->get_discussion_view_url_from_discussion($discussionentity),
544
                get_string('alreadyfirstpost', 'forum'),
545
                null,
546
                \core\output\notification::NOTIFY_ERROR
547
            );
548
    }
549
    if (!$capabilitymanager->can_split_post($USER, $discussionentity, $postentity)) {
550
        redirect(
551
                $urlfactory->get_discussion_view_url_from_discussion($discussionentity),
552
                get_string('cannotsplit', 'forum'),
553
                null,
554
                \core\output\notification::NOTIFY_ERROR
555
            );
556
    }
557
 
558
    $PAGE->set_cm($cm);
559
    $PAGE->set_context($modcontext);
560
    $PAGE->set_secondary_active_tab('modulepage');
561
    $PAGE->activityheader->disable();
562
 
563
    $prunemform = new mod_forum_prune_form(null, array('prune' => $prune, 'confirm' => $prune));
564
 
565
    if ($prunemform->is_cancelled()) {
566
        redirect(forum_go_back_to($urlfactory->get_discussion_view_url_from_discussion($discussionentity)));
567
    } else if ($fromform = $prunemform->get_data()) {
568
        // User submits the data.
569
        $newdiscussion = new stdClass();
570
        $newdiscussion->course       = $discussion->course;
571
        $newdiscussion->forum        = $discussion->forum;
572
        $newdiscussion->name         = $name;
573
        $newdiscussion->firstpost    = $post->id;
574
        $newdiscussion->userid       = $post->userid;
575
        $newdiscussion->groupid      = $discussion->groupid;
576
        $newdiscussion->assessed     = $discussion->assessed;
577
        $newdiscussion->usermodified = $post->userid;
578
        $newdiscussion->timestart    = $discussion->timestart;
579
        $newdiscussion->timeend      = $discussion->timeend;
580
 
581
        $newid = $DB->insert_record('forum_discussions', $newdiscussion);
582
 
583
        $newpost = new stdClass();
584
        $newpost->id      = $post->id;
585
        $newpost->parent  = 0;
586
        $newpost->subject = $name;
587
 
588
        $DB->update_record("forum_posts", $newpost);
589
        $postentity = $postvault->get_from_id($postentity->get_id());
590
 
591
        forum_change_discussionid($post->id, $newid);
592
 
593
        // Update last post in each discussion.
594
        forum_discussion_update_last_post($discussion->id);
595
        forum_discussion_update_last_post($newid);
596
 
597
        // Fire events to reflect the split..
598
        $params = array(
599
            'context' => $modcontext,
600
            'objectid' => $discussion->id,
601
            'other' => array(
602
                'forumid' => $forum->id,
603
            )
604
        );
605
        $event = \mod_forum\event\discussion_updated::create($params);
606
        $event->trigger();
607
 
608
        $params = array(
609
            'context' => $modcontext,
610
            'objectid' => $newid,
611
            'other' => array(
612
                'forumid' => $forum->id,
613
            )
614
        );
615
        $event = \mod_forum\event\discussion_created::create($params);
616
        $event->trigger();
617
 
618
        $params = array(
619
            'context' => $modcontext,
620
            'objectid' => $post->id,
621
            'other' => array(
622
                'discussionid' => $newid,
623
                'forumid' => $forum->id,
624
                'forumtype' => $forum->type,
625
            )
626
        );
627
        $event = \mod_forum\event\post_updated::create($params);
628
        $event->add_record_snapshot('forum_discussions', $discussion);
629
        $event->trigger();
630
 
631
        redirect(
632
            forum_go_back_to($urlfactory->get_discussion_view_url_from_post($postentity)),
633
            get_string('discussionsplit', 'forum'),
634
            null,
635
            \core\output\notification::NOTIFY_SUCCESS
636
        );
637
    } else {
638
        // Display the prune form.
639
        $course = $DB->get_record('course', array('id' => $forum->course));
640
        $subjectstr = format_string($post->subject, true);
641
        $PAGE->navbar->add($subjectstr, new moodle_url('/mod/forum/discuss.php', array('d' => $discussion->id)));
642
        $PAGE->navbar->add(get_string("prunediscussion", "forum"));
643
        $PAGE->set_title(format_string($discussion->name).": ".format_string($post->subject));
644
        $PAGE->set_heading($course->fullname);
645
        echo $OUTPUT->header();
646
        if (!$PAGE->has_secondary_navigation()) {
647
            echo $OUTPUT->heading(format_string($forum->name), 2);
648
        }
649
        echo $OUTPUT->heading(get_string('pruneheading', 'forum'), 3);
650
 
651
        $prunemform->display();
652
 
653
        $postentity = $entityfactory->get_post_from_stdclass($post);
654
        $discussionentity = $entityfactory->get_discussion_from_stdclass($discussion);
655
        $forumentity = $entityfactory->get_forum_from_stdclass($forum, $modcontext, $cm, $course);
656
        $rendererfactory = mod_forum\local\container::get_renderer_factory();
657
        $postsrenderer = $rendererfactory->get_single_discussion_posts_renderer(null, true);
658
        echo $postsrenderer->render($USER, [$forumentity], [$discussionentity], [$postentity]);
659
    }
660
 
661
    echo $OUTPUT->footer();
662
    die;
663
} else {
664
    throw new \moodle_exception('unknowaction');
665
 
666
}
667
 
668
// From now on user must be logged on properly.
669
 
670
require_login($course, false, $cm);
671
 
672
if (isguestuser()) {
673
    // Just in case.
674
    throw new \moodle_exception('noguest');
675
}
676
 
677
$thresholdwarning = forum_check_throttling($forum, $cm);
678
$mformpost = new mod_forum_post_form('post.php', [
679
        'course' => $course,
680
        'cm' => $cm,
681
        'coursecontext' => $coursecontext,
682
        'modcontext' => $modcontext,
683
        'forum' => $forum,
684
        'post' => $post,
685
        'subscribe' => \mod_forum\subscriptions::is_subscribed($USER->id, $forum, null, $cm),
686
        'thresholdwarning' => $thresholdwarning,
687
        'edit' => $edit,
688
        'canreplyprivately' => $canreplyprivately,
689
    ], 'post', '', array('id' => 'mformforum'));
690
 
691
$draftitemid = file_get_submitted_draft_itemid('attachments');
692
$postid = empty($post->id) ? null : $post->id;
693
$attachoptions = mod_forum_post_form::attachment_options($forum);
694
file_prepare_draft_area($draftitemid, $modcontext->id, 'mod_forum', 'attachment', $postid, $attachoptions);
695
 
696
// Load data into form NOW!
697
 
698
if ($USER->id != $post->userid) {   // Not the original author, so add a message to the end.
699
    $data = new stdClass();
700
    $data->date = userdate($post->created);
701
    if ($post->messageformat == FORMAT_HTML) {
702
        $data->name = '<a href="'.$CFG->wwwroot.'/user/view.php?id='.$USER->id.'&course='.$post->course.'">'.
703
            fullname($USER).'</a>';
704
        $post->message .= '<p><span class="edited">('.get_string('editedby', 'forum', $data).')</span></p>';
705
    } else {
706
        $data->name = fullname($USER);
707
        $post->message .= "\n\n(".get_string('editedby', 'forum', $data).')';
708
    }
709
    unset($data);
710
}
711
 
712
$formheading = '';
713
if (!empty($parent)) {
714
    $heading = get_string("yourreply", "forum");
715
    $formheading = get_string('reply', 'forum');
716
} else {
717
    if ($forum->type == 'qanda') {
718
        $heading = get_string('yournewquestion', 'forum');
719
    } else {
720
        $heading = get_string('yournewtopic', 'forum');
721
    }
722
}
723
 
724
$postid = empty($post->id) ? null : $post->id;
725
$draftideditor = file_get_submitted_draft_itemid('message');
726
$editoropts = mod_forum_post_form::editor_options($modcontext, $postid);
727
$currenttext = file_prepare_draft_area($draftideditor, $modcontext->id, 'mod_forum', 'post', $postid, $editoropts, $post->message);
728
$discussionid = isset($discussion) ? $discussion->id : null;
729
$discussionsubscribe = \mod_forum\subscriptions::get_user_default_subscription($forum, $coursecontext, $cm, $discussionid);
730
 
731
$mformpost->set_data(
732
    array(
733
        'attachments' => $draftitemid,
734
        'general' => $heading,
735
        'subject' => $post->subject,
736
        'message' => array(
737
            'text' => $currenttext,
738
            'format' => !isset($post->messageformat) || !is_numeric($post->messageformat) ?
739
                editors_get_preferred_format() : $post->messageformat,
740
            'itemid' => $draftideditor
741
        ),
742
        'discussionsubscribe' => $discussionsubscribe,
743
        'mailnow' => !empty($post->mailnow),
744
        'userid' => $post->userid,
745
        'parent' => $post->parent,
746
        'discussion' => $post->discussion,
747
        'course' => $course->id,
748
        'isprivatereply' => $post->isprivatereply ?? false
749
    ) +
750
 
751
    $pageparams +
752
 
753
    (isset($post->format) ? array('format' => $post->format) : array()) +
754
 
755
    (isset($discussion->timestart) ? array('timestart' => $discussion->timestart) : array()) +
756
 
757
    (isset($discussion->timeend) ? array('timeend' => $discussion->timeend) : array()) +
758
 
759
    (isset($discussion->pinned) ? array('pinned' => $discussion->pinned) : array()) +
760
 
761
    (isset($post->groupid) ? array('groupid' => $post->groupid) : array()) +
762
 
763
    (isset($discussion->id) ? array('discussion' => $discussion->id) : array())
764
);
765
 
766
// If we are being redirected via a no_submit_button press OR if the message is being prefilled.
767
// then set the initial 'dirty' state.
768
// - A prefilled post will exist when being redirected from the inpage reply form.
769
// - A no_submit_button press occurs when being redirected from the inpage add new discussion post form.
770
$dirty = $prefilledpost ? true : false;
771
if ($mformpost->no_submit_button_pressed()) {
772
    $data = $mformpost->get_submitted_data();
773
 
774
    // If a no submit button has been pressed but the default values haven't been then reset the form change.
775
    if (!$dirty && isset($data->message['text']) && !empty(trim($data->message['text']))) {
776
        $dirty = true;
777
    }
778
 
779
    if (!$dirty && isset($data->message['message']) && !empty(trim($data->message['message']))) {
780
        $dirty = true;
781
    }
782
}
783
$mformpost->set_initial_dirty_state($dirty);
784
 
785
if ($mformpost->is_cancelled()) {
786
    if (!isset($discussion->id) || $forum->type === 'single') {
787
        // Single forums don't have a discussion page.
788
        redirect($urlfactory->get_forum_view_url_from_forum($forumentity));
789
    } else {
790
        redirect($urlfactory->get_discussion_view_url_from_discussion($discussionentity));
791
    }
792
} else if ($mformpost->is_submitted() && !$mformpost->no_submit_button_pressed() && $fromform = $mformpost->get_data()) {
793
 
794
    $errordestination = get_local_referer(false) ?: $urlfactory->get_forum_view_url_from_forum($forumentity);
795
 
796
    $fromform->itemid        = $fromform->message['itemid'];
797
    $fromform->messageformat = $fromform->message['format'];
798
    $fromform->message       = $fromform->message['text'];
799
    // WARNING: the $fromform->message array has been overwritten, do not use it anymore!
800
    $fromform->messagetrust  = trusttext_trusted($modcontext);
801
 
802
    // Do not clean text here, text cleaning can be done only after conversion to HTML.
803
    // Word counting now uses text formatting, there is no need to abuse trusttext_pre_edit() here.
804
 
805
    if ($fromform->edit) {
806
        // Updating a post.
807
        unset($fromform->groupid);
808
        $fromform->id = $fromform->edit;
809
        $message = '';
810
 
811
        if (!$capabilitymanager->can_edit_post($USER, $discussionentity, $postentity)) {
812
            redirect(
813
                    $urlfactory->get_view_post_url_from_post($postentity),
814
                    get_string('cannotupdatepost', 'forum'),
815
                    null,
816
                    \core\output\notification::ERROR
817
                );
818
        }
819
 
820
        if (isset($fromform->groupinfo) && $capabilitymanager->can_move_discussions($USER)) {
821
            // If the user has access to all groups and they are changing the group, then update the post.
822
            if (empty($fromform->groupinfo)) {
823
                $fromform->groupinfo = -1;
824
            }
825
 
826
            if (!$capabilitymanager->can_create_discussions($USER, $fromform->groupinfo)) {
827
                redirect(
828
                        $urlfactory->get_view_post_url_from_post($postentity),
829
                        get_string('cannotupdatepost', 'forum'),
830
                        null,
831
                        \core\output\notification::ERROR
832
                    );
833
            }
834
 
835
            if ($discussionentity->get_group_id() != $fromform->groupinfo) {
836
                $DB->set_field('forum_discussions', 'groupid', $fromform->groupinfo, array('firstpost' => $fromform->id));
837
            }
838
        }
839
 
840
        // When editing first post/discussion.
841
        if (!$postentity->has_parent()) {
842
            if ($capabilitymanager->can_pin_discussions($USER)) {
843
                // Can change pinned if we have capability.
844
                $fromform->pinned = !empty($fromform->pinned) ? FORUM_DISCUSSION_PINNED : FORUM_DISCUSSION_UNPINNED;
845
            } else {
846
                // We don't have the capability to change so keep to previous value.
847
                unset($fromform->pinned);
848
            }
849
        }
850
        $updatepost = $fromform;
851
        $updatepost->forum = $forum->id;
852
        if (!forum_update_post($updatepost, $mformpost)) {
853
            throw new \moodle_exception("couldnotupdate", "forum", $errordestination);
854
        }
855
 
856
        forum_trigger_post_updated_event($post, $discussion, $modcontext, $forum);
857
 
858
        if ($USER->id === $postentity->get_author_id()) {
859
            $message .= get_string("postupdated", "forum");
860
        } else {
861
            $realuser = \core_user::get_user($postentity->get_author_id());
862
            $message .= get_string("editedpostupdated", "forum", fullname($realuser));
863
        }
864
 
865
        $subscribemessage = forum_post_subscription($fromform, $forum, $discussion);
866
        if ('single' == $forumentity->get_type()) {
867
            // Single discussion forums are an exception.
868
            // We show the forum itself since it only has one discussion thread.
869
            $discussionurl = $urlfactory->get_forum_view_url_from_forum($forumentity);
870
        } else {
871
            $discussionurl = $urlfactory->get_view_post_url_from_post($postentity);
872
        }
873
 
874
        redirect(
875
            forum_go_back_to($discussionurl),
876
            $message . $subscribemessage,
877
            null,
878
            \core\output\notification::NOTIFY_SUCCESS
879
        );
880
 
881
    } else if ($fromform->discussion) {
882
        // Adding a new post to an existing discussion
883
        // Before we add this we must check that the user will not exceed the blocking threshold.
884
        forum_check_blocking_threshold($thresholdwarning);
885
 
886
        unset($fromform->groupid);
887
        $message = '';
888
        $addpost = $fromform;
889
        $addpost->forum = $forum->id;
890
        if ($fromform->id = forum_add_new_post($addpost, $mformpost)) {
891
            $postentity = $postvault->get_from_id($fromform->id);
892
            $fromform->deleted = 0;
893
            $subscribemessage = forum_post_subscription($fromform, $forum, $discussion);
894
 
895
            if (!empty($fromform->mailnow)) {
896
                $message .= get_string("postmailnow", "forum");
897
            } else {
898
                $message .= '<p>'.get_string("postaddedsuccess", "forum") . '</p>';
899
                $message .= '<p>'.get_string("postaddedtimeleft", "forum", format_time($CFG->maxeditingtime)) . '</p>';
900
            }
901
 
902
            if ($forum->type == 'single') {
903
                // Single discussion forums are an exception.
904
                // We show the forum itself since it only has one discussion thread.
905
                $discussionurl = $urlfactory->get_forum_view_url_from_forum($forumentity);
906
            } else {
907
                $discussionurl = $urlfactory->get_view_post_url_from_post($postentity);
908
            }
909
 
910
            $params = array(
911
                'context' => $modcontext,
912
                'objectid' => $fromform->id,
913
                'other' => array(
914
                    'discussionid' => $discussion->id,
915
                    'forumid' => $forum->id,
916
                    'forumtype' => $forum->type,
917
                )
918
            );
919
            $event = \mod_forum\event\post_created::create($params);
920
            $event->add_record_snapshot('forum_posts', $fromform);
921
            $event->add_record_snapshot('forum_discussions', $discussion);
922
            $event->trigger();
923
 
924
            // Update completion state.
925
            $completion = new completion_info($course);
926
            if ($completion->is_enabled($cm) &&
927
                ($forum->completionreplies || $forum->completionposts)) {
928
                $completion->update_state($cm, COMPLETION_COMPLETE);
929
            }
930
 
931
            redirect(
932
                forum_go_back_to($discussionurl),
933
                $message . $subscribemessage,
934
                null,
935
                \core\output\notification::NOTIFY_SUCCESS
936
            );
937
 
938
        } else {
939
            throw new \moodle_exception("couldnotadd", "forum", $errordestination);
940
        }
941
        exit;
942
 
943
    } else {
944
        // Adding a new discussion.
945
        // The location to redirect to after successfully posting.
946
        $redirectto = new moodle_url('/mod/forum/view.php', array('f' => $fromform->forum));
947
 
948
        $fromform->mailnow = empty($fromform->mailnow) ? 0 : 1;
949
 
950
        $discussion = $fromform;
951
        $discussion->name = $fromform->subject;
952
        $discussion->timelocked = 0;
953
 
954
        $newstopic = false;
955
        if ($forum->type == 'news' && !$fromform->parent) {
956
            $newstopic = true;
957
        }
958
 
959
        if (!empty($fromform->pinned) && $capabilitymanager->can_pin_discussions($USER)) {
960
            $discussion->pinned = FORUM_DISCUSSION_PINNED;
961
        } else {
962
            $discussion->pinned = FORUM_DISCUSSION_UNPINNED;
963
        }
964
 
965
        $allowedgroups = array();
966
        $groupstopostto = array();
967
 
968
        // If we are posting a copy to all groups the user has access to.
969
        if (isset($fromform->posttomygroups)) {
970
            // Post to each of my groups.
971
            require_capability('mod/forum:canposttomygroups', $modcontext);
972
 
973
            // Fetch all of this user's groups.
974
            // Note: all groups are returned when in visible groups mode so we must manually filter.
975
            $allowedgroups = groups_get_activity_allowed_groups($cm);
976
            foreach ($allowedgroups as $groupid => $group) {
977
                if ($capabilitymanager->can_create_discussions($USER, $groupid)) {
978
                    $groupstopostto[] = $groupid;
979
                }
980
            }
981
        } else if (isset($fromform->groupinfo)) {
982
            // Use the value provided in the dropdown group selection.
983
            $groupstopostto[] = $fromform->groupinfo;
984
            $redirectto->param('group', $fromform->groupinfo);
985
        } else if (isset($fromform->groupid) && !empty($fromform->groupid)) {
986
            // Use the value provided in the hidden form element instead.
987
            $groupstopostto[] = $fromform->groupid;
988
            $redirectto->param('group', $fromform->groupid);
989
        } else {
990
            // Use the value for all participants instead.
991
            $groupstopostto[] = -1;
992
        }
993
 
994
        // Before we post this we must check that the user will not exceed the blocking threshold.
995
        forum_check_blocking_threshold($thresholdwarning);
996
 
997
        foreach ($groupstopostto as $group) {
998
            if (!$capabilitymanager->can_create_discussions($USER, $group)) {
999
                throw new \moodle_exception('cannotcreatediscussion', 'forum');
1000
            }
1001
 
1002
            $discussion->groupid = $group;
1003
            $message = '';
1004
            if ($discussion->id = forum_add_discussion($discussion, $mformpost)) {
1005
 
1006
                $params = array(
1007
                    'context' => $modcontext,
1008
                    'objectid' => $discussion->id,
1009
                    'other' => array(
1010
                        'forumid' => $forum->id,
1011
                    )
1012
                );
1013
                $event = \mod_forum\event\discussion_created::create($params);
1014
                $event->add_record_snapshot('forum_discussions', $discussion);
1015
                $event->trigger();
1016
 
1017
                if ($fromform->mailnow) {
1018
                    $message .= get_string("postmailnow", "forum");
1019
                } else {
1020
                    $message .= '<p>'.get_string("postaddedsuccess", "forum") . '</p>';
1021
                    $message .= '<p>'.get_string("postaddedtimeleft", "forum", format_time($CFG->maxeditingtime)) . '</p>';
1022
                }
1023
 
1024
                $subscribemessage = forum_post_subscription($fromform, $forum, $discussion);
1025
            } else {
1026
                throw new \moodle_exception("couldnotadd", "forum", $errordestination);
1027
            }
1028
        }
1029
 
1030
        // Update completion status.
1031
        $completion = new completion_info($course);
1032
        if ($completion->is_enabled($cm) &&
1033
            ($forum->completiondiscussions || $forum->completionposts)) {
1034
            $completion->update_state($cm, COMPLETION_COMPLETE);
1035
        }
1036
 
1037
        // Redirect back to the discussion.
1038
        redirect(
1039
            forum_go_back_to($redirectto->out()),
1040
            $message . $subscribemessage,
1041
            null,
1042
            \core\output\notification::NOTIFY_SUCCESS
1043
        );
1044
    }
1045
}
1046
 
1047
 
1048
// This section is only shown after all checks are in place, and the forumentity and any relevant discussion and post
1049
// entity are available.
1050
 
1051
if (!empty($discussionentity)) {
1052
    $titlesubject = format_string($discussionentity->get_name(), true);
1053
} else if ('news' == $forumentity->get_type()) {
1054
    $titlesubject = get_string("addanewtopic", "forum");
1055
} else {
1056
    $titlesubject = get_string("addanewdiscussion", "forum");
1057
}
1058
 
1059
if (empty($post->edit)) {
1060
    $post->edit = '';
1061
}
1062
 
1063
if (empty($discussion->name)) {
1064
    if (empty($discussion)) {
1065
        $discussion = new stdClass();
1066
    }
1067
    $discussion->name = $forum->name;
1068
}
1069
 
1070
$strdiscussionname = '';
1071
if ('single' == $forumentity->get_type()) {
1072
    // There is only one discussion thread for this forum type. We should
1073
    // not show the discussion name (same as forum name in this case) in
1074
    // the breadcrumbs.
1075
    $strdiscussionname = '';
1076
} else if (!empty($discussionentity)) {
1077
    // Show the discussion name in the breadcrumbs.
1078
    $strdiscussionname = format_string($discussionentity->get_name()) . ': ';
1079
}
1080
 
1081
$forcefocus = empty($reply) ? null : 'message';
1082
 
1083
if (!empty($discussion->id)) {
1084
    $PAGE->navbar->add($titlesubject, $urlfactory->get_discussion_view_url_from_discussion($discussionentity));
1085
}
1086
 
1087
if ($edit) {
1088
    $PAGE->navbar->add(get_string('editdiscussiontopic', 'forum'), $PAGE->url);
1089
} else if ($reply) {
1090
    $PAGE->navbar->add(get_string('addreply', 'forum'));
1091
} else {
1092
    $PAGE->navbar->add(get_string('addanewdiscussion', 'forum'), $PAGE->url);
1093
}
1094
 
1095
$PAGE->set_title("{$course->shortname}: {$strdiscussionname}{$titlesubject}");
1096
$PAGE->set_heading($course->fullname);
1097
$PAGE->set_secondary_active_tab("modulepage");
1098
$activityheaderconfig['hidecompletion'] = true;
1099
$activityheaderconfig['description'] = '';
1100
 
1101
// Remove the activity description.
1102
$PAGE->activityheader->set_attrs($activityheaderconfig);
1103
echo $OUTPUT->header();
1104
 
1105
if ($edit) {
1106
    echo $OUTPUT->heading(get_string('editdiscussiontopic', 'forum'), 2);
1107
} else if ($reply) {
1108
    echo $OUTPUT->heading(get_string('replypostdiscussion', 'forum'), 2);
1109
} else {
1110
    echo $OUTPUT->heading(get_string('addanewdiscussion', 'forum'), 2);
1111
}
1112
 
1113
// Checkup.
1114
if (!empty($parententity) && !$capabilitymanager->can_view_post($USER, $discussionentity, $parententity)) {
1115
    throw new \moodle_exception('cannotreply', 'forum');
1116
}
1117
 
1118
if (empty($parententity) && empty($edit) && !$capabilitymanager->can_create_discussions($USER, $groupid)) {
1119
    throw new \moodle_exception('cannotcreatediscussion', 'forum');
1120
}
1121
 
1122
if (!empty($discussionentity) && 'qanda' == $forumentity->get_type()) {
1123
    $displaywarning = $capabilitymanager->must_post_before_viewing_discussion($USER, $discussionentity);
1124
    $displaywarning = $displaywarning && !forum_user_has_posted($forumentity->get_id(), $discussionentity->get_id(), $USER->id);
1125
    if ($displaywarning) {
1126
        echo $OUTPUT->notification(get_string('qandanotify', 'forum'));
1127
    }
1128
}
1129
 
1130
// If there is a warning message and we are not editing a post we need to handle the warning.
1131
if (!empty($thresholdwarning) && !$edit) {
1132
    // Here we want to throw an exception if they are no longer allowed to post.
1133
    forum_check_blocking_threshold($thresholdwarning);
1134
}
1135
 
1136
if (!empty($parententity)) {
1137
    $postentities = [$parententity];
1138
 
1139
    if (empty($post->edit)) {
1140
        if ('qanda' != $forumentity->get_type() || forum_user_can_see_discussion($forum, $discussion, $modcontext)) {
1141
            $replies = $postvault->get_replies_to_post(
1142
                    $USER,
1143
                    $parententity,
1144
                    $capabilitymanager->can_view_any_private_reply($USER),
1145
                    'created ASC'
1146
                );
1147
            $postentities = array_merge($postentities, $replies);
1148
        }
1149
    }
1150
 
1151
    $rendererfactory = mod_forum\local\container::get_renderer_factory();
1152
    $postsrenderer = $rendererfactory->get_single_discussion_posts_renderer(FORUM_MODE_THREADED, true);
1153
    echo $postsrenderer->render($USER, [$forumentity], [$discussionentity], $postentities);
1154
}
1155
 
1156
// Call print disclosure for enabled plagiarism plugins.
1157
if (!empty($CFG->enableplagiarism)) {
1158
    require_once($CFG->libdir.'/plagiarismlib.php');
1159
    echo plagiarism_print_disclosure($cm->id);
1160
}
1161
 
1162
if (!empty($formheading)) {
1163
    echo $OUTPUT->heading($formheading, 2, array('class' => 'accesshide'));
1164
}
1165
 
1166
if (!empty($postentity)) {
1167
    $data = (object) [
1168
        'tags' => core_tag_tag::get_item_tags_array('mod_forum', 'forum_posts', $postentity->get_id())
1169
    ];
1170
    $mformpost->set_data($data);
1171
}
1172
 
1173
$mformpost->display();
1174
 
1175
echo $OUTPUT->footer();