function finish($postid, $cloneid, $url, $fromform, $ajaxdata = '', $iframeredirect = false) { global $ajax, $iframe; if ($ajax) { if ($ajaxdata) { // Print AJAX data if specified header('Content-Type: text/plain'); print $ajaxdata; exit; } else { // Default otherwise is to print post mod_forumng_post::print_for_ajax_and_exit($postid, $cloneid, array(mod_forumng_post::OPTION_DISCUSSION_SUBJECT => true)); } } if ($iframe) { if ($iframeredirect) { // Still redirect, even though it's in an iframe. redirect($url . '&iframe=1'); } else { // Do not redirect, just output new post. mod_forumng_post::print_for_iframe_and_exit($postid, $cloneid, array(mod_forumng_post::OPTION_DISCUSSION_SUBJECT => true)); } } redirect($url); }
function get_deleted_posts_for_forumng($forumngid, $groupid = 0, $deleteuserid = 0, $creatorid = 0) { global $DB, $CFG, $USER; $where = ' fp.deleted != 0'; $whereparams = array(); if (!empty($groupid)) { $where .= ' AND fd.groupid = ?'; $whereparams[] = $groupid; } if (!empty($deleteuserid)) { $where .= ' AND fp.deleteuserid = ?'; $whereparams[] = $deleteuserid; } if (!empty($creatorid)) { $where .= ' AND fp.userid = ?'; $whereparams[] = $creatorid; } $where .= ' AND fd.deleted = ?'; $whereparams[] = 0; $where .= ' AND fd.forumngid = ?'; $whereparams[] = $forumngid; $orderby = 'fd.id, fp.id'; // See line 827 of mod_forumng_post.php. $result = mod_forumng_post::query_posts($where, $whereparams, $orderby, false, false, false, 0, true); return $result; }
function make_post($discussion, &$allposts, &$userids, $ratingpercent) { // Make reply static $index = 0; $index++; $replyto = $allposts[rand(0, count($allposts) - 1)]; $newpostid = $replyto->reply(my_random_percentage(25) ? 'Reply ' . $index : null, get_post_text(), FORMAT_HTML, array(), false, $userids[mt_rand(0, count($userids) - 1)], false); $newpost = mod_forumng_post::get_from_id($newpostid, mod_forumng::CLONE_DIRECT); $allposts[] = $newpost; // Add ratings for ($i = 0; $i < count($userids); $i++) { if (my_random_percentage($ratingpercent)) { $newpost->rate(2, $userids[$i]); } } }
public function apply($discussion, $all, $selected, $formdata) { global $CFG; $filecontext = $discussion->get_context(); $forum = $discussion; if (!isset($formdata->mailnow)) { $formdata->mailnow = false; } foreach ($selected as $postid) { // Call the lock for selected discussions. $discussion = mod_forumng_discussion::get_from_id($postid, $formdata->clone); if (!$discussion->is_deleted() && !$discussion->is_locked()) { $newpostid = $discussion->lock($formdata->subject, $formdata->message['text'], $formdata->message['format'], $formdata->attachments, $formdata->mailnow, '', '', $formdata->asmoderator); // Save attachments. file_save_draft_area_files($formdata->attachments, $filecontext->id, 'mod_forumng', 'attachment', $newpostid, null); $newtext = file_save_draft_area_files($formdata->message['itemid'], $filecontext->id, 'mod_forumng', 'message', $newpostid, null, $formdata->message['text']); if ($newtext !== $formdata->message['text']) { mod_forumng_post::update_message_for_files($newpostid, $newtext); } } } // Redirect to the Main page. redirect('../../view.php?' . $forum->get_link_params(mod_forumng::PARAM_PLAIN)); }
/** * Return post subject or current discussion title * @param char $item * @param int $id * @returns string */ function forumng_oualerts_custom_info($item, $id) { global $CFG; require_once $CFG->dirroot . '/mod/forumng/mod_forumng.php'; require_once $CFG->dirroot . '/mod/forumng/mod_forumng_post.php'; $title = ''; if ($item == 'post') { $post = mod_forumng_post::get_from_id($id, mod_forumng::CLONE_DIRECT); } if ($post) { $title = $post->get_subject(); if ($title == null) { // We need to get the last previous post that has a subject field. $title = $post->get_effective_subject(true); } } return $title; }
/** * Updates the in-memory digest records to add a new post to the given * user's digests. * @param object $user User object (must include special ->emailtype, etc) * @param array $userdigests Array of user id => digest information object * @param mod_forumng_post $post Post object * @param mod_forumng_post $inreplyto Parent post * @param mod_forumng_discussion $discussion Discus * @param mod_forumng $forum * @param object $cm * @param object $course * @param object $context */ private static function digest_add_post_for_user(&$user, &$userdigests, &$post, &$inreplyto, &$discussion, &$forum, &$cm, &$course, &$context) { global $CFG; // Set up digest for user if required if (!array_key_exists($user->id, $userdigests)) { $userdigests[$user->id] = new StdClass(); $userdigests[$user->id]->discussionid = -1; // So we do header next $userdigests[$user->id]->user = $user; $userdigests[$user->id]->forumngid = -1; // Get header text $headerdata = new object(); $headerdata->sitename = format_string($course->fullname, true); $headerdata->userprefs = $CFG->wwwroot . '/user/edit.php?id=' . $user->id . '&course=' . $course->id; $userdigests[$user->id]->text = get_string('digestmailheader', 'forumng', $headerdata) . "\n\n"; // Get header HTML $html = "<body id='forumng-email'>\n"; $headerdata->userprefs = '<a target="_blank" href="' . $headerdata->userprefs . '">' . get_string('digestmailprefs', 'forumng') . '</a>'; $html .= '<div class="forumng-emailheader"><p>' . get_string('digestmailheader', 'forumng', $headerdata) . '</p></div><hr size="1" noshade="noshade" />'; $userdigests[$user->id]->html = $html; // Get email subject $userdigests[$user->id]->subject = get_string('digestmailsubject', 'forumng', format_string($course->shortname, true)); } // New forum? if ($userdigests[$user->id]->forumngid != $forum->get_id()) { $userdigests[$user->id]->forumngid = $forum->get_id(); } // Is this a new discussion? if ($userdigests[$user->id]->discussionid != $discussion->get_id()) { $strforums = get_string('forums', 'forumng'); // Per-discussion header (text mode) $text = "\n \n"; $text .= '====================================================================='; $text .= "\n \n"; $text .= "{$course->shortname} -> {$strforums} -> " . format_string($forum->get_name(), true); if ($discussion->get_subject(false) !== $forum->get_name()) { $text .= " -> " . format_string($discussion->get_subject(false), true); } $text .= "\n"; // HTML mode $html = '<hr size="1" noshade="noshade" />'; $html .= "<div class='forumng-breadcrumbs'>" . "<a target='_blank' href='{$CFG->wwwroot}/course/view.php?" . "id={$course->id}'>{$course->shortname}</a> -> " . "<a target='_blank' href='{$CFG->wwwroot}/mod/forumng/index.php?" . "id={$course->id}'>{$strforums}</a> -> " . "<a target='_blank' href='{$CFG->wwwroot}/mod/forumng/view.php?" . $forum->get_link_params(mod_forumng::PARAM_HTML) . "'>" . format_string($forum->get_name(), true) . "</a>"; if ($discussion->get_subject(false) !== $forum->get_name()) { $html .= " -> <a target='_blank' href='{$CFG->wwwroot}/mod/forumng/discuss.php?" . $discussion->get_link_params(mod_forumng::PARAM_HTML) . "'>" . format_string($discussion->get_subject(false), true) . "</a>"; } $html .= '</div>'; $userdigests[$user->id]->text .= $text; $userdigests[$user->id]->html .= $html; $userdigests[$user->id]->discussionid = $discussion->get_id(); } // Get both plaintext and html versions (and subject). // The html version will be blank if set to // plain text mode. $post->build_email($inreplyto, $subject, $text, $html, $user->emailtype & 1, $user->emailtype & 2, $user->emailtype & 4, $user->lang, $user->timezone, true); $userdigests[$user->id]->text .= $text; $userdigests[$user->id]->html .= $html; }
} else { if (!$post->can_undelete($whynot)) { print_error($whynot, 'forumng'); } } // Is this the actual delete? if ($_SERVER['REQUEST_METHOD'] == 'POST' && $email != 1) { // Delete or undelete the post if ($delete) { $post->delete(); } else { $post->undelete(); } // Redirect back if ($ajax) { mod_forumng_post::print_for_ajax_and_exit($postid, $cloneid); } // Only include post id if user can see deleted posts $postid = ''; if (!$delete || has_capability('mod/forumng:editanypost', $forum->get_context())) { $postid = '#p' . $post->get_id(); } redirect('discuss.php?' . $discussion->get_link_params(mod_forumng::PARAM_PLAIN) . $expandparam . $postid); } if ($email) { require_once 'deletepost_form.php'; $urlparams = array('p' => $postid, 'delete' => $delete, 'email' => $email); if ($cloneid) { $urlparams['clone'] = $cloneid; } $url = new moodle_url("{$CFG->wwwroot}/mod/forumng/deletepost.php", $urlparams);
/** * Returns all posts in this forum by the given user within the given group. * @param int $userid * @param int $groupid * @param string $order Sort order; the default is fp.id - note this is preferable * to fp.timecreated because it works correctly if there are two posts in * the same second * @return array Array of mod_forumng_post objects */ public function get_all_posts_by_user($userid, $groupid, $order = 'fp.id') { $where = 'fd.forumngid = ? AND fp.userid = ? AND fp.oldversion = 0 AND fp.deleted = 0'; $whereparams = array($this->get_id(), $userid); if ($groupid != self::NO_GROUPS && $groupid != self::ALL_GROUPS) { $where .= ' AND (fd.groupid = ? OR fd.groupid IS NULL)'; $whereparams[] = $groupid; } $result = array(); $posts = mod_forumng_post::query_posts($where, $whereparams, $order, false, false, true, 0, true, true); foreach ($posts as $fields) { $discussionfields = mod_forumng_utils::extract_subobject($fields, 'fd_'); $discussion = new mod_forumng_discussion($this, $discussionfields, false, -1); $result[$fields->id] = new mod_forumng_post($discussion, $fields); } return $result; }
/** * Called when a post is deleted or undeleted or modified, or there is a * larger change to the discussion * @param mod_forumng_post $post Post that has changed; null to always recalculate */ function possible_lastpost_change($post = null) { $recalculate = false; if (!$post) { $recalculate = true; } else { if ($post->get_deleted()) { // For deleted posts, recalculate if this was previously // considered the latest post $recalculate = $this->discussionfields->lastpostid == $post->get_id(); } else { // For other posts, recalculate if this is now newer than the // stored last post $recalculate = $post->get_modified() > $this->discussionfields->timemodified; } } // If necessary, recalculate the date if ($recalculate) { global $DB; $change = new stdClass(); $change->id = $this->get_id(); $records = $DB->get_records_sql("SELECT id " . "FROM {forumng_posts} WHERE discussionid = ? AND deleted = 0 AND oldversion = 0 " . "ORDER BY modified DESC", array($this->get_id()), 0, 1); if (count($records) == 0) { throw new moodle_exception('errorfindinglastpost', 'forumng'); } $rec = reset($records); $change->lastpostid = $rec->id; if ($change->lastpostid != $this->discussionfields->lastpostid) { $DB->update_record('forumng_discussions', $change); } } }
/** * Extend tests that check forumns and discussions being marked as read. * */ public function test_discussions_mark_read() { global $USER, $DB; $this->resetAfterTest(true); $this->setAdminUser(); $adminid = $USER->id; $generator = $this->getDataGenerator()->get_plugin_generator('mod_forumng'); $course = $this->get_new_course(); $etuser1 = $this->get_new_user('editingteacher', $course->id); $suser1 = $this->get_new_user('student', $course->id); $suser2 = $this->get_new_user('student', $course->id); $group1 = $this->get_new_group($course->id); $group2 = $this->get_new_group($course->id); $this->get_new_group_member($group1->id, $etuser1->id); $this->get_new_group_member($group1->id, $suser1->id); // Create 2 forums (1 group forum, 1 no groups), each with 1 discussion. $forum1 = $this->get_new_forumng($course->id, array('groupmode' => VISIBLEGROUPS)); $forum2 = $this->get_new_forumng($course->id); $did1 = $generator->create_discussion(array('course' => $course, 'forum' => $forum1->get_id(), 'userid' => $etuser1->id, 'groupid' => $group1->id)); $did2 = $generator->create_discussion(array('course' => $course, 'forum' => $forum2->get_id(), 'userid' => $etuser1->id)); // Set the time for offset use. $posttime = time(); // Ensure user prefs allow discussions/posts to be marked as read 'automatically'. unset_user_preference('forumng_manualmark', $etuser1); unset_user_preference('forumng_manualmark', $suser1); // Root post auto marked as read for ET the creator, of forum1 at group level. $etforums = mod_forumng::get_course_forums($course, $etuser1->id, mod_forumng::UNREAD_DISCUSSIONS); // Forum contains discussion post read by etuser1. $this->assertFalse($etforums[$forum1->get_id()]->has_unread_discussions()); $this->assertEquals(0, $etforums[$forum1->get_id()]->get_num_unread_discussions()); // Suser1 has NOT read root posts. $s1forums = mod_forumng::get_course_forums($course, $suser1->id, mod_forumng::UNREAD_DISCUSSIONS); // Forums contain discussion posts NOT read by Suser1. $this->assertTrue($s1forums[$forum1->get_id()]->has_unread_discussions()); $this->assertTrue($s1forums[$forum2->get_id()]->has_unread_discussions()); // Discussion contains posts NOT read by S1. $this->assertEquals(1, $s1forums[$forum1->get_id()]->get_num_unread_discussions()); $this->assertEquals(1, $s1forums[$forum2->get_id()]->get_num_unread_discussions()); // User Prefs allow the marking of both discussion root posts as read 'automatically'. $posttime = $posttime + 2; $did1read = mod_forumng_discussion::get_from_id($did1[0], 0); $did1read->mark_read($posttime, $suser1->id); $did2read = mod_forumng_discussion::get_from_id($did2[0], 0); $did2read->mark_read($posttime, $suser1->id); // Check the root posts now marked as read for S1. $s1forums = mod_forumng::get_course_forums($course, $suser1->id, mod_forumng::UNREAD_DISCUSSIONS); // Forums contain NO discussions not read by Suser1. $this->assertFalse($s1forums[$forum1->get_id()]->has_unread_discussions()); $this->assertFalse($s1forums[$forum2->get_id()]->has_unread_discussions()); // No forumn discussions contain root posts not read by Suser1. $this->assertEquals(0, $s1forums[$forum1->get_id()]->get_num_unread_discussions()); $this->assertEquals(0, $s1forums[$forum2->get_id()]->get_num_unread_discussions()); // Set user pref so discussions/posts marked 'manually'. set_user_preference('forumng_manualmark', 1, $etuser1); set_user_preference('forumng_manualmark', 1, $suser1); // Add extra posts to both discussions with time modified offset. $posttime = $posttime + 2; $did1s1p1 = $generator->create_post(array('discussionid' => $did1[0], 'parentpostid' => $did1[1], 'userid' => $suser1->id, 'modified' => $posttime)); $did1etp1 = $generator->create_post(array('discussionid' => $did1[0], 'parentpostid' => $did1[1], 'userid' => $etuser1->id, 'modified' => $posttime)); $did1s2p1 = $generator->create_post(array('discussionid' => $did1[0], 'parentpostid' => $did1[1], 'userid' => $suser2->id, 'modified' => $posttime)); $did2s1p2 = $generator->create_post(array('discussionid' => $did2[0], 'parentpostid' => $did2[1], 'userid' => $suser1->id, 'modified' => $posttime)); $did2etp2 = $generator->create_post(array('discussionid' => $did2[0], 'parentpostid' => $did2[1], 'userid' => $etuser1->id, 'modified' => $posttime)); $did2s2p1 = $generator->create_post(array('discussionid' => $did2[0], 'parentpostid' => $did2[1], 'userid' => $suser2->id, 'modified' => $posttime)); $did1s1post1 = mod_forumng_post::get_from_id($did1s1p1->id, 0); $did2s1post2 = mod_forumng_post::get_from_id($did2s1p2->id, 0); $did1etpost1 = mod_forumng_post::get_from_id($did1etp1->id, 0); $did2etpost2 = mod_forumng_post::get_from_id($did2etp2->id, 0); $did1s2post1 = mod_forumng_post::get_from_id($did1s2p1->id, 0); $did2s2post1 = mod_forumng_post::get_from_id($did2s2p1->id, 0); // Check read status of new posts. $etforums = mod_forumng::get_course_forums($course, $etuser1->id, mod_forumng::UNREAD_DISCUSSIONS); // Discussions DO have posts not read by ET. $this->assertTrue($etforums[$forum1->get_id()]->has_unread_discussions()); $this->assertTrue($etforums[$forum2->get_id()]->has_unread_discussions()); // A number of discussions contain posts NOT read by ET. $this->assertEquals(1, $etforums[$forum1->get_id()]->get_num_unread_discussions()); $this->assertEquals(1, $etforums[$forum2->get_id()]->get_num_unread_discussions()); $s1forums = mod_forumng::get_course_forums($course, $suser1->id, mod_forumng::UNREAD_DISCUSSIONS); // Discussions DO have posts not read by Suser1. $this->assertTrue($s1forums[$forum1->get_id()]->has_unread_discussions()); $this->assertTrue($s1forums[$forum2->get_id()]->has_unread_discussions()); // A number of discussions contain posts NOT read by Suser1. $this->assertEquals(1, $s1forums[$forum1->get_id()]->get_num_unread_discussions()); $this->assertEquals(1, $s1forums[$forum2->get_id()]->get_num_unread_discussions()); // Mark posts read individually. $posttime = $posttime + 2; $did1s1post1->mark_read($posttime, $etuser1->id); // Poster suser1, reader teacher 1. $did2s1post2->mark_read($posttime, $etuser1->id); // Poster suser1, reader teacher 1. $did1etpost1->mark_read($posttime, $suser1->id); // Poster etuser1, reader suser1. $did2etpost2->mark_read($posttime, $suser1->id); // Poster etuser1, reader suser1. $did1s2post1->mark_read($posttime, $suser1->id); $did2s2post1->mark_read($posttime, $suser1->id); $did1s2post1->mark_read($posttime, $etuser1->id); $did2s2post1->mark_read($posttime, $etuser1->id); // Check read status of newly marked read posts. $etforums = mod_forumng::get_course_forums($course, $etuser1->id, mod_forumng::UNREAD_DISCUSSIONS); // Discussions have NO posts not read by ET. $this->assertFalse($etforums[$forum1->get_id()]->has_unread_discussions()); $this->assertFalse($etforums[$forum2->get_id()]->has_unread_discussions()); // No discussions contain posts not read by ET. $this->assertEquals(0, $etforums[$forum1->get_id()]->get_num_unread_discussions()); $this->assertEquals(0, $etforums[$forum2->get_id()]->get_num_unread_discussions()); $s1forums = mod_forumng::get_course_forums($course, $suser1->id, mod_forumng::UNREAD_DISCUSSIONS); // Discussions have NO posts not read by Suser1. $this->assertFalse($s1forums[$forum1->get_id()]->has_unread_discussions()); $this->assertFalse($s1forums[$forum2->get_id()]->has_unread_discussions()); // No discussions contain posts not read by Suser1. $this->assertEquals(0, $s1forums[$forum1->get_id()]->get_num_unread_discussions()); $this->assertEquals(0, $s1forums[$forum2->get_id()]->get_num_unread_discussions()); // Get read counts for ET user, includes their own posts, // also checks both query_forums() and query_discussions(). $discussion1etuser = mod_forumng_discussion::get_from_id($did1[0], 0, $etuser1->id); $etuserposts = $discussion1etuser->get_num_posts(); $this->assertEquals(1, count($etuserposts)); $unreadpostsetuser = $discussion1etuser->get_num_unread_posts(); $this->assertEquals(0, $unreadpostsetuser); $readpostsetuser = $DB->get_records('forumng_read_posts', array('userid' => $etuser1->id)); $this->assertCount(4, $readpostsetuser); $discussion2etuser = mod_forumng_discussion::get_from_id($did2[0], 0, $etuser1->id); $etuserposts = $discussion2etuser->get_num_posts(); $this->assertEquals(1, count($etuserposts)); $unreadpostsetuser = $discussion2etuser->get_num_unread_posts(); $this->assertEquals(0, $unreadpostsetuser); $readpostsetuser = $DB->get_records('forumng_read_posts', array('userid' => $etuser1->id)); $this->assertCount(4, $readpostsetuser); // Get read counts for the student user 1, includes count of their own posts. $discussion1suser1 = mod_forumng_discussion::get_from_id($did1[0], 0, $suser1->id); $suser1posts = $discussion1suser1->get_num_posts(); $this->assertEquals(1, count($suser1posts)); $unreadpostsuser1 = $discussion1suser1->get_num_unread_posts(); $this->assertEquals(0, $unreadpostsuser1); $readpostsuser1 = $DB->get_records('forumng_read_posts', array('userid' => $suser1->id)); $this->assertCount(4, $readpostsuser1); $discussion2suser1 = mod_forumng_discussion::get_from_id($did2[0], 0, $suser1->id); $suser1posts = $discussion2suser1->get_num_posts(); $this->assertEquals(1, count($suser1posts)); $unreadpostsuser1 = $discussion2suser1->get_num_unread_posts(); $this->assertEquals(0, $unreadpostsuser1); $readpostsuser1 = $DB->get_records('forumng_read_posts', array('userid' => $suser1->id)); $this->assertCount(4, $readpostsuser1); // Ensure user prefs allow discussions/posts to be marked as read 'automatically'. unset_user_preference('forumng_manualmark', $etuser1); unset_user_preference('forumng_manualmark', $suser1); // Mark read at forumn/discussion level 'automatically'. $posttime = $posttime + 2; // Mark forumn/discussion 1 read 'automatically'. $did1read = mod_forumng_discussion::get_from_id($did1[0], 0); $did1read->mark_read($posttime, $etuser1->id); $did1read->mark_read($posttime, $suser1->id); // Mark forumn/discussion 2 read 'automatically'. $did2read = mod_forumng_discussion::get_from_id($did2[0], 0); $did2read->mark_read($posttime, $suser1->id); $did2read->mark_read($posttime, $etuser1->id); // Re-check Forumn read status of forum/discussions/posts. $etforums = mod_forumng::get_course_forums($course, $etuser1->id, mod_forumng::UNREAD_DISCUSSIONS); // Forum discussions have NO posts not read by ET. $this->assertFalse($etforums[$forum1->get_id()]->has_unread_discussions('use')); $this->assertFalse($etforums[$forum2->get_id()]->has_unread_discussions()); // No forum discussion contains posts not read by ET. $this->assertEquals(0, $etforums[$forum1->get_id()]->get_num_unread_discussions()); $this->assertEquals(0, $etforums[$forum2->get_id()]->get_num_unread_discussions()); $s1forums = mod_forumng::get_course_forums($course, $suser1->id, mod_forumng::UNREAD_DISCUSSIONS); // Forum discussions have NO posts not read by S1. $this->assertFalse($s1forums[$forum1->get_id()]->has_unread_discussions()); $this->assertFalse($s1forums[$forum2->get_id()]->has_unread_discussions()); // No forum discussion contains posts not read by S1. $this->assertEquals(0, $s1forums[$forum1->get_id()]->get_num_unread_discussions()); $this->assertEquals(0, $s1forums[$forum2->get_id()]->get_num_unread_discussions()); // Add some more posts to discussion 2 only, to remain NOT MARKED manually. $posttime = $posttime + 2; $did2s1p3 = $generator->create_post(array('discussionid' => $did2[0], 'parentpostid' => $did2[1], 'userid' => $suser1->id, 'modified' => $posttime)); $did2s1post3 = mod_forumng_post::get_from_id($did2s1p3->id, 0); $did2etp3 = $generator->create_post(array('discussionid' => $did2[0], 'parentpostid' => $did2[1], 'userid' => $suser2->id, 'modified' => $posttime)); $did2etpost3 = mod_forumng_post::get_from_id($did2etp3->id, 0); // Setuser pref so discussions/posts can be marked 'manually'. set_user_preference('forumng_manualmark', 1, $etuser1); set_user_preference('forumng_manualmark', 1, $suser1); // Check read status of forum/discussions/posts. $etforums = mod_forumng::get_course_forums($course, $etuser1->id, mod_forumng::UNREAD_DISCUSSIONS); // Forumn discussion 1 has NO post not read by ET. $this->assertFalse($etforums[$forum1->get_id()]->has_unread_discussions()); $this->assertEquals(0, $etforums[$forum1->get_id()]->get_num_unread_discussions()); // Forumn discussion 2 has post NOT read by ET. $this->assertTrue($etforums[$forum2->get_id()]->has_unread_discussions()); $this->assertEquals(1, $etforums[$forum2->get_id()]->get_num_unread_discussions()); $s1forums = mod_forumng::get_course_forums($course, $suser1->id, mod_forumng::UNREAD_DISCUSSIONS); // Forumn discussions 1 has NO post unread by S1. $this->assertFalse($s1forums[$forum1->get_id()]->has_unread_discussions()); $this->assertEquals(0, $s1forums[$forum1->get_id()]->get_num_unread_discussions()); // Forumn discussion 2 DOES contain posts not read by S1. $this->assertTrue($s1forums[$forum2->get_id()]->has_unread_discussions()); $this->assertEquals(1, $s1forums[$forum2->get_id()]->get_num_unread_discussions()); // Mark only the older posts read individually. $posttime = $posttime + 2; $did1s1post1->mark_read($posttime, $etuser1->id); // Poster suser1, reader teacher 1. $did2s1post2->mark_read($posttime, $etuser1->id); // Poster suser1, reader teacher 1. $did1etpost1->mark_read($posttime, $suser1->id); // Poster etuser1, reader suser1. $did2etpost2->mark_read($posttime, $suser1->id); // Poster etuser1, reader suser1. // Get read counts for ET user, includes their own posts, // also checks both query_forums() and query_discussions(). $discussion1etuser = mod_forumng_discussion::get_from_id($did1[0], 0, $etuser1->id); $etuserposts = $discussion1etuser->get_num_posts(); $this->assertEquals(4, $etuserposts); $unreadpostsetuser = $discussion1etuser->get_num_unread_posts(); $this->assertEquals(0, $unreadpostsetuser); $readpostsetuser = $DB->get_records('forumng_read_posts', array('userid' => $etuser1->id)); $this->assertCount(2, $readpostsetuser); $discussion2etuser = mod_forumng_discussion::get_from_id($did2[0], 0, $etuser1->id); $etuserposts = $discussion2etuser->get_num_posts(); $this->assertEquals(6, $etuserposts); $unreadpostsetuser = $discussion2etuser->get_num_unread_posts(); $this->assertEquals(2, $unreadpostsetuser); // Get read counts for the student user 1, includes count of their own posts. $discussion1suser1 = mod_forumng_discussion::get_from_id($did1[0], 0, $suser1->id); $suser1posts = $discussion1suser1->get_num_posts(); $this->assertEquals(1, count($suser1posts)); $unreadpostsuser1 = $discussion1suser1->get_num_unread_posts(); $this->assertEquals(0, $unreadpostsuser1); $readpostsuser1 = $DB->get_records('forumng_read_posts', array('userid' => $suser1->id)); $this->assertCount(2, $readpostsuser1); $discussion2suser1 = mod_forumng_discussion::get_from_id($did2[0], 0, $suser1->id); $suser1posts = $discussion2suser1->get_num_posts(); $this->assertEquals(1, count($suser1posts)); $unreadpostsuser1 = $discussion2suser1->get_num_unread_posts(); $this->assertEquals(1, $unreadpostsuser1); $readpostsuser1 = $DB->get_records('forumng_read_posts', array('userid' => $suser1->id)); $this->assertCount(2, $readpostsuser1); // Check read status of forum/discussions/posts. $etforums = mod_forumng::get_course_forums($course, $etuser1->id, mod_forumng::UNREAD_DISCUSSIONS); // Forumn discussion 1 has NO posts not read by ET. $this->assertFalse($etforums[$forum1->get_id()]->has_unread_discussions()); $this->assertEquals(0, $etforums[$forum1->get_id()]->get_num_unread_discussions()); // Forumn discussion 2 contains posts NOT read by ET. $this->assertTrue($etforums[$forum2->get_id()]->has_unread_discussions()); $this->assertEquals(1, $etforums[$forum2->get_id()]->get_num_unread_discussions()); $s1forums = mod_forumng::get_course_forums($course, $suser1->id, mod_forumng::UNREAD_DISCUSSIONS); // Forumn discussion 1 has NO posts not read by S1. $this->assertFalse($etforums[$forum1->get_id()]->has_unread_discussions()); $this->assertEquals(0, $etforums[$forum1->get_id()]->get_num_unread_discussions()); // Forumn discussion 2 contains posts NOT read by S1. $this->assertTrue($etforums[$forum2->get_id()]->has_unread_discussions()); $this->assertEquals(1, $etforums[$forum2->get_id()]->get_num_unread_discussions()); // Mark forumns read 'automatically'. $forums = mod_forumng::get_course_forums($course, $etuser1->id); $posttime = $posttime + 2; $forums[$forum1->get_id()]->mark_read(0, $posttime, $etuser1->id); $forums[$forum2->get_id()]->mark_read(0, $posttime, $etuser1->id); $forums = mod_forumng::get_course_forums($course, $suser1->id); $posttime = $posttime + 2; $forums[$forum2->get_id()]->mark_read(0, $posttime, $suser1->id); $forums[$forum1->get_id()]->mark_read(0, $posttime, $suser1->id); // Check Discussion read status of forum/discussions. $etforums = mod_forumng::get_course_forums($course, $etuser1->id, mod_forumng::UNREAD_DISCUSSIONS); // Forum discussions have NO posts not read by ET. $this->assertFalse($etforums[$forum1->get_id()]->has_unread_discussions()); $this->assertFalse($etforums[$forum2->get_id()]->has_unread_discussions()); // Forum discussions contain NO posts unread by ET. $this->assertEquals(0, $etforums[$forum1->get_id()]->get_num_unread_discussions()); $this->assertEquals(0, $etforums[$forum2->get_id()]->get_num_unread_discussions()); $s1forums = mod_forumng::get_course_forums($course, $suser1->id, mod_forumng::UNREAD_DISCUSSIONS); // Forum discussions have NO posts not read by S1. $this->assertFalse($s1forums[$forum1->get_id()]->has_unread_discussions()); $this->assertFalse($s1forums[$forum2->get_id()]->has_unread_discussions()); // No Forum 1 discussion contains posts not read by S1. $this->assertEquals(0, $s1forums[$forum1->get_id()]->get_num_unread_discussions()); $this->assertEquals(0, $s1forums[$forum2->get_id()]->get_num_unread_discussions()); }
/** * Internal function that obtains HTML of a single post. * @param mixed $postorid Post object or ID of post * @param int $cloneid If $postorid is an id, a clone id may be necessary * to construct the post * @param array $options Post options if any * @return string HTML of post */ private static function get_post_html($postorid, $cloneid = null, $options = array()) { if (is_object($postorid)) { $post = $postorid; } else { $post = mod_forumng_post::get_from_id($postorid, $cloneid, true); } return trim($post->display(true, $options)); }
/** * Create output for post information (Title, date, user) * Returns content and user object (discussion poster, null if anon) * @param object $forum * @param object $discussion * @param object $post * @return array content html, poster user object */ public function render_usage_post_info($forum, $discussion, mod_forumng_post $post) { $user = $post->get_user(); $link = html_writer::link($post->get_url(), format_string($post->get_effective_subject())); $content = html_writer::div($link); $content .= html_writer::div(mod_forumng_utils::display_date($post->get_created())); $content .= html_writer::start_div('fng_userlink'); if ($post->get_asmoderator() == mod_forumng::ASMODERATOR_ANON && !$forum->can_post_anonymously()) { // Hide user details if anon post and user does not have permission to see. $user = null; } else { $content .= $forum->display_user_link($user) . ' '; } if ($post->get_asmoderator() != mod_forumng::ASMODERATOR_NO) { $content .= get_string('moderator', 'mod_forumng'); } $content .= html_writer::end_div(); return array($content, $user); }
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ require_once '../../config.php'; require_once 'mod_forumng.php'; // Post ID $postid = required_param('p', PARAM_INT); $cloneid = optional_param('clone', 0, PARAM_INT); $raw = optional_param('raw', 0, PARAM_INT); $pageparams = array('p' => $postid); if ($cloneid) { $pageparams['clone'] = $cloneid; } if ($raw) { $pageparams['raw'] = $raw; } try { // Get post $post = mod_forumng_post::get_from_id($postid, $cloneid, true, true); // Do all access security checks $post->require_view(); $post->get_discussion()->init_page(new moodle_url('/mod/forumng/expandpost.php', $pageparams), ''); // Display post if ($raw) { print $post->prepare_edit_json(); } else { mod_forumng_post::print_for_ajax_and_exit($post); } } catch (coding_exception $e) { header('Content-Type: text/plain', true, 500); print $e->getMessage(); }
/** * Tests the grading functions in mod_forumng. * Note manual grading is handled in feature/user posts and not tested here... */ public function test_grading() { global $USER, $DB; $this->resetAfterTest(true); $this->setAdminUser(); $adminid = $USER->id; $generator = $this->getDataGenerator()->get_plugin_generator('mod_forumng'); $course = $this->get_new_course(); $user1 = $this->get_new_user('editingteacher', $course->id); $forum1 = $this->get_new_forumng($course->id, array('grading' => mod_forumng::GRADING_MANUAL, 'gradingscale' => 50)); $forum1->update_grades($USER->id); // Should do nothing and throw no excpetion... $forum2 = $this->get_new_forumng($course->id, array('grading' => mod_forumng::GRADING_COUNT, 'gradingscale' => 5, 'ratingscale' => 5)); list($discuss, $postid) = $generator->create_discussion(array('course' => $course->id, 'forum' => $forum2->get_id(), 'userid' => $USER->id)); $post = mod_forumng_post::get_from_id($postid, 0); $post->rate(1); // Calls update_grades(). $post = $generator->create_post(array('discussionid' => $discuss, 'userid' => $USER->id, 'parentpostid' => $postid)); $post = mod_forumng_post::get_from_id($post->id, 0); $post->rate(3); // Calls update_grades(). $grades = grade_get_grades($course->id, 'mod', 'forumng', $forum2->get_id(), $USER->id); $this->assertEquals(2, abs($grades->items[0]->grades[$USER->id]->grade)); // Try another grading type, forumng_update_instance() should update grades. forumng_update_instance((object) array('instance' => $forum2->get_id(), 'grading' => mod_forumng::GRADING_MAX)); $grades = grade_get_grades($course->id, 'mod', 'forumng', $forum2->get_id(), $USER->id); $this->assertEquals(3, abs($grades->items[0]->grades[$USER->id]->grade)); // Try another grading type, forumng_update_instance() should update grades. forumng_update_instance((object) array('instance' => $forum2->get_id(), 'grading' => mod_forumng::GRADING_MIN)); $grades = grade_get_grades($course->id, 'mod', 'forumng', $forum2->get_id(), $USER->id); $this->assertEquals(1, abs($grades->items[0]->grades[$USER->id]->grade)); // Try another grading type, forumng_update_instance() should update grades. forumng_update_instance((object) array('instance' => $forum2->get_id(), 'grading' => mod_forumng::GRADING_SUM)); $grades = grade_get_grades($course->id, 'mod', 'forumng', $forum2->get_id(), $USER->id); $this->assertEquals(4, abs($grades->items[0]->grades[$USER->id]->grade)); // Try another grading type, forumng_update_instance() should update grades. forumng_update_instance((object) array('instance' => $forum2->get_id(), 'grading' => mod_forumng::GRADING_AVERAGE)); $grades = grade_get_grades($course->id, 'mod', 'forumng', $forum2->get_id(), $USER->id); $this->assertEquals(2, abs($grades->items[0]->grades[$USER->id]->grade)); // Try another grading type, forumng_update_instance() should update grades. forumng_update_instance((object) array('instance' => $forum2->get_id(), 'grading' => mod_forumng::GRADING_NONE)); $grades = grade_get_grades($course->id, 'mod', 'forumng', $forum2->get_id(), $USER->id); $this->assertEmpty($grades->items[0]->grades[$USER->id]->grade); }
public function test_rating() { global $USER, $DB; $this->resetAfterTest(); $generator = $this->getDataGenerator()->get_plugin_generator('mod_forumng'); $course = $this->get_new_course(); $course2 = $this->get_new_course(); $suser = $this->get_new_user('student', $course->id); $this->setAdminUser(); $forum = $this->get_new_forumng($course->id, array('name' => 'TEST', 'intro' => 'abc123', 'enableratings' => mod_forumng::FORUMNG_STANDARD_RATING, 'ratingscale' => 10)); $forum2 = $this->get_new_forumng($course->id, array('name' => 'TEST2', 'intro' => 'abc123', 'enableratings' => mod_forumng::FORUMNG_NO_RATING)); $forum3 = $this->get_new_forumng($course2->id, array('name' => 'TEST', 'intro' => 'abc123', 'enableratings' => mod_forumng::FORUMNG_STANDARD_RATING, 'ratingscale' => 10)); $did1 = $generator->create_discussion(array('course' => $course, 'forum' => $forum->get_id(), 'userid' => $suser->id)); $did2 = $generator->create_discussion(array('course' => $course, 'forum' => $forum->get_id(), 'userid' => $suser->id)); $did3 = $generator->create_discussion(array('course' => $course, 'forum' => $forum->get_id(), 'userid' => $suser->id)); $did4 = $generator->create_discussion(array('course' => $course, 'forum' => $forum->get_id(), 'userid' => $suser->id)); // Add rating to all 3 discussions. $rm = new rating_manager(); $params = new stdClass(); $params->context = $forum->get_context(); $params->component = 'mod_forumng'; $params->ratingarea = 'post'; $params->scaleid = $forum->get_rating_scale(); $params->userid = $USER->id; $params->itemid = $did1[1]; $rating = new rating($params); $rating->update_rating(5); $params->itemid = $did2[1]; $rating = new rating($params); $rating->update_rating(5); $params->itemid = $did3[1]; $rating = new rating($params); $rating->update_rating(5); // Check rating object gets added where expected. $post = mod_forumng_post::get_from_id($did1[1], mod_forumng::CLONE_DIRECT, false, false); $ratings = $post->get_ratings(); $this->assertNotNull($ratings); $this->assertEquals($did1[1], $ratings->itemid); $post = mod_forumng_post::get_from_id($did1[1], mod_forumng::CLONE_DIRECT, true, false); $ratings = $post->get_ratings(); $this->assertNotNull($ratings); $this->assertEquals($did1[1], $ratings->itemid); $post = mod_forumng_post::get_from_id($did1[1], mod_forumng::CLONE_DIRECT, true, true); $ratings = $post->get_ratings(); $this->assertNotNull($ratings); $this->assertEquals($did1[1], $ratings->itemid); $ratedposts = $forum->get_all_posts_by_user($suser->id, null, 'fp.id', null, null, true); $this->assertCount(3, $ratedposts); $allposts = $forum->get_all_posts_by_user($suser->id, null); $this->assertCount(4, $allposts); $this->assertNotNull($allposts[$did1[1]]->get_ratings()); // Update grades (does nothing). $forum->update_grades(); // Enable rating grading, forumng_update_instance() should update grades. forumng_update_instance((object) array('instance' => $forum->get_id(), 'grading' => mod_forumng::GRADING_SUM)); $grades = grade_get_grades($course->id, 'mod', 'forumng', $forum->get_id(), $suser->id); // Note sum is set to 10 not 15 as max grade is 10. $this->assertEquals(10, abs($grades->items[0]->grades[$suser->id]->grade)); // Enable rating grading, forumng_update_instance() should update grades. forumng_update_instance((object) array('instance' => $forum->get_id(), 'grading' => mod_forumng::GRADING_COUNT)); $grades = grade_get_grades($course->id, 'mod', 'forumng', $forum->get_id(), $suser->id); $this->assertEquals(3, abs($grades->items[0]->grades[$suser->id]->grade)); // Check get_rated_posts_by_user. $extrapost = $generator->create_post(array('discussionid' => $did1[0], 'parentpostid' => $did1[1], 'userid' => $suser->id, 'created' => 1388589745)); $extraposts = $forum->get_rated_posts_by_user($forum, $suser->id, -1, 'fp.id', null, null); $this->assertCount(0, $extraposts); $extraposts = $forum->get_rated_posts_by_user($forum, $USER->id, -1, 'fp.id', null, null); $this->assertCount(3, $extraposts); $params->itemid = $extrapost->id; $rating = new rating($params); $rating->update_rating(10); $extraposts = $forum->get_rated_posts_by_user($forum, $USER->id, -1, 'fp.id', null, null); $this->assertCount(4, $extraposts); // Now filter out the 'old' extrapost. $extraposts = $forum->get_rated_posts_by_user($forum, $USER->id, -1, 'fp.id', null, null, 1388600000); $this->assertCount(3, $extraposts); // Check discussion delete. $discuss = mod_forumng_discussion::get_from_id($did1[0], mod_forumng::CLONE_DIRECT); $discuss->permanently_delete(); $rating = $DB->get_record('rating', array('itemid' => $did1[1])); $this->assertFalse($rating); $grades = grade_get_grades($course->id, 'mod', 'forumng', $forum->get_id(), $suser->id); $this->assertEquals(2, abs($grades->items[0]->grades[$suser->id]->grade)); // Check discussion move. $discuss = mod_forumng_discussion::get_from_id($did2[0], mod_forumng::CLONE_DIRECT); $discuss->move($forum2, 0); $grades = grade_get_grades($course->id, 'mod', 'forumng', $forum->get_id(), $suser->id); $this->assertEquals(1, abs($grades->items[0]->grades[$suser->id]->grade)); forumng_update_instance((object) array('instance' => $forum2->get_id(), 'grading' => mod_forumng::GRADING_COUNT, 'enableratings' => mod_forumng::FORUMNG_STANDARD_RATING, 'ratingscale' => 10)); $grades = grade_get_grades($course->id, 'mod', 'forumng', $forum2->get_id(), $suser->id); $this->assertEquals(1, abs($grades->items[0]->grades[$suser->id]->grade)); $rating = $DB->get_record('rating', array('itemid' => $did2[1])); $this->assertNotEmpty($rating); $this->assertEquals($forum2->get_context(true)->id, $rating->contextid); // Check discussion copy. $discuss = mod_forumng_discussion::get_from_id($did3[0], mod_forumng::CLONE_DIRECT); $discuss->copy($forum3, 0); $grades = grade_get_grades($course->id, 'mod', 'forumng', $forum->get_id(), $suser->id); $this->assertEquals(1, abs($grades->items[0]->grades[$suser->id]->grade)); // Check rating didn't copy as forum in another course. $ratingtotal = $DB->get_records('rating'); $this->assertCount(2, $ratingtotal); // Check rating does copy to foum in same course. $discuss->copy($forum2, 0); $ratingtotal = $DB->get_records('rating'); $this->assertCount(3, $ratingtotal); // Check forum deleting. course_delete_module($forum->get_course_module_id()); $ratingtotal = $DB->get_records('rating'); $this->assertCount(2, $ratingtotal); $grades = grade_get_grades($course->id, 'mod', 'forumng', $forum->get_id(), $suser->id); $this->assertEmpty($grades->items); }
/** * Renders the expand link for each post. * @param string $linkprefix prefix of the expand link url * @param mod_forumng_discussion $discussion object * @param mod_forumng_post $post object * @return string HTML code for the expand link */ public function render_expand_link($linkprefix, $discussion, $post) { $out = ' <span class="forumng-expandcontainer">[<a class="forumng-expandlink" ' . 'href="' . $linkprefix . 'discuss.php?' . $discussion->get_link_params(mod_forumng::PARAM_HTML) . '&expand=1#p' . $post->get_id() . '"><span class="forumng-expandtext">' . get_string('expandall', 'forumng') . '</span></a>] <img src="' . $this->pix_url('spacer') . '" width="16" height="16" alt="" /></span>'; return $out; }
/** * Tests discussion locking */ public function test_lock() { global $USER, $DB; $this->resetAfterTest(); $this->setAdminUser(); $course1 = $this->get_new_course(); $orig = $this->get_new_forumng($course1->id, array('removeto' => -1, 'removeafter' => 1)); $dis = $this->get_new_discussion($orig, array('userid' => $USER->id)); $dis2 = $this->get_new_discussion($orig, array('userid' => $USER->id)); $dis3 = $this->get_new_discussion($orig, array('userid' => $USER->id)); // Alter post modified times to in past. foreach ($DB->get_records('forumng_posts') as $post) { $new = new stdClass(); $new->id = $post->id; $new->modified = 1420070400; $DB->update_record('forumng_posts', $new); } // Delete dis2 so not auto-locked. $dis2->delete(false); $this->assertFalse($dis->is_locked()); $this->assertFalse($dis->is_auto_locked()); $lockpostid = $dis->lock('sub', 'mess', FORMAT_HTML); $this->assertTrue($dis->is_locked()); $this->assertFalse($dis->is_auto_locked()); $dis = mod_forumng_discussion::get_from_id($dis->get_id(), mod_forumng::CLONE_DIRECT); $this->assertTrue($dis->is_locked()); $this->assertFalse($dis->is_auto_locked()); $dis->unlock(); $this->assertFalse($dis->is_locked()); $this->assertFalse($dis->is_auto_locked()); $lockpost = mod_forumng_post::get_from_id($lockpostid, mod_forumng::CLONE_DIRECT); $this->assertNotEmpty($lockpost->get_deleted()); // Check auto-locking ($dis3 should be auto-locked only). $dis->lock('', '', FORMAT_HTML); mod_forumng_cron::archive_old_discussions(); $dis = mod_forumng_discussion::get_from_id($dis->get_id(), mod_forumng::CLONE_DIRECT); $dis2 = mod_forumng_discussion::get_from_id($dis2->get_id(), mod_forumng::CLONE_DIRECT); $dis3 = mod_forumng_discussion::get_from_id($dis3->get_id(), mod_forumng::CLONE_DIRECT); $this->assertTrue($dis->is_locked()); $this->assertFalse($dis->is_auto_locked()); $this->assertFalse($dis2->is_locked()); $this->assertFalse($dis2->is_auto_locked()); $this->assertTrue($dis3->is_locked()); $this->assertTrue($dis3->is_auto_locked()); }
* @subpackage deletedposts * @copyright 2012 The Open University * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ require_once '../../../../config.php'; require_once $CFG->dirroot . '/mod/forumng/mod_forumng.php'; require_once $CFG->dirroot . '/mod/forumng/feature/deletedposts/locallib.php'; // Redirect to deletepostlist.php. $postid = required_param('p', PARAM_INT); $pageparams = array('p' => $postid); $pageparams['p'] = $postid; $cloneid = optional_param('clone', 0, PARAM_INT); if ($cloneid) { $pageparams['clone'] = $cloneid; } $post = mod_forumng_post::get_from_id($postid, $cloneid); // Get convenience variables. $discussion = $post->get_discussion(); $forum = $post->get_forum(); $course = $forum->get_course(); $cm = $forum->get_course_module(); $pageparams['id'] = $cm->id; $delete = optional_param('delete', 0, PARAM_INT); $groupid = optional_param('group', 0, PARAM_INT); $pageparams['group'] = $groupid; // Set up page. $pagename = get_string($delete ? 'deletepost' : 'undeletepost', 'forumng', $post->get_effective_subject(true)); $url = new moodle_url('/mod/forumng/feature/deletedposts/deletepost.php', $pageparams); $out = $discussion->init_page($url, $pagename); // Do all access security checks. $post->require_view();
function mod_forumng_pluginfile($course, $cm, $context, $filearea, $args, $forcedownload) { global $CFG, $USER; require_once $CFG->dirroot . '/mod/forumng/mod_forumng.php'; // Check remaining slash arguments if (count($args) != 2) { send_file_not_found(); } list($itemid, $filename) = $args; if ($filearea == 'attachment' || $filearea == 'message') { // Get post object and check permissions $cloneid = optional_param('clone', 0, PARAM_INT); $post = mod_forumng_post::get_from_id($itemid, $cloneid); $post->require_view(); if ($cloneid) { // File is actually in other context $context = $post->get_forum()->get_context(true); } } else { if ($filearea == 'draft' || $filearea == 'draftmessage') { // Get draft object and check it's yours (note: I'm not sure whether it is possible to // ever access draft attachments in this manner, as while editing, this access is not // used; maybe from the X view, but I don't think it works there, however perhaps in // future). $draft = mod_forumng_draft::get_from_id($itemid); if ($draft->get_user_id() !== $USER->id) { send_file_not_found(); } } else { send_file_not_found(); } } // Get file object and send it $fs = get_file_storage(); $file = $fs->get_file($context->id, 'mod_forumng', $filearea, $itemid, '/', $filename); if (!$file || $file->is_directory()) { send_file_not_found(); } $lifetime = isset($CFG->filelifetime) ? $CFG->filelifetime : 86400; send_stored_file($file, $lifetime, 0); }
// Old forumng ratings (obsolete). $postid = ' r.postid AS postid '; $from = ' {forumng_ratings} r'; $postjoin = 'INNER JOIN {forumng_posts} fp ON r.postid = fp.id'; $having = 'HAVING COUNT(r.rating) >= ?'; $havingparams[] = $forum->get_rating_threshold(); $groupby = ' GROUP BY r.postid'; } $conditionsparams = array_merge($conditionsparams, $groupparams, $havingparams); $ratingsl = $DB->get_recordset_sql("SELECT {$counttype}, {$postid}\n FROM {$from}\n {$postjoin}\n INNER JOIN {forumng_discussions} fd ON fp.discussionid = fd.id\n INNER JOIN {forumng} f ON f.id = fd.forumngid\n WHERE {$conditions}\n AND fd.deleted = 0\n AND fp.deleted = 0\n AND fp.oldversion = 0\n {$groupwhere}\n {$groupby}\n {$having}\n ORDER BY rawgrade DESC\n ", $conditionsparams, 0, 5); // Get the ratings. foreach ($ratingsl as $apost) { if ($gradingtype == mod_forumng::GRADING_AVERAGE) { $apost->rawgrade = round($apost->rawgrade, 2); } $post = mod_forumng_post::get_from_id($apost->postid, $cloneid, true, true); list($content, $user) = $renderer->render_usage_post_info($forum, $post->get_discussion(), $post); $ratingslist[] = $renderer->render_usage_list_item($forum, $apost->rawgrade, $user, $content); } // Print out ratings usage. $usageoutput .= $renderer->render_usage_ratings($ratingslist, $forum, $gradingstr, $gradingtype); } } if (!empty($usageoutput)) { echo html_writer::start_div('forumng_usage_section'); echo $OUTPUT->heading(get_string('usage', 'forumngfeature_usage'), 4, 'forumng_usage_sectitle'); echo $usageoutput; echo html_writer::start_div('clearer') . html_writer::end_div(); echo html_writer::end_div(); } echo $OUTPUT->footer();
/** * Returns all posts in this forum by the given user within the given group. * @param object $forum * @param int $userid * @param int $groupid * @param int $ratedstart * @param int $ratedend * @param string $order Sort order; the default is fp.id - note this is preferable * to fp.timecreated because it works correctly if there are two posts in * the same second * @param bool $hasrating if true only returns posts which ahve been rated * @return array Array of mod_forumng_post objects */ public function get_rated_posts_by_user($forum, $userid, $groupid, $order = 'fp.id', $ratedstart = null, $ratedend = null, $start = null, $end = null) { global $CFG, $USER; if ($forum->get_enableratings() != mod_forumng::FORUMNG_STANDARD_RATING) { return array(); } $where = 'fd.forumngid = ? AND fp.userid <> ? AND fp.oldversion = 0 AND fp.deleted = 0'; $whereparams = array($this->get_id(), $userid); if ($groupid != self::NO_GROUPS && $groupid != self::ALL_GROUPS) { $where .= ' AND (fd.groupid = ? OR fd.groupid IS NULL)'; $whereparams[] = $groupid; } if (!empty($start)) { $where .= ' AND fp.created >= ?'; $whereparams[] = $start; } if (!empty($end)) { $where .= ' AND fp.created <= ?'; $whereparams[] = $end; } $sqlselectstring = 'SELECT r.itemid FROM {rating} r WHERE r.itemid = fp.id AND r.ratingarea = \'post\' AND r.contextid = ? AND r.userid = ?'; $extraparams = array(); if (!empty($ratedstart)) { $sqlselectstring .= ' AND r.timemodified >= ?'; $extraparams[] = $ratedstart; } if (!empty($ratedend)) { $sqlselectstring .= ' AND r.timemodified <= ?'; $extraparams[] = $ratedend; } $where .= ' AND ' . self::select_exists($sqlselectstring); $whereparams[] = $this->get_context(true)->id; $whereparams[] = $userid; $whereparams = array_merge($whereparams, $extraparams); $result = array(); $posts = mod_forumng_post::query_posts($where, $whereparams, $order, false, false, true, 0, true, true); // Add standard ratings if enabled. if ($this->get_enableratings() == mod_forumng::FORUMNG_STANDARD_RATING) { require_once $CFG->dirroot . '/rating/lib.php'; // If grading is 'No grading' or 'Teacher grades students'. if ($this->get_grading() == mod_forumng::GRADING_NONE || $this->get_grading() == mod_forumng::GRADING_MANUAL) { // Set the aggregation method. if ($this->get_rating_scale() > 0) { $aggregate = RATING_AGGREGATE_AVERAGE; } else { $aggregate = RATING_AGGREGATE_COUNT; } } else { $aggregate = $this->get_grading(); } $ratingoptions = new stdClass(); $ratingoptions->context = $this->get_context(true); $ratingoptions->component = 'mod_forumng'; $ratingoptions->ratingarea = 'post'; $ratingoptions->items = $posts; $ratingoptions->aggregate = $aggregate; $ratingoptions->scaleid = $this->get_rating_scale(); $ratingoptions->userid = $USER->id; $ratingoptions->assesstimestart = $this->get_ratingfrom(); $ratingoptions->assesstimefinish = $this->get_ratinguntil(); $rm = new rating_manager(); $posts = $rm->get_ratings($ratingoptions); } foreach ($posts as $fields) { $discussionfields = mod_forumng_utils::extract_subobject($fields, 'fd_'); $discussion = new mod_forumng_discussion($this, $discussionfields, false, -1); $result[$fields->id] = new mod_forumng_post($discussion, $fields); } return $result; }