Merge branch 'MDL-81073' of https://github.com/paulholden/moodle
[moodle.git] / admin / user / user_bulk_forms.php
blob0b36c941d1583cec9484d60e6e4df65d6956a80d
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.
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 * Bulk user action forms
20 * @package core
21 * @copyright Moodle
22 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
25 defined('MOODLE_INTERNAL') || die();
27 require_once($CFG->libdir.'/formslib.php');
28 require_once($CFG->libdir.'/datalib.php');
30 /**
31 * Bulk user action form
33 * @copyright Moodle
34 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
36 class user_bulk_action_form extends moodleform {
38 /** @var bool */
39 protected $hasbulkactions = false;
41 /** @var array|null */
42 protected $actions = null;
44 /**
45 * Returns an array of action_link's of all bulk actions available for this user.
47 * @param bool $flatlist whether to return a flat list (for easier searching) or a list with
48 * option groups that can be used to build a select element
49 * @return array of action_link objects
51 public function get_actions(bool $flatlist = true): array {
52 if ($this->actions === null) {
53 $this->actions = $this->build_actions();
54 $this->hasbulkactions = !empty($this->actions);
56 if ($flatlist) {
57 return array_reduce($this->actions, fn($carry, $item) => $carry + $item, []);
59 return $this->actions;
62 /**
63 * Builds the list of bulk user actions available for this user.
65 * @return array
67 protected function build_actions(): array {
69 global $CFG;
71 $canaccessbulkactions = has_any_capability(['moodle/user:update', 'moodle/user:delete'], context_system::instance());
73 $syscontext = context_system::instance();
74 $actions = [];
75 if (has_capability('moodle/user:update', $syscontext)) {
76 $actions['confirm'] = new action_link(
77 new moodle_url('/admin/user/user_bulk_confirm.php'),
78 get_string('confirm'));
80 if ($canaccessbulkactions && has_capability('moodle/site:readallmessages', $syscontext) && !empty($CFG->messaging)) {
81 $actions['message'] = new action_link(
82 new moodle_url('/admin/user/user_bulk_message.php'),
83 get_string('messageselectadd'));
85 if (has_capability('moodle/user:delete', $syscontext)) {
86 $actions['delete'] = new action_link(
87 new moodle_url('/admin/user/user_bulk_delete.php'),
88 get_string('delete'));
90 if ($canaccessbulkactions) {
91 $actions['displayonpage'] = new action_link(
92 new moodle_url('/admin/user/user_bulk_display.php'),
93 get_string('displayonpage'));
96 if (has_capability('moodle/user:update', $syscontext)) {
97 $actions['download'] = new action_link(
98 new moodle_url('/admin/user/user_bulk_download.php'),
99 get_string('download', 'admin'));
102 if (has_capability('moodle/user:update', $syscontext)) {
103 $actions['forcepasswordchange'] = new action_link(
104 new moodle_url('/admin/user/user_bulk_forcepasswordchange.php'),
105 get_string('forcepasswordchange'));
107 if ($canaccessbulkactions && has_capability('moodle/cohort:assign', $syscontext)) {
108 $actions['addtocohort'] = new action_link(
109 new moodle_url('/admin/user/user_bulk_cohortadd.php'),
110 get_string('bulkadd', 'core_cohort'));
113 // Collect all bulk user actions.
114 $hook = new \core_user\hook\extend_bulk_user_actions();
116 // Add actions from core.
117 foreach ($actions as $identifier => $action) {
118 $hook->add_action($identifier, $action);
121 // Add actions from the legacy callback 'bulk_user_actions'.
122 $moreactions = get_plugins_with_function('bulk_user_actions', 'lib.php', true, true);
123 foreach ($moreactions as $plugintype => $plugins) {
124 foreach ($plugins as $pluginfunction) {
125 $pluginactions = $pluginfunction();
126 foreach ($pluginactions as $identifier => $action) {
127 $hook->add_action($identifier, $action);
132 // Any plugin can append user bulk actions to this list by implementing a hook callback.
133 \core\hook\manager::get_instance()->dispatch($hook);
135 // This method may be called from 'Bulk actions' and 'Browse user list' pages. Some actions
136 // may be irrelevant in one of the contexts and they can be excluded by specifying the
137 // 'excludeactions' customdata.
138 $excludeactions = $this->_customdata['excludeactions'] ?? [];
139 foreach ($excludeactions as $excludeaction) {
140 $hook->add_action($excludeaction, null);
142 return $hook->get_actions();
146 * Form definition
148 public function definition() {
149 $mform =& $this->_form;
151 $mform->addElement('hidden', 'returnurl');
152 $mform->setType('returnurl', PARAM_LOCALURL);
154 // When 'passuserids' is specified in the customdata, the user ids are expected in the form
155 // data rather than in the $SESSION->bulk_users .
156 $passuserids = !empty($this->_customdata['passuserids']);
157 $mform->addElement('hidden', 'passuserids', $passuserids);
158 $mform->setType('passuserids', PARAM_BOOL);
160 $mform->addElement('hidden', 'userids');
161 $mform->setType('userids', PARAM_SEQUENCE);
163 $actions = ['' => [0 => get_string('choose') . '...']];
164 $bulkactions = $this->get_actions(false);
165 foreach ($bulkactions as $category => $categoryactions) {
166 $actions[$category] = array_map(fn($action) => $action->text, $categoryactions);
168 $objs = array();
169 $objs[] = $selectel = $mform->createElement('selectgroups', 'action', get_string('userbulk', 'admin'), $actions);
170 $selectel->setHiddenLabel(true);
171 if (empty($this->_customdata['hidesubmit'])) {
172 $objs[] =& $mform->createElement('submit', 'doaction', get_string('go'));
174 $mform->addElement('group', 'actionsgrp', get_string('withselectedusers'), $objs, ' ', false);
178 * Is there at least one available bulk action in this form
180 * @return bool
182 public function has_bulk_actions(): bool {
183 return $this->hasbulkactions;
188 * Bulk user form
190 * @copyright Moodle
191 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
193 class user_bulk_form extends moodleform {
196 * Form definition
198 public function definition() {
200 $mform =& $this->_form;
201 $acount =& $this->_customdata['acount'];
202 $scount =& $this->_customdata['scount'];
203 $ausers =& $this->_customdata['ausers'];
204 $susers =& $this->_customdata['susers'];
205 $total =& $this->_customdata['total'];
207 $achoices = array();
208 $schoices = array();
210 if (is_array($ausers)) {
211 if ($total == $acount) {
212 $achoices[0] = get_string('allusers', 'bulkusers', $total);
213 } else {
214 $a = new stdClass();
215 $a->total = $total;
216 $a->count = $acount;
217 $achoices[0] = get_string('allfilteredusers', 'bulkusers', $a);
219 $achoices = $achoices + $ausers;
221 if ($acount > MAX_BULK_USERS) {
222 $achoices[-1] = '...';
225 } else {
226 $achoices[-1] = get_string('nofilteredusers', 'bulkusers', $total);
229 if (is_array($susers)) {
230 $a = new stdClass();
231 $a->total = $total;
232 $a->count = $scount;
233 $schoices[0] = get_string('allselectedusers', 'bulkusers', $a);
234 $schoices = $schoices + $susers;
236 if ($scount > MAX_BULK_USERS) {
237 $schoices[-1] = '...';
240 } else {
241 $schoices[-1] = get_string('noselectedusers', 'bulkusers');
244 $mform->addElement('header', 'users', get_string('usersinlist', 'bulkusers'));
246 $objs = array();
247 $objs[0] =& $mform->createElement('select', 'ausers', get_string('available', 'bulkusers'), $achoices, 'size="15"');
248 $objs[0]->setMultiple(true);
249 $objs[1] =& $mform->createElement('select', 'susers', get_string('selected', 'bulkusers'), $schoices, 'size="15"');
250 $objs[1]->setMultiple(true);
252 $grp =& $mform->addElement('group', 'usersgrp', get_string('users', 'bulkusers'), $objs, ' ', false);
253 $mform->addHelpButton('usersgrp', 'users', 'bulkusers');
255 $mform->addElement('static', 'comment');
257 $objs = array();
258 $objs[] =& $mform->createElement('submit', 'addsel', get_string('addsel', 'bulkusers'));
259 $objs[] =& $mform->createElement('submit', 'removesel', get_string('removesel', 'bulkusers'));
260 $grp =& $mform->addElement('group', 'buttonsgrp', get_string('selectedlist', 'bulkusers'), $objs, null, false);
261 $mform->addHelpButton('buttonsgrp', 'selectedlist', 'bulkusers');
262 $objs = array();
263 $objs[] =& $mform->createElement('submit', 'addall', get_string('addall', 'bulkusers'));
264 $objs[] =& $mform->createElement('submit', 'removeall', get_string('removeall', 'bulkusers'));
265 $grp =& $mform->addElement('group', 'buttonsgrp2', '', $objs, null, false);
267 $renderer =& $mform->defaultRenderer();
268 $template = '<label class="qflabel" style="vertical-align:top">{label}</label> {element}';
269 $renderer->setGroupElementTemplate($template, 'usersgrp');