if ($post->totalscore) { notice(get_string('couldnotdeleteratings', 'rating'), forum_go_back_to("discuss.php?d={$post->discussion}")); } else { if ($replycount && !has_capability('mod/forum:deleteanypost', $modcontext)) { print_error("couldnotdeletereplies", "forum", forum_go_back_to("discuss.php?d={$post->discussion}")); } else { if (!$post->parent) { // post is a discussion topic as well, so delete discussion if ($forum->type == 'single') { notice("Sorry, but you are not allowed to delete that discussion!", forum_go_back_to("discuss.php?d={$post->discussion}")); } forum_delete_discussion($discussion, false, $course, $cm, $forum); add_to_log($discussion->course, "forum", "delete discussion", "view.php?id={$cm->id}", "{$forum->id}", $cm->id); redirect("view.php?f={$discussion->forum}"); } else { if (forum_delete_post($post, has_capability('mod/forum:deleteanypost', $modcontext), $course, $cm, $forum)) { if ($forum->type == 'single') { // Single discussion forums are an exception. We show // the forum itself since it only has one discussion // thread. $discussionurl = "view.php?f={$forum->id}"; } else { $discussionurl = "discuss.php?d={$post->discussion}"; } add_to_log($discussion->course, "forum", "delete post", $discussionurl, "{$post->id}", $cm->id); redirect(forum_go_back_to($discussionurl)); } else { print_error('errorwhiledelete', 'forum'); } } }
/** * Deletes a single forum post. * * @global object * @param object $post Forum post object * @param mixed $children Whether to delete children. If false, returns false * if there are any children (without deleting the post). If true, * recursively deletes all children. If set to special value 'ignore', deletes * post regardless of children (this is for use only when deleting all posts * in a disussion). * @param object $course Course * @param object $cm Course-module * @param object $forum Forum * @param bool $skipcompletion True to skip updating completion state if it * would otherwise be updated, i.e. when deleting entire forum anyway. * @return bool */ function forum_delete_post($post, $children, $course, $cm, $forum, $skipcompletion=false) { global $DB, $CFG; require_once($CFG->libdir.'/completionlib.php'); $context = context_module::instance($cm->id); if ($children !== 'ignore' && ($childposts = $DB->get_records('forum_posts', array('parent'=>$post->id)))) { if ($children) { foreach ($childposts as $childpost) { forum_delete_post($childpost, true, $course, $cm, $forum, $skipcompletion); } } else { return false; } } //delete ratings require_once($CFG->dirroot.'/rating/lib.php'); $delopt = new stdClass; $delopt->contextid = $context->id; $delopt->component = 'mod_forum'; $delopt->ratingarea = 'post'; $delopt->itemid = $post->id; $rm = new rating_manager(); $rm->delete_ratings($delopt); //delete attachments $fs = get_file_storage(); $fs->delete_area_files($context->id, 'mod_forum', 'attachment', $post->id); $fs->delete_area_files($context->id, 'mod_forum', 'post', $post->id); if ($DB->delete_records("forum_posts", array("id" => $post->id))) { forum_tp_delete_read_records(-1, $post->id); // Just in case we are deleting the last post forum_discussion_update_last_post($post->discussion); // Update completion state if we are tracking completion based on number of posts // But don't bother when deleting whole thing if (!$skipcompletion) { $completion = new completion_info($course); if ($completion->is_enabled($cm) == COMPLETION_TRACKING_AUTOMATIC && ($forum->completiondiscussions || $forum->completionreplies || $forum->completionposts)) { $completion->update_state($cm, COMPLETION_INCOMPLETE, $post->userid); } } return true; } return false; }
if ($post->totalscore) { notice(get_string("couldnotdeleteratings", "forum"), forum_go_back_to("discuss.php?d={$post->discussion}")); } else { if ($replycount && !has_capability('mod/forum:deleteanypost', $modcontext)) { error(get_string("couldnotdeletereplies", "forum"), forum_go_back_to("discuss.php?d={$post->discussion}")); } else { if (!$post->parent) { // post is a discussion topic as well, so delete discussion if ($forum->type == 'single') { notice("Sorry, but you are not allowed to delete that discussion!", forum_go_back_to("discuss.php?d={$post->discussion}")); } forum_delete_discussion($discussion); add_to_log($discussion->course, "forum", "delete discussion", "view.php?id={$cm->id}", "{$forum->id}", $cm->id); redirect("view.php?f={$discussion->forum}"); } else { if (forum_delete_post($post, has_capability('mod/forum:deleteanypost', $modcontext))) { if ($forum->type == 'single') { // Single discussion forums are an exception. We show // the forum itself since it only has one discussion // thread. $discussionurl = "view.php?f={$forum->id}"; } else { $discussionurl = "discuss.php?d={$post->discussion}"; } add_to_log($discussion->course, "forum", "delete post", $discussionurl, "{$post->id}", $cm->id); redirect(forum_go_back_to($discussionurl)); } else { error("An error occurred while deleting record {$post->id}"); } } }
/** * Deletes a single forum post. * * @global object * @param object $post Forum post object * @param mixed $children Whether to delete children. If false, returns false * if there are any children (without deleting the post). If true, * recursively deletes all children. If set to special value 'ignore', deletes * post regardless of children (this is for use only when deleting all posts * in a disussion). * @param object $course Course * @param object $cm Course-module * @param object $forum Forum * @param bool $skipcompletion True to skip updating completion state if it * would otherwise be updated, i.e. when deleting entire forum anyway. * @return bool */ function forum_delete_post($post, $children, $course, $cm, $forum, $skipcompletion = false) { global $DB, $CFG, $USER; require_once $CFG->libdir . '/completionlib.php'; $context = context_module::instance($cm->id); if ($children !== 'ignore' && ($childposts = $DB->get_records('forum_posts', array('parent' => $post->id)))) { if ($children) { foreach ($childposts as $childpost) { forum_delete_post($childpost, true, $course, $cm, $forum, $skipcompletion); } } else { return false; } } // Delete ratings. require_once $CFG->dirroot . '/rating/lib.php'; $delopt = new stdClass(); $delopt->contextid = $context->id; $delopt->component = 'mod_forum'; $delopt->ratingarea = 'post'; $delopt->itemid = $post->id; $rm = new rating_manager(); $rm->delete_ratings($delopt); // Delete attachments. $fs = get_file_storage(); $fs->delete_area_files($context->id, 'mod_forum', 'attachment', $post->id); $fs->delete_area_files($context->id, 'mod_forum', 'post', $post->id); // Delete cached RSS feeds. if (!empty($CFG->enablerssfeeds)) { require_once $CFG->dirroot . '/mod/forum/rsslib.php'; forum_rss_delete_file($forum); } if ($DB->delete_records("forum_posts", array("id" => $post->id))) { forum_tp_delete_read_records(-1, $post->id); // Just in case we are deleting the last post forum_discussion_update_last_post($post->discussion); // Update completion state if we are tracking completion based on number of posts // But don't bother when deleting whole thing if (!$skipcompletion) { $completion = new completion_info($course); if ($completion->is_enabled($cm) == COMPLETION_TRACKING_AUTOMATIC && ($forum->completiondiscussions || $forum->completionreplies || $forum->completionposts)) { $completion->update_state($cm, COMPLETION_INCOMPLETE, $post->userid); } } $params = array('context' => $context, 'objectid' => $post->id, 'other' => array('discussionid' => $post->discussion, 'forumid' => $forum->id, 'forumtype' => $forum->type)); if ($post->userid !== $USER->id) { $params['relateduserid'] = $post->userid; } $event = \mod_forum\event\post_deleted::create($params); $event->add_record_snapshot('forum_posts', $post); $event->trigger(); return true; } return false; }
/** * */ function forum_delete_post($post, $children = false) { if ($childposts = get_records('forum_posts', 'parent', $post->id)) { if ($children) { foreach ($childposts as $childpost) { forum_delete_post($childpost, true); } } else { return false; } } if (delete_records("forum_posts", "id", $post->id)) { delete_records("forum_ratings", "post", $post->id); // Just in case forum_tp_delete_read_records(-1, $post->id); if ($post->attachment) { $discussion = get_record("forum_discussions", "id", $post->discussion); $post->course = $discussion->course; $post->forum = $discussion->forum; forum_delete_old_attachments($post); } // Just in case we are deleting the last post forum_discussion_update_last_post($post->discussion); return true; } return false; }
/** * Test post_deleted event. */ public function test_post_deleted() { global $DB; // Setup test data. $course = $this->getDataGenerator()->create_course(); $forum = $this->getDataGenerator()->create_module('forum', array('course' => $course->id)); $user = $this->getDataGenerator()->create_user(); $cm = get_coursemodule_from_instance('forum', $forum->id, $forum->course); // Add a discussion. $record = array(); $record['course'] = $course->id; $record['forum'] = $forum->id; $record['userid'] = $user->id; $discussion = $this->getDataGenerator()->get_plugin_generator('mod_forum')->create_discussion($record); // When creating a discussion we also create a post, so get the post. $discussionpost = $DB->get_records('forum_posts'); // Will only be one here. $discussionpost = reset($discussionpost); // Add a few posts. $record = array(); $record['discussion'] = $discussion->id; $record['userid'] = $user->id; $posts = array(); $posts[$discussionpost->id] = $discussionpost; for ($i = 0; $i < 3; $i++) { $post = $this->getDataGenerator()->get_plugin_generator('mod_forum')->create_post($record); $posts[$post->id] = $post; } // Delete the last post and capture the event. $lastpost = end($posts); $sink = $this->redirectEvents(); forum_delete_post($lastpost, true, $course, $cm, $forum); $events = $sink->get_events(); $this->assertCount(1, $events); $event = reset($events); // Check that the events contain the expected values. $this->assertInstanceOf('\\mod_forum\\event\\post_deleted', $event); $this->assertEquals(context_module::instance($forum->cmid), $event->get_context()); $expected = array($course->id, 'forum', 'delete post', "discuss.php?d={$discussion->id}", $lastpost->id, $forum->cmid); $this->assertEventLegacyLogData($expected, $event); $url = new \moodle_url('/mod/forum/discuss.php', array('d' => $discussion->id)); $this->assertEquals($url, $event->get_url()); $this->assertEventContextNotUsed($event); $this->assertNotEmpty($event->get_name()); // Delete the whole discussion and capture the events. $sink = $this->redirectEvents(); forum_delete_discussion($discussion, true, $course, $cm, $forum); $events = $sink->get_events(); // We will have 3 events. One for the discussion (creating a discussion creates a post), and two for the posts. $this->assertCount(3, $events); // Loop through the events and check they are valid. foreach ($events as $event) { $post = $posts[$event->objectid]; // Check that the event contains the expected values. $this->assertInstanceOf('\\mod_forum\\event\\post_deleted', $event); $this->assertEquals(context_module::instance($forum->cmid), $event->get_context()); $expected = array($course->id, 'forum', 'delete post', "discuss.php?d={$discussion->id}", $post->id, $forum->cmid); $this->assertEventLegacyLogData($expected, $event); $url = new \moodle_url('/mod/forum/discuss.php', array('d' => $discussion->id)); $this->assertEquals($url, $event->get_url()); $this->assertEventContextNotUsed($event); $this->assertNotEmpty($event->get_name()); } }
} elseif ('do_add_topic' == $action) { forum_do_add_topic($sqlm); } elseif ('do_edit_close' == $action) { forum_do_edit_close($sqlm); } elseif ('do_edit_announce' == $action) { forum_do_edit_announce($sqlm); } elseif ('do_edit_stick' == $action) { forum_do_edit_stick($sqlm); } elseif ('move_topic' == $action) { forum_move_topic($sqlm); } elseif ('do_move_topic' == $action) { forum_do_move_topic($sqlm); } elseif ('do_add_post' == $action) { forum_do_add_post($sqlm); } elseif ('delete_post' == $action) { forum_delete_post($sqlm); } elseif ('do_delete_post' == $action) { forum_do_delete_post($sqlm); } elseif ('edit_post' == $action) { forum_edit_post($sqlm); } elseif ('do_edit_post' == $action) { forum_do_edit_post($sqlm); } else { forum_index($sqlr, $sqlm); } // close whats not needed anymore unset($action); unset($action_permission); unset($forum_lang); // page footer require_once 'footer.php';
forum_view_topic(); break; case "add_topic": forum_add_topic(); break; case "do_add_topic": forum_do_add_topic(); break; case "edit_post": forum_edit_post(); break; case "do_edit_post": forum_do_edit_post(); break; case "delete_post": forum_delete_post(); break; case "do_delete_post": forum_do_delete_post(); break; case "do_add_post": forum_do_add_post(); break; case "edit_stick": forum_do_edit_stick(); break; case "edit_announce": forum_do_edit_announce(); break; case "edit_close": forum_do_edit_close();
/** * Deletes a single forum post. * @param object $post Forum post object * @param mixed $children Whether to delete children. If false, returns false * if there are any children (without deleting the post). If true, * recursively deletes all children. If set to special value 'ignore', deletes * post regardless of children (this is for use only when deleting all posts * in a disussion). * @param object $course Course * @param object $cm Course-module * @param object $forum Forum * @param bool $skipcompletion True to skip updating completion state if it * would otherwise be updated, i.e. when deleting entire forum anyway. */ function forum_delete_post($post, $children, $course, $cm, $forum, $skipcompletion = false) { global $DB; $context = get_context_instance(CONTEXT_MODULE, $cm->id); if ($children != 'ignore' && ($childposts = $DB->get_records('forum_posts', array('parent' => $post->id)))) { if ($children) { foreach ($childposts as $childpost) { forum_delete_post($childpost, true, $course, $cm, $forum, $skipcompletion); } } else { return false; } } //delete ratings $DB->delete_records("forum_ratings", array("post" => $post->id)); //delete attachments $fs = get_file_storage(); $fs->delete_area_files($context->id, 'forum_attachment', $post->id); if ($DB->delete_records("forum_posts", array("id" => $post->id))) { forum_tp_delete_read_records(-1, $post->id); // Just in case we are deleting the last post forum_discussion_update_last_post($post->discussion); // Update completion state if we are tracking completion based on number of posts // But don't bother when deleting whole thing if (!$skipcompletion) { $completion = new completion_info($course); if ($completion->is_enabled($cm) == COMPLETION_TRACKING_AUTOMATIC && ($forum->completiondiscussions || $forum->completionreplies || $forum->completionposts)) { $completion->update_state($cm, COMPLETION_INCOMPLETE, $post->userid); } } return true; } return false; }