6e3f5e6517dc95d95544360675344b4bd6ac3c05
[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("discuss.php?d=$post->discussion"));
323         }
325         if ($post->totalscore) {
326             notice(get_string('couldnotdeleteratings', 'rating'),
327                     forum_go_back_to("discuss.php?d=$post->discussion"));
329         } else if ($replycount && !has_capability('mod/forum:deleteanypost', $modcontext)) {
330             print_error("couldnotdeletereplies", "forum",
331                     forum_go_back_to("discuss.php?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("discuss.php?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 = "view.php?f=$forum->id";
363                 } else {
364                     $discussionurl = "discuss.php?d=$post->discussion";
365                 }
367                 $params = array(
368                     'context' => $modcontext,
369                     'objectid' => $post->id,
370                     'other' => array(
371                         'discussionid' => $discussion->id,
372                         'forumid' => $forum->id,
373                         'forumtype' => $forum->type,
374                     )
375                 );
377                 if ($post->userid !== $USER->id) {
378                     $params['relateduserid'] = $post->userid;
379                 }
380                 $event = \mod_forum\event\post_deleted::create($params);
381                 $event->add_record_snapshot('forum_posts', $post);
382                 $event->add_record_snapshot('forum_discussions', $discussion);
383                 $event->trigger();
385                 redirect(forum_go_back_to($discussionurl));
386             } else {
387                 print_error('errorwhiledelete', 'forum');
388             }
389         }
392     } else { // User just asked to delete something
394         forum_set_return();
395         $PAGE->navbar->add(get_string('delete', 'forum'));
396         $PAGE->set_title($course->shortname);
397         $PAGE->set_heading($course->fullname);
399         if ($replycount) {
400             if (!has_capability('mod/forum:deleteanypost', $modcontext)) {
401                 print_error("couldnotdeletereplies", "forum",
402                       forum_go_back_to("discuss.php?d=$post->discussion"));
403             }
404             echo $OUTPUT->header();
405             echo $OUTPUT->heading(format_string($forum->name), 2);
406             echo $OUTPUT->confirm(get_string("deletesureplural", "forum", $replycount+1),
407                          "post.php?delete=$delete&confirm=$delete",
408                          $CFG->wwwroot.'/mod/forum/discuss.php?d='.$post->discussion.'#p'.$post->id);
410             forum_print_post($post, $discussion, $forum, $cm, $course, false, false, false);
412             if (empty($post->edit)) {
413                 $forumtracked = forum_tp_is_tracked($forum);
414                 $posts = forum_get_all_discussion_posts($discussion->id, "created ASC", $forumtracked);
415                 forum_print_posts_nested($course, $cm, $forum, $discussion, $post, false, false, $forumtracked, $posts);
416             }
417         } else {
418             echo $OUTPUT->header();
419             echo $OUTPUT->heading(format_string($forum->name), 2);
420             echo $OUTPUT->confirm(get_string("deletesure", "forum", $replycount),
421                          "post.php?delete=$delete&confirm=$delete",
422                          $CFG->wwwroot.'/mod/forum/discuss.php?d='.$post->discussion.'#p'.$post->id);
423             forum_print_post($post, $discussion, $forum, $cm, $course, false, false, false);
424         }
426     }
427     echo $OUTPUT->footer();
428     die;
431 } else if (!empty($prune)) {  // Pruning
433     if (!$post = forum_get_post_full($prune)) {
434         print_error('invalidpostid', 'forum');
435     }
436     if (!$discussion = $DB->get_record("forum_discussions", array("id" => $post->discussion))) {
437         print_error('notpartofdiscussion', 'forum');
438     }
439     if (!$forum = $DB->get_record("forum", array("id" => $discussion->forum))) {
440         print_error('invalidforumid', 'forum');
441     }
442     if ($forum->type == 'single') {
443         print_error('cannotsplit', 'forum');
444     }
445     if (!$post->parent) {
446         print_error('alreadyfirstpost', 'forum');
447     }
448     if (!$cm = get_coursemodule_from_instance("forum", $forum->id, $forum->course)) { // For the logs
449         print_error('invalidcoursemodule');
450     } else {
451         $modcontext = context_module::instance($cm->id);
452     }
453     if (!has_capability('mod/forum:splitdiscussions', $modcontext)) {
454         print_error('cannotsplit', 'forum');
455     }
457     $PAGE->set_cm($cm);
458     $PAGE->set_context($modcontext);
460     $prunemform = new mod_forum_prune_form(null, array('prune' => $prune, 'confirm' => $prune));
463     if ($prunemform->is_cancelled()) {
464         redirect(forum_go_back_to("discuss.php?d=$post->discussion"));
465     } else if ($fromform = $prunemform->get_data()) {
466         // User submits the data.
467         $newdiscussion = new stdClass();
468         $newdiscussion->course       = $discussion->course;
469         $newdiscussion->forum        = $discussion->forum;
470         $newdiscussion->name         = $name;
471         $newdiscussion->firstpost    = $post->id;
472         $newdiscussion->userid       = $discussion->userid;
473         $newdiscussion->groupid      = $discussion->groupid;
474         $newdiscussion->assessed     = $discussion->assessed;
475         $newdiscussion->usermodified = $post->userid;
476         $newdiscussion->timestart    = $discussion->timestart;
477         $newdiscussion->timeend      = $discussion->timeend;
479         $newid = $DB->insert_record('forum_discussions', $newdiscussion);
481         $newpost = new stdClass();
482         $newpost->id      = $post->id;
483         $newpost->parent  = 0;
484         $newpost->subject = $name;
486         $DB->update_record("forum_posts", $newpost);
488         forum_change_discussionid($post->id, $newid);
490         // Update last post in each discussion.
491         forum_discussion_update_last_post($discussion->id);
492         forum_discussion_update_last_post($newid);
494         // Fire events to reflect the split..
495         $params = array(
496             'context' => $modcontext,
497             'objectid' => $discussion->id,
498             'other' => array(
499                 'forumid' => $forum->id,
500             )
501         );
502         $event = \mod_forum\event\discussion_updated::create($params);
503         $event->trigger();
505         $params = array(
506             'context' => $modcontext,
507             'objectid' => $newid,
508             'other' => array(
509                 'forumid' => $forum->id,
510             )
511         );
512         $event = \mod_forum\event\discussion_created::create($params);
513         $event->trigger();
515         $params = array(
516             'context' => $modcontext,
517             'objectid' => $post->id,
518             'other' => array(
519                 'discussionid' => $newid,
520                 'forumid' => $forum->id,
521                 'forumtype' => $forum->type,
522             )
523         );
524         $event = \mod_forum\event\post_updated::create($params);
525         $event->add_record_snapshot('forum_discussions', $discussion);
526         $event->trigger();
528         redirect(forum_go_back_to("discuss.php?d=$newid"));
530     } else {
531         // Display the prune form.
532         $course = $DB->get_record('course', array('id' => $forum->course));
533         $PAGE->navbar->add(format_string($post->subject, true), new moodle_url('/mod/forum/discuss.php', array('d'=>$discussion->id)));
534         $PAGE->navbar->add(get_string("prune", "forum"));
535         $PAGE->set_title(format_string($discussion->name).": ".format_string($post->subject));
536         $PAGE->set_heading($course->fullname);
537         echo $OUTPUT->header();
538         echo $OUTPUT->heading(format_string($forum->name), 2);
539         echo $OUTPUT->heading(get_string('pruneheading', 'forum'), 3);
541         $prunemform->display();
543         forum_print_post($post, $discussion, $forum, $cm, $course, false, false, false);
544     }
546     echo $OUTPUT->footer();
547     die;
548 } else {
549     print_error('unknowaction');
553 if (!isset($coursecontext)) {
554     // Has not yet been set by post.php.
555     $coursecontext = context_course::instance($forum->course);
559 // from now on user must be logged on properly
561 if (!$cm = get_coursemodule_from_instance('forum', $forum->id, $course->id)) { // For the logs
562     print_error('invalidcoursemodule');
564 $modcontext = context_module::instance($cm->id);
565 require_login($course, false, $cm);
567 if (isguestuser()) {
568     // just in case
569     print_error('noguest');
572 if (!isset($forum->maxattachments)) {  // TODO - delete this once we add a field to the forum table
573     $forum->maxattachments = 3;
576 $thresholdwarning = forum_check_throttling($forum, $cm);
577 $mform_post = new mod_forum_post_form('post.php', array('course' => $course,
578                                                         'cm' => $cm,
579                                                         'coursecontext' => $coursecontext,
580                                                         'modcontext' => $modcontext,
581                                                         'forum' => $forum,
582                                                         'post' => $post,
583                                                         'subscribe' => \mod_forum\subscriptions::is_subscribed($USER->id, $forum,
584                                                                 null, $cm),
585                                                         'thresholdwarning' => $thresholdwarning,
586                                                         'edit' => $edit), 'post', '', array('id' => 'mformforum'));
588 $draftitemid = file_get_submitted_draft_itemid('attachments');
589 file_prepare_draft_area($draftitemid, $modcontext->id, 'mod_forum', 'attachment', empty($post->id)?null:$post->id, mod_forum_post_form::attachment_options($forum));
591 //load data into form NOW!
593 if ($USER->id != $post->userid) {   // Not the original author, so add a message to the end
594     $data = new stdClass();
595     $data->date = userdate($post->modified);
596     if ($post->messageformat == FORMAT_HTML) {
597         $data->name = '<a href="'.$CFG->wwwroot.'/user/view.php?id='.$USER->id.'&course='.$post->course.'">'.
598                        fullname($USER).'</a>';
599         $post->message .= '<p><span class="edited">('.get_string('editedby', 'forum', $data).')</span></p>';
600     } else {
601         $data->name = fullname($USER);
602         $post->message .= "\n\n(".get_string('editedby', 'forum', $data).')';
603     }
604     unset($data);
607 $formheading = '';
608 if (!empty($parent)) {
609     $heading = get_string("yourreply", "forum");
610     $formheading = get_string('reply', 'forum');
611 } else {
612     if ($forum->type == 'qanda') {
613         $heading = get_string('yournewquestion', 'forum');
614     } else {
615         $heading = get_string('yournewtopic', 'forum');
616     }
619 $postid = empty($post->id) ? null : $post->id;
620 $draftid_editor = file_get_submitted_draft_itemid('message');
621 $currenttext = file_prepare_draft_area($draftid_editor, $modcontext->id, 'mod_forum', 'post', $postid, mod_forum_post_form::editor_options($modcontext, $postid), $post->message);
623 $manageactivities = has_capability('moodle/course:manageactivities', $coursecontext);
624 if (\mod_forum\subscriptions::subscription_disabled($forum) && !$manageactivities) {
625     // User does not have permission to subscribe to this discussion at all.
626     $discussionsubscribe = false;
627 } else if (\mod_forum\subscriptions::is_forcesubscribed($forum)) {
628     // User does not have permission to unsubscribe from this discussion at all.
629     $discussionsubscribe = true;
630 } else {
631     if (isset($discussion) && \mod_forum\subscriptions::is_subscribed($USER->id, $forum, $discussion->id, $cm)) {
632         // User is subscribed to the discussion - continue the subscription.
633         $discussionsubscribe = true;
634     } else if (!isset($discussion) && \mod_forum\subscriptions::is_subscribed($USER->id, $forum, null, $cm)) {
635         // Starting a new discussion, and the user is subscribed to the forum - subscribe to the discussion.
636         $discussionsubscribe = true;
637     } else {
638         // User is not subscribed to either forum or discussion. Follow user preference.
639         $discussionsubscribe = $USER->autosubscribe;
640     }
643 $mform_post->set_data(array(        'attachments'=>$draftitemid,
644                                     'general'=>$heading,
645                                     'subject'=>$post->subject,
646                                     'message'=>array(
647                                         'text'=>$currenttext,
648                                         'format'=>empty($post->messageformat) ? editors_get_preferred_format() : $post->messageformat,
649                                         'itemid'=>$draftid_editor
650                                     ),
651                                     'discussionsubscribe' => $discussionsubscribe,
652                                     'mailnow'=>!empty($post->mailnow),
653                                     'userid'=>$post->userid,
654                                     'parent'=>$post->parent,
655                                     'discussion'=>$post->discussion,
656                                     'course'=>$course->id) +
657                                     $page_params +
659                             (isset($post->format)?array(
660                                     'format'=>$post->format):
661                                 array())+
663                             (isset($discussion->timestart)?array(
664                                     'timestart'=>$discussion->timestart):
665                                 array())+
667                             (isset($discussion->timeend)?array(
668                                     'timeend'=>$discussion->timeend):
669                                 array())+
671                             (isset($post->groupid)?array(
672                                     'groupid'=>$post->groupid):
673                                 array())+
675                             (isset($discussion->id)?
676                                     array('discussion'=>$discussion->id):
677                                     array()));
679 if ($mform_post->is_cancelled()) {
680     if (!isset($discussion->id) || $forum->type === 'qanda') {
681         // Q and A forums don't have a discussion page, so treat them like a new thread..
682         redirect(new moodle_url('/mod/forum/view.php', array('f' => $forum->id)));
683     } else {
684         redirect(new moodle_url('/mod/forum/discuss.php', array('d' => $discussion->id)));
685     }
686 } else if ($fromform = $mform_post->get_data()) {
688     if (empty($SESSION->fromurl)) {
689         $errordestination = "$CFG->wwwroot/mod/forum/view.php?f=$forum->id";
690     } else {
691         $errordestination = $SESSION->fromurl;
692     }
694     $fromform->itemid        = $fromform->message['itemid'];
695     $fromform->messageformat = $fromform->message['format'];
696     $fromform->message       = $fromform->message['text'];
697     // WARNING: the $fromform->message array has been overwritten, do not use it anymore!
698     $fromform->messagetrust  = trusttext_trusted($modcontext);
700     if ($fromform->edit) {           // Updating a post
701         unset($fromform->groupid);
702         $fromform->id = $fromform->edit;
703         $message = '';
705         //fix for bug #4314
706         if (!$realpost = $DB->get_record('forum_posts', array('id' => $fromform->id))) {
707             $realpost = new stdClass();
708             $realpost->userid = -1;
709         }
712         // if user has edit any post capability
713         // or has either startnewdiscussion or reply capability and is editting own post
714         // then he can proceed
715         // MDL-7066
716         if ( !(($realpost->userid == $USER->id && (has_capability('mod/forum:replypost', $modcontext)
717                             || has_capability('mod/forum:startdiscussion', $modcontext))) ||
718                             has_capability('mod/forum:editanypost', $modcontext)) ) {
719             print_error('cannotupdatepost', 'forum');
720         }
722         // If the user has access to all groups and they are changing the group, then update the post.
723         if (isset($fromform->groupinfo) && has_capability('mod/forum:movediscussions', $modcontext)) {
724             if (empty($fromform->groupinfo)) {
725                 $fromform->groupinfo = -1;
726             }
728             if (!forum_user_can_post_discussion($forum, $fromform->groupinfo, null, $cm, $modcontext)) {
729                 print_error('cannotupdatepost', 'forum');
730             }
732             $DB->set_field('forum_discussions' ,'groupid' , $fromform->groupinfo, array('firstpost' => $fromform->id));
733         }
735         $updatepost = $fromform; //realpost
736         $updatepost->forum = $forum->id;
737         if (!forum_update_post($updatepost, $mform_post, $message)) {
738             print_error("couldnotupdate", "forum", $errordestination);
739         }
741         // MDL-11818
742         if (($forum->type == 'single') && ($updatepost->parent == '0')){ // updating first post of single discussion type -> updating forum intro
743             $forum->intro = $updatepost->message;
744             $forum->timemodified = time();
745             $DB->update_record("forum", $forum);
746         }
748         $timemessage = 2;
749         if (!empty($message)) { // if we're printing stuff about the file upload
750             $timemessage = 4;
751         }
753         if ($realpost->userid == $USER->id) {
754             $message .= '<br />'.get_string("postupdated", "forum");
755         } else {
756             $realuser = $DB->get_record('user', array('id' => $realpost->userid));
757             $message .= '<br />'.get_string("editedpostupdated", "forum", fullname($realuser));
758         }
760         if ($subscribemessage = forum_post_subscription($fromform, $forum, $discussion)) {
761             $timemessage = 4;
762         }
763         if ($forum->type == 'single') {
764             // Single discussion forums are an exception. We show
765             // the forum itself since it only has one discussion
766             // thread.
767             $discussionurl = "view.php?f=$forum->id";
768         } else {
769             $discussionurl = "discuss.php?d=$discussion->id#p$fromform->id";
770         }
772         $params = array(
773             'context' => $modcontext,
774             'objectid' => $fromform->id,
775             'other' => array(
776                 'discussionid' => $discussion->id,
777                 'forumid' => $forum->id,
778                 'forumtype' => $forum->type,
779             )
780         );
782         if ($realpost->userid !== $USER->id) {
783             $params['relateduserid'] = $realpost->userid;
784         }
786         $event = \mod_forum\event\post_updated::create($params);
787         $event->add_record_snapshot('forum_discussions', $discussion);
788         $event->trigger();
790         redirect(forum_go_back_to("$discussionurl"), $message.$subscribemessage, $timemessage);
792         exit;
795     } else if ($fromform->discussion) { // Adding a new post to an existing discussion
796         // Before we add this we must check that the user will not exceed the blocking threshold.
797         forum_check_blocking_threshold($thresholdwarning);
799         unset($fromform->groupid);
800         $message = '';
801         $addpost = $fromform;
802         $addpost->forum=$forum->id;
803         if ($fromform->id = forum_add_new_post($addpost, $mform_post, $message)) {
804             $timemessage = 2;
805             if (!empty($message)) { // if we're printing stuff about the file upload
806                 $timemessage = 4;
807             }
809             if ($subscribemessage = forum_post_subscription($fromform, $forum, $discussion)) {
810                 $timemessage = 4;
811             }
813             if (!empty($fromform->mailnow)) {
814                 $message .= get_string("postmailnow", "forum");
815                 $timemessage = 4;
816             } else {
817                 $message .= '<p>'.get_string("postaddedsuccess", "forum") . '</p>';
818                 $message .= '<p>'.get_string("postaddedtimeleft", "forum", format_time($CFG->maxeditingtime)) . '</p>';
819             }
821             if ($forum->type == 'single') {
822                 // Single discussion forums are an exception. We show
823                 // the forum itself since it only has one discussion
824                 // thread.
825                 $discussionurl = "view.php?f=$forum->id";
826             } else {
827                 $discussionurl = "discuss.php?d=$discussion->id";
828             }
830             $params = array(
831                 'context' => $modcontext,
832                 'objectid' => $fromform->id,
833                 'other' => array(
834                     'discussionid' => $discussion->id,
835                     'forumid' => $forum->id,
836                     'forumtype' => $forum->type,
837                 )
838             );
839             $event = \mod_forum\event\post_created::create($params);
840             $event->add_record_snapshot('forum_posts', $fromform);
841             $event->add_record_snapshot('forum_discussions', $discussion);
842             $event->trigger();
844             // Update completion state
845             $completion=new completion_info($course);
846             if($completion->is_enabled($cm) &&
847                 ($forum->completionreplies || $forum->completionposts)) {
848                 $completion->update_state($cm,COMPLETION_COMPLETE);
849             }
851             redirect(forum_go_back_to("$discussionurl#p$fromform->id"), $message.$subscribemessage, $timemessage);
853         } else {
854             print_error("couldnotadd", "forum", $errordestination);
855         }
856         exit;
858     } else { // Adding a new discussion.
859         // The location to redirect to after successfully posting.
860         $redirectto = new moodle_url('view.php', array('f' => $fromform->forum));
862         $fromform->mailnow = empty($fromform->mailnow) ? 0 : 1;
864         $discussion = $fromform;
865         $discussion->name = $fromform->subject;
867         $newstopic = false;
868         if ($forum->type == 'news' && !$fromform->parent) {
869             $newstopic = true;
870         }
871         $discussion->timestart = $fromform->timestart;
872         $discussion->timeend = $fromform->timeend;
874         $allowedgroups = array();
875         $groupstopostto = array();
877         // If we are posting a copy to all groups the user has access to.
878         if (isset($fromform->posttomygroups)) {
879             // Post to each of my groups.
880             require_capability('mod/forum:canposttomygroups', $modcontext);
882             // Fetch all of this user's groups.
883             // Note: all groups are returned when in visible groups mode so we must manually filter.
884             $allowedgroups = groups_get_activity_allowed_groups($cm);
885             foreach ($allowedgroups as $groupid => $group) {
886                 if (forum_user_can_post_discussion($forum, $groupid, -1, $cm, $modcontext)) {
887                     $groupstopostto[] = $groupid;
888                 }
889             }
890         } else if (isset($fromform->groupinfo)) {
891             // Use the value provided in the dropdown group selection.
892             $groupstopostto[] = $fromform->groupinfo;
893             $redirectto->param('group', $fromform->groupinfo);
894         } else if (isset($fromform->groupid) && !empty($fromform->groupid)) {
895             // Use the value provided in the hidden form element instead.
896             $groupstopostto[] = $fromform->groupid;
897             $redirectto->param('group', $fromform->groupid);
898         } else {
899             // Use the value for all participants instead.
900             $groupstopostto[] = -1;
901         }
903         // Before we post this we must check that the user will not exceed the blocking threshold.
904         forum_check_blocking_threshold($thresholdwarning);
906         foreach ($groupstopostto as $group) {
907             if (!forum_user_can_post_discussion($forum, $group, -1, $cm, $modcontext)) {
908                 print_error('cannotcreatediscussion', 'forum');
909             }
911             $discussion->groupid = $group;
912             $message = '';
913             if ($discussion->id = forum_add_discussion($discussion, $mform_post, $message)) {
915                 $params = array(
916                     'context' => $modcontext,
917                     'objectid' => $discussion->id,
918                     'other' => array(
919                         'forumid' => $forum->id,
920                     )
921                 );
922                 $event = \mod_forum\event\discussion_created::create($params);
923                 $event->add_record_snapshot('forum_discussions', $discussion);
924                 $event->trigger();
926                 $timemessage = 2;
927                 if (!empty($message)) { // If we're printing stuff about the file upload.
928                     $timemessage = 4;
929                 }
931                 if ($fromform->mailnow) {
932                     $message .= get_string("postmailnow", "forum");
933                     $timemessage = 4;
934                 } else {
935                     $message .= '<p>'.get_string("postaddedsuccess", "forum") . '</p>';
936                     $message .= '<p>'.get_string("postaddedtimeleft", "forum", format_time($CFG->maxeditingtime)) . '</p>';
937                 }
939                 if ($subscribemessage = forum_post_subscription($fromform, $forum, $discussion)) {
940                     $timemessage = 6;
941                 }
942             } else {
943                 print_error("couldnotadd", "forum", $errordestination);
944             }
945         }
947         // Update completion status.
948         $completion = new completion_info($course);
949         if ($completion->is_enabled($cm) &&
950                 ($forum->completiondiscussions || $forum->completionposts)) {
951             $completion->update_state($cm, COMPLETION_COMPLETE);
952         }
954         // Redirect back to the discussion.
955         redirect(forum_go_back_to($redirectto->out()), $message . $subscribemessage, $timemessage);
956     }
961 // To get here they need to edit a post, and the $post
962 // variable will be loaded with all the particulars,
963 // so bring up the form.
965 // $course, $forum are defined.  $discussion is for edit and reply only.
967 if ($post->discussion) {
968     if (! $toppost = $DB->get_record("forum_posts", array("discussion" => $post->discussion, "parent" => 0))) {
969         print_error('cannotfindparentpost', 'forum', '', $post->id);
970     }
971 } else {
972     $toppost = new stdClass();
973     $toppost->subject = ($forum->type == "news") ? get_string("addanewtopic", "forum") :
974                                                    get_string("addanewdiscussion", "forum");
977 if (empty($post->edit)) {
978     $post->edit = '';
981 if (empty($discussion->name)) {
982     if (empty($discussion)) {
983         $discussion = new stdClass();
984     }
985     $discussion->name = $forum->name;
987 if ($forum->type == 'single') {
988     // There is only one discussion thread for this forum type. We should
989     // not show the discussion name (same as forum name in this case) in
990     // the breadcrumbs.
991     $strdiscussionname = '';
992 } else {
993     // Show the discussion name in the breadcrumbs.
994     $strdiscussionname = format_string($discussion->name).':';
997 $forcefocus = empty($reply) ? NULL : 'message';
999 if (!empty($discussion->id)) {
1000     $PAGE->navbar->add(format_string($toppost->subject, true), "discuss.php?d=$discussion->id");
1003 if ($post->parent) {
1004     $PAGE->navbar->add(get_string('reply', 'forum'));
1007 if ($edit) {
1008     $PAGE->navbar->add(get_string('edit', 'forum'));
1011 $PAGE->set_title("$course->shortname: $strdiscussionname ".format_string($toppost->subject));
1012 $PAGE->set_heading($course->fullname);
1014 echo $OUTPUT->header();
1015 echo $OUTPUT->heading(format_string($forum->name), 2);
1017 // checkup
1018 if (!empty($parent) && !forum_user_can_see_post($forum, $discussion, $post, null, $cm)) {
1019     print_error('cannotreply', 'forum');
1021 if (empty($parent) && empty($edit) && !forum_user_can_post_discussion($forum, $groupid, -1, $cm, $modcontext)) {
1022     print_error('cannotcreatediscussion', 'forum');
1025 if ($forum->type == 'qanda'
1026             && !has_capability('mod/forum:viewqandawithoutposting', $modcontext)
1027             && !empty($discussion->id)
1028             && !forum_user_has_posted($forum->id, $discussion->id, $USER->id)) {
1029     echo $OUTPUT->notification(get_string('qandanotify','forum'));
1032 // If there is a warning message and we are not editing a post we need to handle the warning.
1033 if (!empty($thresholdwarning) && !$edit) {
1034     // Here we want to throw an exception if they are no longer allowed to post.
1035     forum_check_blocking_threshold($thresholdwarning);
1038 if (!empty($parent)) {
1039     if (!$discussion = $DB->get_record('forum_discussions', array('id' => $parent->discussion))) {
1040         print_error('notpartofdiscussion', 'forum');
1041     }
1043     forum_print_post($parent, $discussion, $forum, $cm, $course, false, false, false);
1044     if (empty($post->edit)) {
1045         if ($forum->type != 'qanda' || forum_user_can_see_discussion($forum, $discussion, $modcontext)) {
1046             $forumtracked = forum_tp_is_tracked($forum);
1047             $posts = forum_get_all_discussion_posts($discussion->id, "created ASC", $forumtracked);
1048             forum_print_posts_threaded($course, $cm, $forum, $discussion, $parent, 0, false, $forumtracked, $posts);
1049         }
1050     }
1051 } else {
1052     if (!empty($forum->intro)) {
1053         echo $OUTPUT->box(format_module_intro('forum', $forum, $cm->id), 'generalbox', 'intro');
1055         if (!empty($CFG->enableplagiarism)) {
1056             require_once($CFG->libdir.'/plagiarismlib.php');
1057             echo plagiarism_print_disclosure($cm->id);
1058         }
1059     }
1062 if (!empty($formheading)) {
1063     echo $OUTPUT->heading($formheading, 2, array('class' => 'accesshide'));
1065 $mform_post->display();
1067 echo $OUTPUT->footer();