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]); } } }
// 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();
* @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();
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); }
/** * 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; }
/** * 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 * @param int $asmoderator values are ASMODERATOR_NO, ASMODERATOR_IDENTIFY or ASMODERATOR_ANON * @param array $tags array of tags to add to a discussion * @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, $asmoderator = self::ASMODERATOR_NO, $tags = null) { global $DB, $CFG; require_once $CFG->dirroot . '/tag/lib.php'; $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, $asmoderator); // 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 (self::search_installed()) { mod_forumng_post::get_from_id($postid, $this->get_course_module_id())->search_update(); } // If tags add to tag_instance records. if ($tags != null) { tag_set('forumng_discussions', $discussionobj->id, $tags, 'mod_forumng', $this->context->id); } $transaction->allow_commit(); return array($newdiscussion->get_id(), $postid); }
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); }
/** * 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()); }
/** * 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)); }
/** * 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); }