Commit | Line | Data |
---|---|---|
82af55d7 | 1 | <?php |
82af55d7 MD |
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/>. | |
16 | ||
82af55d7 | 17 | /** |
a2ed6e69 | 18 | * Provides user rendering functionality such as printing private files tree and displaying a search utility |
82af55d7 MD |
19 | * |
20 | * @package core_user | |
21 | * @copyright 2010 Dongsheng Cai <dongsheng@moodle.com> | |
22 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later | |
23 | */ | |
24 | ||
82af55d7 MD |
25 | defined('MOODLE_INTERNAL') || die(); |
26 | ||
02d1a0a5 | 27 | /** |
a2ed6e69 | 28 | * Provides user rendering functionality such as printing private files tree and displaying a search utility |
02d1a0a5 MA |
29 | * @copyright 2010 Dongsheng Cai <dongsheng@moodle.com> |
30 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later | |
31 | */ | |
82af55d7 MD |
32 | class core_user_renderer extends plugin_renderer_base { |
33 | ||
cbe8e5b3 MA |
34 | /** |
35 | * Prints user search utility that can search user by first initial of firstname and/or first initial of lastname | |
36 | * Prints a header with a title and the number of users found within that subset | |
37 | * @param string $url the url to return to, complete with any parameters needed for the return | |
cbe8e5b3 MA |
38 | * @param string $firstinitial the first initial of the firstname |
39 | * @param string $lastinitial the first initial of the lastname | |
40 | * @param int $usercount the amount of users meeting the search criteria | |
2b267d31 | 41 | * @param int $totalcount the amount of users of the set/subset being searched |
cbe8e5b3 MA |
42 | * @param string $heading heading of the subset being searched, default is All Participants |
43 | * @return string html output | |
44 | */ | |
41877849 | 45 | public function user_search($url, $firstinitial, $lastinitial, $usercount, $totalcount, $heading = null) { |
cbe8e5b3 | 46 | |
8b844f70 IT |
47 | if ($firstinitial !== 'all') { |
48 | set_user_preference('ifirst', $firstinitial); | |
49 | } | |
50 | if ($lastinitial !== 'all') { | |
51 | set_user_preference('ilast', $lastinitial); | |
52 | } | |
cbe8e5b3 MA |
53 | |
54 | if (!isset($heading)) { | |
55 | $heading = get_string('allparticipants'); | |
56 | } | |
57 | ||
58 | $content = html_writer::start_tag('form', array('action' => new moodle_url($url))); | |
59 | $content .= html_writer::start_tag('div'); | |
60 | ||
41877849 | 61 | // Search utility heading. |
1dcd0d34 | 62 | $content .= $this->output->heading($heading.get_string('labelsep', 'langconfig').$usercount.'/'.$totalcount, 3); |
cbe8e5b3 | 63 | |
8b844f70 IT |
64 | // Initials bar. |
65 | $prefixfirst = 'sifirst'; | |
66 | $prefixlast = 'silast'; | |
1dcd0d34 TH |
67 | $content .= $this->output->initials_bar($firstinitial, 'firstinitial', get_string('firstname'), $prefixfirst, $url); |
68 | $content .= $this->output->initials_bar($lastinitial, 'lastinitial', get_string('lastname'), $prefixlast, $url); | |
cbe8e5b3 | 69 | |
cbe8e5b3 | 70 | $content .= html_writer::end_tag('div'); |
f836166a | 71 | $content .= html_writer::tag('div', ' '); |
cbe8e5b3 MA |
72 | $content .= html_writer::end_tag('form'); |
73 | ||
74 | return $content; | |
75 | } | |
76 | ||
c4e868d5 MG |
77 | /** |
78 | * Displays the list of tagged users | |
79 | * | |
80 | * @param array $userlist | |
81 | * @param bool $exclusivemode if set to true it means that no other entities tagged with this tag | |
82 | * are displayed on the page and the per-page limit may be bigger | |
83 | * @return string | |
84 | */ | |
85 | public function user_list($userlist, $exclusivemode) { | |
86 | $tagfeed = new core_tag\output\tagfeed(); | |
87 | foreach ($userlist as $user) { | |
88 | $userpicture = $this->output->user_picture($user, array('size' => $exclusivemode ? 100 : 35)); | |
89 | $fullname = fullname($user); | |
90 | if (user_can_view_profile($user)) { | |
91 | $profilelink = new moodle_url('/user/view.php', array('id' => $user->id)); | |
92 | $fullname = html_writer::link($profilelink, $fullname); | |
93 | } | |
94 | $tagfeed->add($userpicture, $fullname); | |
95 | } | |
96 | ||
97 | $items = $tagfeed->export_for_template($this->output); | |
98 | ||
99 | if ($exclusivemode) { | |
100 | $output = '<div><ul class="inline-list">'; | |
101 | foreach ($items['items'] as $item) { | |
102 | $output .= '<li><div class="user-box">'. $item['img'] . $item['heading'] ."</div></li>\n"; | |
103 | } | |
104 | $output .= "</ul></div>\n"; | |
105 | return $output; | |
106 | } | |
107 | ||
108 | return $this->output->render_from_template('core_tag/tagfeed', $items); | |
109 | } | |
110 | ||
9651e491 JP |
111 | /** |
112 | * Renders the unified filter element for the course participants page. | |
113 | * | |
114 | * @param stdClass $course The course object. | |
115 | * @param context $context The context object. | |
116 | * @param array $filtersapplied Array of currently applied filters. | |
bb4a7923 | 117 | * @param string|moodle_url $baseurl The url with params needed to call up this page. |
9651e491 JP |
118 | * @return bool|string |
119 | */ | |
bb4a7923 | 120 | public function unified_filter($course, $context, $filtersapplied, $baseurl = null) { |
9651e491 JP |
121 | global $CFG, $DB, $USER; |
122 | ||
5616a319 | 123 | require_once($CFG->dirroot . '/enrol/locallib.php'); |
a471bc49 | 124 | require_once($CFG->dirroot . '/lib/grouplib.php'); |
5616a319 DW |
125 | $manager = new course_enrolment_manager($this->page, $course); |
126 | ||
9651e491 | 127 | $filteroptions = []; |
5616a319 DW |
128 | |
129 | // Filter options for role. | |
a63cd3e2 AH |
130 | $roleseditable = has_capability('moodle/role:assign', $context); |
131 | $roles = get_viewable_roles($context); | |
132 | if ($roleseditable) { | |
133 | $roles += get_assignable_roles($context, ROLENAME_ALIAS); | |
134 | } | |
135 | ||
5616a319 | 136 | $criteria = get_string('role'); |
90ce66a9 | 137 | $roleoptions = $this->format_filter_option(USER_FILTER_ROLE, $criteria, -1, get_string('noroles', 'role')); |
5616a319 DW |
138 | foreach ($roles as $id => $role) { |
139 | $roleoptions += $this->format_filter_option(USER_FILTER_ROLE, $criteria, $id, $role); | |
140 | } | |
141 | $filteroptions += $roleoptions; | |
142 | ||
143 | // Filter options for groups, if available. | |
a471bc49 DW |
144 | if (has_capability('moodle/site:accessallgroups', $context) || $course->groupmode != SEPARATEGROUPS) { |
145 | // List all groups if the user can access all groups, or we are in visible group mode or no groups mode. | |
146 | $groups = $manager->get_all_groups(); | |
5290d060 SA |
147 | if (!empty($groups)) { |
148 | // Add 'No group' option, to enable filtering users without any group. | |
149 | $nogroup[USERSWITHOUTGROUP] = (object)['name' => get_string('nogroup', 'group')]; | |
150 | $groups = $nogroup + $groups; | |
151 | } | |
a471bc49 DW |
152 | } else { |
153 | // Otherwise, just list the groups the user belongs to. | |
154 | $groups = groups_get_all_groups($course->id, $USER->id); | |
5616a319 | 155 | } |
a471bc49 DW |
156 | $criteria = get_string('group'); |
157 | $groupoptions = []; | |
158 | foreach ($groups as $id => $group) { | |
159 | $groupoptions += $this->format_filter_option(USER_FILTER_GROUP, $criteria, $id, $group->name); | |
160 | } | |
161 | $filteroptions += $groupoptions; | |
5616a319 DW |
162 | |
163 | $canreviewenrol = has_capability('moodle/course:enrolreview', $context); | |
164 | ||
165 | // Filter options for status. | |
166 | if ($canreviewenrol) { | |
167 | $criteria = get_string('status'); | |
168 | // Add statuses. | |
169 | $filteroptions += $this->format_filter_option(USER_FILTER_STATUS, $criteria, ENROL_USER_ACTIVE, get_string('active')); | |
170 | $filteroptions += $this->format_filter_option(USER_FILTER_STATUS, $criteria, ENROL_USER_SUSPENDED, | |
171 | get_string('inactive')); | |
172 | } | |
173 | ||
174 | // Filter options for enrolment methods. | |
175 | if ($canreviewenrol && $enrolmentmethods = $manager->get_enrolment_instance_names(true)) { | |
176 | $criteria = get_string('enrolmentinstances', 'enrol'); | |
177 | $enroloptions = []; | |
178 | foreach ($enrolmentmethods as $id => $enrolname) { | |
179 | $enroloptions += $this->format_filter_option(USER_FILTER_ENROLMENT, $criteria, $id, $enrolname); | |
180 | } | |
181 | $filteroptions += $enroloptions; | |
182 | } | |
183 | ||
9651e491 JP |
184 | $isfrontpage = ($course->id == SITEID); |
185 | ||
186 | // Get the list of fields we have to hide. | |
187 | $hiddenfields = array(); | |
188 | if (!has_capability('moodle/course:viewhiddenuserfields', $context)) { | |
189 | $hiddenfields = array_flip(explode(',', $CFG->hiddenuserfields)); | |
190 | } | |
191 | $haslastaccess = !isset($hiddenfields['lastaccess']); | |
192 | // Filter options for last access. | |
193 | if ($haslastaccess) { | |
194 | // Get minimum lastaccess for this course and display a dropbox to filter by lastaccess going back this far. | |
195 | // We need to make it diferently for normal courses and site course. | |
196 | if (!$isfrontpage) { | |
197 | $params = ['courseid' => $course->id, 'timeaccess' => 0]; | |
198 | $select = 'courseid = :courseid AND timeaccess != :timeaccess'; | |
199 | $minlastaccess = $DB->get_field_select('user_lastaccess', 'MIN(timeaccess)', $select, $params); | |
200 | $lastaccess0exists = $DB->record_exists('user_lastaccess', $params); | |
201 | } else { | |
202 | $params = ['lastaccess' => 0]; | |
203 | $select = 'lastaccess != :lastaccess'; | |
204 | $minlastaccess = $DB->get_field_select('user', 'MIN(lastaccess)', $select, $params); | |
205 | $lastaccess0exists = $DB->record_exists('user', $params); | |
206 | } | |
207 | $now = usergetmidnight(time()); | |
208 | $timeoptions = []; | |
209 | $criteria = get_string('usersnoaccesssince'); | |
210 | ||
211 | // Days. | |
212 | for ($i = 1; $i < 7; $i++) { | |
213 | $timestamp = strtotime('-' . $i . ' days', $now); | |
c8351261 MG |
214 | if ($timestamp < $minlastaccess) { |
215 | break; | |
9651e491 | 216 | } |
c8351261 MG |
217 | $value = get_string('numdays', 'moodle', $i); |
218 | $timeoptions += $this->format_filter_option(USER_FILTER_LAST_ACCESS, $criteria, $timestamp, $value); | |
9651e491 JP |
219 | } |
220 | // Weeks. | |
221 | for ($i = 1; $i < 10; $i++) { | |
222 | $timestamp = strtotime('-'.$i.' weeks', $now); | |
c8351261 MG |
223 | if ($timestamp < $minlastaccess) { |
224 | break; | |
9651e491 | 225 | } |
c8351261 MG |
226 | $value = get_string('numweeks', 'moodle', $i); |
227 | $timeoptions += $this->format_filter_option(USER_FILTER_LAST_ACCESS, $criteria, $timestamp, $value); | |
9651e491 JP |
228 | } |
229 | // Months. | |
230 | for ($i = 2; $i < 12; $i++) { | |
231 | $timestamp = strtotime('-'.$i.' months', $now); | |
c8351261 MG |
232 | if ($timestamp < $minlastaccess) { |
233 | break; | |
9651e491 | 234 | } |
c8351261 MG |
235 | $value = get_string('nummonths', 'moodle', $i); |
236 | $timeoptions += $this->format_filter_option(USER_FILTER_LAST_ACCESS, $criteria, $timestamp, $value); | |
9651e491 JP |
237 | } |
238 | // Try a year. | |
c8351261 | 239 | $timestamp = strtotime('-1 year', $now); |
9651e491 | 240 | if ($timestamp >= $minlastaccess) { |
c8351261 | 241 | $value = get_string('numyear', 'moodle', 1); |
9651e491 JP |
242 | $timeoptions += $this->format_filter_option(USER_FILTER_LAST_ACCESS, $criteria, $timestamp, $value); |
243 | } | |
244 | if (!empty($lastaccess0exists)) { | |
245 | $value = get_string('never', 'moodle'); | |
246 | $timeoptions += $this->format_filter_option(USER_FILTER_LAST_ACCESS, $criteria, $timestamp, $value); | |
247 | } | |
248 | if (count($timeoptions) > 1) { | |
249 | $filteroptions += $timeoptions; | |
250 | } | |
251 | } | |
252 | ||
c8351261 MG |
253 | // Add missing applied filters to the filter options. |
254 | $filteroptions = $this->handle_missing_applied_filters($filtersapplied, $filteroptions); | |
255 | ||
bb4a7923 | 256 | $indexpage = new \core_user\output\unified_filter($filteroptions, $filtersapplied, $baseurl); |
9651e491 JP |
257 | $context = $indexpage->export_for_template($this->output); |
258 | ||
259 | return $this->output->render_from_template('core_user/unified_filter', $context); | |
260 | } | |
261 | ||
77ba77f1 AN |
262 | /** |
263 | * Render the data required for the participants filter on the course participants page. | |
264 | * | |
265 | * @param context $context The context of the course being displayed | |
266 | * @param string $tableregionid The table to be updated by this filter | |
267 | * @return string | |
268 | */ | |
269 | public function participants_filter(context $context, string $tableregionid): string { | |
270 | $renderable = new \core_user\output\participants_filter($context, $tableregionid); | |
271 | $templatecontext = $renderable->export_for_template($this->output); | |
272 | ||
273 | return $this->output->render_from_template('core_user/participantsfilter', $templatecontext); | |
274 | } | |
275 | ||
9651e491 JP |
276 | /** |
277 | * Returns a formatted filter option. | |
278 | * | |
279 | * @param int $filtertype The filter type (e.g. status, role, group, enrolment, last access). | |
280 | * @param string $criteria The string label of the filter type. | |
281 | * @param int $value The value for the filter option. | |
282 | * @param string $label The string representation of the filter option's value. | |
283 | * @return array The formatted option with the ['filtertype:value' => 'criteria: label'] format. | |
284 | */ | |
285 | protected function format_filter_option($filtertype, $criteria, $value, $label) { | |
286 | $optionlabel = get_string('filteroption', 'moodle', (object)['criteria' => $criteria, 'value' => $label]); | |
287 | $optionvalue = "$filtertype:$value"; | |
288 | return [$optionvalue => $optionlabel]; | |
289 | } | |
c8351261 MG |
290 | |
291 | /** | |
292 | * Handles cases when after reloading the applied filters are missing in the filter options. | |
293 | * | |
294 | * @param array $filtersapplied The applied filters. | |
295 | * @param array $filteroptions The filter options. | |
296 | * @return array The formatted options with the ['filtertype:value' => 'criteria: label'] format. | |
297 | */ | |
298 | private function handle_missing_applied_filters($filtersapplied, $filteroptions) { | |
299 | global $DB; | |
300 | ||
301 | foreach ($filtersapplied as $filter) { | |
302 | if (!array_key_exists($filter, $filteroptions)) { | |
303 | $filtervalue = explode(':', $filter); | |
446b21b5 AN |
304 | if (count($filtervalue) !== 2) { |
305 | continue; | |
306 | } | |
c8351261 MG |
307 | $key = $filtervalue[0]; |
308 | $value = $filtervalue[1]; | |
309 | ||
310 | switch($key) { | |
311 | case USER_FILTER_LAST_ACCESS: | |
312 | $now = usergetmidnight(time()); | |
313 | $criteria = get_string('usersnoaccesssince'); | |
314 | // Days. | |
315 | for ($i = 1; $i < 7; $i++) { | |
316 | $timestamp = strtotime('-' . $i . ' days', $now); | |
317 | if ($timestamp < $value) { | |
318 | break; | |
319 | } | |
320 | $val = get_string('numdays', 'moodle', $i); | |
321 | $filteroptions += $this->format_filter_option(USER_FILTER_LAST_ACCESS, $criteria, $timestamp, $val); | |
322 | } | |
323 | // Weeks. | |
324 | for ($i = 1; $i < 10; $i++) { | |
325 | $timestamp = strtotime('-'.$i.' weeks', $now); | |
326 | if ($timestamp < $value) { | |
327 | break; | |
328 | } | |
329 | $val = get_string('numweeks', 'moodle', $i); | |
330 | $filteroptions += $this->format_filter_option(USER_FILTER_LAST_ACCESS, $criteria, $timestamp, $val); | |
331 | } | |
332 | // Months. | |
333 | for ($i = 2; $i < 12; $i++) { | |
334 | $timestamp = strtotime('-'.$i.' months', $now); | |
335 | if ($timestamp < $value) { | |
336 | break; | |
337 | } | |
338 | $val = get_string('nummonths', 'moodle', $i); | |
339 | $filteroptions += $this->format_filter_option(USER_FILTER_LAST_ACCESS, $criteria, $timestamp, $val); | |
340 | } | |
341 | // Try a year. | |
342 | $timestamp = strtotime('-1 year', $now); | |
343 | if ($timestamp >= $value) { | |
344 | $val = get_string('numyear', 'moodle', 1); | |
345 | $filteroptions += $this->format_filter_option(USER_FILTER_LAST_ACCESS, $criteria, $timestamp, $val); | |
346 | } | |
762f8dc1 | 347 | break; |
c8351261 MG |
348 | case USER_FILTER_ROLE: |
349 | $criteria = get_string('role'); | |
350 | if ($role = $DB->get_record('role', array('id' => $value))) { | |
351 | $role = role_get_name($role); | |
352 | $filteroptions += $this->format_filter_option(USER_FILTER_ROLE, $criteria, $value, $role); | |
353 | } | |
762f8dc1 | 354 | break; |
c8351261 MG |
355 | } |
356 | } | |
357 | } | |
358 | return $filteroptions; | |
359 | } | |
82af55d7 | 360 | } |