MDL-30811 forum: Update use of redirect to include message and type
[moodle.git] / mod / forum / post.php
1 <?php
3 // This file is part of Moodle - http://moodle.org/
4 //
5 // Moodle is free software: you can redistribute it and/or modify
6 // it under the terms of the GNU General Public License as published by
7 // the Free Software Foundation, either version 3 of the License, or
8 // (at your option) any later version.
9 //
10 // Moodle is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 // GNU General Public License for more details.
14 //
15 // You should have received a copy of the GNU General Public License
16 // along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
18 /**
19  * Edit and save a new post to a discussion
20  *
21  * @package   mod_forum
22  * @copyright 1999 onwards Martin Dougiamas  {@link http://moodle.com}
23  * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
24  */
26 require_once('../../config.php');
27 require_once('lib.php');
28 require_once($CFG->libdir.'/completionlib.php');
30 $reply   = optional_param('reply', 0, PARAM_INT);
31 $forum   = optional_param('forum', 0, PARAM_INT);
32 $edit    = optional_param('edit', 0, PARAM_INT);
33 $delete  = optional_param('delete', 0, PARAM_INT);
34 $prune   = optional_param('prune', 0, PARAM_INT);
35 $name    = optional_param('name', '', PARAM_CLEAN);
36 $confirm = optional_param('confirm', 0, PARAM_INT);
37 $groupid = optional_param('groupid', null, PARAM_INT);
39 $PAGE->set_url('/mod/forum/post.php', array(
40         'reply' => $reply,
41         'forum' => $forum,
42         'edit'  => $edit,
43         'delete'=> $delete,
44         'prune' => $prune,
45         'name'  => $name,
46         'confirm'=>$confirm,
47         'groupid'=>$groupid,
48         ));
49 //these page_params will be passed as hidden variables later in the form.
50 $page_params = array('reply'=>$reply, 'forum'=>$forum, 'edit'=>$edit);
52 $sitecontext = context_system::instance();
54 if (!isloggedin() or isguestuser()) {
56     if (!isloggedin() and !get_local_referer()) {
57         // No referer+not logged in - probably coming in via email  See MDL-9052
58         require_login();
59     }
61     if (!empty($forum)) {      // User is starting a new discussion in a forum
62         if (! $forum = $DB->get_record('forum', array('id' => $forum))) {
63             print_error('invalidforumid', 'forum');
64         }
65     } else if (!empty($reply)) {      // User is writing a new reply
66         if (! $parent = forum_get_post_full($reply)) {
67             print_error('invalidparentpostid', 'forum');
68         }
69         if (! $discussion = $DB->get_record('forum_discussions', array('id' => $parent->discussion))) {
70             print_error('notpartofdiscussion', 'forum');
71         }
72         if (! $forum = $DB->get_record('forum', array('id' => $discussion->forum))) {
73             print_error('invalidforumid');
74         }
75     }
76     if (! $course = $DB->get_record('course', array('id' => $forum->course))) {
77         print_error('invalidcourseid');
78     }
80     if (!$cm = get_coursemodule_from_instance('forum', $forum->id, $course->id)) { // For the logs
81         print_error('invalidcoursemodule');
82     } else {
83         $modcontext = context_module::instance($cm->id);
84     }
86     $PAGE->set_cm($cm, $course, $forum);
87     $PAGE->set_context($modcontext);
88     $PAGE->set_title($course->shortname);
89     $PAGE->set_heading($course->fullname);
90     $referer = get_local_referer(false);
92     echo $OUTPUT->header();
93     echo $OUTPUT->confirm(get_string('noguestpost', 'forum').'<br /><br />'.get_string('liketologin'), get_login_url(), $referer);
94     echo $OUTPUT->footer();
95     exit;
96 }
98 require_login(0, false);   // Script is useless unless they're logged in
100 if (!empty($forum)) {      // User is starting a new discussion in a forum
101     if (! $forum = $DB->get_record("forum", array("id" => $forum))) {
102         print_error('invalidforumid', 'forum');
103     }
104     if (! $course = $DB->get_record("course", array("id" => $forum->course))) {
105         print_error('invalidcourseid');
106     }
107     if (! $cm = get_coursemodule_from_instance("forum", $forum->id, $course->id)) {
108         print_error("invalidcoursemodule");
109     }
111     // Retrieve the contexts.
112     $modcontext    = context_module::instance($cm->id);
113     $coursecontext = context_course::instance($course->id);
115     if (! forum_user_can_post_discussion($forum, $groupid, -1, $cm)) {
116         if (!isguestuser()) {
117             if (!is_enrolled($coursecontext)) {
118                 if (enrol_selfenrol_available($course->id)) {
119                     $SESSION->wantsurl = qualified_me();
120                     $SESSION->enrolcancel = get_local_referer(false);
121                     redirect(new moodle_url('/enrol/index.php', array('id' => $course->id,
122                         'returnurl' => '/mod/forum/view.php?f=' . $forum->id)),
123                         get_string('youneedtoenrol'));
124                 }
125             }
126         }
127         print_error('nopostforum', 'forum');
128     }
130     if (!$cm->visible and !has_capability('moodle/course:viewhiddenactivities', $modcontext)) {
131         print_error("activityiscurrentlyhidden");
132     }
134     $SESSION->fromurl = get_local_referer(false);
136     // Load up the $post variable.
138     $post = new stdClass();
139     $post->course        = $course->id;
140     $post->forum         = $forum->id;
141     $post->discussion    = 0;           // ie discussion # not defined yet
142     $post->parent        = 0;
143     $post->subject       = '';
144     $post->userid        = $USER->id;
145     $post->message       = '';
146     $post->messageformat = editors_get_preferred_format();
147     $post->messagetrust  = 0;
149     if (isset($groupid)) {
150         $post->groupid = $groupid;
151     } else {
152         $post->groupid = groups_get_activity_group($cm);
153     }
155     // Unsetting this will allow the correct return URL to be calculated later.
156     unset($SESSION->fromdiscussion);
158 } else if (!empty($reply)) {      // User is writing a new reply
160     if (! $parent = forum_get_post_full($reply)) {
161         print_error('invalidparentpostid', 'forum');
162     }
163     if (! $discussion = $DB->get_record("forum_discussions", array("id" => $parent->discussion))) {
164         print_error('notpartofdiscussion', 'forum');
165     }
166     if (! $forum = $DB->get_record("forum", array("id" => $discussion->forum))) {
167         print_error('invalidforumid', 'forum');
168     }
169     if (! $course = $DB->get_record("course", array("id" => $discussion->course))) {
170         print_error('invalidcourseid');
171     }
172     if (! $cm = get_coursemodule_from_instance("forum", $forum->id, $course->id)) {
173         print_error('invalidcoursemodule');
174     }
176     // Ensure lang, theme, etc. is set up properly. MDL-6926
177     $PAGE->set_cm($cm, $course, $forum);
179     // Retrieve the contexts.
180     $modcontext    = context_module::instance($cm->id);
181     $coursecontext = context_course::instance($course->id);
183     if (! forum_user_can_post($forum, $discussion, $USER, $cm, $course, $modcontext)) {
184         if (!isguestuser()) {
185             if (!is_enrolled($coursecontext)) {  // User is a guest here!
186                 $SESSION->wantsurl = qualified_me();
187                 $SESSION->enrolcancel = get_local_referer(false);
188                 redirect(new moodle_url('/enrol/index.php', array('id' => $course->id,
189                     'returnurl' => '/mod/forum/view.php?f=' . $forum->id)),
190                     get_string('youneedtoenrol'));
191             }
192         }
193         print_error('nopostforum', 'forum');
194     }
196     // Make sure user can post here
197     if (isset($cm->groupmode) && empty($course->groupmodeforce)) {
198         $groupmode =  $cm->groupmode;
199     } else {
200         $groupmode = $course->groupmode;
201     }
202     if ($groupmode == SEPARATEGROUPS and !has_capability('moodle/site:accessallgroups', $modcontext)) {
203         if ($discussion->groupid == -1) {
204             print_error('nopostforum', 'forum');
205         } else {
206             if (!groups_is_member($discussion->groupid)) {
207                 print_error('nopostforum', 'forum');
208             }
209         }
210     }
212     if (!$cm->visible and !has_capability('moodle/course:viewhiddenactivities', $modcontext)) {
213         print_error("activityiscurrentlyhidden");
214     }
216     // Load up the $post variable.
218     $post = new stdClass();
219     $post->course      = $course->id;
220     $post->forum       = $forum->id;
221     $post->discussion  = $parent->discussion;
222     $post->parent      = $parent->id;
223     $post->subject     = $parent->subject;
224     $post->userid      = $USER->id;
225     $post->message     = '';
227     $post->groupid = ($discussion->groupid == -1) ? 0 : $discussion->groupid;
229     $strre = get_string('re', 'forum');
230     if (!(substr($post->subject, 0, strlen($strre)) == $strre)) {
231         $post->subject = $strre.' '.$post->subject;
232     }
234     // Unsetting this will allow the correct return URL to be calculated later.
235     unset($SESSION->fromdiscussion);
237 } else if (!empty($edit)) {  // User is editing their own post
239     if (! $post = forum_get_post_full($edit)) {
240         print_error('invalidpostid', 'forum');
241     }
242     if ($post->parent) {
243         if (! $parent = forum_get_post_full($post->parent)) {
244             print_error('invalidparentpostid', 'forum');
245         }
246     }
248     if (! $discussion = $DB->get_record("forum_discussions", array("id" => $post->discussion))) {
249         print_error('notpartofdiscussion', 'forum');
250     }
251     if (! $forum = $DB->get_record("forum", array("id" => $discussion->forum))) {
252         print_error('invalidforumid', 'forum');
253     }
254     if (! $course = $DB->get_record("course", array("id" => $discussion->course))) {
255         print_error('invalidcourseid');
256     }
257     if (!$cm = get_coursemodule_from_instance("forum", $forum->id, $course->id)) {
258         print_error('invalidcoursemodule');
259     } else {
260         $modcontext = context_module::instance($cm->id);
261     }
263     $PAGE->set_cm($cm, $course, $forum);
265     if (!($forum->type == 'news' && !$post->parent && $discussion->timestart > time())) {
266         if (((time() - $post->created) > $CFG->maxeditingtime) and
267                     !has_capability('mod/forum:editanypost', $modcontext)) {
268             print_error('maxtimehaspassed', 'forum', '', format_time($CFG->maxeditingtime));
269         }
270     }
271     if (($post->userid <> $USER->id) and
272                 !has_capability('mod/forum:editanypost', $modcontext)) {
273         print_error('cannoteditposts', 'forum');
274     }
277     // Load up the $post variable.
278     $post->edit   = $edit;
279     $post->course = $course->id;
280     $post->forum  = $forum->id;
281     $post->groupid = ($discussion->groupid == -1) ? 0 : $discussion->groupid;
283     $post = trusttext_pre_edit($post, 'message', $modcontext);
285     // Unsetting this will allow the correct return URL to be calculated later.
286     unset($SESSION->fromdiscussion);
288 }else if (!empty($delete)) {  // User is deleting a post
290     if (! $post = forum_get_post_full($delete)) {
291         print_error('invalidpostid', 'forum');
292     }
293     if (! $discussion = $DB->get_record("forum_discussions", array("id" => $post->discussion))) {
294         print_error('notpartofdiscussion', 'forum');
295     }
296     if (! $forum = $DB->get_record("forum", array("id" => $discussion->forum))) {
297         print_error('invalidforumid', 'forum');
298     }
299     if (!$cm = get_coursemodule_from_instance("forum", $forum->id, $forum->course)) {
300         print_error('invalidcoursemodule');
301     }
302     if (!$course = $DB->get_record('course', array('id' => $forum->course))) {
303         print_error('invalidcourseid');
304     }
306     require_login($course, false, $cm);
307     $modcontext = context_module::instance($cm->id);
309     if ( !(($post->userid == $USER->id && has_capability('mod/forum:deleteownpost', $modcontext))
310                 || has_capability('mod/forum:deleteanypost', $modcontext)) ) {
311         print_error('cannotdeletepost', 'forum');
312     }
315     $replycount = forum_count_replies($post);
317     if (!empty($confirm) && confirm_sesskey()) {    // User has confirmed the delete
318         //check user capability to delete post.
319         $timepassed = time() - $post->created;
320         if (($timepassed > $CFG->maxeditingtime) && !has_capability('mod/forum:deleteanypost', $modcontext)) {
321             print_error("cannotdeletepost", "forum",
322                         forum_go_back_to(new moodle_url("/mod/forum/discuss.php", array('d' => $post->discussion))));
323         }
325         if ($post->totalscore) {
326             notice(get_string('couldnotdeleteratings', 'rating'),
327                    forum_go_back_to(new moodle_url("/mod/forum/discuss.php", array('d' => $post->discussion))));
329         } else if ($replycount && !has_capability('mod/forum:deleteanypost', $modcontext)) {
330             print_error("couldnotdeletereplies", "forum",
331                         forum_go_back_to(new moodle_url("/mod/forum/discuss.php", array('d' => $post->discussion))));
333         } else {
334             if (! $post->parent) {  // post is a discussion topic as well, so delete discussion
335                 if ($forum->type == 'single') {
336                     notice("Sorry, but you are not allowed to delete that discussion!",
337                            forum_go_back_to(new moodle_url("/mod/forum/discuss.php", array('d' => $post->discussion))));
338                 }
339                 forum_delete_discussion($discussion, false, $course, $cm, $forum);
341                 $params = array(
342                     'objectid' => $discussion->id,
343                     'context' => $modcontext,
344                     'other' => array(
345                         'forumid' => $forum->id,
346                     )
347                 );
349                 $event = \mod_forum\event\discussion_deleted::create($params);
350                 $event->add_record_snapshot('forum_discussions', $discussion);
351                 $event->trigger();
353                 redirect("view.php?f=$discussion->forum");
355             } else if (forum_delete_post($post, has_capability('mod/forum:deleteanypost', $modcontext),
356                 $course, $cm, $forum)) {
358                 if ($forum->type == 'single') {
359                     // Single discussion forums are an exception. We show
360                     // the forum itself since it only has one discussion
361                     // thread.
362                     $discussionurl = new moodle_url("/mod/forum/view.php", array('f' => $forum->id));
363                 } else {
364                     $discussionurl = new moodle_url("/mod/forum/discuss.php", array('d' => $discussion->id));
365                 }
367                 redirect(forum_go_back_to($discussionurl));
368             } else {
369                 print_error('errorwhiledelete', 'forum');
370             }
371         }
374     } else { // User just asked to delete something
376         forum_set_return();
377         $PAGE->navbar->add(get_string('delete', 'forum'));
378         $PAGE->set_title($course->shortname);
379         $PAGE->set_heading($course->fullname);
381         if ($replycount) {
382             if (!has_capability('mod/forum:deleteanypost', $modcontext)) {
383                 print_error("couldnotdeletereplies", "forum",
384                       forum_go_back_to(new moodle_url('/mod/forum/discuss.php', array('d' => $post->discussion), 'p'.$post->id)));
385             }
386             echo $OUTPUT->header();
387             echo $OUTPUT->heading(format_string($forum->name), 2);
388             echo $OUTPUT->confirm(get_string("deletesureplural", "forum", $replycount+1),
389                          "post.php?delete=$delete&confirm=$delete",
390                          $CFG->wwwroot.'/mod/forum/discuss.php?d='.$post->discussion.'#p'.$post->id);
392             forum_print_post($post, $discussion, $forum, $cm, $course, false, false, false);
394             if (empty($post->edit)) {
395                 $forumtracked = forum_tp_is_tracked($forum);
396                 $posts = forum_get_all_discussion_posts($discussion->id, "created ASC", $forumtracked);
397                 forum_print_posts_nested($course, $cm, $forum, $discussion, $post, false, false, $forumtracked, $posts);
398             }
399         } else {
400             echo $OUTPUT->header();
401             echo $OUTPUT->heading(format_string($forum->name), 2);
402             echo $OUTPUT->confirm(get_string("deletesure", "forum", $replycount),
403                          "post.php?delete=$delete&confirm=$delete",
404                          $CFG->wwwroot.'/mod/forum/discuss.php?d='.$post->discussion.'#p'.$post->id);
405             forum_print_post($post, $discussion, $forum, $cm, $course, false, false, false);
406         }
408     }
409     echo $OUTPUT->footer();
410     die;
413 } else if (!empty($prune)) {  // Pruning
415     if (!$post = forum_get_post_full($prune)) {
416         print_error('invalidpostid', 'forum');
417     }
418     if (!$discussion = $DB->get_record("forum_discussions", array("id" => $post->discussion))) {
419         print_error('notpartofdiscussion', 'forum');
420     }
421     if (!$forum = $DB->get_record("forum", array("id" => $discussion->forum))) {
422         print_error('invalidforumid', 'forum');
423     }
424     if ($forum->type == 'single') {
425         print_error('cannotsplit', 'forum');
426     }
427     if (!$post->parent) {
428         print_error('alreadyfirstpost', 'forum');
429     }
430     if (!$cm = get_coursemodule_from_instance("forum", $forum->id, $forum->course)) { // For the logs
431         print_error('invalidcoursemodule');
432     } else {
433         $modcontext = context_module::instance($cm->id);
434     }
435     if (!has_capability('mod/forum:splitdiscussions', $modcontext)) {
436         print_error('cannotsplit', 'forum');
437     }
439     $PAGE->set_cm($cm);
440     $PAGE->set_context($modcontext);
442     $prunemform = new mod_forum_prune_form(null, array('prune' => $prune, 'confirm' => $prune));
445     if ($prunemform->is_cancelled()) {
446         redirect(forum_go_back_to(new moodle_url("/mod/forum/discuss.php", array('d' => $post->discussion))));
447     } else if ($fromform = $prunemform->get_data()) {
448         // User submits the data.
449         $newdiscussion = new stdClass();
450         $newdiscussion->course       = $discussion->course;
451         $newdiscussion->forum        = $discussion->forum;
452         $newdiscussion->name         = $name;
453         $newdiscussion->firstpost    = $post->id;
454         $newdiscussion->userid       = $discussion->userid;
455         $newdiscussion->groupid      = $discussion->groupid;
456         $newdiscussion->assessed     = $discussion->assessed;
457         $newdiscussion->usermodified = $post->userid;
458         $newdiscussion->timestart    = $discussion->timestart;
459         $newdiscussion->timeend      = $discussion->timeend;
461         $newid = $DB->insert_record('forum_discussions', $newdiscussion);
463         $newpost = new stdClass();
464         $newpost->id      = $post->id;
465         $newpost->parent  = 0;
466         $newpost->subject = $name;
468         $DB->update_record("forum_posts", $newpost);
470         forum_change_discussionid($post->id, $newid);
472         // Update last post in each discussion.
473         forum_discussion_update_last_post($discussion->id);
474         forum_discussion_update_last_post($newid);
476         // Fire events to reflect the split..
477         $params = array(
478             'context' => $modcontext,
479             'objectid' => $discussion->id,
480             'other' => array(
481                 'forumid' => $forum->id,
482             )
483         );
484         $event = \mod_forum\event\discussion_updated::create($params);
485         $event->trigger();
487         $params = array(
488             'context' => $modcontext,
489             'objectid' => $newid,
490             'other' => array(
491                 'forumid' => $forum->id,
492             )
493         );
494         $event = \mod_forum\event\discussion_created::create($params);
495         $event->trigger();
497         $params = array(
498             'context' => $modcontext,
499             'objectid' => $post->id,
500             'other' => array(
501                 'discussionid' => $newid,
502                 'forumid' => $forum->id,
503                 'forumtype' => $forum->type,
504             )
505         );
506         $event = \mod_forum\event\post_updated::create($params);
507         $event->add_record_snapshot('forum_discussions', $discussion);
508         $event->trigger();
510         redirect(forum_go_back_to(new moodle_url("/mod/forum/discuss.php", array('d' => $newid))));
512     } else {
513         // Display the prune form.
514         $course = $DB->get_record('course', array('id' => $forum->course));
515         $PAGE->navbar->add(format_string($post->subject, true), new moodle_url('/mod/forum/discuss.php', array('d'=>$discussion->id)));
516         $PAGE->navbar->add(get_string("prune", "forum"));
517         $PAGE->set_title(format_string($discussion->name).": ".format_string($post->subject));
518         $PAGE->set_heading($course->fullname);
519         echo $OUTPUT->header();
520         echo $OUTPUT->heading(format_string($forum->name), 2);
521         echo $OUTPUT->heading(get_string('pruneheading', 'forum'), 3);
523         $prunemform->display();
525         forum_print_post($post, $discussion, $forum, $cm, $course, false, false, false);
526     }
528     echo $OUTPUT->footer();
529     die;
530 } else {
531     print_error('unknowaction');
535 if (!isset($coursecontext)) {
536     // Has not yet been set by post.php.
537     $coursecontext = context_course::instance($forum->course);
541 // from now on user must be logged on properly
543 if (!$cm = get_coursemodule_from_instance('forum', $forum->id, $course->id)) { // For the logs
544     print_error('invalidcoursemodule');
546 $modcontext = context_module::instance($cm->id);
547 require_login($course, false, $cm);
549 if (isguestuser()) {
550     // just in case
551     print_error('noguest');
554 if (!isset($forum->maxattachments)) {  // TODO - delete this once we add a field to the forum table
555     $forum->maxattachments = 3;
558 $thresholdwarning = forum_check_throttling($forum, $cm);
559 $mform_post = new mod_forum_post_form('post.php', array('course' => $course,
560                                                         'cm' => $cm,
561                                                         'coursecontext' => $coursecontext,
562                                                         'modcontext' => $modcontext,
563                                                         'forum' => $forum,
564                                                         'post' => $post,
565                                                         'subscribe' => \mod_forum\subscriptions::is_subscribed($USER->id, $forum,
566                                                                 null, $cm),
567                                                         'thresholdwarning' => $thresholdwarning,
568                                                         'edit' => $edit), 'post', '', array('id' => 'mformforum'));
570 $draftitemid = file_get_submitted_draft_itemid('attachments');
571 file_prepare_draft_area($draftitemid, $modcontext->id, 'mod_forum', 'attachment', empty($post->id)?null:$post->id, mod_forum_post_form::attachment_options($forum));
573 //load data into form NOW!
575 if ($USER->id != $post->userid) {   // Not the original author, so add a message to the end
576     $data = new stdClass();
577     $data->date = userdate($post->modified);
578     if ($post->messageformat == FORMAT_HTML) {
579         $data->name = '<a href="'.$CFG->wwwroot.'/user/view.php?id='.$USER->id.'&course='.$post->course.'">'.
580                        fullname($USER).'</a>';
581         $post->message .= '<p><span class="edited">('.get_string('editedby', 'forum', $data).')</span></p>';
582     } else {
583         $data->name = fullname($USER);
584         $post->message .= "\n\n(".get_string('editedby', 'forum', $data).')';
585     }
586     unset($data);
589 $formheading = '';
590 if (!empty($parent)) {
591     $heading = get_string("yourreply", "forum");
592     $formheading = get_string('reply', 'forum');
593 } else {
594     if ($forum->type == 'qanda') {
595         $heading = get_string('yournewquestion', 'forum');
596     } else {
597         $heading = get_string('yournewtopic', 'forum');
598     }
601 $postid = empty($post->id) ? null : $post->id;
602 $draftid_editor = file_get_submitted_draft_itemid('message');
603 $currenttext = file_prepare_draft_area($draftid_editor, $modcontext->id, 'mod_forum', 'post', $postid, mod_forum_post_form::editor_options($modcontext, $postid), $post->message);
605 $manageactivities = has_capability('moodle/course:manageactivities', $coursecontext);
606 if (\mod_forum\subscriptions::subscription_disabled($forum) && !$manageactivities) {
607     // User does not have permission to subscribe to this discussion at all.
608     $discussionsubscribe = false;
609 } else if (\mod_forum\subscriptions::is_forcesubscribed($forum)) {
610     // User does not have permission to unsubscribe from this discussion at all.
611     $discussionsubscribe = true;
612 } else {
613     if (isset($discussion) && \mod_forum\subscriptions::is_subscribed($USER->id, $forum, $discussion->id, $cm)) {
614         // User is subscribed to the discussion - continue the subscription.
615         $discussionsubscribe = true;
616     } else if (!isset($discussion) && \mod_forum\subscriptions::is_subscribed($USER->id, $forum, null, $cm)) {
617         // Starting a new discussion, and the user is subscribed to the forum - subscribe to the discussion.
618         $discussionsubscribe = true;
619     } else {
620         // User is not subscribed to either forum or discussion. Follow user preference.
621         $discussionsubscribe = $USER->autosubscribe;
622     }
625 $mform_post->set_data(array(        'attachments'=>$draftitemid,
626                                     'general'=>$heading,
627                                     'subject'=>$post->subject,
628                                     'message'=>array(
629                                         'text'=>$currenttext,
630                                         'format'=>empty($post->messageformat) ? editors_get_preferred_format() : $post->messageformat,
631                                         'itemid'=>$draftid_editor
632                                     ),
633                                     'discussionsubscribe' => $discussionsubscribe,
634                                     'mailnow'=>!empty($post->mailnow),
635                                     'userid'=>$post->userid,
636                                     'parent'=>$post->parent,
637                                     'discussion'=>$post->discussion,
638                                     'course'=>$course->id) +
639                                     $page_params +
641                             (isset($post->format)?array(
642                                     'format'=>$post->format):
643                                 array())+
645                             (isset($discussion->timestart)?array(
646                                     'timestart'=>$discussion->timestart):
647                                 array())+
649                             (isset($discussion->timeend)?array(
650                                     'timeend'=>$discussion->timeend):
651                                 array())+
653                             (isset($discussion->pinned) ? array(
654                                      'pinned' => $discussion->pinned) :
655                                 array()) +
657                             (isset($post->groupid)?array(
658                                     'groupid'=>$post->groupid):
659                                 array())+
661                             (isset($discussion->id)?
662                                     array('discussion'=>$discussion->id):
663                                     array()));
665 if ($mform_post->is_cancelled()) {
666     if (!isset($discussion->id) || $forum->type === 'qanda') {
667         // Q and A forums don't have a discussion page, so treat them like a new thread..
668         redirect(new moodle_url('/mod/forum/view.php', array('f' => $forum->id)));
669     } else {
670         redirect(new moodle_url('/mod/forum/discuss.php', array('d' => $discussion->id)));
671     }
672 } else if ($fromform = $mform_post->get_data()) {
674     if (empty($SESSION->fromurl)) {
675         $errordestination = "$CFG->wwwroot/mod/forum/view.php?f=$forum->id";
676     } else {
677         $errordestination = $SESSION->fromurl;
678     }
680     $fromform->itemid        = $fromform->message['itemid'];
681     $fromform->messageformat = $fromform->message['format'];
682     $fromform->message       = $fromform->message['text'];
683     // WARNING: the $fromform->message array has been overwritten, do not use it anymore!
684     $fromform->messagetrust  = trusttext_trusted($modcontext);
686     if ($fromform->edit) {           // Updating a post
687         unset($fromform->groupid);
688         $fromform->id = $fromform->edit;
689         $message = '';
691         //fix for bug #4314
692         if (!$realpost = $DB->get_record('forum_posts', array('id' => $fromform->id))) {
693             $realpost = new stdClass();
694             $realpost->userid = -1;
695         }
698         // if user has edit any post capability
699         // or has either startnewdiscussion or reply capability and is editting own post
700         // then he can proceed
701         // MDL-7066
702         if ( !(($realpost->userid == $USER->id && (has_capability('mod/forum:replypost', $modcontext)
703                             || has_capability('mod/forum:startdiscussion', $modcontext))) ||
704                             has_capability('mod/forum:editanypost', $modcontext)) ) {
705             print_error('cannotupdatepost', 'forum');
706         }
708         // If the user has access to all groups and they are changing the group, then update the post.
709         if (isset($fromform->groupinfo) && has_capability('mod/forum:movediscussions', $modcontext)) {
710             if (empty($fromform->groupinfo)) {
711                 $fromform->groupinfo = -1;
712             }
714             if (!forum_user_can_post_discussion($forum, $fromform->groupinfo, null, $cm, $modcontext)) {
715                 print_error('cannotupdatepost', 'forum');
716             }
718             $DB->set_field('forum_discussions' ,'groupid' , $fromform->groupinfo, array('firstpost' => $fromform->id));
719         }
720         // When editing first post/discussion.
721         if (!$fromform->parent) {
722             if (has_capability('mod/forum:pindiscussions', $modcontext)) {
723                 // Can change pinned if we have capability.
724                 $fromform->pinned = !empty($fromform->pinned) ? FORUM_DISCUSSION_PINNED : FORUM_DISCUSSION_UNPINNED;
725             } else {
726                 // We don't have the capability to change so keep to previous value.
727                 unset($fromform->pinned);
728             }
729         }
730         $updatepost = $fromform; //realpost
731         $updatepost->forum = $forum->id;
732         if (!forum_update_post($updatepost, $mform_post, $message)) {
733             print_error("couldnotupdate", "forum", $errordestination);
734         }
736         // MDL-11818
737         if (($forum->type == 'single') && ($updatepost->parent == '0')){ // updating first post of single discussion type -> updating forum intro
738             $forum->intro = $updatepost->message;
739             $forum->timemodified = time();
740             $DB->update_record("forum", $forum);
741         }
743         if ($realpost->userid == $USER->id) {
744             $message .= '<br />'.get_string("postupdated", "forum");
745         } else {
746             $realuser = $DB->get_record('user', array('id' => $realpost->userid));
747             $message .= '<br />'.get_string("editedpostupdated", "forum", fullname($realuser));
748         }
750         $subscribemessage = forum_post_subscription($fromform, $forum, $discussion);
751         if ($forum->type == 'single') {
752             // Single discussion forums are an exception. We show
753             // the forum itself since it only has one discussion
754             // thread.
755             $discussionurl = new moodle_url("/mod/forum/view.php", array('f' => $forum->id));
756         } else {
757             $discussionurl = new moodle_url("/mod/forum/discuss.php", array('d' => $discussion->id), 'p' . $fromform->id);
758         }
760         $params = array(
761             'context' => $modcontext,
762             'objectid' => $fromform->id,
763             'other' => array(
764                 'discussionid' => $discussion->id,
765                 'forumid' => $forum->id,
766                 'forumtype' => $forum->type,
767             )
768         );
770         if ($realpost->userid !== $USER->id) {
771             $params['relateduserid'] = $realpost->userid;
772         }
774         $event = \mod_forum\event\post_updated::create($params);
775         $event->add_record_snapshot('forum_discussions', $discussion);
776         $event->trigger();
778         redirect(
779                 forum_go_back_to($discussionurl),
780                 $message . $subscribemessage,
781                 null,
782                 \core\output\notification::NOTIFY_SUCCESS
783             );
785     } else if ($fromform->discussion) { // Adding a new post to an existing discussion
786         // Before we add this we must check that the user will not exceed the blocking threshold.
787         forum_check_blocking_threshold($thresholdwarning);
789         unset($fromform->groupid);
790         $message = '';
791         $addpost = $fromform;
792         $addpost->forum=$forum->id;
793         if ($fromform->id = forum_add_new_post($addpost, $mform_post, $message)) {
794             $subscribemessage = forum_post_subscription($fromform, $forum, $discussion);
796             if (!empty($fromform->mailnow)) {
797                 $message .= get_string("postmailnow", "forum");
798             } else {
799                 $message .= '<p>'.get_string("postaddedsuccess", "forum") . '</p>';
800                 $message .= '<p>'.get_string("postaddedtimeleft", "forum", format_time($CFG->maxeditingtime)) . '</p>';
801             }
803             if ($forum->type == 'single') {
804                 // Single discussion forums are an exception. We show
805                 // the forum itself since it only has one discussion
806                 // thread.
807                 $discussionurl = new moodle_url("/mod/forum/view.php", array('f' => $forum->id), 'p'.$fromform->id);
808             } else {
809                 $discussionurl = new moodle_url("/mod/forum/discuss.php", array('d' => $discussion->id), 'p'.$fromform->id);
810             }
812             $params = array(
813                 'context' => $modcontext,
814                 'objectid' => $fromform->id,
815                 'other' => array(
816                     'discussionid' => $discussion->id,
817                     'forumid' => $forum->id,
818                     'forumtype' => $forum->type,
819                 )
820             );
821             $event = \mod_forum\event\post_created::create($params);
822             $event->add_record_snapshot('forum_posts', $fromform);
823             $event->add_record_snapshot('forum_discussions', $discussion);
824             $event->trigger();
826             // Update completion state
827             $completion=new completion_info($course);
828             if($completion->is_enabled($cm) &&
829                 ($forum->completionreplies || $forum->completionposts)) {
830                 $completion->update_state($cm,COMPLETION_COMPLETE);
831             }
833             redirect(
834                     forum_go_back_to($discussionurl),
835                     $message . $subscribemessage,
836                     null,
837                     \core\output\notification::NOTIFY_SUCCESS
838                 );
840         } else {
841             print_error("couldnotadd", "forum", $errordestination);
842         }
843         exit;
845     } else { // Adding a new discussion.
846         // The location to redirect to after successfully posting.
847         $redirectto = new moodle_url('view.php', array('f' => $fromform->forum));
849         $fromform->mailnow = empty($fromform->mailnow) ? 0 : 1;
851         $discussion = $fromform;
852         $discussion->name = $fromform->subject;
854         $newstopic = false;
855         if ($forum->type == 'news' && !$fromform->parent) {
856             $newstopic = true;
857         }
858         $discussion->timestart = $fromform->timestart;
859         $discussion->timeend = $fromform->timeend;
861         if (has_capability('mod/forum:pindiscussions', $modcontext) && !empty($fromform->pinned)) {
862             $discussion->pinned = FORUM_DISCUSSION_PINNED;
863         } else {
864             $discussion->pinned = FORUM_DISCUSSION_UNPINNED;
865         }
867         $allowedgroups = array();
868         $groupstopostto = array();
870         // If we are posting a copy to all groups the user has access to.
871         if (isset($fromform->posttomygroups)) {
872             // Post to each of my groups.
873             require_capability('mod/forum:canposttomygroups', $modcontext);
875             // Fetch all of this user's groups.
876             // Note: all groups are returned when in visible groups mode so we must manually filter.
877             $allowedgroups = groups_get_activity_allowed_groups($cm);
878             foreach ($allowedgroups as $groupid => $group) {
879                 if (forum_user_can_post_discussion($forum, $groupid, -1, $cm, $modcontext)) {
880                     $groupstopostto[] = $groupid;
881                 }
882             }
883         } else if (isset($fromform->groupinfo)) {
884             // Use the value provided in the dropdown group selection.
885             $groupstopostto[] = $fromform->groupinfo;
886             $redirectto->param('group', $fromform->groupinfo);
887         } else if (isset($fromform->groupid) && !empty($fromform->groupid)) {
888             // Use the value provided in the hidden form element instead.
889             $groupstopostto[] = $fromform->groupid;
890             $redirectto->param('group', $fromform->groupid);
891         } else {
892             // Use the value for all participants instead.
893             $groupstopostto[] = -1;
894         }
896         // Before we post this we must check that the user will not exceed the blocking threshold.
897         forum_check_blocking_threshold($thresholdwarning);
899         foreach ($groupstopostto as $group) {
900             if (!forum_user_can_post_discussion($forum, $group, -1, $cm, $modcontext)) {
901                 print_error('cannotcreatediscussion', 'forum');
902             }
904             $discussion->groupid = $group;
905             $message = '';
906             if ($discussion->id = forum_add_discussion($discussion, $mform_post, $message)) {
908                 $params = array(
909                     'context' => $modcontext,
910                     'objectid' => $discussion->id,
911                     'other' => array(
912                         'forumid' => $forum->id,
913                     )
914                 );
915                 $event = \mod_forum\event\discussion_created::create($params);
916                 $event->add_record_snapshot('forum_discussions', $discussion);
917                 $event->trigger();
919                 if ($fromform->mailnow) {
920                     $message .= get_string("postmailnow", "forum");
921                 } else {
922                     $message .= '<p>'.get_string("postaddedsuccess", "forum") . '</p>';
923                     $message .= '<p>'.get_string("postaddedtimeleft", "forum", format_time($CFG->maxeditingtime)) . '</p>';
924                 }
926                 $subscribemessage = forum_post_subscription($fromform, $forum, $discussion);
927             } else {
928                 print_error("couldnotadd", "forum", $errordestination);
929             }
930         }
932         // Update completion status.
933         $completion = new completion_info($course);
934         if ($completion->is_enabled($cm) &&
935                 ($forum->completiondiscussions || $forum->completionposts)) {
936             $completion->update_state($cm, COMPLETION_COMPLETE);
937         }
939         // Redirect back to the discussion.
940         redirect(
941                 forum_go_back_to($redirectto->out()),
942                 $message . $subscribemessage,
943                 null,
944                 \core\output\notification::NOTIFY_SUCCESS
945             );
946     }
951 // To get here they need to edit a post, and the $post
952 // variable will be loaded with all the particulars,
953 // so bring up the form.
955 // $course, $forum are defined.  $discussion is for edit and reply only.
957 if ($post->discussion) {
958     if (! $toppost = $DB->get_record("forum_posts", array("discussion" => $post->discussion, "parent" => 0))) {
959         print_error('cannotfindparentpost', 'forum', '', $post->id);
960     }
961 } else {
962     $toppost = new stdClass();
963     $toppost->subject = ($forum->type == "news") ? get_string("addanewtopic", "forum") :
964                                                    get_string("addanewdiscussion", "forum");
967 if (empty($post->edit)) {
968     $post->edit = '';
971 if (empty($discussion->name)) {
972     if (empty($discussion)) {
973         $discussion = new stdClass();
974     }
975     $discussion->name = $forum->name;
977 if ($forum->type == 'single') {
978     // There is only one discussion thread for this forum type. We should
979     // not show the discussion name (same as forum name in this case) in
980     // the breadcrumbs.
981     $strdiscussionname = '';
982 } else {
983     // Show the discussion name in the breadcrumbs.
984     $strdiscussionname = format_string($discussion->name).':';
987 $forcefocus = empty($reply) ? NULL : 'message';
989 if (!empty($discussion->id)) {
990     $PAGE->navbar->add(format_string($toppost->subject, true), "discuss.php?d=$discussion->id");
993 if ($post->parent) {
994     $PAGE->navbar->add(get_string('reply', 'forum'));
997 if ($edit) {
998     $PAGE->navbar->add(get_string('edit', 'forum'));
1001 $PAGE->set_title("$course->shortname: $strdiscussionname ".format_string($toppost->subject));
1002 $PAGE->set_heading($course->fullname);
1004 echo $OUTPUT->header();
1005 echo $OUTPUT->heading(format_string($forum->name), 2);
1007 // checkup
1008 if (!empty($parent) && !forum_user_can_see_post($forum, $discussion, $post, null, $cm)) {
1009     print_error('cannotreply', 'forum');
1011 if (empty($parent) && empty($edit) && !forum_user_can_post_discussion($forum, $groupid, -1, $cm, $modcontext)) {
1012     print_error('cannotcreatediscussion', 'forum');
1015 if ($forum->type == 'qanda'
1016             && !has_capability('mod/forum:viewqandawithoutposting', $modcontext)
1017             && !empty($discussion->id)
1018             && !forum_user_has_posted($forum->id, $discussion->id, $USER->id)) {
1019     echo $OUTPUT->notification(get_string('qandanotify','forum'));
1022 // If there is a warning message and we are not editing a post we need to handle the warning.
1023 if (!empty($thresholdwarning) && !$edit) {
1024     // Here we want to throw an exception if they are no longer allowed to post.
1025     forum_check_blocking_threshold($thresholdwarning);
1028 if (!empty($parent)) {
1029     if (!$discussion = $DB->get_record('forum_discussions', array('id' => $parent->discussion))) {
1030         print_error('notpartofdiscussion', 'forum');
1031     }
1033     forum_print_post($parent, $discussion, $forum, $cm, $course, false, false, false);
1034     if (empty($post->edit)) {
1035         if ($forum->type != 'qanda' || forum_user_can_see_discussion($forum, $discussion, $modcontext)) {
1036             $forumtracked = forum_tp_is_tracked($forum);
1037             $posts = forum_get_all_discussion_posts($discussion->id, "created ASC", $forumtracked);
1038             forum_print_posts_threaded($course, $cm, $forum, $discussion, $parent, 0, false, $forumtracked, $posts);
1039         }
1040     }
1041 } else {
1042     if (!empty($forum->intro)) {
1043         echo $OUTPUT->box(format_module_intro('forum', $forum, $cm->id), 'generalbox', 'intro');
1045         if (!empty($CFG->enableplagiarism)) {
1046             require_once($CFG->libdir.'/plagiarismlib.php');
1047             echo plagiarism_print_disclosure($cm->id);
1048         }
1049     }
1052 if (!empty($formheading)) {
1053     echo $OUTPUT->heading($formheading, 2, array('class' => 'accesshide'));
1055 $mform_post->display();
1057 echo $OUTPUT->footer();