MDL-6074 blocks: Hide user in online users block
[moodle.git] / blocks / online_users / classes / fetcher.php
1 <?php
2 // This file is part of Moodle - http://moodle.org/
3 //
4 // Moodle is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU General Public License as published by
6 // the Free Software Foundation, either version 3 of the License, or
7 // (at your option) any later version.
8 //
9 // Moodle is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 // GNU General Public License for more details.
13 //
14 // You should have received a copy of the GNU General Public License
15 // along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
17 /**
18  * File containing onlineusers class.
19  *
20  * @package    block_online_users
21  * @copyright  1999 onwards Martin Dougiamas (http://dougiamas.com)
22  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
23  */
25 namespace block_online_users;
27 defined('MOODLE_INTERNAL') || die();
29 /**
30  * Class used to list and count online users
31  *
32  * @package    block_online_users
33  * @copyright  1999 onwards Martin Dougiamas (http://dougiamas.com)
34  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
35  */
36 class fetcher {
38     /** @var string The SQL query for retrieving a list of online users */
39     public $sql;
40     /** @var string The SQL query for counting the number of online users */
41     public $csql;
42     /** @var string The params for the SQL queries */
43     public $params;
45     /**
46      * Class constructor
47      *
48      * @param int $currentgroup The group (if any) to filter on
49      * @param int $now Time now
50      * @param int $timetoshowusers Number of seconds to show online users
51      * @param context $context Context object used to generate the sql for users enrolled in a specific course
52      * @param bool $sitelevel Whether to check online users at site level.
53      * @param int $courseid The course id to check
54      */
55     public function __construct($currentgroup, $now, $timetoshowusers, $context, $sitelevel = true, $courseid = null) {
56         $this->set_sql($currentgroup, $now, $timetoshowusers, $context, $sitelevel, $courseid);
57     }
59     /**
60      * Store the SQL queries & params for listing online users
61      *
62      * @param int $currentgroup The group (if any) to filter on
63      * @param int $now Time now
64      * @param int $timetoshowusers Number of seconds to show online users
65      * @param context $context Context object used to generate the sql for users enrolled in a specific course
66      * @param bool $sitelevel Whether to check online users at site level.
67      * @param int $courseid The course id to check
68      */
69     protected function set_sql($currentgroup, $now, $timetoshowusers, $context, $sitelevel, $courseid) {
70         global $USER, $DB;
72         $timefrom = 100 * floor(($now - $timetoshowusers) / 100); // Round to nearest 100 seconds for better query cache.
74         $groupmembers = "";
75         $groupselect  = "";
76         $groupby       = "";
77         $lastaccess    = ", lastaccess";
78         $timeaccess    = ", ul.timeaccess AS lastaccess";
79         $uservisibility = ", up.value AS uservisibility";
80         $params = array();
82         $userfields = \user_picture::fields('u', array('username'));
84         // Add this to the SQL to show only group users.
85         if ($currentgroup !== null) {
86             $groupmembers = ", {groups_members} gm";
87             $groupselect = "AND u.id = gm.userid AND gm.groupid = :currentgroup";
88             $groupby = "GROUP BY $userfields";
89             $lastaccess = ", MAX(u.lastaccess) AS lastaccess";
90             $timeaccess = ", MAX(ul.timeaccess) AS lastaccess";
91             $uservisibility = ", MAX(up.value) AS uservisibility";
92             $params['currentgroup'] = $currentgroup;
93         }
95         $params['now'] = $now;
96         $params['timefrom'] = $timefrom;
97         $params['userid'] = $USER->id;
98         $params['name'] = 'block_online_users_uservisibility';
100         if ($sitelevel) {
101             $sql = "SELECT $userfields $lastaccess $uservisibility
102                       FROM {user} u $groupmembers
103                  LEFT JOIN {user_preferences} up ON up.userid = u.id
104                            AND up.name = :name
105                      WHERE u.lastaccess > :timefrom
106                            AND u.lastaccess <= :now
107                            AND u.deleted = 0
108                            AND (" . $DB->sql_cast_char2int('up.value') . " = 1
109                                OR up.value IS NULL
110                                OR u.id = :userid)
111                            $groupselect $groupby
112                   ORDER BY lastaccess DESC ";
114             $csql = "SELECT COUNT(u.id)
115                        FROM {user} u $groupmembers
116                   LEFT JOIN {user_preferences} up ON up.userid = u.id
117                             AND up.name = :name
118                       WHERE u.lastaccess > :timefrom
119                             AND u.lastaccess <= :now
120                             AND u.deleted = 0
121                             AND (" . $DB->sql_cast_char2int('up.value') . " = 1
122                                 OR up.value IS NULL
123                                 OR u.id = :userid)
124                             $groupselect";
125         } else {
126             // Course level - show only enrolled users for now.
127             // TODO: add a new capability for viewing of all users (guests+enrolled+viewing).
128             list($esqljoin, $eparams) = get_enrolled_sql($context);
129             $params = array_merge($params, $eparams);
131             $sql = "SELECT $userfields $timeaccess $uservisibility
132                       FROM {user_lastaccess} ul $groupmembers, {user} u
133                       JOIN ($esqljoin) euj ON euj.id = u.id
134                  LEFT JOIN {user_preferences} up ON up.userid = u.id
135                            AND up.name = :name
136                      WHERE ul.timeaccess > :timefrom
137                            AND u.id = ul.userid
138                            AND ul.courseid = :courseid
139                            AND ul.timeaccess <= :now
140                            AND u.deleted = 0
141                            AND (" . $DB->sql_cast_char2int('up.value') . " = 1
142                                OR up.value IS NULL
143                                OR u.id = :userid)
144                            $groupselect $groupby
145                   ORDER BY lastaccess DESC";
147             $csql = "SELECT COUNT(u.id)
148                       FROM {user_lastaccess} ul $groupmembers, {user} u
149                       JOIN ($esqljoin) euj ON euj.id = u.id
150                  LEFT JOIN {user_preferences} up ON up.userid = u.id
151                            AND up.name = :name
152                      WHERE ul.timeaccess > :timefrom
153                            AND u.id = ul.userid
154                            AND ul.courseid = :courseid
155                            AND ul.timeaccess <= :now
156                            AND u.deleted = 0
157                            AND (" . $DB->sql_cast_char2int('up.value') . " = 1
158                                OR up.value IS NULL
159                                OR u.id = :userid)
160                            $groupselect";
162             $params['courseid'] = $courseid;
163         }
164         $this->sql = $sql;
165         $this->csql = $csql;
166         $this->params = $params;
167     }
169     /**
170      * Get a list of the most recent online users
171      *
172      * @param int $userlimit The maximum number of users that will be returned (optional, unlimited if not set)
173      * @return array
174      */
175     public function get_users($userlimit = 0) {
176         global $DB;
177         $users = $DB->get_records_sql($this->sql, $this->params, 0, $userlimit);
178         return $users;
179     }
181     /**
182      * Count the number of online users
183      *
184      * @return int
185      */
186     public function count_users() {
187         global $DB;
188         return $DB->count_records_sql($this->csql, $this->params);
189     }