function forumng_delete_instance($id) { global $DB; require_once dirname(__FILE__) . '/mod_forumng.php'; $cm = get_coursemodule_from_instance('forumng', $id); $forum = mod_forumng::get_from_id($id, mod_forumng::CLONE_DIRECT, true, $cm); $forum->delete_all_data(); if (mod_forumng::search_installed()) { $cm = $forum->get_course_module(); local_ousearch_document::delete_module_instance_data($cm); } if ($forum->is_shared()) { // Find all the clone instances. $clones = $forum->get_clone_details(); $transaction = $DB->start_delegated_transaction(); foreach ($clones as $clone) { try { course_delete_module($clone->context->instanceid); } catch (moodle_exception $e) { notify("Could not delete the Clone\n forumng (coursemoduleid) {$clone->context}->instanceid "); return false; } rebuild_course_cache($clone->courseid, true); } $transaction->allow_commit(); } return $DB->delete_records('forumng', array('id' => $id)); }
$url->param('_qf__advancedsearch_form', $form); } // Search in a single forum if ($cmid) { $forum = mod_forumng::get_from_cmid($cmid, $cloneid); $cm = $forum->get_course_module(); $course = $forum->get_course(); $forum->require_view(mod_forumng::NO_GROUPS, 0, true); mod_forumng::search_installed(); $allforums = false; } if ($courseid) { $course = $DB->get_record('course', array('id' => $courseid), '*', MUST_EXIST); require_login($course); $coursecontext = context_course::instance($courseid); mod_forumng::search_installed(); $allforums = true; } // Set up page $PAGE->set_url($url); $PAGE->set_heading($course->fullname); if ($allforums) { $PAGE->set_context($coursecontext); $PAGE->set_title($course->shortname . ': ' . get_string('searchallforums', 'forumng')); } else { $PAGE->set_context($forum->get_context()); $PAGE->set_cm($cm, $course); $PAGE->set_title($course->shortname . ': ' . format_string($forum->get_name())); } $PAGE->set_pagelayout('base'); $PAGE->navbar->add(get_string('advancedsearch', 'forumng'));
protected function after_execute() { global $DB, $CFG; // Add forumng related files, no need to match by // itemname (just internally handled context) $this->add_related_files('mod_forumng', 'intro', null); // Add post related files, matching by itemname = 'forumng_post' $this->add_related_files('mod_forumng', 'message', 'forumng_post'); $this->add_related_files('mod_forumng', 'attachment', 'forumng_post'); $this->add_related_files('mod_forumng', 'draft', 'forumng_draft'); // Now fix the lastpostid for each discussion // TODO Does this work on MySQL? No idea. $DB->execute("\nUPDATE {forumng_discussions} SET lastpostid=(\n SELECT\n MAX(id)\n FROM\n {forumng_posts} fp\n WHERE\n fp.discussionid = {forumng_discussions}.id\n AND fp.oldversion=0\n AND fp.deleted=0\n) WHERE forumngid = ?", array($this->forumngid)); require_once $CFG->dirroot . '/mod/forumng/mod_forumng.php'; // Create search index if user data restored. if ($this->get_setting_value('userinfo') && mod_forumng::search_installed()) { mod_forumng::search_update_all(false, $this->get_courseid(), $this->task->get_moduleid()); } }
/** * Tests deleting discussion and permanent delete * Checks completion */ public function test_delete() { global $DB, $USER, $SITE, $CFG; require_once $CFG->dirroot . '/mod/forumng/mod_forumng_cron.php'; $CFG->enablecompletion = true; $this->resetAfterTest(true); $this->setAdminUser(); $course = $this->get_new_course(); $course->enablecompletion = 1; update_course($course); $forum = $this->get_new_forumng($course->id, array('removeafter' => 1, 'removeto' => 0, 'completion' => 2, 'completiondiscussions' => 1)); $completion = new completion_info($forum->get_course()); $discussion = $this->get_new_discussion($forum, array('userid' => $USER->id)); $root1 = $discussion->get_root_post(); // Get completion status. $complete = $completion->get_data($forum->get_course_module()); $this->assertEquals(COMPLETION_COMPLETE, $complete->completionstate); $discussion2 = $this->get_new_discussion($forum, array('userid' => $USER->id)); // Make post old. $root2 = $discussion2->get_root_post(); $dataobject = new stdClass(); $dataobject->id = $root2->get_id(); $dataobject->modified = $root2->get_modified() - 100; $DB->update_record('forumng_posts', $dataobject); // Check perm delete by manual call. $discussion->permanently_delete(false); $this->assertFalse($DB->get_record('forumng_discussions', array('id' => $discussion->get_id()))); $this->assertFalse($DB->get_record('forumng_posts', array('id' => $root1->get_id()))); // Check cron cleanup (Does permanently_delete() on discussion2). mod_forumng_cron::archive_old_discussions(); $this->assertFalse($DB->get_record('forumng_discussions', array('id' => $discussion2->get_id()))); $this->assertFalse($DB->get_record('forumng_posts', array('id' => $root2->get_id()))); $complete = $completion->get_data($forum->get_course_module()); $this->assertEquals(COMPLETION_INCOMPLETE, $complete->completionstate); if (mod_forumng::search_installed()) { $searchdoc = $root2->search_get_document(); $this->assertFalse($searchdoc->find()); $query = new local_ousearch_search('Message for discussion'); $query->set_coursemodule($forum->get_course_module(true)); $results = $query->query(); $this->assertEmpty($results->results); } }
protected function after_execute() { global $DB, $CFG; // Add forumng related files, no need to match by // itemname (just internally handled context) $this->add_related_files('mod_forumng', 'intro', null); // Add post related files, matching by itemname = 'forumng_post' $this->add_related_files('mod_forumng', 'message', 'forumng_post'); $this->add_related_files('mod_forumng', 'attachment', 'forumng_post'); $this->add_related_files('mod_forumng', 'draft', 'forumng_draft'); // Now fix the lastpostid for each discussion // TODO Does this work on MySQL? No idea. $DB->execute("\nUPDATE {forumng_discussions} SET lastpostid=(\n SELECT\n MAX(id)\n FROM\n {forumng_posts} fp\n WHERE\n fp.discussionid = {forumng_discussions}.id\n AND fp.oldversion=0\n AND fp.deleted=0\n) WHERE forumngid = ?", array($this->forumngid)); require_once $CFG->dirroot . '/mod/forumng/mod_forumng.php'; // Create search index if user data restored. if ($this->get_setting_value('userinfo') && mod_forumng::search_installed()) { mod_forumng::search_update_all(false, $this->get_courseid(), $this->task->get_moduleid(), $this->get_task()->get_progress()); } // See what $this->task->get_moduleid() contains, then check master|clone. // If we have the module id we can use that to get the cm. if ($cmid = $this->task->get_moduleid()) { // Check to see whether forum is shared or a clone. if ($this->shared) { // Master. // Get the ID number - probably from the course_modules table using $this->task->get_moduleid() in a query. $cm = $DB->get_record('course_modules', array('id' => $cmid), '*', MUST_EXIST); $idnumber = $cm->idnumber; // Check for any other forumng module instances using the same ID number - . // if any then add _1 to end (if already has _number at end then increment that number e.g. _2). $newidnumber = $this->get_new_idnumber($idnumber); // Set new idnumber. $cm->idnumber = $newidnumber; $DB->update_record('course_modules', $cm); } else { if ($this->type === 'clone') { // Clone. $cm = $DB->get_record('course_modules', array('id' => $cmid), '*', MUST_EXIST); $forumng = $DB->get_record('forumng', array('id' => $cm->instance), '*', MUST_EXIST); // If clone get original cmid ID number, if exists and has AUTO_ prefix, // If exists and has AUTO_ prefix. if (!empty($forumng->originalcmid)) { $originalcm = $DB->get_record_sql('select * from {course_modules} where module = (select id from {modules} where name = ?) and id = ?', array('forumng', $forumng->originalcmid)); $strippedidnumber = $originalcm->idnumber; // If exists and has AUTO_ prefix. $idnumber = $this->strip_auto_from_idnumber($originalcm->idnumber); if ($idnumber != $originalcm->idnumber) { $strippedidnumber = $idnumber; // We have an AUTO_ prefix. // Do we have a valid suffix. $suffix = $this->get_possible_suffix($originalcm->idnumber, '_'); if ($suffix != 0) { // We have a valid suffix. // Remove the suffix from the idnumber by getting the last '_' . $strippedidnumber = $this->remove_suffix($idnumber, '_'); } // Place auto back in. $strippedidnumber = 'AUTO_' . $strippedidnumber; // Get cmid for all forumng module instances (joining to forumng table to ensure we get only master forums) // that have matching idnumber (regardless of their _number suffix). $cms = $DB->get_records_sql('select cm.id as cmid, cm.idnumber from {course_modules} cm inner join {forumng} f on cm.instance = f.id where cm.idnumber like ? and f.shared = ? and cm.module = (select id from {modules} where name = ?) order by cmid desc', array($strippedidnumber . '%', 1, 'forumng')); // Set originalcmid field. $forumng->originalcmid = $this->get_cmid_for_forumng_idnumbers($strippedidnumber, $cms); if ($forumng->originalcmid) { $DB->update_record('forumng', $forumng); } } } } } } if (!empty($this->grouptags)) { foreach ($this->grouptags as $groupid => $tags) { mod_forumng::set_group_tags($this->forumngid, $groupid, $tags); } } }
/** * Tests discussion copying to another group and another course forum * (Does not check attachments or ratings copying) */ public function test_copy() { global $USER; $this->resetAfterTest(); $this->setAdminUser(); $course1 = $this->get_new_course(); $course2 = $this->get_new_course(); $group1 = $this->get_new_group($course1->id); $group2 = $this->get_new_group($course1->id); $orig = $this->get_new_forumng($course1->id, array('groupmode' => VISIBLEGROUPS)); $other = $this->get_new_forumng($course2->id); $dis = $this->get_new_discussion($orig, array('groupid' => $group1->id, 'userid' => $USER->id)); $lastpost = mod_forumng_post::get_from_id($dis->get_last_post_id(), 0); $dis->create_reply($lastpost, 'reply', 'reply', FORMAT_HTML); $dis->copy($orig, $group2->id); $dis->copy($other, mod_forumng::CLONE_DIRECT); $forums1 = mod_forumng::get_course_forums($course1); $forums2 = mod_forumng::get_course_forums($course2); $this->assertEquals(2, $forums1[$orig->get_id()]->get_num_discussions()); $this->assertEquals(1, $forums2[$other->get_id()]->get_num_discussions()); $list = $forums1[$orig->get_id()]->get_discussion_list($group2->id); $this->assertFalse($list->is_empty()); $discussion = $list->get_normal_discussions(); $this->assertEquals(2, reset($discussion)->get_num_posts()); if (mod_forumng::search_installed()) { $searchdoc = reset($discussion)->get_root_post()->search_get_document(); $this->assertTrue($searchdoc->find()); $query = new local_ousearch_search('reply'); $query->set_coursemodule($other->get_course_module(true)); $results = $query->query(); $this->assertNotEmpty($results->results); } }
/** * Calls search_update on each child of the current post, and recurses. * Used when the subject's discussion is changed. */ public function search_update_children() { if (!mod_forumng::search_installed()) { return; } // If the in-memory post object isn't already part of a full // discussion... if (!is_array($this->children)) { // ...then get one $discussion = mod_forumng_discussion::get_from_id($this->discussion->get_id(), $this->get_forum()->get_course_module_id()); $post = $discussion->get_root_post()->find_child($this->get_id()); // Do this update on the new discussion $post->search_update_children(); return; } // Loop through all children foreach ($this->children as $child) { // Update its search fields $child->search_update(); // Recurse $child->search_update_children(); } }
/** * Creates a new discussion in this forum. * @param int $groupid Group ID for the discussion or null if it should show * to all groups * @param string $subject Subject of message * @param string $message Message content * @param int $format Format of message content * @param bool $attachments True if discussion contains attachments * @param bool $mailnow True to mail ASAP, else false * @param int $timestart Visibility time of discussion (seconds since epoch) or null * @param int $timeend Time at which discussion disappears (seconds since epoch) or null * @param bool $locked True if discussion should be locked * @param bool $sticky True if discussion should be sticky * @param int $userid User ID or 0 for current user * @param bool $log True to log this * @return array Array with 2 elements ($discussionid, $postid) */ public function create_discussion($groupid, $subject, $message, $format, $attachments = false, $mailnow = false, $timestart = 0, $timeend = 0, $locked = false, $sticky = false, $userid = 0, $log = true) { global $DB; $userid = mod_forumng_utils::get_real_userid($userid); // Prepare discussion object $discussionobj = new StdClass(); $discussionobj->forumngid = $this->forumfields->id; $discussionobj->groupid = $groupid == self::ALL_GROUPS || $groupid == self::NO_GROUPS ? null : $groupid; $discussionobj->postid = null; // Temporary until we create that first post $discussionobj->lastpostid = null; $discussionobj->timestart = $timestart; $discussionobj->timeend = $timeend; $discussionobj->deleted = 0; $discussionobj->locked = $locked ? 1 : 0; $discussionobj->sticky = $sticky ? 1 : 0; // Create discussion $transaction = $DB->start_delegated_transaction(); $discussionobj->id = $DB->insert_record('forumng_discussions', $discussionobj); $newdiscussion = new mod_forumng_discussion($this, $discussionobj, false, -1); // Create initial post $postid = $newdiscussion->create_root_post($subject, $message, $format, $attachments, $mailnow, $userid); // Update discussion so that it contains the post id $changes = new StdClass(); $changes->id = $discussionobj->id; $changes->postid = $postid; $changes->lastpostid = $postid; $DB->update_record('forumng_discussions', $changes); $newdiscussion->log('add discussion'); if (mod_forumng::search_installed()) { mod_forumng_post::get_from_id($postid, $this->get_course_module_id())->search_update(); } $transaction->allow_commit(); return array($newdiscussion->get_id(), $postid); }