diff --git a/mod/forum/index.php b/mod/forum/index.php index 96e13635b45..87666b998ab 100644 --- a/mod/forum/index.php +++ b/mod/forum/index.php @@ -230,9 +230,10 @@ if ($generalforums) { $unreadlink = '0'; } - if ($forum->trackingtype == FORUM_TRACKING_ON) { + if (($forum->trackingtype == FORUM_TRACKING_ON) && ($CFG->forum_allowforcedreadtracking)) { $trackedlink = $stryes; - + } else if ($forum->trackingtype === FORUM_TRACKING_OFF || ($USER->trackforums == 0)) { + $trackedlink = '-'; } else { $aurl = new moodle_url('/mod/forum/settracking.php', array('id'=>$forum->id)); if (!isset($untracked[$forum->id])) { @@ -368,9 +369,10 @@ if ($course->id != SITEID) { // Only real courses have learning forums $unreadlink = '0'; } - if ($forum->trackingtype == FORUM_TRACKING_ON) { + if (($forum->trackingtype == FORUM_TRACKING_ON) && ($CFG->forum_allowforcedreadtracking)) { $trackedlink = $stryes; - + } else if ($forum->trackingtype === FORUM_TRACKING_OFF || ($USER->trackforums == 0)) { + $trackedlink = '-'; } else { $aurl = new moodle_url('/mod/forum/settracking.php', array('id'=>$forum->id)); if (!isset($untracked[$forum->id])) { diff --git a/mod/forum/lang/en/forum.php b/mod/forum/lang/en/forum.php index 0ab864fb297..af18efa01c9 100644 --- a/mod/forum/lang/en/forum.php +++ b/mod/forum/lang/en/forum.php @@ -173,6 +173,8 @@ $string['everyoneisnowsubscribed'] = 'Everyone is now subscribed to this forum'; $string['everyoneissubscribed'] = 'Everyone is subscribed to this forum'; $string['existingsubscribers'] = 'Existing subscribers'; $string['exportdiscussion'] = 'Export whole discussion'; +$string['forcedreadtracking'] = 'Allow forced read tracking'; +$string['forcedreadtracking_desc'] = 'Allows forums to be set to forced read tracking. Will result in decreased performance for some users, particularly on courses with many forums and posts. When off, any forums previously set to Forced are treated as optional.'; $string['forcessubscribe'] = 'This forum forces everyone to be subscribed'; $string['forum'] = 'Forum'; $string['forum:addinstance'] = 'Add a new forum'; @@ -430,16 +432,14 @@ $string['timestartenderror'] = 'Display end date cannot be earlier than the star $string['trackforum'] = 'Track unread posts'; $string['tracking'] = 'Track'; $string['trackingoff'] = 'Off'; -$string['trackingon'] = 'On'; +$string['trackingon'] = 'Forced'; $string['trackingoptional'] = 'Optional'; $string['trackingtype'] = 'Read tracking'; $string['trackingtype_help'] = 'If enabled, participants can track read and unread posts in the forum and in discussions. There are three options: -* Optional - Participants can choose whether to turn tracking on or off via a link in the administration block -* On - Tracking is always on -* Off - Read and unread posts are not tracked - -Note: Forum tracking must also be enabled in the user\'s profile settings.'; +* Optional - Participants can choose whether to turn tracking on or off via a link in the administration block. Forum tracking must also be enabled in the user\'s profile settings. +* Forced - Tracking is always on, regardless of user setting. Available depending on administrative setting. +* Off - Read and unread posts are not tracked.'; $string['unread'] = 'Unread'; $string['unreadposts'] = 'Unread posts'; $string['unreadpostsnumber'] = '{$a} unread posts'; diff --git a/mod/forum/lib.php b/mod/forum/lib.php index a63bd093efe..086df753af9 100644 --- a/mod/forum/lib.php +++ b/mod/forum/lib.php @@ -6269,6 +6269,14 @@ function forum_tp_mark_posts_read($user, $postids) { $params = array_merge($params, $new_params); $params[] = $cutoffdate; + if ($CFG->forum_allowforcedreadtracking) { + $trackingsql = "AND (f.trackingtype = ".FORUM_TRACKING_ON." + OR (f.trackingtype = ".FORUM_TRACKING_OPTIONAL." AND tf.id IS NULL))"; + } else { + $trackingsql = "AND ((f.trackingtype = ".FORUM_TRACKING_OPTIONAL." OR f.trackingtype = ".FORUM_TRACKING_ON.") + AND tf.id IS NULL)"; + } + $sql = "INSERT INTO {forum_read} (userid, postid, discussionid, forumid, firstread, lastread) SELECT ?, p.id, p.discussion, d.forum, ?, ? @@ -6278,8 +6286,7 @@ function forum_tp_mark_posts_read($user, $postids) { LEFT JOIN {forum_track_prefs} tf ON (tf.userid = ? AND tf.forumid = f.id) WHERE p.id $usql AND p.modified >= ? - AND (f.trackingtype = ".FORUM_TRACKING_ON." - OR (f.trackingtype = ".FORUM_TRACKING_OPTIONAL." AND tf.id IS NULL))"; + $trackingsql"; $status = $DB->execute($sql, $params) && $status; } @@ -6602,9 +6609,9 @@ function forum_tp_count_forum_read_records($userid, $forumid, $groupid=false) { function forum_tp_get_course_unread_posts($userid, $courseid) { global $CFG, $DB; - $now = round(time(), -2); // db cache friendliness - $cutoffdate = $now - ($CFG->forum_oldpostdays*24*60*60); - $params = array($userid, $userid, $courseid, $cutoffdate); + $now = round(time(), -2); // DB cache friendliness. + $cutoffdate = $now - ($CFG->forum_oldpostdays * 24 * 60 * 60); + $params = array($userid, $userid, $courseid, $cutoffdate, $userid); if (!empty($CFG->forum_enabletimedposts)) { $timedsql = "AND d.timestart < ? AND (d.timeend = 0 OR d.timeend > ?)"; @@ -6614,6 +6621,16 @@ function forum_tp_get_course_unread_posts($userid, $courseid) { $timedsql = ""; } + if ($CFG->forum_allowforcedreadtracking) { + $trackingsql = "AND (f.trackingtype = ".FORUM_TRACKING_ON." + OR (f.trackingtype = ".FORUM_TRACKING_OPTIONAL." AND tf.id IS NULL + AND (SELECT trackforums FROM {user} WHERE id = ?) = 1))"; + } else { + $trackingsql = "AND ((f.trackingtype = ".FORUM_TRACKING_OPTIONAL." OR f.trackingtype = ".FORUM_TRACKING_ON.") + AND tf.id IS NULL + AND (SELECT trackforums FROM {user} WHERE id = ?) = 1)"; + } + $sql = "SELECT f.id, COUNT(p.id) AS unread FROM {forum_posts} p JOIN {forum_discussions} d ON d.id = p.discussion @@ -6623,8 +6640,7 @@ function forum_tp_get_course_unread_posts($userid, $courseid) { LEFT JOIN {forum_track_prefs} tf ON (tf.userid = ? AND tf.forumid = f.id) WHERE f.course = ? AND p.modified >= ? AND r.id is NULL - AND (f.trackingtype = ".FORUM_TRACKING_ON." - OR (f.trackingtype = ".FORUM_TRACKING_OPTIONAL." AND tf.id IS NULL)) + $trackingsql $timedsql GROUP BY f.id"; @@ -6767,14 +6783,24 @@ function forum_tp_delete_read_records($userid=-1, $postid=-1, $discussionid=-1, function forum_tp_get_untracked_forums($userid, $courseid) { global $CFG, $DB; + if ($CFG->forum_allowforcedreadtracking) { + $trackingsql = "AND (f.trackingtype = ".FORUM_TRACKING_OFF." + OR (f.trackingtype = ".FORUM_TRACKING_OPTIONAL." AND (ft.id IS NOT NULL + OR (SELECT trackforums FROM {user} WHERE id = ?) = 0)))"; + } else { + $trackingsql = "AND (f.trackingtype = ".FORUM_TRACKING_OFF." + OR ((f.trackingtype = ".FORUM_TRACKING_OPTIONAL." OR f.trackingtype = ".FORUM_TRACKING_ON.") + AND (ft.id IS NOT NULL + OR (SELECT trackforums FROM {user} WHERE id = ?) = 0)))"; + } + $sql = "SELECT f.id FROM {forum} f LEFT JOIN {forum_track_prefs} ft ON (ft.forumid = f.id AND ft.userid = ?) WHERE f.course = ? - AND (f.trackingtype = ".FORUM_TRACKING_OFF." - OR (f.trackingtype = ".FORUM_TRACKING_OPTIONAL." AND ft.id IS NOT NULL))"; + $trackingsql"; - if ($forums = $DB->get_records_sql($sql, array($userid, $courseid))) { + if ($forums = $DB->get_records_sql($sql, array($userid, $courseid, $userid))) { foreach ($forums as $forum) { $forums[$forum->id] = $forum; } @@ -6815,11 +6841,14 @@ function forum_tp_can_track_forums($forum=false, $user=false) { } if ($forum === false) { - // general abitily to track forums - return (bool)$user->trackforums; + if ($CFG->forum_allowforcedreadtracking) { + // Since we can force tracking, assume yes without a specific forum. + return true; + } else { + return (bool)$user->trackforums; + } } - // Work toward always passing an object... if (is_numeric($forum)) { debugging('Better use proper forum object.', DEBUG_DEVELOPER); @@ -6829,7 +6858,13 @@ function forum_tp_can_track_forums($forum=false, $user=false) { $forumallows = ($forum->trackingtype == FORUM_TRACKING_OPTIONAL); $forumforced = ($forum->trackingtype == FORUM_TRACKING_ON); - return ($forumforced || $forumallows) && !empty($user->trackforums); + if ($CFG->forum_allowforcedreadtracking) { + // If we allow forcing, then forced forums takes procidence over user setting. + return ($forumforced || ($forumallows && (!empty($user->trackforums) && (bool)$user->trackforums))); + } else { + // If we don't allow forcing, user setting trumps. + return ($forumforced || $forumallows) && !empty($user->trackforums); + } } /** @@ -6866,9 +6901,13 @@ function forum_tp_is_tracked($forum, $user=false) { $forumallows = ($forum->trackingtype == FORUM_TRACKING_OPTIONAL); $forumforced = ($forum->trackingtype == FORUM_TRACKING_ON); + $userpref = $DB->get_record('forum_track_prefs', array('userid' => $user->id, 'forumid' => $forum->id)); - return $forumforced || - ($forumallows && $DB->get_record('forum_track_prefs', array('userid' => $user->id, 'forumid' => $forum->id)) === false); + if ($CFG->forum_allowforcedreadtracking) { + return $forumforced || ($forumallows && $userpref === false); + } else { + return ($forumallows || $forumforced) && $userpref === false; + } } /** @@ -7678,10 +7717,8 @@ function forum_extend_settings_navigation(settings_navigation $settingsnav, navi } if ($enrolled && forum_tp_can_track_forums($forumobject)) { // keep tracking info for users with suspended enrolments - if ($forumobject->trackingtype != FORUM_TRACKING_OPTIONAL) { - //tracking forced on or off in forum settings so dont provide a link here to change it - //could add unclickable text like for forced subscription but not sure this justifies adding another menu item - } else { + if ($forumobject->trackingtype == FORUM_TRACKING_OPTIONAL + || ((!$CFG->forum_allowforcedreadtracking) && $forumobject->trackingtype == FORUM_TRACKING_ON)) { if (forum_tp_is_tracked($forumobject)) { $linktext = get_string('notrackforum', 'forum'); } else { @@ -7952,21 +7989,11 @@ class forum_existing_subscriber_selector extends forum_subscriber_selector_base function forum_cm_info_view(cm_info $cm) { global $CFG; - // Get tracking status (once per request) - static $initialised; - static $usetracking, $strunreadpostsone; - if (!isset($initialised)) { - if ($usetracking = forum_tp_can_track_forums()) { - $strunreadpostsone = get_string('unreadpostsone', 'forum'); - } - $initialised = true; - } - - if ($usetracking) { + if (forum_tp_can_track_forums()) { if ($unread = forum_tp_count_forum_unread_posts($cm, $cm->get_course())) { $out = ' '; if ($unread == 1) { - $out .= $strunreadpostsone; + $out .= get_string('unreadpostsone', 'forum'); } else { $out .= get_string('unreadpostsnumber', 'forum', $unread); } diff --git a/mod/forum/mod_form.php b/mod/forum/mod_form.php index 70c8f628c53..a702cdb76c0 100644 --- a/mod/forum/mod_form.php +++ b/mod/forum/mod_form.php @@ -86,10 +86,16 @@ class mod_forum_mod_form extends moodleform_mod { $options = array(); $options[FORUM_TRACKING_OPTIONAL] = get_string('trackingoptional', 'forum'); $options[FORUM_TRACKING_OFF] = get_string('trackingoff', 'forum'); - $options[FORUM_TRACKING_ON] = get_string('trackingon', 'forum'); + if ($CFG->forum_allowforcedreadtracking) { + $options[FORUM_TRACKING_ON] = get_string('trackingon', 'forum'); + } $mform->addElement('select', 'trackingtype', get_string('trackingtype', 'forum'), $options); $mform->addHelpButton('trackingtype', 'trackingtype', 'forum'); - $mform->setDefault('trackingtype', $CFG->forum_trackingtype); + $default = $CFG->forum_trackingtype; + if ((!$CFG->forum_allowforcedreadtracking) && ($default == FORUM_TRACKING_ON)) { + $default = FORUM_TRACKING_OPTIONAL; + } + $mform->setDefault('trackingtype', $default); if ($CFG->enablerssfeeds && isset($CFG->forum_enablerssfeeds) && $CFG->forum_enablerssfeeds) { //------------------------------------------------------------------------------- diff --git a/mod/forum/settings.php b/mod/forum/settings.php index b6bf51d4f66..adc80cedc9a 100644 --- a/mod/forum/settings.php +++ b/mod/forum/settings.php @@ -69,6 +69,10 @@ if ($ADMIN->fulltree) { $settings->add(new admin_setting_configcheckbox('forum_trackreadposts', get_string('trackforum', 'forum'), get_string('configtrackreadposts', 'forum'), 1)); + // Default whether user needs to mark a post as read. + $settings->add(new admin_setting_configcheckbox('forum_allowforcedreadtracking', get_string('forcedreadtracking', 'forum'), + get_string('forcedreadtracking_desc', 'forum'), 0)); + // Default number of days that a post is considered old $settings->add(new admin_setting_configtext('forum_oldpostdays', get_string('oldpostdays', 'forum'), get_string('configoldpostdays', 'forum'), 14, PARAM_INT)); diff --git a/mod/forum/tests/behat/track_read_posts.feature b/mod/forum/tests/behat/track_read_posts.feature index 2b9c33499d8..d08ce1d7567 100644 --- a/mod/forum/tests/behat/track_read_posts.feature +++ b/mod/forum/tests/behat/track_read_posts.feature @@ -8,37 +8,18 @@ Feature: A teacher can set one of 3 possible options for tracking read forum pos Given the following "users" exists: | username | firstname | lastname | email | trackforums | | student1 | Student | 1 | student1@asd.com | 1 | + | student2 | Student | 2 | student2@asd.com | 0 | And the following "courses" exists: | fullname | shortname | category | | Course 1 | C1 | 0 | And the following "course enrolments" exists: | user | course | role | | student1 | C1 | student | + | student2 | C1 | student | And I log in as "admin" And I follow "Course 1" And I turn editing mode on - @javascript - Scenario: Tracking forum posts on - Given I add a "Forum" to section "1" and I fill the form with: - | Forum name | Test forum name | - | Forum type | Standard forum for general use | - | Description | Test forum description | - | Read tracking | On | - And I add a new discussion to "Test forum name" forum with: - | Subject | Test post subject | - | Message | Test post message | - And I wait "6" seconds - And I log out - When I log in as "student1" - And I follow "Course 1" - Then I should see "1 unread post" - And I follow "1 unread post" - And I should not see "Don't track unread posts" - And I follow "Test post subject" - And I follow "Course 1" - And I should not see "1 unread post" - @javascript Scenario: Tracking forum posts off Given I add a "Forum" to section "1" and I fill the form with: @@ -58,7 +39,7 @@ Feature: A teacher can set one of 3 possible options for tracking read forum pos And I should not see "Track unread posts" @javascript - Scenario: Tracking forum posts optional + Scenario: Tracking forum posts optional with user tracking on Given I add a "Forum" to section "1" and I fill the form with: | Forum name | Test forum name | | Forum type | Standard forum for general use | @@ -83,3 +64,128 @@ Feature: A teacher can set one of 3 possible options for tracking read forum pos And I follow "1" And I follow "Course 1" And I should not see "1 unread post" + + @javascript + Scenario: Tracking forum posts optional with user tracking off + Given I add a "Forum" to section "1" and I fill the form with: + | Forum name | Test forum name | + | Forum type | Standard forum for general use | + | Description | Test forum description | + | Read tracking | Optional | + And I add a new discussion to "Test forum name" forum with: + | Subject | Test post subject | + | Message | Test post message | + And I wait "6" seconds + And I log out + When I log in as "student2" + And I follow "Course 1" + Then I should not see "1 unread post" + And I follow "Test forum name" + And I should not see "Track unread posts" + + @javascript + Scenario: Tracking forum posts forced with user tracking on + And I set the following administration settings values: + | Allow forced read tracking | 1 | + And I follow "Home" + And I follow "Course 1" + Given I add a "Forum" to section "1" and I fill the form with: + | Forum name | Test forum name | + | Forum type | Standard forum for general use | + | Description | Test forum description | + | Read tracking | Force | + And I add a new discussion to "Test forum name" forum with: + | Subject | Test post subject | + | Message | Test post message | + And I wait "6" seconds + And I log out + When I log in as "student1" + And I follow "Course 1" + Then I should see "1 unread post" + And I follow "1 unread post" + And I should not see "Don't track unread posts" + And I follow "Test post subject" + And I follow "Course 1" + And I should not see "1 unread post" + + @javascript + Scenario: Tracking forum posts forced with user tracking off + And I set the following administration settings values: + | Allow forced read tracking | 1 | + And I follow "Home" + And I follow "Course 1" + Given I add a "Forum" to section "1" and I fill the form with: + | Forum name | Test forum name | + | Forum type | Standard forum for general use | + | Description | Test forum description | + | Read tracking | Force | + And I add a new discussion to "Test forum name" forum with: + | Subject | Test post subject | + | Message | Test post message | + And I wait "6" seconds + And I log out + When I log in as "student2" + And I follow "Course 1" + Then I should see "1 unread post" + And I follow "1 unread post" + And I should not see "Don't track unread posts" + And I follow "Test post subject" + And I follow "Course 1" + And I should not see "1 unread post" + + @javascript + Scenario: Tracking forum posts forced (with force disabled) with user tracking on + And I set the following administration settings values: + | Allow forced read tracking | 1 | + And I follow "Home" + And I follow "Course 1" + Given I add a "Forum" to section "1" and I fill the form with: + | Forum name | Test forum name | + | Forum type | Standard forum for general use | + | Description | Test forum description | + | Read tracking | Force | + And I add a new discussion to "Test forum name" forum with: + | Subject | Test post subject | + | Message | Test post message | + And I wait "6" seconds + And I set the following administration settings values: + | Allow forced read tracking | 0 | + And I log out + When I log in as "student1" + And I follow "Course 1" + Then I should see "1 unread post" + And I follow "Test forum name" + And I follow "Don't track unread posts" + And I wait "4" seconds + And I follow "Course 1" + And I should not see "1 unread post" + And I follow "Test forum name" + And I follow "Track unread posts" + And I wait "4" seconds + And I follow "1" + And I follow "Course 1" + And I should not see "1 unread post" + + @javascript + Scenario: Tracking forum posts forced (with force disabled) with user tracking off + And I set the following administration settings values: + | Allow forced read tracking | 1 | + And I follow "Home" + And I follow "Course 1" + Given I add a "Forum" to section "1" and I fill the form with: + | Forum name | Test forum name | + | Forum type | Standard forum for general use | + | Description | Test forum description | + | Read tracking | Force | + And I add a new discussion to "Test forum name" forum with: + | Subject | Test post subject | + | Message | Test post message | + And I wait "6" seconds + And I set the following administration settings values: + | Allow forced read tracking | 0 | + And I log out + When I log in as "student2" + And I follow "Course 1" + Then I should not see "1 unread post" + And I follow "Test forum name" + And I should not see "Track unread posts" diff --git a/mod/forum/tests/lib_test.php b/mod/forum/tests/lib_test.php index d5bfb7a8f07..8806af1ea38 100644 --- a/mod/forum/tests/lib_test.php +++ b/mod/forum/tests/lib_test.php @@ -181,7 +181,7 @@ class mod_forum_lib_testcase extends advanced_testcase { $user1 = $this->getDataGenerator()->create_user(); $course1 = $this->getDataGenerator()->create_course(); $course2 = $this->getDataGenerator()->create_course(); - $student = $DB->get_record('role', array('shortname'=>'student')); + $student = $DB->get_record('role', array('shortname' => 'student')); $e1 = $metaplugin->add_instance($course2, array('customint1' => $course1->id)); $enrol1 = $DB->get_record('enrol', array('id' => $e1)); @@ -201,4 +201,410 @@ class mod_forum_lib_testcase extends advanced_testcase { $this->assertInstanceOf('\core\event\user_enrolment_deleted', $event); $this->assertEquals('user_unenrolled', $event->get_legacy_eventname()); } + + /** + * Test the logic in the forum_tp_can_track_forums() function. + */ + public function test_forum_tp_can_track_forums() { + global $CFG; + + $this->resetAfterTest(); + + $useron = $this->getDataGenerator()->create_user(array('trackforums' => 1)); + $useroff = $this->getDataGenerator()->create_user(array('trackforums' => 0)); + $course = $this->getDataGenerator()->create_course(); + $options = array('course' => $course->id, 'trackingtype' => FORUM_TRACKING_OFF); // Off. + $forumoff = $this->getDataGenerator()->create_module('forum', $options); + + $options = array('course' => $course->id, 'trackingtype' => FORUM_TRACKING_ON); // On. + $forumforce = $this->getDataGenerator()->create_module('forum', $options); + + $options = array('course' => $course->id, 'trackingtype' => FORUM_TRACKING_OPTIONAL); // Optional. + $forumoptional = $this->getDataGenerator()->create_module('forum', $options); + + // Allow force. + $CFG->forum_allowforcedreadtracking = 1; + + // User on, forum off, should be off. + $result = forum_tp_can_track_forums($forumoff, $useron); + $this->assertEquals(false, $result); + + // User on, forum on, should be on. + $result = forum_tp_can_track_forums($forumforce, $useron); + $this->assertEquals(true, $result); + + // User on, forum optional, should be on. + $result = forum_tp_can_track_forums($forumoptional, $useron); + $this->assertEquals(true, $result); + + // User off, forum off, should be off. + $result = forum_tp_can_track_forums($forumoff, $useroff); + $this->assertEquals(false, $result); + + // User off, forum force, should be on. + $result = forum_tp_can_track_forums($forumforce, $useroff); + $this->assertEquals(true, $result); + + // User off, forum optional, should be off. + $result = forum_tp_can_track_forums($forumoptional, $useroff); + $this->assertEquals(false, $result); + + // Don't allow force. + $CFG->forum_allowforcedreadtracking = 0; + + // User on, forum off, should be off. + $result = forum_tp_can_track_forums($forumoff, $useron); + $this->assertEquals(false, $result); + + // User on, forum on, should be on. + $result = forum_tp_can_track_forums($forumforce, $useron); + $this->assertEquals(true, $result); + + // User on, forum optional, should be on. + $result = forum_tp_can_track_forums($forumoptional, $useron); + $this->assertEquals(true, $result); + + // User off, forum off, should be off. + $result = forum_tp_can_track_forums($forumoff, $useroff); + $this->assertEquals(false, $result); + + // User off, forum force, should be off. + $result = forum_tp_can_track_forums($forumforce, $useroff); + $this->assertEquals(false, $result); + + // User off, forum optional, should be off. + $result = forum_tp_can_track_forums($forumoptional, $useroff); + $this->assertEquals(false, $result); + + } + + /** + * Test the logic in the test_forum_tp_is_tracked() function. + */ + public function test_forum_tp_is_tracked() { + global $CFG; + + $this->resetAfterTest(); + + $useron = $this->getDataGenerator()->create_user(array('trackforums' => 1)); + $useroff = $this->getDataGenerator()->create_user(array('trackforums' => 0)); + $course = $this->getDataGenerator()->create_course(); + $options = array('course' => $course->id, 'trackingtype' => FORUM_TRACKING_OFF); // Off. + $forumoff = $this->getDataGenerator()->create_module('forum', $options); + + $options = array('course' => $course->id, 'trackingtype' => FORUM_TRACKING_ON); // On. + $forumforce = $this->getDataGenerator()->create_module('forum', $options); + + $options = array('course' => $course->id, 'trackingtype' => FORUM_TRACKING_OPTIONAL); // Optional. + $forumoptional = $this->getDataGenerator()->create_module('forum', $options); + + // Allow force. + $CFG->forum_allowforcedreadtracking = 1; + + // User on, forum off, should be off. + $result = forum_tp_is_tracked($forumoff, $useron); + $this->assertEquals(false, $result); + + // User on, forum force, should be on. + $result = forum_tp_is_tracked($forumforce, $useron); + $this->assertEquals(true, $result); + + // User on, forum optional, should be on. + $result = forum_tp_is_tracked($forumoptional, $useron); + $this->assertEquals(true, $result); + + // User off, forum off, should be off. + $result = forum_tp_is_tracked($forumoff, $useroff); + $this->assertEquals(false, $result); + + // User off, forum force, should be on. + $result = forum_tp_is_tracked($forumforce, $useroff); + $this->assertEquals(true, $result); + + // User off, forum optional, should be off. + $result = forum_tp_is_tracked($forumoptional, $useroff); + $this->assertEquals(false, $result); + + // Don't allow force. + $CFG->forum_allowforcedreadtracking = 0; + + // User on, forum off, should be off. + $result = forum_tp_is_tracked($forumoff, $useron); + $this->assertEquals(false, $result); + + // User on, forum force, should be on. + $result = forum_tp_is_tracked($forumforce, $useron); + $this->assertEquals(true, $result); + + // User on, forum optional, should be on. + $result = forum_tp_is_tracked($forumoptional, $useron); + $this->assertEquals(true, $result); + + // User off, forum off, should be off. + $result = forum_tp_is_tracked($forumoff, $useroff); + $this->assertEquals(false, $result); + + // User off, forum force, should be off. + $result = forum_tp_is_tracked($forumforce, $useroff); + $this->assertEquals(false, $result); + + // User off, forum optional, should be off. + $result = forum_tp_is_tracked($forumoptional, $useroff); + $this->assertEquals(false, $result); + + // Stop tracking so we can test again. + forum_tp_stop_tracking($forumforce->id, $useron->id); + forum_tp_stop_tracking($forumoptional->id, $useron->id); + forum_tp_stop_tracking($forumforce->id, $useroff->id); + forum_tp_stop_tracking($forumoptional->id, $useroff->id); + + // Allow force. + $CFG->forum_allowforcedreadtracking = 1; + + // User on, preference off, forum force, should be on. + $result = forum_tp_is_tracked($forumforce, $useron); + $this->assertEquals(true, $result); + + // User on, preference off, forum optional, should be on. + $result = forum_tp_is_tracked($forumoptional, $useron); + $this->assertEquals(false, $result); + + // User off, preference off, forum force, should be on. + $result = forum_tp_is_tracked($forumforce, $useroff); + $this->assertEquals(true, $result); + + // User off, preference off, forum optional, should be off. + $result = forum_tp_is_tracked($forumoptional, $useroff); + $this->assertEquals(false, $result); + + // Don't allow force. + $CFG->forum_allowforcedreadtracking = 0; + + // User on, preference off, forum force, should be on. + $result = forum_tp_is_tracked($forumforce, $useron); + $this->assertEquals(false, $result); + + // User on, preference off, forum optional, should be on. + $result = forum_tp_is_tracked($forumoptional, $useron); + $this->assertEquals(false, $result); + + // User off, preference off, forum force, should be off. + $result = forum_tp_is_tracked($forumforce, $useroff); + $this->assertEquals(false, $result); + + // User off, preference off, forum optional, should be off. + $result = forum_tp_is_tracked($forumoptional, $useroff); + $this->assertEquals(false, $result); + } + + /** + * Test the logic in the forum_tp_get_course_unread_posts() function. + */ + public function test_forum_tp_get_course_unread_posts() { + global $CFG; + + $this->resetAfterTest(); + + $useron = $this->getDataGenerator()->create_user(array('trackforums' => 1)); + $useroff = $this->getDataGenerator()->create_user(array('trackforums' => 0)); + $course = $this->getDataGenerator()->create_course(); + $options = array('course' => $course->id, 'trackingtype' => FORUM_TRACKING_OFF); // Off. + $forumoff = $this->getDataGenerator()->create_module('forum', $options); + + $options = array('course' => $course->id, 'trackingtype' => FORUM_TRACKING_ON); // On. + $forumforce = $this->getDataGenerator()->create_module('forum', $options); + + $options = array('course' => $course->id, 'trackingtype' => FORUM_TRACKING_OPTIONAL); // Optional. + $forumoptional = $this->getDataGenerator()->create_module('forum', $options); + + // Add discussions to the tracking off forum. + $record = new stdClass(); + $record->course = $course->id; + $record->userid = $useron->id; + $record->forum = $forumoff->id; + $discussionoff = $this->getDataGenerator()->get_plugin_generator('mod_forum')->create_discussion($record); + + // Add discussions to the tracking forced forum. + $record = new stdClass(); + $record->course = $course->id; + $record->userid = $useron->id; + $record->forum = $forumforce->id; + $discussionforce = $this->getDataGenerator()->get_plugin_generator('mod_forum')->create_discussion($record); + + // Add post to the tracking forced discussion. + $record = new stdClass(); + $record->course = $course->id; + $record->userid = $useroff->id; + $record->forum = $forumforce->id; + $record->discussion = $discussionforce->id; + $this->getDataGenerator()->get_plugin_generator('mod_forum')->create_post($record); + + // Add discussions to the tracking optional forum. + $record = new stdClass(); + $record->course = $course->id; + $record->userid = $useron->id; + $record->forum = $forumoptional->id; + $discussionoptional = $this->getDataGenerator()->get_plugin_generator('mod_forum')->create_discussion($record); + + // Allow force. + $CFG->forum_allowforcedreadtracking = 1; + + $result = forum_tp_get_course_unread_posts($useron->id, $course->id); + $this->assertEquals(2, count($result)); + $this->assertEquals(false, isset($result[$forumoff->id])); + $this->assertEquals(true, isset($result[$forumforce->id])); + $this->assertEquals(2, $result[$forumforce->id]->unread); + $this->assertEquals(true, isset($result[$forumoptional->id])); + $this->assertEquals(1, $result[$forumoptional->id]->unread); + + $result = forum_tp_get_course_unread_posts($useroff->id, $course->id); + $this->assertEquals(1, count($result)); + $this->assertEquals(false, isset($result[$forumoff->id])); + $this->assertEquals(true, isset($result[$forumforce->id])); + $this->assertEquals(2, $result[$forumforce->id]->unread); + $this->assertEquals(false, isset($result[$forumoptional->id])); + + // Don't allow force. + $CFG->forum_allowforcedreadtracking = 0; + + $result = forum_tp_get_course_unread_posts($useron->id, $course->id); + $this->assertEquals(2, count($result)); + $this->assertEquals(false, isset($result[$forumoff->id])); + $this->assertEquals(true, isset($result[$forumforce->id])); + $this->assertEquals(2, $result[$forumforce->id]->unread); + $this->assertEquals(true, isset($result[$forumoptional->id])); + $this->assertEquals(1, $result[$forumoptional->id]->unread); + + $result = forum_tp_get_course_unread_posts($useroff->id, $course->id); + $this->assertEquals(0, count($result)); + $this->assertEquals(false, isset($result[$forumoff->id])); + $this->assertEquals(false, isset($result[$forumforce->id])); + $this->assertEquals(false, isset($result[$forumoptional->id])); + + // Stop tracking so we can test again. + forum_tp_stop_tracking($forumforce->id, $useron->id); + forum_tp_stop_tracking($forumoptional->id, $useron->id); + forum_tp_stop_tracking($forumforce->id, $useroff->id); + forum_tp_stop_tracking($forumoptional->id, $useroff->id); + + // Allow force. + $CFG->forum_allowforcedreadtracking = 1; + + $result = forum_tp_get_course_unread_posts($useron->id, $course->id); + $this->assertEquals(1, count($result)); + $this->assertEquals(false, isset($result[$forumoff->id])); + $this->assertEquals(true, isset($result[$forumforce->id])); + $this->assertEquals(2, $result[$forumforce->id]->unread); + $this->assertEquals(false, isset($result[$forumoptional->id])); + + $result = forum_tp_get_course_unread_posts($useroff->id, $course->id); + $this->assertEquals(1, count($result)); + $this->assertEquals(false, isset($result[$forumoff->id])); + $this->assertEquals(true, isset($result[$forumforce->id])); + $this->assertEquals(2, $result[$forumforce->id]->unread); + $this->assertEquals(false, isset($result[$forumoptional->id])); + + // Don't allow force. + $CFG->forum_allowforcedreadtracking = 0; + + $result = forum_tp_get_course_unread_posts($useron->id, $course->id); + $this->assertEquals(0, count($result)); + $this->assertEquals(false, isset($result[$forumoff->id])); + $this->assertEquals(false, isset($result[$forumforce->id])); + $this->assertEquals(false, isset($result[$forumoptional->id])); + + $result = forum_tp_get_course_unread_posts($useroff->id, $course->id); + $this->assertEquals(0, count($result)); + $this->assertEquals(false, isset($result[$forumoff->id])); + $this->assertEquals(false, isset($result[$forumforce->id])); + $this->assertEquals(false, isset($result[$forumoptional->id])); + } + + /** + * Test the logic in the test_forum_tp_get_untracked_forums() function. + */ + public function test_forum_tp_get_untracked_forums() { + global $CFG; + + $this->resetAfterTest(); + + $useron = $this->getDataGenerator()->create_user(array('trackforums' => 1)); + $useroff = $this->getDataGenerator()->create_user(array('trackforums' => 0)); + $course = $this->getDataGenerator()->create_course(); + $options = array('course' => $course->id, 'trackingtype' => FORUM_TRACKING_OFF); // Off. + $forumoff = $this->getDataGenerator()->create_module('forum', $options); + + $options = array('course' => $course->id, 'trackingtype' => FORUM_TRACKING_ON); // On. + $forumforce = $this->getDataGenerator()->create_module('forum', $options); + + $options = array('course' => $course->id, 'trackingtype' => FORUM_TRACKING_OPTIONAL); // Optional. + $forumoptional = $this->getDataGenerator()->create_module('forum', $options); + + // Allow force. + $CFG->forum_allowforcedreadtracking = 1; + + // On user with force on. + $result = forum_tp_get_untracked_forums($useron->id, $course->id); + $this->assertEquals(1, count($result)); + $this->assertEquals(true, isset($result[$forumoff->id])); + + // Off user with force on. + $result = forum_tp_get_untracked_forums($useroff->id, $course->id); + $this->assertEquals(2, count($result)); + $this->assertEquals(true, isset($result[$forumoff->id])); + $this->assertEquals(true, isset($result[$forumoptional->id])); + + // Don't allow force. + $CFG->forum_allowforcedreadtracking = 0; + + // On user with force off. + $result = forum_tp_get_untracked_forums($useron->id, $course->id); + $this->assertEquals(1, count($result)); + $this->assertEquals(true, isset($result[$forumoff->id])); + + // Off user with force off. + $result = forum_tp_get_untracked_forums($useroff->id, $course->id); + $this->assertEquals(3, count($result)); + $this->assertEquals(true, isset($result[$forumoff->id])); + $this->assertEquals(true, isset($result[$forumoptional->id])); + $this->assertEquals(true, isset($result[$forumforce->id])); + + // Stop tracking so we can test again. + forum_tp_stop_tracking($forumforce->id, $useron->id); + forum_tp_stop_tracking($forumoptional->id, $useron->id); + forum_tp_stop_tracking($forumforce->id, $useroff->id); + forum_tp_stop_tracking($forumoptional->id, $useroff->id); + + // Allow force. + $CFG->forum_allowforcedreadtracking = 1; + + // On user with force on. + $result = forum_tp_get_untracked_forums($useron->id, $course->id); + $this->assertEquals(2, count($result)); + $this->assertEquals(true, isset($result[$forumoff->id])); + $this->assertEquals(true, isset($result[$forumoptional->id])); + + // Off user with force on. + $result = forum_tp_get_untracked_forums($useroff->id, $course->id); + $this->assertEquals(2, count($result)); + $this->assertEquals(true, isset($result[$forumoff->id])); + $this->assertEquals(true, isset($result[$forumoptional->id])); + + // Don't allow force. + $CFG->forum_allowforcedreadtracking = 0; + + // On user with force off. + $result = forum_tp_get_untracked_forums($useron->id, $course->id); + $this->assertEquals(3, count($result)); + $this->assertEquals(true, isset($result[$forumoff->id])); + $this->assertEquals(true, isset($result[$forumoptional->id])); + $this->assertEquals(true, isset($result[$forumforce->id])); + + // Off user with force off. + $result = forum_tp_get_untracked_forums($useroff->id, $course->id); + $this->assertEquals(3, count($result)); + $this->assertEquals(true, isset($result[$forumoff->id])); + $this->assertEquals(true, isset($result[$forumoptional->id])); + $this->assertEquals(true, isset($result[$forumforce->id])); + } }