MDL-68169 user: Add enrolment instance filter
[moodle.git] / user / classes / output / participants_filter.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  * Class for rendering user filters on the course participants page.
19  *
20  * @package    core_user
21  * @copyright  2020 Michael Hawkins <michaelh@moodle.com>
22  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
23  */
24 namespace core_user\output;
26 use context_course;
27 use renderable;
28 use renderer_base;
29 use stdClass;
30 use templatable;
32 /**
33  * Class for rendering user filters on the course participants page.
34  *
35  * @copyright  2020 Michael Hawkins <michaelh@moodle.com>
36  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
37  */
38 class participants_filter implements renderable, templatable {
40     /** @var context_course $context The context where the filters are being rendered. */
41     protected $context;
43     /** @var string $tableregionid The table to be updated by this filter */
44     protected $tableregionid;
46     /** @var stdClass $course The course shown */
47     protected $course;
49     /**
50      * Participants filter constructor.
51      *
52      * @param context_course $context The context where the filters are being rendered.
53      * @param string $tableregionid The table to be updated by this filter
54      */
55     public function __construct(context_course $context, string $tableregionid) {
56         $this->context = $context;
57         $this->tableregionid = $tableregionid;
59         $this->course = get_course($context->instanceid);
60     }
62     /**
63      * Get data for all filter types.
64      *
65      * @return array
66      */
67     protected function get_filtertypes(): array {
68         $filtertypes = [];
70         if ($filtertype = $this->get_enrolmentstatus_filter()) {
71             $filtertypes[] = $filtertype;
72         }
74         if ($filtertype = $this->get_roles_filter()) {
75             $filtertypes[] = $filtertype;
76         }
78         if ($filtertype = $this->get_enrolments_filter()) {
79             $filtertypes[] = $filtertype;
80         }
82         if ($filtertype = $this->get_groups_filter()) {
83             $filtertypes[] = $filtertype;
84         }
86         return $filtertypes;
87     }
89     /**
90      * Get data for the enrolment status filter.
91      *
92      * @return stdClass|null
93      */
94     protected function get_enrolmentstatus_filter(): ?stdClass {
95         if (!has_capability('moodle/course:enrolreview', $this->context)) {
96             return null;
97         }
99         return $this->get_filter_object(
100             'status',
101             get_string('participationstatus', 'core_enrol'),
102             false,
103             true,
104             null,
105             [
106                 (object) [
107                     'value' => ENROL_USER_ACTIVE,
108                     'title' => get_string('active'),
109                 ],
110                 (object) [
111                     'value' => ENROL_USER_SUSPENDED,
112                     'title'  => get_string('inactive'),
113                 ],
114             ]
115         );
116     }
118     /**
119      * Get data for the roles filter.
120      *
121      * @return stdClass|null
122      */
123     protected function get_roles_filter(): ?stdClass {
124         $roles = [];
125         $roles += [-1 => get_string('noroles', 'role')];
126         $roles += get_viewable_roles($this->context);
128         if (has_capability('moodle/role:assign', $this->context)) {
129             $roles += get_assignable_roles($this->context, ROLENAME_ALIAS);
130         }
132         return $this->get_filter_object(
133             'roles',
134             get_string('roles', 'core_role'),
135             false,
136             true,
137             null,
138             array_map(function($id, $title) {
139                 return (object) [
140                     'value' => $id,
141                     'title' => $title,
142                 ];
143             }, array_keys($roles), array_values($roles))
144         );
145     }
147     /**
148      * Get data for the roles filter.
149      *
150      * @return stdClass|null
151      */
152     protected function get_enrolments_filter(): ?stdClass {
153         if (!has_capability('moodle/course:enrolreview', $this->context)) {
154             return null;
155         }
157         if ($this->course->id == SITEID) {
158             // No enrolment methods for the site.
159             return null;
160         }
162         $instances = enrol_get_instances($this->course->id, true);
163         $plugins = enrol_get_plugins(false);
165         return $this->get_filter_object(
166             'enrolments',
167             get_string('enrolmentinstances', 'core_enrol'),
168             false,
169             true,
170             null,
171             array_filter(array_map(function($instance) use ($plugins): ?stdClass {
172                 if (!array_key_exists($instance->enrol, $plugins)) {
173                     return null;
174                 }
176                 return (object) [
177                     'value' => $instance->id,
178                     'title' => $plugins[$instance->enrol]->get_instance_name($instance),
179                 ];
180             }, array_values($instances)))
181         );
182     }
184     /**
185      * Get data for the groups filter.
186      *
187      * @return stdClass|null
188      */
189     protected function get_groups_filter(): ?stdClass {
190         global $USER;
192         // Filter options for groups, if available.
193         $seeallgroups = has_capability('moodle/site:accessallgroups', $this->context);
194         $seeallgroups = $seeallgroups || ($this->course->groupmode != SEPARATEGROUPS);
195         if ($seeallgroups) {
196             $groups = [];
197             $groups += [USERSWITHOUTGROUP => (object) [
198                     'id' => USERSWITHOUTGROUP,
199                     'name' => get_string('nogroup', 'group'),
200                 ]];
201             $groups += groups_get_all_groups($this->course->id);
202         } else {
203             // Otherwise, just list the groups the user belongs to.
204             $groups = groups_get_all_groups($this->course->id, $USER->id);
205         }
207         if (empty($groups)) {
208             return null;
209         }
211         return $this->get_filter_object(
212             'groups',
213             get_string('groups', 'core_group'),
214             false,
215             true,
216             null,
217             array_map(function($group) {
218                 return (object) [
219                     'value' => $group->id,
220                     'title' => $group->name,
221                 ];
222             }, array_values($groups))
223         );
224     }
226     /**
227      * Export the renderer data in a mustache template friendly format.
228      *
229      * @param renderer_base $output Unused.
230      * @return stdClass Data in a format compatible with a mustache template.
231      */
232     public function export_for_template(renderer_base $output): stdClass {
233         return (object) [
234             'tableregionid' => $this->tableregionid,
235             'courseid' => $this->context->instanceid,
236             'filtertypes' => $this->get_filtertypes(),
237         ];
239         return $data;
240     }
242     /**
243      * Get a standardised filter object.
244      *
245      * @param string $name
246      * @param string $title
247      * @param bool $custom
248      * @param bool $multiple
249      * @param string|null $filterclass
250      * @param array $values
251      * @return stdClass|null
252      */
253     protected function get_filter_object(
254         string $name,
255         string $title,
256         bool $custom,
257         bool $multiple,
258         ?string $filterclass,
259         array $values
260     ): ?stdClass {
261         if (empty($values)) {
262             // Do not show empty filters.
263             return null;
264         }
266         return (object) [
267             'name' => $name,
268             'title' => $title,
269             'allowcustom' => $custom,
270             'allowmultiple' => $multiple,
271             'filtertypeclass' => $filterclass,
272             'values' => $values,
273         ];
274     }