diff --git a/blocks/online_users/amd/build/change_user_visibility.min.js b/blocks/online_users/amd/build/change_user_visibility.min.js new file mode 100644 index 00000000000..f45ae5b30d8 --- /dev/null +++ b/blocks/online_users/amd/build/change_user_visibility.min.js @@ -0,0 +1 @@ +define(["jquery","core/ajax","core/str","core/notification"],function(a,b,c,d){var e={CHANGE_VISIBILITY_LINK:"#change-user-visibility",CHANGE_VISIBILITY_ICON:"#change-user-visibility .icon"},f=function(a,c){var e="show"==a?1:0,f=[{name:"block_online_users_uservisibility",value:e,userid:c}],j={methodname:"core_user_set_user_preferences",args:{preferences:f}};b.call([j])[0].then(function(b){if(b.saved){var c=g(a);h(c),i(c)}})["catch"](d.exception)},g=function(a){return"show"==a?"hide":"show"},h=function(b){k(b).then(function(c){a(e.CHANGE_VISIBILITY_LINK).attr({"data-action":b,title:c})})["catch"](d.exception)},i=function(b){var c=a(e.CHANGE_VISIBILITY_ICON);k(b).then(function(d){a(c).attr({title:d,"aria-label":d}),c.is("img")?a(c).attr({src:M.util.image_url("t/"+b),alt:d}):(a(c).addClass(j(b)),a(c).removeClass(j(g(b))))})["catch"](d.exception)},j=function(a){return"show"==a?"fa-eye-slash":"fa-eye"},k=function(a){return c.get_string("online_status:"+a,"block_online_users")};return{init:function(){a(e.CHANGE_VISIBILITY_LINK).on("click",function(b){b.preventDefault();var c=a(this).attr("data-action"),d=a(this).attr("data-userid");f(c,d)})}}}); \ No newline at end of file diff --git a/blocks/online_users/amd/src/change_user_visibility.js b/blocks/online_users/amd/src/change_user_visibility.js new file mode 100644 index 00000000000..4fbed820fdd --- /dev/null +++ b/blocks/online_users/amd/src/change_user_visibility.js @@ -0,0 +1,171 @@ +// This file is part of Moodle - http://moodle.org/ +// +// Moodle is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Moodle is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Moodle. If not, see . + +/** + * A javascript module that handles the change of the user's visibility in the + * online users block. + * + * @module block_online_users/change_user_visibility + * @package block_online_users + * @copyright 2018 Mihail Geshoski + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +define(['jquery', 'core/ajax', 'core/str', 'core/notification'], + function($, Ajax, Str, Notification) { + + /** + * Selectors. + * + * @access private + * @type {Object} + */ + var SELECTORS = { + CHANGE_VISIBILITY_LINK: '#change-user-visibility', + CHANGE_VISIBILITY_ICON: '#change-user-visibility .icon' + }; + + /** + * Change user visibility in the online users block. + * + * @method changeVisibility + * @param {String} action + * @param {String} userid + * @private + */ + var changeVisibility = function(action, userid) { + + var value = action == "show" ? 1 : 0; + var preferences = [{ + 'name': 'block_online_users_uservisibility', + 'value': value, + 'userid': userid + }]; + + var request = { + methodname: 'core_user_set_user_preferences', + args: { + preferences: preferences + } + }; + Ajax.call([request])[0].then(function(data) { + if (data.saved) { + var newAction = oppositeAction(action); + changeVisibilityLinkAttr(newAction); + changeVisibilityIconAttr(newAction); + } + return; + }).catch(Notification.exception); + }; + + /** + * Get the opposite action. + * + * @method oppositeAction + * @param {String} action + * @return {String} + * @private + */ + var oppositeAction = function(action) { + return action == 'show' ? 'hide' : 'show'; + }; + + /** + * Change the attribute values of the user visibility link in the online users block. + * + * @method changeVisibilityLinkAttr + * @param {String} action + * @private + */ + var changeVisibilityLinkAttr = function(action) { + getTitle(action).then(function(title) { + $(SELECTORS.CHANGE_VISIBILITY_LINK).attr({ + 'data-action': action, + 'title': title + }); + return; + }).catch(Notification.exception); + }; + + /** + * Change the attribute values of the user visibility icon in the online users block. + * + * @method changeVisibilityIconAttr + * @param {String} action + * @private + */ + var changeVisibilityIconAttr = function(action) { + var icon = $(SELECTORS.CHANGE_VISIBILITY_ICON); + getTitle(action).then(function(title) { + // Add the proper title to the icon. + $(icon).attr({ + 'title': title, + 'aria-label': title + }); + // If the icon is an image. + if (icon.is("img")) { + $(icon).attr({ + 'src': M.util.image_url('t/' + action), + 'alt': title + }); + } else { + // Add the new icon class and remove the old one. + $(icon).addClass(getIconClass(action)); + $(icon).removeClass(getIconClass(oppositeAction(action))); + } + return; + }).catch(Notification.exception); + }; + + /** + * Get the proper class for the user visibility icon in the online users block. + * + * @method getIconClass + * @param {String} action + * @return {String} + * @private + */ + var getIconClass = function(action) { + return action == 'show' ? 'fa-eye-slash' : 'fa-eye'; + }; + + /** + * Get the title description of the user visibility link in the online users block. + * + * @method getTitle + * @param {String} action + * @return {object} jQuery promise + * @private + */ + var getTitle = function(action) { + return Str.get_string('online_status:' + action, 'block_online_users'); + }; + + return { + // Public variables and functions. + /** + * Initialise change user visibility function. + * + * @method init + */ + init: function() { + $(SELECTORS.CHANGE_VISIBILITY_LINK).on('click', function(e) { + e.preventDefault(); + var action = ($(this).attr('data-action')); + var userid = ($(this).attr('data-userid')); + changeVisibility(action, userid); + }); + } + }; +}); diff --git a/blocks/online_users/block_online_users.php b/blocks/online_users/block_online_users.php index 08521a3069e..01ada957dad 100644 --- a/blocks/online_users/block_online_users.php +++ b/blocks/online_users/block_online_users.php @@ -105,6 +105,7 @@ class block_online_users extends block_base { //Now, we have in users, the list of users to show //Because they are online if (!empty($users)) { + $this->page->requires->js_call_amd('block_online_users/change_user_visibility', 'init'); //Accessibility: Don't want 'Alt' text for the user picture; DO want it for the envelope/message link (existing lang string). //Accessibility: Converted
to
    , inherit existing classes & styles. $this->content->text .= "
      \n"; @@ -122,18 +123,30 @@ class block_online_users extends block_base { $this->content->text .= '
      '.$OUTPUT->user_picture($user, array('size'=>16, 'alttext'=>false)); $this->content->text .= get_string('guestuser').'
      '; - } else { + } else { // Not a guest user. $this->content->text .= ''; - } - if ($canshowicon and ($USER->id != $user->id) and !isguestuser($user)) { // Only when logged in and messaging active etc - $anchortagcontents = $OUTPUT->pix_icon('t/message', get_string('messageselectadd')); - $anchorurl = new moodle_url('/message/index.php', array('id' => $user->id)); - $anchortag = html_writer::link($anchorurl, $anchortagcontents, - array('title' => get_string('messageselectadd'))); - $this->content->text .= '
      '.$anchortag.'
      '; + if ($USER->id == $user->id) { + $action = ($user->uservisibility != null && $user->uservisibility == 0) ? 'show' : 'hide'; + $anchortagcontents = $OUTPUT->pix_icon('t/' . $action, + get_string('online_status:' . $action, 'block_online_users')); + $anchortag = html_writer::link("", $anchortagcontents, + array('title' => get_string('online_status:' . $action, 'block_online_users'), + 'data-action' => $action, 'data-userid' => $user->id, 'id' => 'change-user-visibility')); + + $this->content->text .= '
      ' . $anchortag . '
      '; + } else { + if ($canshowicon) { // Only when logged in and messaging active etc. + $anchortagcontents = $OUTPUT->pix_icon('t/message', get_string('messageselectadd')); + $anchorurl = new moodle_url('/message/index.php', array('id' => $user->id)); + $anchortag = html_writer::link($anchorurl, $anchortagcontents, + array('title' => get_string('messageselectadd'))); + + $this->content->text .= '
      '.$anchortag.'
      '; + } + } } $this->content->text .= "\n"; } diff --git a/blocks/online_users/classes/fetcher.php b/blocks/online_users/classes/fetcher.php index 1c6d15aac3a..20f706f97e2 100644 --- a/blocks/online_users/classes/fetcher.php +++ b/blocks/online_users/classes/fetcher.php @@ -67,6 +67,8 @@ class fetcher { * @param int $courseid The course id to check */ protected function set_sql($currentgroup, $now, $timetoshowusers, $context, $sitelevel, $courseid) { + global $USER, $DB; + $timefrom = 100 * floor(($now - $timetoshowusers) / 100); // Round to nearest 100 seconds for better query cache. $groupmembers = ""; @@ -74,6 +76,7 @@ class fetcher { $groupby = ""; $lastaccess = ", lastaccess"; $timeaccess = ", ul.timeaccess AS lastaccess"; + $uservisibility = ", up.value AS uservisibility"; $params = array(); $userfields = \user_picture::fields('u', array('username')); @@ -85,52 +88,75 @@ class fetcher { $groupby = "GROUP BY $userfields"; $lastaccess = ", MAX(u.lastaccess) AS lastaccess"; $timeaccess = ", MAX(ul.timeaccess) AS lastaccess"; + $uservisibility = ", MAX(up.value) AS uservisibility"; $params['currentgroup'] = $currentgroup; } $params['now'] = $now; $params['timefrom'] = $timefrom; + $params['userid'] = $USER->id; + $params['name'] = 'block_online_users_uservisibility'; + if ($sitelevel) { - $sql = "SELECT $userfields $lastaccess + $sql = "SELECT $userfields $lastaccess $uservisibility FROM {user} u $groupmembers + LEFT JOIN {user_preferences} up ON up.userid = u.id + AND up.name = :name WHERE u.lastaccess > :timefrom AND u.lastaccess <= :now AND u.deleted = 0 + AND (" . $DB->sql_cast_char2int('up.value') . " = 1 + OR up.value IS NULL + OR u.id = :userid) $groupselect $groupby ORDER BY lastaccess DESC "; $csql = "SELECT COUNT(u.id) - FROM {user} u $groupmembers - WHERE u.lastaccess > :timefrom - AND u.lastaccess <= :now - AND u.deleted = 0 - $groupselect"; - + FROM {user} u $groupmembers + LEFT JOIN {user_preferences} up ON up.userid = u.id + AND up.name = :name + WHERE u.lastaccess > :timefrom + AND u.lastaccess <= :now + AND u.deleted = 0 + AND (" . $DB->sql_cast_char2int('up.value') . " = 1 + OR up.value IS NULL + OR u.id = :userid) + $groupselect"; } else { // Course level - show only enrolled users for now. // TODO: add a new capability for viewing of all users (guests+enrolled+viewing). list($esqljoin, $eparams) = get_enrolled_sql($context); $params = array_merge($params, $eparams); - $sql = "SELECT $userfields $timeaccess + $sql = "SELECT $userfields $timeaccess $uservisibility FROM {user_lastaccess} ul $groupmembers, {user} u JOIN ($esqljoin) euj ON euj.id = u.id + LEFT JOIN {user_preferences} up ON up.userid = u.id + AND up.name = :name WHERE ul.timeaccess > :timefrom AND u.id = ul.userid AND ul.courseid = :courseid AND ul.timeaccess <= :now AND u.deleted = 0 + AND (" . $DB->sql_cast_char2int('up.value') . " = 1 + OR up.value IS NULL + OR u.id = :userid) $groupselect $groupby ORDER BY lastaccess DESC"; $csql = "SELECT COUNT(u.id) FROM {user_lastaccess} ul $groupmembers, {user} u JOIN ($esqljoin) euj ON euj.id = u.id + LEFT JOIN {user_preferences} up ON up.userid = u.id + AND up.name = :name WHERE ul.timeaccess > :timefrom AND u.id = ul.userid AND ul.courseid = :courseid AND ul.timeaccess <= :now AND u.deleted = 0 + AND (" . $DB->sql_cast_char2int('up.value') . " = 1 + OR up.value IS NULL + OR u.id = :userid) $groupselect"; $params['courseid'] = $courseid; diff --git a/blocks/online_users/classes/privacy/provider.php b/blocks/online_users/classes/privacy/provider.php index 50d0280bc3f..3f29a8e980c 100644 --- a/blocks/online_users/classes/privacy/provider.php +++ b/blocks/online_users/classes/privacy/provider.php @@ -24,23 +24,47 @@ namespace block_online_users\privacy; +use core_privacy\local\metadata\collection; +use core_privacy\local\request\writer; +use core_privacy\local\request\transform; + defined('MOODLE_INTERNAL') || die(); /** - * Privacy Subsystem for block_online_users implementing null_provider. + * Privacy Subsystem for block_online_users. * * @copyright 2018 Zig Tan * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ -class provider implements \core_privacy\local\metadata\null_provider { +class provider implements + \core_privacy\local\metadata\provider, + \core_privacy\local\request\user_preference_provider { /** - * Get the language string identifier with the component's language - * file to explain why this plugin stores no data. + * Describe all the places where this plugin stores personal data. * - * @return string + * @param collection $collection Collection of items to add metadata to. + * @return collection Collection with our added items. */ - public static function get_reason() : string { - return 'privacy:metadata'; + public static function get_metadata(collection $collection) : collection { + + $collection->add_user_preference('block_online_users_uservisibility', + 'privacy:metadata:preference:uservisibility'); + + return $collection; + } + + /** + * Export user preferences controlled by this plugin. + * + * @param int $userid ID of the user we are exporting data form. + */ + public static function export_user_preferences(int $userid) { + + $uservisibility = get_user_preferences('block_online_users_uservisibility', 1, $userid); + + writer::export_user_preference('block_online_users', + 'block_online_users_uservisibility', transform::yesno($uservisibility), + get_string('privacy:metadata:preference:uservisibility', 'block_online_users')); } } diff --git a/blocks/online_users/lang/en/block_online_users.php b/blocks/online_users/lang/en/block_online_users.php index ff79ce502b6..c6bc0223f1a 100644 --- a/blocks/online_users/lang/en/block_online_users.php +++ b/blocks/online_users/lang/en/block_online_users.php @@ -30,7 +30,9 @@ $string['numusers'] = '{$a} online users'; $string['online_users:addinstance'] = 'Add a new online users block'; $string['online_users:myaddinstance'] = 'Add a new online users block to Dashboard'; $string['online_users:viewlist'] = 'View list of online users'; +$string['online_status:hide'] = 'Hide my online status from other users'; +$string['online_status:show'] = 'Show my online status to other users'; $string['periodnminutes'] = 'last {$a} minutes'; $string['pluginname'] = 'Online users'; $string['timetosee'] = 'Remove after inactivity (minutes)'; -$string['privacy:metadata'] = 'The Online users block only shows data stored in other locations.'; +$string['privacy:metadata:preference:uservisibility'] = 'Online status visible to other users in the Online users block.'; diff --git a/blocks/online_users/lib.php b/blocks/online_users/lib.php new file mode 100644 index 00000000000..0c760803630 --- /dev/null +++ b/blocks/online_users/lib.php @@ -0,0 +1,46 @@ +. + +/** + * Contains functions called by core. + * + * @package block_online_users + * @copyright 2018 Mihail Geshoski + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +defined('MOODLE_INTERNAL') || die(); + +/** + * Callback to define user preferences. + * + * @return array + */ +function block_online_users_user_preferences() { + $preferences = array(); + $preferences['block_online_users_uservisibility'] = array( + 'type' => PARAM_INT, + 'null' => NULL_NOT_ALLOWED, + 'default' => 1, + 'choices' => array(0, 1), + 'permissioncallback' => function($user, $preferencename) { + global $USER; + return $user->id == $USER->id; + } + ); + + return $preferences; +} diff --git a/blocks/online_users/styles.css b/blocks/online_users/styles.css index 90be20393c0..bebee5abc1b 100644 --- a/blocks/online_users/styles.css +++ b/blocks/online_users/styles.css @@ -11,7 +11,8 @@ vertical-align: text-bottom; } -.block_online_users .content .list li.listentry .message { +.block_online_users .content .list li.listentry .message, +.block_online_users .content .list li.listentry .uservisibility { float: right; margin-top: 3px; } diff --git a/blocks/online_users/tests/behat/block_online_users_course.feature b/blocks/online_users/tests/behat/block_online_users_course.feature index e86e4d8c1e0..20b0d950f1e 100644 --- a/blocks/online_users/tests/behat/block_online_users_course.feature +++ b/blocks/online_users/tests/behat/block_online_users_course.feature @@ -39,3 +39,35 @@ Feature: The online users block allow you to see who is currently online And I should see "Student 1" in the "Online users" "block" And I should not see "Student 2" in the "Online users" "block" And I should see "2 online users" in the "Online users" "block" + + @javascript + Scenario: Hide/show user's online status from/to other users in the online users block on course page + Given I log in as "teacher1" + And I am on "Course 1" course homepage with editing mode on + And I add the "Online users" block + And I log out + When I log in as "student1" + And I am on "Course 1" course homepage + Then "Hide" "icon" should exist in the "#change-user-visibility" "css_element" + When I click on "#change-user-visibility" "css_element" + And I wait "1" seconds + Then "Show" "icon" should exist in the "#change-user-visibility" "css_element" + And I log out + When I log in as "teacher1" + And I am on "Course 1" course homepage + Then I should see "1 online user" in the "Online users" "block" + And I should see "Teacher 1" in the "Online users" "block" + And I should not see "Student 1" in the "Online users" "block" + And I log out + When I log in as "student1" + And I am on "Course 1" course homepage + Then "Show" "icon" should exist in the "#change-user-visibility" "css_element" + When I click on "#change-user-visibility" "css_element" + And I wait "1" seconds + Then "Hide" "icon" should exist in the "#change-user-visibility" "css_element" + And I log out + When I log in as "teacher1" + And I am on "Course 1" course homepage + Then I should see "2 online users" in the "Online users" "block" + And I should see "Teacher 1" in the "Online users" "block" + And I should see "Student 1" in the "Online users" "block" diff --git a/blocks/online_users/tests/behat/block_online_users_dashboard.feature b/blocks/online_users/tests/behat/block_online_users_dashboard.feature index 34207c5cdea..0d01207a605 100644 --- a/blocks/online_users/tests/behat/block_online_users_dashboard.feature +++ b/blocks/online_users/tests/behat/block_online_users_dashboard.feature @@ -26,3 +26,29 @@ Feature: The online users block allow you to see who is currently online on dash And I should see "Student 1" in the "Online users" "block" And I should see "Student 2" in the "Online users" "block" And I should see "3 online users" in the "Online users" "block" + + @javascript + Scenario: Hide/show user's online status from/to other users in the online users block on dashboard + Given I log in as "student1" + And I should see "1 online user" in the "Online users" "block" + And I should see "Student 1" in the "Online users" "block" + And "Hide" "icon" should exist in the "#change-user-visibility" "css_element" + When I click on "#change-user-visibility" "css_element" + And I wait "1" seconds + Then "Show" "icon" should exist in the "#change-user-visibility" "css_element" + And I log out + When I log in as "student2" + Then I should see "1 online user" in the "Online users" "block" + And I should see "Student 2" in the "Online users" "block" + And I should not see "Student 1" in the "Online users" "block" + And I log out + When I log in as "student1" + Then "Show" "icon" should exist in the "#change-user-visibility" "css_element" + When I click on "#change-user-visibility" "css_element" + And I wait "1" seconds + Then "Hide" "icon" should exist in the "#change-user-visibility" "css_element" + And I log out + When I log in as "student2" + Then I should see "2 online users" in the "Online users" "block" + And I should see "Student 2" in the "Online users" "block" + And I should see "Student 1" in the "Online users" "block" diff --git a/blocks/online_users/tests/behat/block_online_users_frontpage.feature b/blocks/online_users/tests/behat/block_online_users_frontpage.feature index 6237d3d436f..0c5bbddaf9e 100644 --- a/blocks/online_users/tests/behat/block_online_users_frontpage.feature +++ b/blocks/online_users/tests/behat/block_online_users_frontpage.feature @@ -49,3 +49,38 @@ Feature: The online users block allow you to see who is currently online on fron And I should see "Student 1" in the "Online users" "block" And I should see "Student 2" in the "Online users" "block" And I should see "3 online users" in the "Online users" "block" + + @javascript + Scenario: Hide/show user's online status from/to other users in the online users block on front page + Given I log in as "admin" + And I am on site homepage + And I navigate to "Turn editing on" node in "Front page settings" + And I add the "Online users" block + And I log out + When I log in as "student1" + And I am on site homepage + Then "Hide" "icon" should exist in the "#change-user-visibility" "css_element" + When I click on "#change-user-visibility" "css_element" + And I wait "1" seconds + Then "Show" "icon" should exist in the "#change-user-visibility" "css_element" + And I log out + When I log in as "student2" + And I am on site homepage + Then I should see "2 online user" in the "Online users" "block" + And I should see "Admin" in the "Online users" "block" + And I should see "Student 2" in the "Online users" "block" + And I should not see "Student 1" in the "Online users" "block" + And I log out + When I log in as "student1" + And I am on site homepage + Then "Show" "icon" should exist in the "#change-user-visibility" "css_element" + When I click on "#change-user-visibility" "css_element" + And I wait "1" seconds + Then "Hide" "icon" should exist in the "#change-user-visibility" "css_element" + And I log out + When I log in as "student2" + And I am on site homepage + Then I should see "3 online users" in the "Online users" "block" + And I should see "Admin" in the "Online users" "block" + And I should see "Student 2" in the "Online users" "block" + And I should see "Student 1" in the "Online users" "block" diff --git a/blocks/online_users/tests/online_users_test.php b/blocks/online_users/tests/online_users_test.php index 9ff1e3cb14d..946e456fbed 100644 --- a/blocks/online_users/tests/online_users_test.php +++ b/blocks/online_users/tests/online_users_test.php @@ -148,4 +148,134 @@ class block_online_users_testcase extends advanced_testcase { $this->assertEquals($usercount, count($users), 'There was a problem counting the number of online users at site level'); $this->assertEquals(12, $usercount, 'There was a problem counting the number of online users at site level'); } + + /** + * Check user visibility setting for course group members. + */ + public function test_user_visibility_course1_group1_members() { + global $CFG; + + $groupid = $this->data['group1']->id; + $now = time(); + $timetoshowusers = $CFG->block_online_users_timetosee * 60; + $context = context_course::instance($this->data['course1']->id); + $courseid = $this->data['course1']->id; + $user1 = $this->data['user1']; + $user2 = $this->data['user2']; + // Set user2 as logged user. + $this->setUser($user2); + $onlineusers = new fetcher($groupid, $now, $timetoshowusers, $context, false, $courseid); + $users = $onlineusers->get_users(); + $usercount = $onlineusers->count_users(); + // User1 should be displayed in the online users block. + $this->assertEquals(3, $usercount); + $this->assertTrue(array_key_exists($user1->id, $users)); + // Set user1 as logged user. + $this->setUser($user1); + // Set visibility to 'hide' for user1. + set_user_preference('block_online_users_uservisibility', 0); + // Test if the fetcher gets all the users including user1. + $onlineusers = new fetcher($groupid, $now, $timetoshowusers, $context, false, $courseid); + $users = $onlineusers->get_users(); + $usercount = $onlineusers->count_users(); + // User1 should be displayed in the online users block. + $this->assertEquals(3, $usercount); + $this->assertTrue(array_key_exists($user1->id, $users)); + // Set user2 as logged user. + $this->setUser($user2); + // Test if the fetcher gets all the users excluding user1. + $onlineusers = new fetcher($groupid, $now, $timetoshowusers, $context, false, $courseid); + $users = $onlineusers->get_users(); + $usercount = $onlineusers->count_users(); + // User1 should not be displayed in the online users block. + $this->assertEquals(2, $usercount); + $this->assertFalse(array_key_exists($user1->id, $users)); + } + + /** + * Check user visibility setting at course level. + */ + public function test_user_visibility_courses() { + global $CFG; + + $currentgroup = null; + $now = time(); + $timetoshowusers = $CFG->block_online_users_timetosee * 60; + $context = context_course::instance($this->data['course1']->id); + $courseid = $this->data['course1']->id; + $user1 = $this->data['user1']; + $user2 = $this->data['user2']; + // Set user2 as logged user. + $this->setUser($user2); + // Test if the fetcher gets all the users including user1. + $onlineusers = new fetcher($currentgroup, $now, $timetoshowusers, $context, false, $courseid); + $users = $onlineusers->get_users(); + $usercount = $onlineusers->count_users(); + // User1 should be displayed in the online users block. + $this->assertEquals(9, $usercount); + $this->assertTrue(array_key_exists($user1->id, $users)); + // Set user1 as logged user. + $this->setUser($user1); + // Set visibility to 'hide' for user1. + set_user_preference('block_online_users_uservisibility', 0); + // Test if the fetcher gets all the users including user1. + $onlineusers = new fetcher($currentgroup, $now, $timetoshowusers, $context, false, $courseid); + $users = $onlineusers->get_users(); + $usercount = $onlineusers->count_users(); + // User1 should be displayed in the online users block. + $this->assertEquals(9, $usercount); + $this->assertTrue(array_key_exists($user1->id, $users)); + // Set user2 as logged user. + $this->setUser($user2); + // Test if the fetcher gets all the users excluding user1. + $onlineusers = new fetcher($currentgroup, $now, $timetoshowusers, $context, false, $courseid); + $users = $onlineusers->get_users(); + $usercount = $onlineusers->count_users(); + // User1 should not be displayed in the online users block. + $this->assertEquals(8, $usercount); + $this->assertFalse(array_key_exists($user1->id, $users)); + } + + /** + * Check user visibility setting at site level. + */ + public function test_user_visibility_sitelevel() { + global $CFG; + + $currentgroup = null; + $now = time(); + $timetoshowusers = $CFG->block_online_users_timetosee * 60; + $context = context_system::instance(); + $user1 = $this->data['user1']; + $user2 = $this->data['user2']; + // Set user2 as logged user. + $this->setUser($user2); + // Test if the fetcher gets all the users including user1. + $onlineusers = new fetcher($currentgroup, $now, $timetoshowusers, $context, true); + $users = $onlineusers->get_users(); + $usercount = $onlineusers->count_users(); + // User1 should be displayed in the online users block. + $this->assertEquals(12, $usercount); + $this->assertTrue(array_key_exists($user1->id, $users)); + // Set user1 as logged user. + $this->setUser($user1); + // Set visibility to 'hide' for user1. + set_user_preference('block_online_users_uservisibility', 0); + // Test if the fetcher gets all the users including user1. + $onlineusers = new fetcher($currentgroup, $now, $timetoshowusers, $context, true); + $users = $onlineusers->get_users(); + $usercount = $onlineusers->count_users(); + // User1 should be displayed in the online users block. + $this->assertEquals(12, $usercount); + $this->assertTrue(array_key_exists($user1->id, $users)); + // Set user2 as logged user. + $this->setUser($user2); + // Test if the fetcher gets all the users excluding user1. + $onlineusers = new fetcher($currentgroup, $now, $timetoshowusers, $context, true); + $users = $onlineusers->get_users(); + $usercount = $onlineusers->count_users(); + // User1 should not be displayed in the online users block. + $this->assertEquals(11, $usercount); + $this->assertFalse(array_key_exists($user1->id, $users)); + } } diff --git a/blocks/online_users/version.php b/blocks/online_users/version.php index 6bbce9fa393..1db749f211e 100644 --- a/blocks/online_users/version.php +++ b/blocks/online_users/version.php @@ -24,6 +24,6 @@ defined('MOODLE_INTERNAL') || die(); -$plugin->version = 2018051400; // The current plugin version (Date: YYYYMMDDXX) +$plugin->version = 2018051401; // The current plugin version (Date: YYYYMMDDXX) $plugin->requires = 2018050800; // Requires this Moodle version $plugin->component = 'block_online_users'; // Full name of the plugin (used for diagnostics) diff --git a/lib/db/services.php b/lib/db/services.php index 976108971c7..3493fcafed5 100644 --- a/lib/db/services.php +++ b/lib/db/services.php @@ -1353,6 +1353,7 @@ $functions = array( 'description' => 'Set user preferences.', 'type' => 'write', 'capabilities' => 'moodle/site:config', + 'ajax' => true ), 'core_user_agree_site_policy' => array( 'classname' => 'core_user_external',