1 |
efrain |
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/>.
|
|
|
16 |
|
|
|
17 |
use core_external\external_description;
|
|
|
18 |
use core_external\external_value;
|
|
|
19 |
use core_external\external_format_value;
|
|
|
20 |
use core_external\external_single_structure;
|
|
|
21 |
use core_external\external_multiple_structure;
|
|
|
22 |
use core_external\external_function_parameters;
|
|
|
23 |
use core_external\external_warnings;
|
|
|
24 |
|
|
|
25 |
/**
|
|
|
26 |
* User external functions
|
|
|
27 |
*
|
|
|
28 |
* @package core_user
|
|
|
29 |
* @category external
|
|
|
30 |
* @copyright 2011 Jerome Mouneyrac
|
|
|
31 |
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
|
|
32 |
* @since Moodle 2.2
|
|
|
33 |
*/
|
|
|
34 |
class core_user_external extends \core_external\external_api {
|
|
|
35 |
|
|
|
36 |
/**
|
|
|
37 |
* Returns description of method parameters
|
|
|
38 |
*
|
|
|
39 |
* @return external_function_parameters
|
|
|
40 |
* @since Moodle 2.2
|
|
|
41 |
*/
|
|
|
42 |
public static function create_users_parameters() {
|
|
|
43 |
global $CFG;
|
|
|
44 |
$userfields = [
|
|
|
45 |
'createpassword' => new external_value(PARAM_BOOL, 'True if password should be created and mailed to user.',
|
|
|
46 |
VALUE_OPTIONAL),
|
|
|
47 |
// General.
|
|
|
48 |
'username' => new external_value(core_user::get_property_type('username'),
|
|
|
49 |
'Username policy is defined in Moodle security config.'),
|
|
|
50 |
'auth' => new external_value(core_user::get_property_type('auth'), 'Auth plugins include manual, ldap, etc',
|
|
|
51 |
VALUE_DEFAULT, 'manual', core_user::get_property_null('auth')),
|
|
|
52 |
'password' => new external_value(core_user::get_property_type('password'),
|
|
|
53 |
'Plain text password consisting of any characters', VALUE_OPTIONAL),
|
|
|
54 |
'firstname' => new external_value(core_user::get_property_type('firstname'), 'The first name(s) of the user'),
|
|
|
55 |
'lastname' => new external_value(core_user::get_property_type('lastname'), 'The family name of the user'),
|
|
|
56 |
'email' => new external_value(core_user::get_property_type('email'), 'A valid and unique email address'),
|
|
|
57 |
'maildisplay' => new external_value(core_user::get_property_type('maildisplay'), 'Email visibility', VALUE_OPTIONAL),
|
|
|
58 |
'city' => new external_value(core_user::get_property_type('city'), 'Home city of the user', VALUE_OPTIONAL),
|
|
|
59 |
'country' => new external_value(core_user::get_property_type('country'),
|
|
|
60 |
'Home country code of the user, such as AU or CZ', VALUE_OPTIONAL),
|
|
|
61 |
'timezone' => new external_value(core_user::get_property_type('timezone'),
|
|
|
62 |
'Timezone code such as Australia/Perth, or 99 for default', VALUE_OPTIONAL),
|
|
|
63 |
'description' => new external_value(core_user::get_property_type('description'), 'User profile description, no HTML',
|
|
|
64 |
VALUE_OPTIONAL),
|
|
|
65 |
// Additional names.
|
|
|
66 |
'firstnamephonetic' => new external_value(core_user::get_property_type('firstnamephonetic'),
|
|
|
67 |
'The first name(s) phonetically of the user', VALUE_OPTIONAL),
|
|
|
68 |
'lastnamephonetic' => new external_value(core_user::get_property_type('lastnamephonetic'),
|
|
|
69 |
'The family name phonetically of the user', VALUE_OPTIONAL),
|
|
|
70 |
'middlename' => new external_value(core_user::get_property_type('middlename'), 'The middle name of the user',
|
|
|
71 |
VALUE_OPTIONAL),
|
|
|
72 |
'alternatename' => new external_value(core_user::get_property_type('alternatename'), 'The alternate name of the user',
|
|
|
73 |
VALUE_OPTIONAL),
|
|
|
74 |
// Interests.
|
|
|
75 |
'interests' => new external_value(PARAM_TEXT, 'User interests (separated by commas)', VALUE_OPTIONAL),
|
|
|
76 |
// Optional.
|
|
|
77 |
'idnumber' => new external_value(core_user::get_property_type('idnumber'),
|
|
|
78 |
'An arbitrary ID code number perhaps from the institution', VALUE_DEFAULT, ''),
|
|
|
79 |
'institution' => new external_value(core_user::get_property_type('institution'), 'institution', VALUE_OPTIONAL),
|
|
|
80 |
'department' => new external_value(core_user::get_property_type('department'), 'department', VALUE_OPTIONAL),
|
|
|
81 |
'phone1' => new external_value(core_user::get_property_type('phone1'), 'Phone 1', VALUE_OPTIONAL),
|
|
|
82 |
'phone2' => new external_value(core_user::get_property_type('phone2'), 'Phone 2', VALUE_OPTIONAL),
|
|
|
83 |
'address' => new external_value(core_user::get_property_type('address'), 'Postal address', VALUE_OPTIONAL),
|
|
|
84 |
// Other user preferences stored in the user table.
|
|
|
85 |
'lang' => new external_value(core_user::get_property_type('lang'), 'Language code such as "en", must exist on server',
|
|
|
86 |
VALUE_DEFAULT, core_user::get_property_default('lang'), core_user::get_property_null('lang')),
|
|
|
87 |
'calendartype' => new external_value(core_user::get_property_type('calendartype'),
|
|
|
88 |
'Calendar type such as "gregorian", must exist on server', VALUE_DEFAULT, $CFG->calendartype, VALUE_OPTIONAL),
|
|
|
89 |
'theme' => new external_value(core_user::get_property_type('theme'),
|
|
|
90 |
'Theme name such as "standard", must exist on server', VALUE_OPTIONAL),
|
|
|
91 |
'mailformat' => new external_value(core_user::get_property_type('mailformat'),
|
|
|
92 |
'Mail format code is 0 for plain text, 1 for HTML etc', VALUE_OPTIONAL),
|
|
|
93 |
// Custom user profile fields.
|
|
|
94 |
'customfields' => new external_multiple_structure(
|
|
|
95 |
new external_single_structure(
|
|
|
96 |
[
|
|
|
97 |
'type' => new external_value(PARAM_ALPHANUMEXT, 'The name of the custom field'),
|
|
|
98 |
'value' => new external_value(PARAM_RAW, 'The value of the custom field')
|
|
|
99 |
]
|
|
|
100 |
), 'User custom fields (also known as user profil fields)', VALUE_OPTIONAL),
|
|
|
101 |
// User preferences.
|
|
|
102 |
'preferences' => new external_multiple_structure(
|
|
|
103 |
new external_single_structure(
|
|
|
104 |
[
|
|
|
105 |
'type' => new external_value(PARAM_RAW, 'The name of the preference'),
|
|
|
106 |
'value' => new external_value(PARAM_RAW, 'The value of the preference')
|
|
|
107 |
]
|
|
|
108 |
), 'User preferences', VALUE_OPTIONAL),
|
|
|
109 |
];
|
|
|
110 |
return new external_function_parameters(
|
|
|
111 |
[
|
|
|
112 |
'users' => new external_multiple_structure(
|
|
|
113 |
new external_single_structure($userfields)
|
|
|
114 |
)
|
|
|
115 |
]
|
|
|
116 |
);
|
|
|
117 |
}
|
|
|
118 |
|
|
|
119 |
/**
|
|
|
120 |
* Create one or more users.
|
|
|
121 |
*
|
|
|
122 |
* @throws invalid_parameter_exception
|
|
|
123 |
* @param array $users An array of users to create.
|
|
|
124 |
* @return array An array of arrays
|
|
|
125 |
* @since Moodle 2.2
|
|
|
126 |
*/
|
|
|
127 |
public static function create_users($users) {
|
|
|
128 |
global $CFG, $DB;
|
|
|
129 |
require_once($CFG->dirroot."/lib/weblib.php");
|
|
|
130 |
require_once($CFG->dirroot."/user/lib.php");
|
|
|
131 |
require_once($CFG->dirroot."/user/editlib.php");
|
|
|
132 |
require_once($CFG->dirroot."/user/profile/lib.php"); // Required for customfields related function.
|
|
|
133 |
|
|
|
134 |
// Ensure the current user is allowed to run this function.
|
|
|
135 |
$context = context_system::instance();
|
|
|
136 |
self::validate_context($context);
|
|
|
137 |
require_capability('moodle/user:create', $context);
|
|
|
138 |
|
|
|
139 |
// Do basic automatic PARAM checks on incoming data, using params description.
|
|
|
140 |
// If any problems are found then exceptions are thrown with helpful error messages.
|
|
|
141 |
$params = self::validate_parameters(self::create_users_parameters(), array('users' => $users));
|
|
|
142 |
|
|
|
143 |
$availableauths = core_component::get_plugin_list('auth');
|
|
|
144 |
unset($availableauths['mnet']); // These would need mnethostid too.
|
|
|
145 |
unset($availableauths['webservice']); // We do not want new webservice users for now.
|
|
|
146 |
|
|
|
147 |
$availablethemes = core_component::get_plugin_list('theme');
|
|
|
148 |
$availablelangs = get_string_manager()->get_list_of_translations();
|
|
|
149 |
|
|
|
150 |
$transaction = $DB->start_delegated_transaction();
|
|
|
151 |
|
|
|
152 |
$userids = array();
|
|
|
153 |
foreach ($params['users'] as $user) {
|
|
|
154 |
// Make sure that the username, firstname and lastname are not blank.
|
|
|
155 |
foreach (array('username', 'firstname', 'lastname') as $fieldname) {
|
|
|
156 |
if (trim($user[$fieldname]) === '') {
|
|
|
157 |
throw new invalid_parameter_exception('The field '.$fieldname.' cannot be blank');
|
|
|
158 |
}
|
|
|
159 |
}
|
|
|
160 |
|
|
|
161 |
// Make sure that the username doesn't already exist.
|
|
|
162 |
if ($DB->record_exists('user', array('username' => $user['username'], 'mnethostid' => $CFG->mnet_localhost_id))) {
|
|
|
163 |
throw new invalid_parameter_exception('Username already exists: '.$user['username']);
|
|
|
164 |
}
|
|
|
165 |
|
|
|
166 |
// Make sure auth is valid.
|
|
|
167 |
if (empty($availableauths[$user['auth']])) {
|
|
|
168 |
throw new invalid_parameter_exception('Invalid authentication type: '.$user['auth']);
|
|
|
169 |
}
|
|
|
170 |
|
|
|
171 |
// Make sure lang is valid.
|
|
|
172 |
if (empty($availablelangs[$user['lang']])) {
|
|
|
173 |
throw new invalid_parameter_exception('Invalid language code: '.$user['lang']);
|
|
|
174 |
}
|
|
|
175 |
|
|
|
176 |
// Make sure lang is valid.
|
|
|
177 |
if (!empty($user['theme']) && empty($availablethemes[$user['theme']])) { // Theme is VALUE_OPTIONAL,
|
|
|
178 |
// so no default value
|
|
|
179 |
// We need to test if the client sent it
|
|
|
180 |
// => !empty($user['theme']).
|
|
|
181 |
throw new invalid_parameter_exception('Invalid theme: '.$user['theme']);
|
|
|
182 |
}
|
|
|
183 |
|
|
|
184 |
// Make sure we have a password or have to create one.
|
|
|
185 |
$authplugin = get_auth_plugin($user['auth']);
|
|
|
186 |
if ($authplugin->is_internal() && empty($user['password']) && empty($user['createpassword'])) {
|
|
|
187 |
throw new invalid_parameter_exception('Invalid password: you must provide a password, or set createpassword.');
|
|
|
188 |
}
|
|
|
189 |
|
|
|
190 |
$user['confirmed'] = true;
|
|
|
191 |
$user['mnethostid'] = $CFG->mnet_localhost_id;
|
|
|
192 |
|
|
|
193 |
// Start of user info validation.
|
|
|
194 |
// Make sure we validate current user info as handled by current GUI. See user/editadvanced_form.php func validation().
|
|
|
195 |
if (!validate_email($user['email'])) {
|
|
|
196 |
throw new invalid_parameter_exception('Email address is invalid: '.$user['email']);
|
|
|
197 |
} else if (empty($CFG->allowaccountssameemail)) {
|
|
|
198 |
// Make a case-insensitive query for the given email address.
|
|
|
199 |
$select = $DB->sql_equal('email', ':email', false) . ' AND mnethostid = :mnethostid';
|
|
|
200 |
$params = array(
|
|
|
201 |
'email' => $user['email'],
|
|
|
202 |
'mnethostid' => $user['mnethostid']
|
|
|
203 |
);
|
|
|
204 |
// If there are other user(s) that already have the same email, throw an error.
|
|
|
205 |
if ($DB->record_exists_select('user', $select, $params)) {
|
|
|
206 |
throw new invalid_parameter_exception('Email address already exists: '.$user['email']);
|
|
|
207 |
}
|
|
|
208 |
}
|
|
|
209 |
// End of user info validation.
|
|
|
210 |
|
|
|
211 |
$createpassword = !empty($user['createpassword']);
|
|
|
212 |
unset($user['createpassword']);
|
|
|
213 |
$updatepassword = false;
|
|
|
214 |
if ($authplugin->is_internal()) {
|
|
|
215 |
if ($createpassword) {
|
|
|
216 |
$user['password'] = '';
|
|
|
217 |
} else {
|
|
|
218 |
$updatepassword = true;
|
|
|
219 |
}
|
|
|
220 |
} else {
|
|
|
221 |
$user['password'] = AUTH_PASSWORD_NOT_CACHED;
|
|
|
222 |
}
|
|
|
223 |
|
|
|
224 |
// Create the user data now!
|
|
|
225 |
$user['id'] = user_create_user($user, $updatepassword, false);
|
|
|
226 |
|
|
|
227 |
$userobject = (object)$user;
|
|
|
228 |
|
|
|
229 |
// Set user interests.
|
|
|
230 |
if (!empty($user['interests'])) {
|
|
|
231 |
$trimmedinterests = array_map('trim', explode(',', $user['interests']));
|
|
|
232 |
$interests = array_filter($trimmedinterests, function($value) {
|
|
|
233 |
return !empty($value);
|
|
|
234 |
});
|
|
|
235 |
useredit_update_interests($userobject, $interests);
|
|
|
236 |
}
|
|
|
237 |
|
|
|
238 |
// Custom fields.
|
|
|
239 |
if (!empty($user['customfields'])) {
|
|
|
240 |
foreach ($user['customfields'] as $customfield) {
|
|
|
241 |
// Profile_save_data() saves profile file it's expecting a user with the correct id,
|
|
|
242 |
// and custom field to be named profile_field_"shortname".
|
|
|
243 |
$user["profile_field_".$customfield['type']] = $customfield['value'];
|
|
|
244 |
}
|
|
|
245 |
profile_save_data((object) $user);
|
|
|
246 |
}
|
|
|
247 |
|
|
|
248 |
if ($createpassword) {
|
|
|
249 |
setnew_password_and_mail($userobject);
|
|
|
250 |
unset_user_preference('create_password', $userobject);
|
|
|
251 |
set_user_preference('auth_forcepasswordchange', 1, $userobject);
|
|
|
252 |
}
|
|
|
253 |
|
|
|
254 |
// Trigger event.
|
|
|
255 |
\core\event\user_created::create_from_userid($user['id'])->trigger();
|
|
|
256 |
|
|
|
257 |
// Preferences.
|
|
|
258 |
if (!empty($user['preferences'])) {
|
|
|
259 |
$userpref = (object)$user;
|
|
|
260 |
foreach ($user['preferences'] as $preference) {
|
|
|
261 |
$userpref->{'preference_'.$preference['type']} = $preference['value'];
|
|
|
262 |
}
|
|
|
263 |
useredit_update_user_preference($userpref);
|
|
|
264 |
}
|
|
|
265 |
|
|
|
266 |
$userids[] = array('id' => $user['id'], 'username' => $user['username']);
|
|
|
267 |
}
|
|
|
268 |
|
|
|
269 |
$transaction->allow_commit();
|
|
|
270 |
|
|
|
271 |
return $userids;
|
|
|
272 |
}
|
|
|
273 |
|
|
|
274 |
/**
|
|
|
275 |
* Returns description of method result value
|
|
|
276 |
*
|
|
|
277 |
* @return external_description
|
|
|
278 |
* @since Moodle 2.2
|
|
|
279 |
*/
|
|
|
280 |
public static function create_users_returns() {
|
|
|
281 |
return new external_multiple_structure(
|
|
|
282 |
new external_single_structure(
|
|
|
283 |
array(
|
|
|
284 |
'id' => new external_value(core_user::get_property_type('id'), 'user id'),
|
|
|
285 |
'username' => new external_value(core_user::get_property_type('username'), 'user name'),
|
|
|
286 |
)
|
|
|
287 |
)
|
|
|
288 |
);
|
|
|
289 |
}
|
|
|
290 |
|
|
|
291 |
|
|
|
292 |
/**
|
|
|
293 |
* Returns description of method parameters
|
|
|
294 |
*
|
|
|
295 |
* @return external_function_parameters
|
|
|
296 |
* @since Moodle 2.2
|
|
|
297 |
*/
|
|
|
298 |
public static function delete_users_parameters() {
|
|
|
299 |
return new external_function_parameters(
|
|
|
300 |
array(
|
|
|
301 |
'userids' => new external_multiple_structure(new external_value(core_user::get_property_type('id'), 'user ID')),
|
|
|
302 |
)
|
|
|
303 |
);
|
|
|
304 |
}
|
|
|
305 |
|
|
|
306 |
/**
|
|
|
307 |
* Delete users
|
|
|
308 |
*
|
|
|
309 |
* @throws moodle_exception
|
|
|
310 |
* @param array $userids
|
|
|
311 |
* @return null
|
|
|
312 |
* @since Moodle 2.2
|
|
|
313 |
*/
|
|
|
314 |
public static function delete_users($userids) {
|
|
|
315 |
global $CFG, $DB, $USER;
|
|
|
316 |
require_once($CFG->dirroot."/user/lib.php");
|
|
|
317 |
|
|
|
318 |
// Ensure the current user is allowed to run this function.
|
|
|
319 |
$context = context_system::instance();
|
|
|
320 |
require_capability('moodle/user:delete', $context);
|
|
|
321 |
self::validate_context($context);
|
|
|
322 |
|
|
|
323 |
$params = self::validate_parameters(self::delete_users_parameters(), array('userids' => $userids));
|
|
|
324 |
|
|
|
325 |
$transaction = $DB->start_delegated_transaction();
|
|
|
326 |
|
|
|
327 |
foreach ($params['userids'] as $userid) {
|
|
|
328 |
$user = $DB->get_record('user', array('id' => $userid, 'deleted' => 0), '*', MUST_EXIST);
|
|
|
329 |
// Must not allow deleting of admins or self!!!
|
|
|
330 |
if (is_siteadmin($user)) {
|
|
|
331 |
throw new moodle_exception('useradminodelete', 'error');
|
|
|
332 |
}
|
|
|
333 |
if ($USER->id == $user->id) {
|
|
|
334 |
throw new moodle_exception('usernotdeletederror', 'error');
|
|
|
335 |
}
|
|
|
336 |
user_delete_user($user);
|
|
|
337 |
}
|
|
|
338 |
|
|
|
339 |
$transaction->allow_commit();
|
|
|
340 |
|
|
|
341 |
return null;
|
|
|
342 |
}
|
|
|
343 |
|
|
|
344 |
/**
|
|
|
345 |
* Returns description of method result value
|
|
|
346 |
*
|
|
|
347 |
* @return null
|
|
|
348 |
* @since Moodle 2.2
|
|
|
349 |
*/
|
|
|
350 |
public static function delete_users_returns() {
|
|
|
351 |
return null;
|
|
|
352 |
}
|
|
|
353 |
|
|
|
354 |
/**
|
|
|
355 |
* Returns description of method parameters.
|
|
|
356 |
*
|
|
|
357 |
* @return external_function_parameters
|
|
|
358 |
* @since Moodle 3.2
|
|
|
359 |
*/
|
|
|
360 |
public static function update_user_preferences_parameters() {
|
|
|
361 |
return new external_function_parameters(
|
|
|
362 |
array(
|
|
|
363 |
'userid' => new external_value(PARAM_INT, 'id of the user, default to current user', VALUE_DEFAULT, 0),
|
|
|
364 |
'emailstop' => new external_value(core_user::get_property_type('emailstop'),
|
|
|
365 |
'Enable or disable notifications for this user', VALUE_DEFAULT, null),
|
|
|
366 |
'preferences' => new external_multiple_structure(
|
|
|
367 |
new external_single_structure(
|
|
|
368 |
array(
|
|
|
369 |
'type' => new external_value(PARAM_RAW, 'The name of the preference'),
|
|
|
370 |
'value' => new external_value(PARAM_RAW, 'The value of the preference, do not set this field if you
|
|
|
371 |
want to remove (unset) the current value.', VALUE_DEFAULT, null),
|
|
|
372 |
)
|
|
|
373 |
), 'User preferences', VALUE_DEFAULT, array()
|
|
|
374 |
)
|
|
|
375 |
)
|
|
|
376 |
);
|
|
|
377 |
}
|
|
|
378 |
|
|
|
379 |
/**
|
|
|
380 |
* Update the user's preferences.
|
|
|
381 |
*
|
|
|
382 |
* @param int $userid
|
|
|
383 |
* @param bool|null $emailstop
|
|
|
384 |
* @param array $preferences
|
|
|
385 |
* @return null
|
|
|
386 |
* @since Moodle 3.2
|
|
|
387 |
*/
|
|
|
388 |
public static function update_user_preferences($userid = 0, $emailstop = null, $preferences = array()) {
|
|
|
389 |
global $USER, $CFG;
|
|
|
390 |
|
|
|
391 |
require_once($CFG->dirroot . '/user/lib.php');
|
|
|
392 |
require_once($CFG->dirroot . '/user/editlib.php');
|
|
|
393 |
require_once($CFG->dirroot . '/message/lib.php');
|
|
|
394 |
|
|
|
395 |
if (empty($userid)) {
|
|
|
396 |
$userid = $USER->id;
|
|
|
397 |
}
|
|
|
398 |
|
|
|
399 |
$systemcontext = context_system::instance();
|
|
|
400 |
self::validate_context($systemcontext);
|
|
|
401 |
$params = array(
|
|
|
402 |
'userid' => $userid,
|
|
|
403 |
'emailstop' => $emailstop,
|
|
|
404 |
'preferences' => $preferences
|
|
|
405 |
);
|
|
|
406 |
$params = self::validate_parameters(self::update_user_preferences_parameters(), $params);
|
|
|
407 |
$preferences = $params['preferences'];
|
|
|
408 |
|
|
|
409 |
// Preferences.
|
|
|
410 |
if (!empty($preferences)) {
|
|
|
411 |
$userpref = ['id' => $userid];
|
|
|
412 |
foreach ($preferences as $preference) {
|
|
|
413 |
|
|
|
414 |
/*
|
|
|
415 |
* Rename user message provider preferences to avoid orphan settings on old app versions.
|
|
|
416 |
* @todo Remove this "translation" block on MDL-73284.
|
|
|
417 |
*/
|
|
|
418 |
if (preg_match('/message_provider_.*_loggedin/', $preference['type']) ||
|
|
|
419 |
preg_match('/message_provider_.*_loggedoff/', $preference['type'])) {
|
|
|
420 |
$nameparts = explode('_', $preference['type']);
|
|
|
421 |
array_pop($nameparts);
|
|
|
422 |
$preference['type'] = implode('_', $nameparts).'_enabled';
|
|
|
423 |
}
|
|
|
424 |
|
|
|
425 |
$userpref['preference_' . $preference['type']] = $preference['value'];
|
|
|
426 |
}
|
|
|
427 |
useredit_update_user_preference($userpref);
|
|
|
428 |
}
|
|
|
429 |
|
|
|
430 |
// Check if they want to update the email.
|
|
|
431 |
if ($emailstop !== null) {
|
|
|
432 |
$otheruser = ($userid == $USER->id) ? $USER : core_user::get_user($userid, '*', MUST_EXIST);
|
|
|
433 |
core_user::require_active_user($otheruser);
|
|
|
434 |
if (core_message_can_edit_message_profile($otheruser) && $otheruser->emailstop != $emailstop) {
|
|
|
435 |
$user = new stdClass();
|
|
|
436 |
$user->id = $userid;
|
|
|
437 |
$user->emailstop = $emailstop;
|
|
|
438 |
user_update_user($user);
|
|
|
439 |
|
|
|
440 |
// Update the $USER if we should.
|
|
|
441 |
if ($userid == $USER->id) {
|
|
|
442 |
$USER->emailstop = $emailstop;
|
|
|
443 |
}
|
|
|
444 |
}
|
|
|
445 |
}
|
|
|
446 |
|
|
|
447 |
return null;
|
|
|
448 |
}
|
|
|
449 |
|
|
|
450 |
/**
|
|
|
451 |
* Returns description of method result value
|
|
|
452 |
*
|
|
|
453 |
* @return null
|
|
|
454 |
* @since Moodle 3.2
|
|
|
455 |
*/
|
|
|
456 |
public static function update_user_preferences_returns() {
|
|
|
457 |
return null;
|
|
|
458 |
}
|
|
|
459 |
|
|
|
460 |
/**
|
|
|
461 |
* Returns description of method parameters
|
|
|
462 |
*
|
|
|
463 |
* @return external_function_parameters
|
|
|
464 |
* @since Moodle 2.2
|
|
|
465 |
*/
|
|
|
466 |
public static function update_users_parameters() {
|
|
|
467 |
$userfields = [
|
|
|
468 |
'id' => new external_value(core_user::get_property_type('id'), 'ID of the user'),
|
|
|
469 |
// General.
|
|
|
470 |
'username' => new external_value(core_user::get_property_type('username'),
|
|
|
471 |
'Username policy is defined in Moodle security config.', VALUE_OPTIONAL, '', NULL_NOT_ALLOWED),
|
|
|
472 |
'auth' => new external_value(core_user::get_property_type('auth'), 'Auth plugins include manual, ldap, etc',
|
|
|
473 |
VALUE_OPTIONAL, '', NULL_NOT_ALLOWED),
|
|
|
474 |
'suspended' => new external_value(core_user::get_property_type('suspended'),
|
|
|
475 |
'Suspend user account, either false to enable user login or true to disable it', VALUE_OPTIONAL),
|
|
|
476 |
'password' => new external_value(core_user::get_property_type('password'),
|
|
|
477 |
'Plain text password consisting of any characters', VALUE_OPTIONAL, '', NULL_NOT_ALLOWED),
|
|
|
478 |
'firstname' => new external_value(core_user::get_property_type('firstname'), 'The first name(s) of the user',
|
|
|
479 |
VALUE_OPTIONAL, '', NULL_NOT_ALLOWED),
|
|
|
480 |
'lastname' => new external_value(core_user::get_property_type('lastname'), 'The family name of the user',
|
|
|
481 |
VALUE_OPTIONAL),
|
|
|
482 |
'email' => new external_value(core_user::get_property_type('email'), 'A valid and unique email address', VALUE_OPTIONAL,
|
|
|
483 |
'', NULL_NOT_ALLOWED),
|
|
|
484 |
'maildisplay' => new external_value(core_user::get_property_type('maildisplay'), 'Email visibility', VALUE_OPTIONAL),
|
|
|
485 |
'city' => new external_value(core_user::get_property_type('city'), 'Home city of the user', VALUE_OPTIONAL),
|
|
|
486 |
'country' => new external_value(core_user::get_property_type('country'),
|
|
|
487 |
'Home country code of the user, such as AU or CZ', VALUE_OPTIONAL),
|
|
|
488 |
'timezone' => new external_value(core_user::get_property_type('timezone'),
|
|
|
489 |
'Timezone code such as Australia/Perth, or 99 for default', VALUE_OPTIONAL),
|
|
|
490 |
'description' => new external_value(core_user::get_property_type('description'), 'User profile description, no HTML',
|
|
|
491 |
VALUE_OPTIONAL),
|
|
|
492 |
// User picture.
|
|
|
493 |
'userpicture' => new external_value(PARAM_INT,
|
|
|
494 |
'The itemid where the new user picture has been uploaded to, 0 to delete', VALUE_OPTIONAL),
|
|
|
495 |
// Additional names.
|
|
|
496 |
'firstnamephonetic' => new external_value(core_user::get_property_type('firstnamephonetic'),
|
|
|
497 |
'The first name(s) phonetically of the user', VALUE_OPTIONAL),
|
|
|
498 |
'lastnamephonetic' => new external_value(core_user::get_property_type('lastnamephonetic'),
|
|
|
499 |
'The family name phonetically of the user', VALUE_OPTIONAL),
|
|
|
500 |
'middlename' => new external_value(core_user::get_property_type('middlename'), 'The middle name of the user',
|
|
|
501 |
VALUE_OPTIONAL),
|
|
|
502 |
'alternatename' => new external_value(core_user::get_property_type('alternatename'), 'The alternate name of the user',
|
|
|
503 |
VALUE_OPTIONAL),
|
|
|
504 |
// Interests.
|
|
|
505 |
'interests' => new external_value(PARAM_TEXT, 'User interests (separated by commas)', VALUE_OPTIONAL),
|
|
|
506 |
// Optional.
|
|
|
507 |
'idnumber' => new external_value(core_user::get_property_type('idnumber'),
|
|
|
508 |
'An arbitrary ID code number perhaps from the institution', VALUE_OPTIONAL),
|
|
|
509 |
'institution' => new external_value(core_user::get_property_type('institution'), 'Institution', VALUE_OPTIONAL),
|
|
|
510 |
'department' => new external_value(core_user::get_property_type('department'), 'Department', VALUE_OPTIONAL),
|
|
|
511 |
'phone1' => new external_value(core_user::get_property_type('phone1'), 'Phone', VALUE_OPTIONAL),
|
|
|
512 |
'phone2' => new external_value(core_user::get_property_type('phone2'), 'Mobile phone', VALUE_OPTIONAL),
|
|
|
513 |
'address' => new external_value(core_user::get_property_type('address'), 'Postal address', VALUE_OPTIONAL),
|
|
|
514 |
// Other user preferences stored in the user table.
|
|
|
515 |
'lang' => new external_value(core_user::get_property_type('lang'), 'Language code such as "en", must exist on server',
|
|
|
516 |
VALUE_OPTIONAL, '', NULL_NOT_ALLOWED),
|
|
|
517 |
'calendartype' => new external_value(core_user::get_property_type('calendartype'),
|
|
|
518 |
'Calendar type such as "gregorian", must exist on server', VALUE_OPTIONAL, '', NULL_NOT_ALLOWED),
|
|
|
519 |
'theme' => new external_value(core_user::get_property_type('theme'),
|
|
|
520 |
'Theme name such as "standard", must exist on server', VALUE_OPTIONAL),
|
|
|
521 |
'mailformat' => new external_value(core_user::get_property_type('mailformat'),
|
|
|
522 |
'Mail format code is 0 for plain text, 1 for HTML etc', VALUE_OPTIONAL),
|
|
|
523 |
// Custom user profile fields.
|
|
|
524 |
'customfields' => new external_multiple_structure(
|
|
|
525 |
new external_single_structure(
|
|
|
526 |
[
|
|
|
527 |
'type' => new external_value(PARAM_ALPHANUMEXT, 'The name of the custom field'),
|
|
|
528 |
'value' => new external_value(PARAM_RAW, 'The value of the custom field')
|
|
|
529 |
]
|
|
|
530 |
), 'User custom fields (also known as user profil fields)', VALUE_OPTIONAL),
|
|
|
531 |
// User preferences.
|
|
|
532 |
'preferences' => new external_multiple_structure(
|
|
|
533 |
new external_single_structure(
|
|
|
534 |
[
|
|
|
535 |
'type' => new external_value(PARAM_RAW, 'The name of the preference'),
|
|
|
536 |
'value' => new external_value(PARAM_RAW, 'The value of the preference')
|
|
|
537 |
]
|
|
|
538 |
), 'User preferences', VALUE_OPTIONAL),
|
|
|
539 |
];
|
|
|
540 |
return new external_function_parameters(
|
|
|
541 |
[
|
|
|
542 |
'users' => new external_multiple_structure(
|
|
|
543 |
new external_single_structure($userfields)
|
|
|
544 |
)
|
|
|
545 |
]
|
|
|
546 |
);
|
|
|
547 |
}
|
|
|
548 |
|
|
|
549 |
/**
|
|
|
550 |
* Update users
|
|
|
551 |
*
|
|
|
552 |
* @param array $users
|
|
|
553 |
* @return null
|
|
|
554 |
* @since Moodle 2.2
|
|
|
555 |
*/
|
|
|
556 |
public static function update_users($users) {
|
|
|
557 |
global $CFG, $DB, $USER;
|
|
|
558 |
require_once($CFG->dirroot."/user/lib.php");
|
|
|
559 |
require_once($CFG->dirroot."/user/profile/lib.php"); // Required for customfields related function.
|
|
|
560 |
require_once($CFG->dirroot.'/user/editlib.php');
|
|
|
561 |
|
|
|
562 |
// Ensure the current user is allowed to run this function.
|
|
|
563 |
$context = context_system::instance();
|
|
|
564 |
require_capability('moodle/user:update', $context);
|
|
|
565 |
self::validate_context($context);
|
|
|
566 |
|
|
|
567 |
$params = self::validate_parameters(self::update_users_parameters(), array('users' => $users));
|
|
|
568 |
|
|
|
569 |
$filemanageroptions = array('maxbytes' => $CFG->maxbytes,
|
|
|
570 |
'subdirs' => 0,
|
|
|
571 |
'maxfiles' => 1,
|
|
|
572 |
'accepted_types' => 'optimised_image');
|
|
|
573 |
|
|
|
574 |
$warnings = array();
|
|
|
575 |
foreach ($params['users'] as $user) {
|
|
|
576 |
// Catch any exception while updating a user and return it as a warning.
|
|
|
577 |
try {
|
|
|
578 |
$transaction = $DB->start_delegated_transaction();
|
|
|
579 |
|
|
|
580 |
// First check the user exists.
|
|
|
581 |
if (!$existinguser = core_user::get_user($user['id'])) {
|
|
|
582 |
throw new moodle_exception('invaliduserid', '', '', null,
|
|
|
583 |
'Invalid user ID');
|
|
|
584 |
}
|
|
|
585 |
// Check if we are trying to update an admin.
|
|
|
586 |
if ($existinguser->id != $USER->id and is_siteadmin($existinguser) and !is_siteadmin($USER)) {
|
|
|
587 |
throw new moodle_exception('usernotupdatedadmin', '', '', null,
|
|
|
588 |
'Cannot update admin accounts');
|
|
|
589 |
}
|
|
|
590 |
// Other checks (deleted, remote or guest users).
|
|
|
591 |
if ($existinguser->deleted) {
|
|
|
592 |
throw new moodle_exception('usernotupdateddeleted', '', '', null,
|
|
|
593 |
'User is a deleted user');
|
|
|
594 |
}
|
|
|
595 |
if (is_mnet_remote_user($existinguser)) {
|
|
|
596 |
throw new moodle_exception('usernotupdatedremote', '', '', null,
|
|
|
597 |
'User is a remote user');
|
|
|
598 |
}
|
|
|
599 |
if (isguestuser($existinguser->id)) {
|
|
|
600 |
throw new moodle_exception('usernotupdatedguest', '', '', null,
|
|
|
601 |
'Cannot update guest account');
|
|
|
602 |
}
|
|
|
603 |
// Check duplicated emails.
|
|
|
604 |
if (isset($user['email']) && $user['email'] !== $existinguser->email) {
|
|
|
605 |
if (!validate_email($user['email'])) {
|
|
|
606 |
throw new moodle_exception('useremailinvalid', '', '', null,
|
|
|
607 |
'Invalid email address');
|
|
|
608 |
} else if (empty($CFG->allowaccountssameemail)) {
|
|
|
609 |
// Make a case-insensitive query for the given email address
|
|
|
610 |
// and make sure to exclude the user being updated.
|
|
|
611 |
$select = $DB->sql_equal('email', ':email', false) . ' AND mnethostid = :mnethostid AND id <> :userid';
|
|
|
612 |
$params = array(
|
|
|
613 |
'email' => $user['email'],
|
|
|
614 |
'mnethostid' => $CFG->mnet_localhost_id,
|
|
|
615 |
'userid' => $user['id']
|
|
|
616 |
);
|
|
|
617 |
// Skip if there are other user(s) that already have the same email.
|
|
|
618 |
if ($DB->record_exists_select('user', $select, $params)) {
|
|
|
619 |
throw new moodle_exception('useremailduplicate', '', '', null,
|
|
|
620 |
'Duplicate email address');
|
|
|
621 |
}
|
|
|
622 |
}
|
|
|
623 |
}
|
|
|
624 |
|
|
|
625 |
user_update_user($user, true, false);
|
|
|
626 |
|
|
|
627 |
$userobject = (object)$user;
|
|
|
628 |
|
|
|
629 |
// Update user picture if it was specified for this user.
|
|
|
630 |
if (empty($CFG->disableuserimages) && isset($user['userpicture'])) {
|
|
|
631 |
$userobject->deletepicture = null;
|
|
|
632 |
|
|
|
633 |
if ($user['userpicture'] == 0) {
|
|
|
634 |
$userobject->deletepicture = true;
|
|
|
635 |
} else {
|
|
|
636 |
$userobject->imagefile = $user['userpicture'];
|
|
|
637 |
}
|
|
|
638 |
|
|
|
639 |
core_user::update_picture($userobject, $filemanageroptions);
|
|
|
640 |
}
|
|
|
641 |
|
|
|
642 |
// Update user interests.
|
|
|
643 |
if (!empty($user['interests'])) {
|
|
|
644 |
$trimmedinterests = array_map('trim', explode(',', $user['interests']));
|
|
|
645 |
$interests = array_filter($trimmedinterests, function($value) {
|
|
|
646 |
return !empty($value);
|
|
|
647 |
});
|
|
|
648 |
useredit_update_interests($userobject, $interests);
|
|
|
649 |
}
|
|
|
650 |
|
|
|
651 |
// Update user custom fields.
|
|
|
652 |
if (!empty($user['customfields'])) {
|
|
|
653 |
|
|
|
654 |
foreach ($user['customfields'] as $customfield) {
|
|
|
655 |
// Profile_save_data() saves profile file it's expecting a user with the correct id,
|
|
|
656 |
// and custom field to be named profile_field_"shortname".
|
|
|
657 |
$user["profile_field_".$customfield['type']] = $customfield['value'];
|
|
|
658 |
}
|
|
|
659 |
profile_save_data((object) $user);
|
|
|
660 |
}
|
|
|
661 |
|
|
|
662 |
// Trigger event.
|
|
|
663 |
\core\event\user_updated::create_from_userid($user['id'])->trigger();
|
|
|
664 |
|
|
|
665 |
// Preferences.
|
|
|
666 |
if (!empty($user['preferences'])) {
|
|
|
667 |
$userpref = clone($existinguser);
|
|
|
668 |
foreach ($user['preferences'] as $preference) {
|
|
|
669 |
$userpref->{'preference_'.$preference['type']} = $preference['value'];
|
|
|
670 |
}
|
|
|
671 |
useredit_update_user_preference($userpref);
|
|
|
672 |
}
|
|
|
673 |
if (isset($user['suspended']) and $user['suspended']) {
|
|
|
674 |
\core\session\manager::kill_user_sessions($user['id']);
|
|
|
675 |
}
|
|
|
676 |
|
|
|
677 |
$transaction->allow_commit();
|
|
|
678 |
} catch (Exception $e) {
|
|
|
679 |
try {
|
|
|
680 |
$transaction->rollback($e);
|
|
|
681 |
} catch (Exception $e) {
|
|
|
682 |
$warning = [];
|
|
|
683 |
$warning['item'] = 'user';
|
|
|
684 |
$warning['itemid'] = $user['id'];
|
|
|
685 |
if ($e instanceof moodle_exception) {
|
|
|
686 |
$warning['warningcode'] = $e->errorcode;
|
|
|
687 |
} else {
|
|
|
688 |
$warning['warningcode'] = $e->getCode();
|
|
|
689 |
}
|
|
|
690 |
$warning['message'] = $e->getMessage();
|
|
|
691 |
$warnings[] = $warning;
|
|
|
692 |
}
|
|
|
693 |
}
|
|
|
694 |
}
|
|
|
695 |
|
|
|
696 |
return ['warnings' => $warnings];
|
|
|
697 |
}
|
|
|
698 |
|
|
|
699 |
/**
|
|
|
700 |
* Returns description of method result value
|
|
|
701 |
*
|
|
|
702 |
* @return external_description
|
|
|
703 |
* @since Moodle 2.2
|
|
|
704 |
*/
|
|
|
705 |
public static function update_users_returns() {
|
|
|
706 |
return new external_single_structure(
|
|
|
707 |
array(
|
|
|
708 |
'warnings' => new external_warnings()
|
|
|
709 |
)
|
|
|
710 |
);
|
|
|
711 |
}
|
|
|
712 |
|
|
|
713 |
/**
|
|
|
714 |
* Returns description of method parameters
|
|
|
715 |
*
|
|
|
716 |
* @return external_function_parameters
|
|
|
717 |
* @since Moodle 2.4
|
|
|
718 |
*/
|
|
|
719 |
public static function get_users_by_field_parameters() {
|
|
|
720 |
return new external_function_parameters(
|
|
|
721 |
array(
|
|
|
722 |
'field' => new external_value(PARAM_ALPHA, 'the search field can be
|
|
|
723 |
\'id\' or \'idnumber\' or \'username\' or \'email\''),
|
|
|
724 |
'values' => new external_multiple_structure(
|
|
|
725 |
new external_value(PARAM_RAW, 'the value to match'))
|
|
|
726 |
)
|
|
|
727 |
);
|
|
|
728 |
}
|
|
|
729 |
|
|
|
730 |
/**
|
|
|
731 |
* Get user information for a unique field.
|
|
|
732 |
*
|
|
|
733 |
* @throws coding_exception
|
|
|
734 |
* @throws invalid_parameter_exception
|
|
|
735 |
* @param string $field
|
|
|
736 |
* @param array $values
|
|
|
737 |
* @return array An array of arrays containg user profiles.
|
|
|
738 |
* @since Moodle 2.4
|
|
|
739 |
*/
|
|
|
740 |
public static function get_users_by_field($field, $values) {
|
|
|
741 |
global $CFG, $USER, $DB;
|
|
|
742 |
require_once($CFG->dirroot . "/user/lib.php");
|
|
|
743 |
|
|
|
744 |
$params = self::validate_parameters(self::get_users_by_field_parameters(),
|
|
|
745 |
array('field' => $field, 'values' => $values));
|
|
|
746 |
|
|
|
747 |
// This array will keep all the users that are allowed to be searched,
|
|
|
748 |
// according to the current user's privileges.
|
|
|
749 |
$cleanedvalues = array();
|
|
|
750 |
|
|
|
751 |
switch ($field) {
|
|
|
752 |
case 'id':
|
|
|
753 |
$paramtype = core_user::get_property_type('id');
|
|
|
754 |
break;
|
|
|
755 |
case 'idnumber':
|
|
|
756 |
$paramtype = core_user::get_property_type('idnumber');
|
|
|
757 |
break;
|
|
|
758 |
case 'username':
|
|
|
759 |
$paramtype = core_user::get_property_type('username');
|
|
|
760 |
break;
|
|
|
761 |
case 'email':
|
|
|
762 |
$paramtype = core_user::get_property_type('email');
|
|
|
763 |
break;
|
|
|
764 |
default:
|
|
|
765 |
throw new coding_exception('invalid field parameter',
|
|
|
766 |
'The search field \'' . $field . '\' is not supported, look at the web service documentation');
|
|
|
767 |
}
|
|
|
768 |
|
|
|
769 |
// Clean the values.
|
|
|
770 |
foreach ($values as $value) {
|
|
|
771 |
$cleanedvalue = clean_param($value, $paramtype);
|
|
|
772 |
if ( $value != $cleanedvalue) {
|
|
|
773 |
throw new invalid_parameter_exception('The field \'' . $field .
|
|
|
774 |
'\' value is invalid: ' . $value . '(cleaned value: '.$cleanedvalue.')');
|
|
|
775 |
}
|
|
|
776 |
$cleanedvalues[] = $cleanedvalue;
|
|
|
777 |
}
|
|
|
778 |
|
|
|
779 |
// Retrieve the users.
|
|
|
780 |
$users = $DB->get_records_list('user', $field, $cleanedvalues, 'id');
|
|
|
781 |
|
|
|
782 |
$context = context_system::instance();
|
|
|
783 |
self::validate_context($context);
|
|
|
784 |
|
|
|
785 |
// Finally retrieve each users information.
|
|
|
786 |
$returnedusers = array();
|
|
|
787 |
foreach ($users as $user) {
|
|
|
788 |
$userdetails = user_get_user_details_courses($user);
|
|
|
789 |
|
|
|
790 |
// Return the user only if the searched field is returned.
|
|
|
791 |
// Otherwise it means that the $USER was not allowed to search the returned user.
|
|
|
792 |
if (!empty($userdetails) and !empty($userdetails[$field])) {
|
|
|
793 |
$returnedusers[] = $userdetails;
|
|
|
794 |
}
|
|
|
795 |
}
|
|
|
796 |
|
|
|
797 |
return $returnedusers;
|
|
|
798 |
}
|
|
|
799 |
|
|
|
800 |
/**
|
|
|
801 |
* Returns description of method result value
|
|
|
802 |
*
|
|
|
803 |
* @return external_multiple_structure
|
|
|
804 |
* @since Moodle 2.4
|
|
|
805 |
*/
|
|
|
806 |
public static function get_users_by_field_returns() {
|
|
|
807 |
return new external_multiple_structure(self::user_description());
|
|
|
808 |
}
|
|
|
809 |
|
|
|
810 |
|
|
|
811 |
/**
|
|
|
812 |
* Returns description of get_users() parameters.
|
|
|
813 |
*
|
|
|
814 |
* @return external_function_parameters
|
|
|
815 |
* @since Moodle 2.5
|
|
|
816 |
*/
|
|
|
817 |
public static function get_users_parameters() {
|
|
|
818 |
return new external_function_parameters(
|
|
|
819 |
array(
|
|
|
820 |
'criteria' => new external_multiple_structure(
|
|
|
821 |
new external_single_structure(
|
|
|
822 |
array(
|
|
|
823 |
'key' => new external_value(PARAM_ALPHA, 'the user column to search, expected keys (value format) are:
|
|
|
824 |
"id" (int) matching user id,
|
|
|
825 |
"lastname" (string) user last name (Note: you can use % for searching but it may be considerably slower!),
|
|
|
826 |
"firstname" (string) user first name (Note: you can use % for searching but it may be considerably slower!),
|
|
|
827 |
"idnumber" (string) matching user idnumber,
|
|
|
828 |
"username" (string) matching user username,
|
|
|
829 |
"email" (string) user email (Note: you can use % for searching but it may be considerably slower!),
|
|
|
830 |
"auth" (string) matching user auth plugin'),
|
|
|
831 |
'value' => new external_value(PARAM_RAW, 'the value to search')
|
|
|
832 |
)
|
|
|
833 |
), 'the key/value pairs to be considered in user search. Values can not be empty.
|
|
|
834 |
Specify different keys only once (fullname => \'user1\', auth => \'manual\', ...) -
|
|
|
835 |
key occurences are forbidden.
|
|
|
836 |
The search is executed with AND operator on the criterias. Invalid criterias (keys) are ignored,
|
|
|
837 |
the search is still executed on the valid criterias.
|
|
|
838 |
You can search without criteria, but the function is not designed for it.
|
|
|
839 |
It could very slow or timeout. The function is designed to search some specific users.'
|
|
|
840 |
)
|
|
|
841 |
)
|
|
|
842 |
);
|
|
|
843 |
}
|
|
|
844 |
|
|
|
845 |
/**
|
|
|
846 |
* Retrieve matching user.
|
|
|
847 |
*
|
|
|
848 |
* @throws moodle_exception
|
|
|
849 |
* @param array $criteria the allowed array keys are id/lastname/firstname/idnumber/username/email/auth.
|
|
|
850 |
* @return array An array of arrays containing user profiles.
|
|
|
851 |
* @since Moodle 2.5
|
|
|
852 |
*/
|
|
|
853 |
public static function get_users($criteria = array()) {
|
|
|
854 |
global $CFG, $USER, $DB;
|
|
|
855 |
|
|
|
856 |
require_once($CFG->dirroot . "/user/lib.php");
|
|
|
857 |
|
|
|
858 |
$params = self::validate_parameters(self::get_users_parameters(),
|
|
|
859 |
array('criteria' => $criteria));
|
|
|
860 |
|
|
|
861 |
// Validate the criteria and retrieve the users.
|
|
|
862 |
$users = array();
|
|
|
863 |
$warnings = array();
|
|
|
864 |
$sqlparams = array();
|
|
|
865 |
$usedkeys = array();
|
|
|
866 |
|
|
|
867 |
// Do not retrieve deleted users.
|
|
|
868 |
$sql = ' deleted = 0';
|
|
|
869 |
|
|
|
870 |
foreach ($params['criteria'] as $criteriaindex => $criteria) {
|
|
|
871 |
|
|
|
872 |
// Check that the criteria has never been used.
|
|
|
873 |
if (array_key_exists($criteria['key'], $usedkeys)) {
|
|
|
874 |
throw new moodle_exception('keyalreadyset', '', '', null, 'The key ' . $criteria['key'] . ' can only be sent once');
|
|
|
875 |
} else {
|
|
|
876 |
$usedkeys[$criteria['key']] = true;
|
|
|
877 |
}
|
|
|
878 |
|
|
|
879 |
$invalidcriteria = false;
|
|
|
880 |
// Clean the parameters.
|
|
|
881 |
$paramtype = PARAM_RAW;
|
|
|
882 |
switch ($criteria['key']) {
|
|
|
883 |
case 'id':
|
|
|
884 |
$paramtype = core_user::get_property_type('id');
|
|
|
885 |
break;
|
|
|
886 |
case 'idnumber':
|
|
|
887 |
$paramtype = core_user::get_property_type('idnumber');
|
|
|
888 |
break;
|
|
|
889 |
case 'username':
|
|
|
890 |
$paramtype = core_user::get_property_type('username');
|
|
|
891 |
break;
|
|
|
892 |
case 'email':
|
|
|
893 |
// We use PARAM_RAW to allow searches with %.
|
|
|
894 |
$paramtype = core_user::get_property_type('email');
|
|
|
895 |
break;
|
|
|
896 |
case 'auth':
|
|
|
897 |
$paramtype = core_user::get_property_type('auth');
|
|
|
898 |
break;
|
|
|
899 |
case 'lastname':
|
|
|
900 |
case 'firstname':
|
|
|
901 |
$paramtype = core_user::get_property_type('firstname');
|
|
|
902 |
break;
|
|
|
903 |
default:
|
|
|
904 |
// Send back a warning that this search key is not supported in this version.
|
|
|
905 |
// This warning will make the function extandable without breaking clients.
|
|
|
906 |
$warnings[] = array(
|
|
|
907 |
'item' => $criteria['key'],
|
|
|
908 |
'warningcode' => 'invalidfieldparameter',
|
|
|
909 |
'message' =>
|
|
|
910 |
'The search key \'' . $criteria['key'] . '\' is not supported, look at the web service documentation'
|
|
|
911 |
);
|
|
|
912 |
// Do not add this invalid criteria to the created SQL request.
|
|
|
913 |
$invalidcriteria = true;
|
|
|
914 |
unset($params['criteria'][$criteriaindex]);
|
|
|
915 |
break;
|
|
|
916 |
}
|
|
|
917 |
|
|
|
918 |
if (!$invalidcriteria) {
|
|
|
919 |
$cleanedvalue = clean_param($criteria['value'], $paramtype);
|
|
|
920 |
|
|
|
921 |
$sql .= ' AND ';
|
|
|
922 |
|
|
|
923 |
// Create the SQL.
|
|
|
924 |
switch ($criteria['key']) {
|
|
|
925 |
case 'id':
|
|
|
926 |
case 'idnumber':
|
|
|
927 |
case 'username':
|
|
|
928 |
case 'auth':
|
|
|
929 |
$sql .= $criteria['key'] . ' = :' . $criteria['key'];
|
|
|
930 |
$sqlparams[$criteria['key']] = $cleanedvalue;
|
|
|
931 |
break;
|
|
|
932 |
case 'email':
|
|
|
933 |
case 'lastname':
|
|
|
934 |
case 'firstname':
|
|
|
935 |
$sql .= $DB->sql_like($criteria['key'], ':' . $criteria['key'], false);
|
|
|
936 |
$sqlparams[$criteria['key']] = $cleanedvalue;
|
|
|
937 |
break;
|
|
|
938 |
default:
|
|
|
939 |
break;
|
|
|
940 |
}
|
|
|
941 |
}
|
|
|
942 |
}
|
|
|
943 |
|
|
|
944 |
$users = $DB->get_records_select('user', $sql, $sqlparams, 'id ASC');
|
|
|
945 |
|
|
|
946 |
// Finally retrieve each users information.
|
|
|
947 |
$returnedusers = array();
|
|
|
948 |
foreach ($users as $user) {
|
|
|
949 |
$userdetails = user_get_user_details_courses($user);
|
|
|
950 |
|
|
|
951 |
// Return the user only if all the searched fields are returned.
|
|
|
952 |
// Otherwise it means that the $USER was not allowed to search the returned user.
|
|
|
953 |
if (!empty($userdetails)) {
|
|
|
954 |
$validuser = true;
|
|
|
955 |
|
|
|
956 |
foreach ($params['criteria'] as $criteria) {
|
|
|
957 |
if (empty($userdetails[$criteria['key']])) {
|
|
|
958 |
$validuser = false;
|
|
|
959 |
}
|
|
|
960 |
}
|
|
|
961 |
|
|
|
962 |
if ($validuser) {
|
|
|
963 |
$returnedusers[] = $userdetails;
|
|
|
964 |
}
|
|
|
965 |
}
|
|
|
966 |
}
|
|
|
967 |
|
|
|
968 |
return array('users' => $returnedusers, 'warnings' => $warnings);
|
|
|
969 |
}
|
|
|
970 |
|
|
|
971 |
/**
|
|
|
972 |
* Returns description of get_users result value.
|
|
|
973 |
*
|
|
|
974 |
* @return external_description
|
|
|
975 |
* @since Moodle 2.5
|
|
|
976 |
*/
|
|
|
977 |
public static function get_users_returns() {
|
|
|
978 |
return new external_single_structure(
|
|
|
979 |
array('users' => new external_multiple_structure(
|
|
|
980 |
self::user_description()
|
|
|
981 |
),
|
|
|
982 |
'warnings' => new external_warnings('always set to \'key\'', 'faulty key name')
|
|
|
983 |
)
|
|
|
984 |
);
|
|
|
985 |
}
|
|
|
986 |
|
|
|
987 |
/**
|
|
|
988 |
* Returns description of method parameters
|
|
|
989 |
*
|
|
|
990 |
* @return external_function_parameters
|
|
|
991 |
* @since Moodle 2.2
|
|
|
992 |
*/
|
|
|
993 |
public static function get_course_user_profiles_parameters() {
|
|
|
994 |
return new external_function_parameters(
|
|
|
995 |
array(
|
|
|
996 |
'userlist' => new external_multiple_structure(
|
|
|
997 |
new external_single_structure(
|
|
|
998 |
array(
|
|
|
999 |
'userid' => new external_value(core_user::get_property_type('id'), 'userid'),
|
|
|
1000 |
'courseid' => new external_value(PARAM_INT, 'courseid'),
|
|
|
1001 |
)
|
|
|
1002 |
)
|
|
|
1003 |
)
|
|
|
1004 |
)
|
|
|
1005 |
);
|
|
|
1006 |
}
|
|
|
1007 |
|
|
|
1008 |
/**
|
|
|
1009 |
* Get course participant's details
|
|
|
1010 |
*
|
|
|
1011 |
* @param array $userlist array of user ids and according course ids
|
|
|
1012 |
* @return array An array of arrays describing course participants
|
|
|
1013 |
* @since Moodle 2.2
|
|
|
1014 |
*/
|
|
|
1015 |
public static function get_course_user_profiles($userlist) {
|
|
|
1016 |
global $CFG, $USER, $DB;
|
|
|
1017 |
require_once($CFG->dirroot . "/user/lib.php");
|
|
|
1018 |
$params = self::validate_parameters(self::get_course_user_profiles_parameters(), array('userlist' => $userlist));
|
|
|
1019 |
|
|
|
1020 |
$userids = array();
|
|
|
1021 |
$courseids = array();
|
|
|
1022 |
foreach ($params['userlist'] as $value) {
|
|
|
1023 |
$userids[] = $value['userid'];
|
|
|
1024 |
$courseids[$value['userid']] = $value['courseid'];
|
|
|
1025 |
}
|
|
|
1026 |
|
|
|
1027 |
// Cache all courses.
|
|
|
1028 |
$courses = array();
|
|
|
1029 |
list($sqlcourseids, $params) = $DB->get_in_or_equal(array_unique($courseids), SQL_PARAMS_NAMED);
|
|
|
1030 |
$cselect = ', ' . context_helper::get_preload_record_columns_sql('ctx');
|
|
|
1031 |
$cjoin = "LEFT JOIN {context} ctx ON (ctx.instanceid = c.id AND ctx.contextlevel = :contextlevel)";
|
|
|
1032 |
$params['contextlevel'] = CONTEXT_COURSE;
|
|
|
1033 |
$coursesql = "SELECT c.* $cselect
|
|
|
1034 |
FROM {course} c $cjoin
|
|
|
1035 |
WHERE c.id $sqlcourseids";
|
|
|
1036 |
$rs = $DB->get_recordset_sql($coursesql, $params);
|
|
|
1037 |
foreach ($rs as $course) {
|
|
|
1038 |
// Adding course contexts to cache.
|
|
|
1039 |
context_helper::preload_from_record($course);
|
|
|
1040 |
// Cache courses.
|
|
|
1041 |
$courses[$course->id] = $course;
|
|
|
1042 |
}
|
|
|
1043 |
$rs->close();
|
|
|
1044 |
|
|
|
1045 |
list($sqluserids, $params) = $DB->get_in_or_equal($userids, SQL_PARAMS_NAMED);
|
|
|
1046 |
$uselect = ', ' . context_helper::get_preload_record_columns_sql('ctx');
|
|
|
1047 |
$ujoin = "LEFT JOIN {context} ctx ON (ctx.instanceid = u.id AND ctx.contextlevel = :contextlevel)";
|
|
|
1048 |
$params['contextlevel'] = CONTEXT_USER;
|
|
|
1049 |
$usersql = "SELECT u.* $uselect
|
|
|
1050 |
FROM {user} u $ujoin
|
|
|
1051 |
WHERE u.id $sqluserids";
|
|
|
1052 |
$users = $DB->get_recordset_sql($usersql, $params);
|
|
|
1053 |
$result = array();
|
|
|
1054 |
foreach ($users as $user) {
|
|
|
1055 |
if (!empty($user->deleted)) {
|
|
|
1056 |
continue;
|
|
|
1057 |
}
|
|
|
1058 |
context_helper::preload_from_record($user);
|
|
|
1059 |
$course = $courses[$courseids[$user->id]];
|
|
|
1060 |
$context = context_course::instance($courseids[$user->id], IGNORE_MISSING);
|
|
|
1061 |
self::validate_context($context);
|
|
|
1062 |
if ($userarray = user_get_user_details($user, $course)) {
|
|
|
1063 |
$result[] = $userarray;
|
|
|
1064 |
}
|
|
|
1065 |
}
|
|
|
1066 |
|
|
|
1067 |
$users->close();
|
|
|
1068 |
|
|
|
1069 |
return $result;
|
|
|
1070 |
}
|
|
|
1071 |
|
|
|
1072 |
/**
|
|
|
1073 |
* Returns description of method result value
|
|
|
1074 |
*
|
|
|
1075 |
* @return external_description
|
|
|
1076 |
* @since Moodle 2.2
|
|
|
1077 |
*/
|
|
|
1078 |
public static function get_course_user_profiles_returns() {
|
|
|
1079 |
$additionalfields = array(
|
|
|
1080 |
'groups' => new external_multiple_structure(
|
|
|
1081 |
new external_single_structure(
|
|
|
1082 |
array(
|
|
|
1083 |
'id' => new external_value(PARAM_INT, 'group id'),
|
|
|
1084 |
'name' => new external_value(PARAM_RAW, 'group name'),
|
|
|
1085 |
'description' => new external_value(PARAM_RAW, 'group description'),
|
|
|
1086 |
'descriptionformat' => new external_format_value('description'),
|
|
|
1087 |
)
|
|
|
1088 |
), 'user groups', VALUE_OPTIONAL),
|
|
|
1089 |
'roles' => new external_multiple_structure(
|
|
|
1090 |
new external_single_structure(
|
|
|
1091 |
array(
|
|
|
1092 |
'roleid' => new external_value(PARAM_INT, 'role id'),
|
|
|
1093 |
'name' => new external_value(PARAM_RAW, 'role name'),
|
|
|
1094 |
'shortname' => new external_value(PARAM_ALPHANUMEXT, 'role shortname'),
|
|
|
1095 |
'sortorder' => new external_value(PARAM_INT, 'role sortorder')
|
|
|
1096 |
)
|
|
|
1097 |
), 'user roles', VALUE_OPTIONAL),
|
|
|
1098 |
'enrolledcourses' => new external_multiple_structure(
|
|
|
1099 |
new external_single_structure(
|
|
|
1100 |
array(
|
|
|
1101 |
'id' => new external_value(PARAM_INT, 'Id of the course'),
|
|
|
1102 |
'fullname' => new external_value(PARAM_RAW, 'Fullname of the course'),
|
|
|
1103 |
'shortname' => new external_value(PARAM_RAW, 'Shortname of the course')
|
|
|
1104 |
)
|
|
|
1105 |
), 'Courses where the user is enrolled - limited by which courses the user is able to see', VALUE_OPTIONAL)
|
|
|
1106 |
);
|
|
|
1107 |
|
|
|
1108 |
return new external_multiple_structure(self::user_description($additionalfields));
|
|
|
1109 |
}
|
|
|
1110 |
|
|
|
1111 |
/**
|
|
|
1112 |
* Create user return value description.
|
|
|
1113 |
*
|
|
|
1114 |
* @param array $additionalfields some additional field
|
|
|
1115 |
* @return external_description
|
|
|
1116 |
*/
|
|
|
1117 |
public static function user_description($additionalfields = array()) {
|
|
|
1118 |
$userfields = array(
|
|
|
1119 |
'id' => new external_value(core_user::get_property_type('id'), 'ID of the user'),
|
|
|
1120 |
'username' => new external_value(core_user::get_property_type('username'), 'The username', VALUE_OPTIONAL),
|
|
|
1121 |
'firstname' => new external_value(core_user::get_property_type('firstname'), 'The first name(s) of the user', VALUE_OPTIONAL),
|
|
|
1122 |
'lastname' => new external_value(core_user::get_property_type('lastname'), 'The family name of the user', VALUE_OPTIONAL),
|
|
|
1123 |
'fullname' => new external_value(core_user::get_property_type('firstname'), 'The fullname of the user'),
|
|
|
1124 |
'email' => new external_value(core_user::get_property_type('email'), 'An email address - allow email as root@localhost', VALUE_OPTIONAL),
|
|
|
1125 |
'address' => new external_value(core_user::get_property_type('address'), 'Postal address', VALUE_OPTIONAL),
|
|
|
1126 |
'phone1' => new external_value(core_user::get_property_type('phone1'), 'Phone 1', VALUE_OPTIONAL),
|
|
|
1127 |
'phone2' => new external_value(core_user::get_property_type('phone2'), 'Phone 2', VALUE_OPTIONAL),
|
|
|
1128 |
'department' => new external_value(core_user::get_property_type('department'), 'department', VALUE_OPTIONAL),
|
|
|
1129 |
'institution' => new external_value(core_user::get_property_type('institution'), 'institution', VALUE_OPTIONAL),
|
|
|
1130 |
'idnumber' => new external_value(core_user::get_property_type('idnumber'), 'An arbitrary ID code number perhaps from the institution', VALUE_OPTIONAL),
|
|
|
1131 |
'interests' => new external_value(PARAM_TEXT, 'user interests (separated by commas)', VALUE_OPTIONAL),
|
|
|
1132 |
'firstaccess' => new external_value(core_user::get_property_type('firstaccess'), 'first access to the site (0 if never)', VALUE_OPTIONAL),
|
|
|
1133 |
'lastaccess' => new external_value(core_user::get_property_type('lastaccess'), 'last access to the site (0 if never)', VALUE_OPTIONAL),
|
|
|
1134 |
'auth' => new external_value(core_user::get_property_type('auth'), 'Auth plugins include manual, ldap, etc', VALUE_OPTIONAL),
|
|
|
1135 |
'suspended' => new external_value(core_user::get_property_type('suspended'), 'Suspend user account, either false to enable user login or true to disable it', VALUE_OPTIONAL),
|
|
|
1136 |
'confirmed' => new external_value(core_user::get_property_type('confirmed'), 'Active user: 1 if confirmed, 0 otherwise', VALUE_OPTIONAL),
|
|
|
1137 |
'lang' => new external_value(core_user::get_property_type('lang'), 'Language code such as "en", must exist on server', VALUE_OPTIONAL),
|
|
|
1138 |
'calendartype' => new external_value(core_user::get_property_type('calendartype'), 'Calendar type such as "gregorian", must exist on server', VALUE_OPTIONAL),
|
|
|
1139 |
'theme' => new external_value(core_user::get_property_type('theme'), 'Theme name such as "standard", must exist on server', VALUE_OPTIONAL),
|
|
|
1140 |
'timezone' => new external_value(core_user::get_property_type('timezone'), 'Timezone code such as Australia/Perth, or 99 for default', VALUE_OPTIONAL),
|
|
|
1141 |
'mailformat' => new external_value(core_user::get_property_type('mailformat'), 'Mail format code is 0 for plain text, 1 for HTML etc', VALUE_OPTIONAL),
|
|
|
1142 |
'trackforums' => new external_value(core_user::get_property_type('trackforums'),
|
|
|
1143 |
'Whether the user is tracking forums.', VALUE_OPTIONAL),
|
|
|
1144 |
'description' => new external_value(core_user::get_property_type('description'), 'User profile description', VALUE_OPTIONAL),
|
|
|
1145 |
'descriptionformat' => new external_format_value(core_user::get_property_type('descriptionformat'), VALUE_OPTIONAL),
|
|
|
1146 |
'city' => new external_value(core_user::get_property_type('city'), 'Home city of the user', VALUE_OPTIONAL),
|
|
|
1147 |
'country' => new external_value(core_user::get_property_type('country'), 'Home country code of the user, such as AU or CZ', VALUE_OPTIONAL),
|
|
|
1148 |
'profileimageurlsmall' => new external_value(PARAM_URL, 'User image profile URL - small version'),
|
|
|
1149 |
'profileimageurl' => new external_value(PARAM_URL, 'User image profile URL - big version'),
|
|
|
1150 |
'customfields' => new external_multiple_structure(
|
|
|
1151 |
new external_single_structure(
|
|
|
1152 |
array(
|
|
|
1153 |
'type' => new external_value(PARAM_ALPHANUMEXT, 'The type of the custom field - text field, checkbox...'),
|
|
|
1154 |
'value' => new external_value(PARAM_RAW, 'The value of the custom field (as stored in the database)'),
|
|
|
1155 |
'displayvalue' => new external_value(PARAM_RAW, 'The value of the custom field for display',
|
|
|
1156 |
VALUE_OPTIONAL),
|
|
|
1157 |
'name' => new external_value(PARAM_RAW, 'The name of the custom field'),
|
|
|
1158 |
'shortname' => new external_value(PARAM_RAW, 'The shortname of the custom field - to be able to build the field class in the code'),
|
|
|
1159 |
)
|
|
|
1160 |
), 'User custom fields (also known as user profile fields)', VALUE_OPTIONAL),
|
|
|
1161 |
'preferences' => new external_multiple_structure(
|
|
|
1162 |
new external_single_structure(
|
|
|
1163 |
array(
|
|
|
1164 |
'name' => new external_value(PARAM_RAW, 'The name of the preferences'),
|
|
|
1165 |
'value' => new external_value(PARAM_RAW, 'The value of the preference'),
|
|
|
1166 |
)
|
|
|
1167 |
), 'Users preferences', VALUE_OPTIONAL)
|
|
|
1168 |
);
|
|
|
1169 |
if (!empty($additionalfields)) {
|
|
|
1170 |
$userfields = array_merge($userfields, $additionalfields);
|
|
|
1171 |
}
|
|
|
1172 |
return new external_single_structure($userfields);
|
|
|
1173 |
}
|
|
|
1174 |
|
|
|
1175 |
/**
|
|
|
1176 |
* Returns description of method parameters
|
|
|
1177 |
*
|
|
|
1178 |
* @return external_function_parameters
|
|
|
1179 |
* @since Moodle 2.6
|
|
|
1180 |
*/
|
|
|
1181 |
public static function add_user_private_files_parameters() {
|
|
|
1182 |
return new external_function_parameters(
|
|
|
1183 |
array(
|
|
|
1184 |
'draftid' => new external_value(PARAM_INT, 'draft area id')
|
|
|
1185 |
)
|
|
|
1186 |
);
|
|
|
1187 |
}
|
|
|
1188 |
|
|
|
1189 |
/**
|
|
|
1190 |
* Copy files from a draft area to users private files area.
|
|
|
1191 |
*
|
|
|
1192 |
* @throws invalid_parameter_exception
|
|
|
1193 |
* @throws moodle_exception
|
|
|
1194 |
* @param int $draftid Id of a draft area containing files.
|
|
|
1195 |
* @return array An array of warnings
|
|
|
1196 |
* @since Moodle 2.6
|
|
|
1197 |
*/
|
|
|
1198 |
public static function add_user_private_files($draftid) {
|
|
|
1199 |
global $CFG, $USER;
|
|
|
1200 |
require_once($CFG->libdir . "/filelib.php");
|
|
|
1201 |
|
|
|
1202 |
$params = self::validate_parameters(self::add_user_private_files_parameters(), array('draftid' => $draftid));
|
|
|
1203 |
|
|
|
1204 |
if (isguestuser()) {
|
|
|
1205 |
throw new invalid_parameter_exception('Guest users cannot upload files');
|
|
|
1206 |
}
|
|
|
1207 |
|
|
|
1208 |
$context = context_user::instance($USER->id);
|
|
|
1209 |
require_capability('moodle/user:manageownfiles', $context);
|
|
|
1210 |
|
|
|
1211 |
$maxbytes = $CFG->userquota;
|
|
|
1212 |
$maxareabytes = $CFG->userquota;
|
|
|
1213 |
if (has_capability('moodle/user:ignoreuserquota', $context)) {
|
|
|
1214 |
$maxbytes = USER_CAN_IGNORE_FILE_SIZE_LIMITS;
|
|
|
1215 |
$maxareabytes = FILE_AREA_MAX_BYTES_UNLIMITED;
|
|
|
1216 |
} else {
|
|
|
1217 |
// Get current used space for this user (private files only).
|
|
|
1218 |
$fileareainfo = file_get_file_area_info($context->id, 'user', 'private');
|
|
|
1219 |
$usedspace = $fileareainfo['filesize_without_references'];
|
|
|
1220 |
|
|
|
1221 |
// Get the total size of the new files we want to add to private files.
|
|
|
1222 |
$newfilesinfo = file_get_draft_area_info($params['draftid']);
|
|
|
1223 |
|
|
|
1224 |
if (($newfilesinfo['filesize_without_references'] + $usedspace) > $maxareabytes) {
|
|
|
1225 |
throw new moodle_exception('maxareabytes');
|
|
|
1226 |
}
|
|
|
1227 |
}
|
|
|
1228 |
|
|
|
1229 |
$options = array('subdirs' => 1,
|
|
|
1230 |
'maxbytes' => $maxbytes,
|
|
|
1231 |
'maxfiles' => -1,
|
|
|
1232 |
'areamaxbytes' => $maxareabytes);
|
|
|
1233 |
|
|
|
1234 |
file_merge_files_from_draft_area_into_filearea($draftid, $context->id, 'user', 'private', 0, $options);
|
|
|
1235 |
|
|
|
1236 |
return null;
|
|
|
1237 |
}
|
|
|
1238 |
|
|
|
1239 |
/**
|
|
|
1240 |
* Returns description of method result value
|
|
|
1241 |
*
|
|
|
1242 |
* @return external_description
|
|
|
1243 |
* @since Moodle 2.2
|
|
|
1244 |
*/
|
|
|
1245 |
public static function add_user_private_files_returns() {
|
|
|
1246 |
return null;
|
|
|
1247 |
}
|
|
|
1248 |
|
|
|
1249 |
/**
|
|
|
1250 |
* Returns description of method parameters.
|
|
|
1251 |
*
|
|
|
1252 |
* @return external_function_parameters
|
|
|
1253 |
* @since Moodle 2.6
|
|
|
1254 |
*/
|
|
|
1255 |
public static function add_user_device_parameters() {
|
|
|
1256 |
return new external_function_parameters(
|
|
|
1257 |
array(
|
|
|
1258 |
'appid' => new external_value(PARAM_NOTAGS, 'the app id, usually something like com.moodle.moodlemobile'),
|
|
|
1259 |
'name' => new external_value(PARAM_NOTAGS, 'the device name, \'occam\' or \'iPhone\' etc.'),
|
|
|
1260 |
'model' => new external_value(PARAM_NOTAGS, 'the device model \'Nexus4\' or \'iPad1,1\' etc.'),
|
|
|
1261 |
'platform' => new external_value(PARAM_NOTAGS, 'the device platform \'iOS\' or \'Android\' etc.'),
|
|
|
1262 |
'version' => new external_value(PARAM_NOTAGS, 'the device version \'6.1.2\' or \'4.2.2\' etc.'),
|
|
|
1263 |
'pushid' => new external_value(PARAM_RAW, 'the device PUSH token/key/identifier/registration id'),
|
|
|
1264 |
'uuid' => new external_value(PARAM_RAW, 'the device UUID'),
|
|
|
1265 |
'publickey' => new external_value(PARAM_RAW, 'the app generated public key', VALUE_DEFAULT, null),
|
|
|
1266 |
)
|
|
|
1267 |
);
|
|
|
1268 |
}
|
|
|
1269 |
|
|
|
1270 |
/**
|
|
|
1271 |
* Add a user device in Moodle database (for PUSH notifications usually).
|
|
|
1272 |
*
|
|
|
1273 |
* @throws moodle_exception
|
|
|
1274 |
* @param string $appid The app id, usually something like com.moodle.moodlemobile.
|
|
|
1275 |
* @param string $name The device name, occam or iPhone etc.
|
|
|
1276 |
* @param string $model The device model Nexus4 or iPad1.1 etc.
|
|
|
1277 |
* @param string $platform The device platform iOs or Android etc.
|
|
|
1278 |
* @param string $version The device version 6.1.2 or 4.2.2 etc.
|
|
|
1279 |
* @param string $pushid The device PUSH token/key/identifier/registration id.
|
|
|
1280 |
* @param string $uuid The device UUID.
|
|
|
1281 |
* @param string $publickey The app generated public key
|
|
|
1282 |
* @return array List of possible warnings.
|
|
|
1283 |
* @since Moodle 2.6
|
|
|
1284 |
*/
|
|
|
1285 |
public static function add_user_device($appid, $name, $model, $platform, $version, $pushid, $uuid, $publickey = null) {
|
|
|
1286 |
global $CFG, $USER, $DB;
|
|
|
1287 |
require_once($CFG->dirroot . "/user/lib.php");
|
|
|
1288 |
|
|
|
1289 |
$params = self::validate_parameters(self::add_user_device_parameters(),
|
|
|
1290 |
array('appid' => $appid,
|
|
|
1291 |
'name' => $name,
|
|
|
1292 |
'model' => $model,
|
|
|
1293 |
'platform' => $platform,
|
|
|
1294 |
'version' => $version,
|
|
|
1295 |
'pushid' => $pushid,
|
|
|
1296 |
'uuid' => $uuid,
|
|
|
1297 |
'publickey' => $publickey,
|
|
|
1298 |
));
|
|
|
1299 |
|
|
|
1300 |
$warnings = array();
|
|
|
1301 |
|
|
|
1302 |
// Prevent duplicate keys for users.
|
|
|
1303 |
if ($DB->get_record('user_devices', array('pushid' => $params['pushid'], 'userid' => $USER->id))) {
|
|
|
1304 |
$warnings['warning'][] = array(
|
|
|
1305 |
'item' => $params['pushid'],
|
|
|
1306 |
'warningcode' => 'existingkeyforthisuser',
|
|
|
1307 |
'message' => 'This key is already stored for this user'
|
|
|
1308 |
);
|
|
|
1309 |
return $warnings;
|
|
|
1310 |
}
|
|
|
1311 |
|
|
|
1312 |
// Notice that we can have multiple devices because previously it was allowed to have repeated ones.
|
|
|
1313 |
// Since we don't have a clear way to decide which one is the more appropiate, we update all.
|
|
|
1314 |
if ($userdevices = $DB->get_records('user_devices', array('uuid' => $params['uuid'],
|
|
|
1315 |
'appid' => $params['appid'], 'userid' => $USER->id))) {
|
|
|
1316 |
|
|
|
1317 |
foreach ($userdevices as $userdevice) {
|
|
|
1318 |
$userdevice->version = $params['version']; // Maybe the user upgraded the device.
|
|
|
1319 |
$userdevice->pushid = $params['pushid'];
|
|
|
1320 |
$userdevice->publickey = $params['publickey'];
|
|
|
1321 |
$userdevice->timemodified = time();
|
|
|
1322 |
$DB->update_record('user_devices', $userdevice);
|
|
|
1323 |
}
|
|
|
1324 |
|
|
|
1325 |
} else {
|
|
|
1326 |
$userdevice = new stdclass;
|
|
|
1327 |
$userdevice->userid = $USER->id;
|
|
|
1328 |
$userdevice->appid = $params['appid'];
|
|
|
1329 |
$userdevice->name = $params['name'];
|
|
|
1330 |
$userdevice->model = $params['model'];
|
|
|
1331 |
$userdevice->platform = $params['platform'];
|
|
|
1332 |
$userdevice->version = $params['version'];
|
|
|
1333 |
$userdevice->pushid = $params['pushid'];
|
|
|
1334 |
$userdevice->uuid = $params['uuid'];
|
|
|
1335 |
$userdevice->publickey = $params['publickey'];
|
|
|
1336 |
$userdevice->timecreated = time();
|
|
|
1337 |
$userdevice->timemodified = $userdevice->timecreated;
|
|
|
1338 |
|
|
|
1339 |
if (!$DB->insert_record('user_devices', $userdevice)) {
|
|
|
1340 |
throw new moodle_exception("There was a problem saving in the database the device with key: " . $params['pushid']);
|
|
|
1341 |
}
|
|
|
1342 |
}
|
|
|
1343 |
|
|
|
1344 |
return $warnings;
|
|
|
1345 |
}
|
|
|
1346 |
|
|
|
1347 |
/**
|
|
|
1348 |
* Returns description of method result value.
|
|
|
1349 |
*
|
|
|
1350 |
* @return external_multiple_structure
|
|
|
1351 |
* @since Moodle 2.6
|
|
|
1352 |
*/
|
|
|
1353 |
public static function add_user_device_returns() {
|
|
|
1354 |
return new external_multiple_structure(
|
|
|
1355 |
new external_warnings()
|
|
|
1356 |
);
|
|
|
1357 |
}
|
|
|
1358 |
|
|
|
1359 |
/**
|
|
|
1360 |
* Returns description of method parameters.
|
|
|
1361 |
*
|
|
|
1362 |
* @return external_function_parameters
|
|
|
1363 |
* @since Moodle 2.9
|
|
|
1364 |
*/
|
|
|
1365 |
public static function remove_user_device_parameters() {
|
|
|
1366 |
return new external_function_parameters(
|
|
|
1367 |
array(
|
|
|
1368 |
'uuid' => new external_value(PARAM_RAW, 'the device UUID'),
|
|
|
1369 |
'appid' => new external_value(PARAM_NOTAGS,
|
|
|
1370 |
'the app id, if empty devices matching the UUID for the user will be removed',
|
|
|
1371 |
VALUE_DEFAULT, ''),
|
|
|
1372 |
)
|
|
|
1373 |
);
|
|
|
1374 |
}
|
|
|
1375 |
|
|
|
1376 |
/**
|
|
|
1377 |
* Remove a user device from the Moodle database (for PUSH notifications usually).
|
|
|
1378 |
*
|
|
|
1379 |
* @param string $uuid The device UUID.
|
|
|
1380 |
* @param string $appid The app id, opitonal parameter. If empty all the devices fmatching the UUID or the user will be removed.
|
|
|
1381 |
* @return array List of possible warnings and removal status.
|
|
|
1382 |
* @since Moodle 2.9
|
|
|
1383 |
*/
|
|
|
1384 |
public static function remove_user_device($uuid, $appid = "") {
|
|
|
1385 |
global $CFG;
|
|
|
1386 |
require_once($CFG->dirroot . "/user/lib.php");
|
|
|
1387 |
|
|
|
1388 |
$params = self::validate_parameters(self::remove_user_device_parameters(), array('uuid' => $uuid, 'appid' => $appid));
|
|
|
1389 |
|
|
|
1390 |
$context = context_system::instance();
|
|
|
1391 |
self::validate_context($context);
|
|
|
1392 |
|
|
|
1393 |
// Warnings array, it can be empty at the end but is mandatory.
|
|
|
1394 |
$warnings = array();
|
|
|
1395 |
|
|
|
1396 |
$removed = user_remove_user_device($params['uuid'], $params['appid']);
|
|
|
1397 |
|
|
|
1398 |
if (!$removed) {
|
|
|
1399 |
$warnings[] = array(
|
|
|
1400 |
'item' => $params['uuid'],
|
|
|
1401 |
'warningcode' => 'devicedoesnotexist',
|
|
|
1402 |
'message' => 'The device doesn\'t exists in the database'
|
|
|
1403 |
);
|
|
|
1404 |
}
|
|
|
1405 |
|
|
|
1406 |
$result = array(
|
|
|
1407 |
'removed' => $removed,
|
|
|
1408 |
'warnings' => $warnings
|
|
|
1409 |
);
|
|
|
1410 |
|
|
|
1411 |
return $result;
|
|
|
1412 |
}
|
|
|
1413 |
|
|
|
1414 |
/**
|
|
|
1415 |
* Returns description of method result value.
|
|
|
1416 |
*
|
|
|
1417 |
* @return external_multiple_structure
|
|
|
1418 |
* @since Moodle 2.9
|
|
|
1419 |
*/
|
|
|
1420 |
public static function remove_user_device_returns() {
|
|
|
1421 |
return new external_single_structure(
|
|
|
1422 |
array(
|
|
|
1423 |
'removed' => new external_value(PARAM_BOOL, 'True if removed, false if not removed because it doesn\'t exists'),
|
|
|
1424 |
'warnings' => new external_warnings(),
|
|
|
1425 |
)
|
|
|
1426 |
);
|
|
|
1427 |
}
|
|
|
1428 |
|
|
|
1429 |
/**
|
|
|
1430 |
* Returns description of method parameters
|
|
|
1431 |
*
|
|
|
1432 |
* @return external_function_parameters
|
|
|
1433 |
* @since Moodle 2.9
|
|
|
1434 |
*/
|
|
|
1435 |
public static function view_user_list_parameters() {
|
|
|
1436 |
return new external_function_parameters(
|
|
|
1437 |
array(
|
|
|
1438 |
'courseid' => new external_value(PARAM_INT, 'id of the course, 0 for site')
|
|
|
1439 |
)
|
|
|
1440 |
);
|
|
|
1441 |
}
|
|
|
1442 |
|
|
|
1443 |
/**
|
|
|
1444 |
* Trigger the user_list_viewed event.
|
|
|
1445 |
*
|
|
|
1446 |
* @param int $courseid id of course
|
|
|
1447 |
* @return array of warnings and status result
|
|
|
1448 |
* @since Moodle 2.9
|
|
|
1449 |
* @throws moodle_exception
|
|
|
1450 |
*/
|
|
|
1451 |
public static function view_user_list($courseid) {
|
|
|
1452 |
global $CFG;
|
|
|
1453 |
require_once($CFG->dirroot . "/user/lib.php");
|
|
|
1454 |
require_once($CFG->dirroot . '/course/lib.php');
|
|
|
1455 |
|
|
|
1456 |
$params = self::validate_parameters(self::view_user_list_parameters(),
|
|
|
1457 |
array(
|
|
|
1458 |
'courseid' => $courseid
|
|
|
1459 |
));
|
|
|
1460 |
|
|
|
1461 |
$warnings = array();
|
|
|
1462 |
|
|
|
1463 |
if (empty($params['courseid'])) {
|
|
|
1464 |
$params['courseid'] = SITEID;
|
|
|
1465 |
}
|
|
|
1466 |
|
|
|
1467 |
$course = get_course($params['courseid']);
|
|
|
1468 |
|
|
|
1469 |
if ($course->id == SITEID) {
|
|
|
1470 |
$context = context_system::instance();
|
|
|
1471 |
} else {
|
|
|
1472 |
$context = context_course::instance($course->id);
|
|
|
1473 |
}
|
|
|
1474 |
self::validate_context($context);
|
|
|
1475 |
|
|
|
1476 |
course_require_view_participants($context);
|
|
|
1477 |
|
|
|
1478 |
user_list_view($course, $context);
|
|
|
1479 |
|
|
|
1480 |
$result = array();
|
|
|
1481 |
$result['status'] = true;
|
|
|
1482 |
$result['warnings'] = $warnings;
|
|
|
1483 |
return $result;
|
|
|
1484 |
}
|
|
|
1485 |
|
|
|
1486 |
/**
|
|
|
1487 |
* Returns description of method result value
|
|
|
1488 |
*
|
|
|
1489 |
* @return external_description
|
|
|
1490 |
* @since Moodle 2.9
|
|
|
1491 |
*/
|
|
|
1492 |
public static function view_user_list_returns() {
|
|
|
1493 |
return new external_single_structure(
|
|
|
1494 |
array(
|
|
|
1495 |
'status' => new external_value(PARAM_BOOL, 'status: true if success'),
|
|
|
1496 |
'warnings' => new external_warnings()
|
|
|
1497 |
)
|
|
|
1498 |
);
|
|
|
1499 |
}
|
|
|
1500 |
|
|
|
1501 |
/**
|
|
|
1502 |
* Returns description of method parameters
|
|
|
1503 |
*
|
|
|
1504 |
* @return external_function_parameters
|
|
|
1505 |
* @since Moodle 2.9
|
|
|
1506 |
*/
|
|
|
1507 |
public static function view_user_profile_parameters() {
|
|
|
1508 |
return new external_function_parameters(
|
|
|
1509 |
array(
|
|
|
1510 |
'userid' => new external_value(PARAM_INT, 'id of the user, 0 for current user', VALUE_REQUIRED),
|
|
|
1511 |
'courseid' => new external_value(PARAM_INT, 'id of the course, default site course', VALUE_DEFAULT, 0)
|
|
|
1512 |
)
|
|
|
1513 |
);
|
|
|
1514 |
}
|
|
|
1515 |
|
|
|
1516 |
/**
|
|
|
1517 |
* Trigger the user profile viewed event.
|
|
|
1518 |
*
|
|
|
1519 |
* @param int $userid id of user
|
|
|
1520 |
* @param int $courseid id of course
|
|
|
1521 |
* @return array of warnings and status result
|
|
|
1522 |
* @since Moodle 2.9
|
|
|
1523 |
* @throws moodle_exception
|
|
|
1524 |
*/
|
|
|
1525 |
public static function view_user_profile($userid, $courseid = 0) {
|
|
|
1526 |
global $CFG, $USER;
|
|
|
1527 |
require_once($CFG->dirroot . "/user/profile/lib.php");
|
|
|
1528 |
|
|
|
1529 |
$params = self::validate_parameters(self::view_user_profile_parameters(),
|
|
|
1530 |
array(
|
|
|
1531 |
'userid' => $userid,
|
|
|
1532 |
'courseid' => $courseid
|
|
|
1533 |
));
|
|
|
1534 |
|
|
|
1535 |
$warnings = array();
|
|
|
1536 |
|
|
|
1537 |
if (empty($params['userid'])) {
|
|
|
1538 |
$params['userid'] = $USER->id;
|
|
|
1539 |
}
|
|
|
1540 |
|
|
|
1541 |
if (empty($params['courseid'])) {
|
|
|
1542 |
$params['courseid'] = SITEID;
|
|
|
1543 |
}
|
|
|
1544 |
|
|
|
1545 |
$course = get_course($params['courseid']);
|
|
|
1546 |
$user = core_user::get_user($params['userid'], '*', MUST_EXIST);
|
|
|
1547 |
core_user::require_active_user($user);
|
|
|
1548 |
|
|
|
1549 |
if ($course->id == SITEID) {
|
|
|
1550 |
$coursecontext = context_system::instance();;
|
|
|
1551 |
} else {
|
|
|
1552 |
$coursecontext = context_course::instance($course->id);
|
|
|
1553 |
}
|
|
|
1554 |
self::validate_context($coursecontext);
|
|
|
1555 |
|
|
|
1556 |
$currentuser = $USER->id == $user->id;
|
|
|
1557 |
$usercontext = context_user::instance($user->id);
|
|
|
1558 |
|
|
|
1559 |
if (!$currentuser and
|
|
|
1560 |
!has_capability('moodle/user:viewdetails', $coursecontext) and
|
|
|
1561 |
!has_capability('moodle/user:viewdetails', $usercontext)) {
|
|
|
1562 |
throw new moodle_exception('cannotviewprofile');
|
|
|
1563 |
}
|
|
|
1564 |
|
|
|
1565 |
// Case like user/profile.php.
|
|
|
1566 |
if ($course->id == SITEID) {
|
|
|
1567 |
profile_view($user, $usercontext);
|
|
|
1568 |
} else {
|
|
|
1569 |
// Case like user/view.php.
|
|
|
1570 |
if (!$currentuser and !can_access_course($course, $user, '', true)) {
|
|
|
1571 |
throw new moodle_exception('notenrolledprofile');
|
|
|
1572 |
}
|
|
|
1573 |
|
|
|
1574 |
profile_view($user, $coursecontext, $course);
|
|
|
1575 |
}
|
|
|
1576 |
|
|
|
1577 |
$result = array();
|
|
|
1578 |
$result['status'] = true;
|
|
|
1579 |
$result['warnings'] = $warnings;
|
|
|
1580 |
return $result;
|
|
|
1581 |
}
|
|
|
1582 |
|
|
|
1583 |
/**
|
|
|
1584 |
* Returns description of method result value
|
|
|
1585 |
*
|
|
|
1586 |
* @return external_description
|
|
|
1587 |
* @since Moodle 2.9
|
|
|
1588 |
*/
|
|
|
1589 |
public static function view_user_profile_returns() {
|
|
|
1590 |
return new external_single_structure(
|
|
|
1591 |
array(
|
|
|
1592 |
'status' => new external_value(PARAM_BOOL, 'status: true if success'),
|
|
|
1593 |
'warnings' => new external_warnings()
|
|
|
1594 |
)
|
|
|
1595 |
);
|
|
|
1596 |
}
|
|
|
1597 |
|
|
|
1598 |
/**
|
|
|
1599 |
* Returns description of method parameters
|
|
|
1600 |
*
|
|
|
1601 |
* @return external_function_parameters
|
|
|
1602 |
* @since Moodle 3.2
|
|
|
1603 |
*/
|
|
|
1604 |
public static function get_user_preferences_parameters() {
|
|
|
1605 |
return new external_function_parameters(
|
|
|
1606 |
array(
|
|
|
1607 |
'name' => new external_value(PARAM_RAW, 'preference name, empty for all', VALUE_DEFAULT, ''),
|
|
|
1608 |
'userid' => new external_value(PARAM_INT, 'id of the user, default to current user', VALUE_DEFAULT, 0)
|
|
|
1609 |
)
|
|
|
1610 |
);
|
|
|
1611 |
}
|
|
|
1612 |
|
|
|
1613 |
/**
|
|
|
1614 |
* Return user preferences.
|
|
|
1615 |
*
|
|
|
1616 |
* @param string $name preference name, empty for all
|
|
|
1617 |
* @param int $userid id of the user, 0 for current user
|
|
|
1618 |
* @return array of warnings and preferences
|
|
|
1619 |
* @since Moodle 3.2
|
|
|
1620 |
* @throws moodle_exception
|
|
|
1621 |
*/
|
|
|
1622 |
public static function get_user_preferences($name = '', $userid = 0) {
|
|
|
1623 |
global $USER;
|
|
|
1624 |
|
|
|
1625 |
$params = self::validate_parameters(self::get_user_preferences_parameters(),
|
|
|
1626 |
array(
|
|
|
1627 |
'name' => $name,
|
|
|
1628 |
'userid' => $userid
|
|
|
1629 |
));
|
|
|
1630 |
$preferences = array();
|
|
|
1631 |
$warnings = array();
|
|
|
1632 |
|
|
|
1633 |
$context = context_system::instance();
|
|
|
1634 |
self::validate_context($context);
|
|
|
1635 |
|
|
|
1636 |
if (empty($params['name'])) {
|
|
|
1637 |
$name = null;
|
|
|
1638 |
}
|
|
|
1639 |
if (empty($params['userid'])) {
|
|
|
1640 |
$user = null;
|
|
|
1641 |
} else {
|
|
|
1642 |
$user = core_user::get_user($params['userid'], '*', MUST_EXIST);
|
|
|
1643 |
core_user::require_active_user($user);
|
|
|
1644 |
if ($user->id != $USER->id) {
|
|
|
1645 |
// Only admins can retrieve other users preferences.
|
|
|
1646 |
require_capability('moodle/site:config', $context);
|
|
|
1647 |
}
|
|
|
1648 |
}
|
|
|
1649 |
|
|
|
1650 |
$userpreferences = get_user_preferences($name, null, $user);
|
|
|
1651 |
// Check if we received just one preference.
|
|
|
1652 |
if (!is_array($userpreferences)) {
|
|
|
1653 |
$userpreferences = array($name => $userpreferences);
|
|
|
1654 |
}
|
|
|
1655 |
|
|
|
1656 |
foreach ($userpreferences as $name => $value) {
|
|
|
1657 |
$preferences[] = array(
|
|
|
1658 |
'name' => $name,
|
|
|
1659 |
'value' => $value,
|
|
|
1660 |
);
|
|
|
1661 |
}
|
|
|
1662 |
|
|
|
1663 |
$result = array();
|
|
|
1664 |
$result['preferences'] = $preferences;
|
|
|
1665 |
$result['warnings'] = $warnings;
|
|
|
1666 |
return $result;
|
|
|
1667 |
}
|
|
|
1668 |
|
|
|
1669 |
/**
|
|
|
1670 |
* Returns description of method result value
|
|
|
1671 |
*
|
|
|
1672 |
* @return external_description
|
|
|
1673 |
* @since Moodle 3.2
|
|
|
1674 |
*/
|
|
|
1675 |
public static function get_user_preferences_returns() {
|
|
|
1676 |
return new external_single_structure(
|
|
|
1677 |
array(
|
|
|
1678 |
'preferences' => new external_multiple_structure(
|
|
|
1679 |
new external_single_structure(
|
|
|
1680 |
array(
|
|
|
1681 |
'name' => new external_value(PARAM_RAW, 'The name of the preference'),
|
|
|
1682 |
'value' => new external_value(PARAM_RAW, 'The value of the preference'),
|
|
|
1683 |
)
|
|
|
1684 |
),
|
|
|
1685 |
'User custom fields (also known as user profile fields)'
|
|
|
1686 |
),
|
|
|
1687 |
'warnings' => new external_warnings()
|
|
|
1688 |
)
|
|
|
1689 |
);
|
|
|
1690 |
}
|
|
|
1691 |
|
|
|
1692 |
/**
|
|
|
1693 |
* Returns description of method parameters
|
|
|
1694 |
*
|
|
|
1695 |
* @return external_function_parameters
|
|
|
1696 |
* @since Moodle 3.2
|
|
|
1697 |
*/
|
|
|
1698 |
public static function update_picture_parameters() {
|
|
|
1699 |
return new external_function_parameters(
|
|
|
1700 |
array(
|
|
|
1701 |
'draftitemid' => new external_value(PARAM_INT, 'Id of the user draft file to use as image'),
|
|
|
1702 |
'delete' => new external_value(PARAM_BOOL, 'If we should delete the user picture', VALUE_DEFAULT, false),
|
|
|
1703 |
'userid' => new external_value(PARAM_INT, 'Id of the user, 0 for current user', VALUE_DEFAULT, 0)
|
|
|
1704 |
)
|
|
|
1705 |
);
|
|
|
1706 |
}
|
|
|
1707 |
|
|
|
1708 |
/**
|
|
|
1709 |
* Update or delete the user picture in the site
|
|
|
1710 |
*
|
|
|
1711 |
* @param int $draftitemid id of the user draft file to use as image
|
|
|
1712 |
* @param bool $delete if we should delete the user picture
|
|
|
1713 |
* @param int $userid id of the user, 0 for current user
|
|
|
1714 |
* @return array warnings and success status
|
|
|
1715 |
* @since Moodle 3.2
|
|
|
1716 |
* @throws moodle_exception
|
|
|
1717 |
*/
|
|
|
1718 |
public static function update_picture($draftitemid, $delete = false, $userid = 0) {
|
|
|
1719 |
global $CFG, $USER, $PAGE;
|
|
|
1720 |
|
|
|
1721 |
$params = self::validate_parameters(
|
|
|
1722 |
self::update_picture_parameters(),
|
|
|
1723 |
array(
|
|
|
1724 |
'draftitemid' => $draftitemid,
|
|
|
1725 |
'delete' => $delete,
|
|
|
1726 |
'userid' => $userid
|
|
|
1727 |
)
|
|
|
1728 |
);
|
|
|
1729 |
|
|
|
1730 |
$context = context_system::instance();
|
|
|
1731 |
self::validate_context($context);
|
|
|
1732 |
|
|
|
1733 |
if (!empty($CFG->disableuserimages)) {
|
|
|
1734 |
throw new moodle_exception('userimagesdisabled', 'admin');
|
|
|
1735 |
}
|
|
|
1736 |
|
|
|
1737 |
if (empty($params['userid']) or $params['userid'] == $USER->id) {
|
|
|
1738 |
$user = $USER;
|
|
|
1739 |
require_capability('moodle/user:editownprofile', $context);
|
|
|
1740 |
} else {
|
|
|
1741 |
$user = core_user::get_user($params['userid'], '*', MUST_EXIST);
|
|
|
1742 |
core_user::require_active_user($user);
|
|
|
1743 |
$personalcontext = context_user::instance($user->id);
|
|
|
1744 |
|
|
|
1745 |
require_capability('moodle/user:editprofile', $personalcontext);
|
|
|
1746 |
if (is_siteadmin($user) and !is_siteadmin($USER)) { // Only admins may edit other admins.
|
|
|
1747 |
throw new moodle_exception('useradmineditadmin');
|
|
|
1748 |
}
|
|
|
1749 |
}
|
|
|
1750 |
|
|
|
1751 |
// Load the appropriate auth plugin.
|
|
|
1752 |
$userauth = get_auth_plugin($user->auth);
|
|
|
1753 |
if (is_mnet_remote_user($user) or !$userauth->can_edit_profile() or $userauth->edit_profile_url()) {
|
|
|
1754 |
throw new moodle_exception('noprofileedit', 'auth');
|
|
|
1755 |
}
|
|
|
1756 |
|
|
|
1757 |
$filemanageroptions = array(
|
|
|
1758 |
'maxbytes' => $CFG->maxbytes,
|
|
|
1759 |
'subdirs' => 0,
|
|
|
1760 |
'maxfiles' => 1,
|
|
|
1761 |
'accepted_types' => 'optimised_image'
|
|
|
1762 |
);
|
|
|
1763 |
$user->deletepicture = $params['delete'];
|
|
|
1764 |
$user->imagefile = $params['draftitemid'];
|
|
|
1765 |
$success = core_user::update_picture($user, $filemanageroptions);
|
|
|
1766 |
|
|
|
1767 |
$result = array(
|
|
|
1768 |
'success' => $success,
|
|
|
1769 |
'warnings' => array(),
|
|
|
1770 |
);
|
|
|
1771 |
if ($success) {
|
|
|
1772 |
$userpicture = new user_picture(core_user::get_user($user->id));
|
|
|
1773 |
$userpicture->size = 1; // Size f1.
|
|
|
1774 |
$result['profileimageurl'] = $userpicture->get_url($PAGE)->out(false);
|
|
|
1775 |
}
|
|
|
1776 |
return $result;
|
|
|
1777 |
}
|
|
|
1778 |
|
|
|
1779 |
/**
|
|
|
1780 |
* Returns description of method result value
|
|
|
1781 |
*
|
|
|
1782 |
* @return external_description
|
|
|
1783 |
* @since Moodle 3.2
|
|
|
1784 |
*/
|
|
|
1785 |
public static function update_picture_returns() {
|
|
|
1786 |
return new external_single_structure(
|
|
|
1787 |
array(
|
|
|
1788 |
'success' => new external_value(PARAM_BOOL, 'True if the image was updated, false otherwise.'),
|
|
|
1789 |
'profileimageurl' => new external_value(PARAM_URL, 'New profile user image url', VALUE_OPTIONAL),
|
|
|
1790 |
'warnings' => new external_warnings()
|
|
|
1791 |
)
|
|
|
1792 |
);
|
|
|
1793 |
}
|
|
|
1794 |
|
|
|
1795 |
/**
|
|
|
1796 |
* Returns description of method parameters
|
|
|
1797 |
*
|
|
|
1798 |
* @return external_function_parameters
|
|
|
1799 |
* @since Moodle 3.2
|
|
|
1800 |
*/
|
|
|
1801 |
public static function set_user_preferences_parameters() {
|
|
|
1802 |
return new external_function_parameters(
|
|
|
1803 |
array(
|
|
|
1804 |
'preferences' => new external_multiple_structure(
|
|
|
1805 |
new external_single_structure(
|
|
|
1806 |
array(
|
|
|
1807 |
'name' => new external_value(PARAM_RAW, 'The name of the preference'),
|
|
|
1808 |
'value' => new external_value(PARAM_RAW, 'The value of the preference'),
|
|
|
1809 |
'userid' => new external_value(PARAM_INT,
|
|
|
1810 |
'Id of the user to set the preference (default to current user)', VALUE_DEFAULT, 0),
|
|
|
1811 |
)
|
|
|
1812 |
)
|
|
|
1813 |
)
|
|
|
1814 |
)
|
|
|
1815 |
);
|
|
|
1816 |
}
|
|
|
1817 |
|
|
|
1818 |
/**
|
|
|
1819 |
* Set user preferences.
|
|
|
1820 |
*
|
|
|
1821 |
* @param array $preferences list of preferences including name, value and userid
|
|
|
1822 |
* @return array of warnings and preferences saved
|
|
|
1823 |
* @since Moodle 3.2
|
|
|
1824 |
* @throws moodle_exception
|
|
|
1825 |
*/
|
|
|
1826 |
public static function set_user_preferences($preferences) {
|
|
|
1827 |
global $PAGE, $USER;
|
|
|
1828 |
|
|
|
1829 |
$params = self::validate_parameters(self::set_user_preferences_parameters(), array('preferences' => $preferences));
|
|
|
1830 |
$warnings = array();
|
|
|
1831 |
$saved = array();
|
|
|
1832 |
|
|
|
1833 |
$context = context_system::instance();
|
|
|
1834 |
$PAGE->set_context($context);
|
|
|
1835 |
|
|
|
1836 |
$userscache = array();
|
|
|
1837 |
foreach ($params['preferences'] as $pref) {
|
|
|
1838 |
$userid = $pref['userid'] ?: $USER->id;
|
|
|
1839 |
|
|
|
1840 |
// Check to which user set the preference.
|
|
|
1841 |
if (!empty($userscache[$userid])) {
|
|
|
1842 |
$user = $userscache[$userid];
|
|
|
1843 |
} else {
|
|
|
1844 |
try {
|
|
|
1845 |
$user = core_user::get_user($userid, '*', MUST_EXIST);
|
|
|
1846 |
core_user::require_active_user($user);
|
|
|
1847 |
$userscache[$userid] = $user;
|
|
|
1848 |
} catch (Exception $e) {
|
|
|
1849 |
$warnings[] = array(
|
|
|
1850 |
'item' => 'user',
|
|
|
1851 |
'itemid' => $userid,
|
|
|
1852 |
'warningcode' => 'invaliduser',
|
|
|
1853 |
'message' => $e->getMessage()
|
|
|
1854 |
);
|
|
|
1855 |
continue;
|
|
|
1856 |
}
|
|
|
1857 |
}
|
|
|
1858 |
|
|
|
1859 |
try {
|
|
|
1860 |
|
|
|
1861 |
// Support legacy preferences from the old M.util.set_user_preference API (always using the current user).
|
|
|
1862 |
if (isset($USER->ajax_updatable_user_prefs[$pref['name']])) {
|
|
|
1863 |
debugging('Updating preferences via ajax_updatable_user_prefs is deprecated. ' .
|
|
|
1864 |
'Please use the "core_user/repository" module instead.', DEBUG_DEVELOPER);
|
|
|
1865 |
|
|
|
1866 |
set_user_preference($pref['name'], $pref['value']);
|
|
|
1867 |
$saved[] = array(
|
|
|
1868 |
'name' => $pref['name'],
|
|
|
1869 |
'userid' => $USER->id,
|
|
|
1870 |
);
|
|
|
1871 |
} else if (core_user::can_edit_preference($pref['name'], $user)) {
|
|
|
1872 |
$value = core_user::clean_preference($pref['value'], $pref['name']);
|
|
|
1873 |
set_user_preference($pref['name'], $value, $user->id);
|
|
|
1874 |
$saved[] = array(
|
|
|
1875 |
'name' => $pref['name'],
|
|
|
1876 |
'userid' => $user->id,
|
|
|
1877 |
);
|
|
|
1878 |
} else {
|
|
|
1879 |
$warnings[] = array(
|
|
|
1880 |
'item' => 'user',
|
|
|
1881 |
'itemid' => $user->id,
|
|
|
1882 |
'warningcode' => 'nopermission',
|
|
|
1883 |
'message' => 'You are not allowed to change the preference '.s($pref['name']).' for user '.$user->id
|
|
|
1884 |
);
|
|
|
1885 |
}
|
|
|
1886 |
} catch (Exception $e) {
|
|
|
1887 |
$warnings[] = array(
|
|
|
1888 |
'item' => 'user',
|
|
|
1889 |
'itemid' => $user->id,
|
|
|
1890 |
'warningcode' => 'errorsavingpreference',
|
|
|
1891 |
'message' => $e->getMessage()
|
|
|
1892 |
);
|
|
|
1893 |
}
|
|
|
1894 |
}
|
|
|
1895 |
|
|
|
1896 |
$result = array();
|
|
|
1897 |
$result['saved'] = $saved;
|
|
|
1898 |
$result['warnings'] = $warnings;
|
|
|
1899 |
return $result;
|
|
|
1900 |
}
|
|
|
1901 |
|
|
|
1902 |
/**
|
|
|
1903 |
* Returns description of method result value
|
|
|
1904 |
*
|
|
|
1905 |
* @return external_description
|
|
|
1906 |
* @since Moodle 3.2
|
|
|
1907 |
*/
|
|
|
1908 |
public static function set_user_preferences_returns() {
|
|
|
1909 |
return new external_single_structure(
|
|
|
1910 |
array(
|
|
|
1911 |
'saved' => new external_multiple_structure(
|
|
|
1912 |
new external_single_structure(
|
|
|
1913 |
array(
|
|
|
1914 |
'name' => new external_value(PARAM_RAW, 'The name of the preference'),
|
|
|
1915 |
'userid' => new external_value(PARAM_INT, 'The user the preference was set for'),
|
|
|
1916 |
)
|
|
|
1917 |
), 'Preferences saved'
|
|
|
1918 |
),
|
|
|
1919 |
'warnings' => new external_warnings()
|
|
|
1920 |
)
|
|
|
1921 |
);
|
|
|
1922 |
}
|
|
|
1923 |
|
|
|
1924 |
/**
|
|
|
1925 |
* Returns description of method parameters.
|
|
|
1926 |
*
|
|
|
1927 |
* @return external_function_parameters
|
|
|
1928 |
* @since Moodle 3.2
|
|
|
1929 |
*/
|
|
|
1930 |
public static function agree_site_policy_parameters() {
|
|
|
1931 |
return new external_function_parameters(array());
|
|
|
1932 |
}
|
|
|
1933 |
|
|
|
1934 |
/**
|
|
|
1935 |
* Agree the site policy for the current user.
|
|
|
1936 |
*
|
|
|
1937 |
* @return array of warnings and status result
|
|
|
1938 |
* @since Moodle 3.2
|
|
|
1939 |
* @throws moodle_exception
|
|
|
1940 |
*/
|
|
|
1941 |
public static function agree_site_policy() {
|
|
|
1942 |
global $CFG, $DB, $USER;
|
|
|
1943 |
|
|
|
1944 |
$warnings = array();
|
|
|
1945 |
|
|
|
1946 |
$context = context_system::instance();
|
|
|
1947 |
try {
|
|
|
1948 |
// We expect an exception here since the user didn't agree the site policy yet.
|
|
|
1949 |
self::validate_context($context);
|
|
|
1950 |
} catch (Exception $e) {
|
|
|
1951 |
// We are expecting only a sitepolicynotagreed exception.
|
|
|
1952 |
if (!($e instanceof moodle_exception) or $e->errorcode != 'sitepolicynotagreed') {
|
|
|
1953 |
// In case we receive a different exception, throw it.
|
|
|
1954 |
throw $e;
|
|
|
1955 |
}
|
|
|
1956 |
}
|
|
|
1957 |
|
|
|
1958 |
$manager = new \core_privacy\local\sitepolicy\manager();
|
|
|
1959 |
if (!empty($USER->policyagreed)) {
|
|
|
1960 |
$status = false;
|
|
|
1961 |
$warnings[] = array(
|
|
|
1962 |
'item' => 'user',
|
|
|
1963 |
'itemid' => $USER->id,
|
|
|
1964 |
'warningcode' => 'alreadyagreed',
|
|
|
1965 |
'message' => 'The user already agreed the site policy.'
|
|
|
1966 |
);
|
|
|
1967 |
} else if (!$manager->is_defined()) {
|
|
|
1968 |
$status = false;
|
|
|
1969 |
$warnings[] = array(
|
|
|
1970 |
'item' => 'user',
|
|
|
1971 |
'itemid' => $USER->id,
|
|
|
1972 |
'warningcode' => 'nositepolicy',
|
|
|
1973 |
'message' => 'The site does not have a site policy configured.'
|
|
|
1974 |
);
|
|
|
1975 |
} else {
|
|
|
1976 |
$status = $manager->accept();
|
|
|
1977 |
}
|
|
|
1978 |
|
|
|
1979 |
$result = array();
|
|
|
1980 |
$result['status'] = $status;
|
|
|
1981 |
$result['warnings'] = $warnings;
|
|
|
1982 |
return $result;
|
|
|
1983 |
}
|
|
|
1984 |
|
|
|
1985 |
/**
|
|
|
1986 |
* Returns description of method result value.
|
|
|
1987 |
*
|
|
|
1988 |
* @return external_description
|
|
|
1989 |
* @since Moodle 3.2
|
|
|
1990 |
*/
|
|
|
1991 |
public static function agree_site_policy_returns() {
|
|
|
1992 |
return new external_single_structure(
|
|
|
1993 |
array(
|
|
|
1994 |
'status' => new external_value(PARAM_BOOL, 'Status: true only if we set the policyagreed to 1 for the user'),
|
|
|
1995 |
'warnings' => new external_warnings()
|
|
|
1996 |
)
|
|
|
1997 |
);
|
|
|
1998 |
}
|
|
|
1999 |
|
|
|
2000 |
/**
|
|
|
2001 |
* Returns description of method parameters.
|
|
|
2002 |
*
|
|
|
2003 |
* @return external_function_parameters
|
|
|
2004 |
* @since Moodle 3.4
|
|
|
2005 |
*/
|
|
|
2006 |
public static function get_private_files_info_parameters() {
|
|
|
2007 |
return new external_function_parameters(
|
|
|
2008 |
array(
|
|
|
2009 |
'userid' => new external_value(PARAM_INT, 'Id of the user, default to current user.', VALUE_DEFAULT, 0)
|
|
|
2010 |
)
|
|
|
2011 |
);
|
|
|
2012 |
}
|
|
|
2013 |
|
|
|
2014 |
/**
|
|
|
2015 |
* Returns general information about files in the user private files area.
|
|
|
2016 |
*
|
|
|
2017 |
* @param int $userid Id of the user, default to current user.
|
|
|
2018 |
* @return array of warnings and file area information
|
|
|
2019 |
* @since Moodle 3.4
|
|
|
2020 |
* @throws moodle_exception
|
|
|
2021 |
*/
|
|
|
2022 |
public static function get_private_files_info($userid = 0) {
|
|
|
2023 |
global $CFG, $USER;
|
|
|
2024 |
require_once($CFG->libdir . '/filelib.php');
|
|
|
2025 |
|
|
|
2026 |
$params = self::validate_parameters(self::get_private_files_info_parameters(), array('userid' => $userid));
|
|
|
2027 |
$warnings = array();
|
|
|
2028 |
|
|
|
2029 |
$context = context_system::instance();
|
|
|
2030 |
self::validate_context($context);
|
|
|
2031 |
|
|
|
2032 |
if (empty($params['userid']) || $params['userid'] == $USER->id) {
|
|
|
2033 |
$usercontext = context_user::instance($USER->id);
|
|
|
2034 |
require_capability('moodle/user:manageownfiles', $usercontext);
|
|
|
2035 |
} else {
|
|
|
2036 |
$user = core_user::get_user($params['userid'], '*', MUST_EXIST);
|
|
|
2037 |
core_user::require_active_user($user);
|
|
|
2038 |
// Only admins can retrieve other users information.
|
|
|
2039 |
require_capability('moodle/site:config', $context);
|
|
|
2040 |
$usercontext = context_user::instance($user->id);
|
|
|
2041 |
}
|
|
|
2042 |
|
|
|
2043 |
$fileareainfo = file_get_file_area_info($usercontext->id, 'user', 'private');
|
|
|
2044 |
|
|
|
2045 |
$result = array();
|
|
|
2046 |
$result['filecount'] = $fileareainfo['filecount'];
|
|
|
2047 |
$result['foldercount'] = $fileareainfo['foldercount'];
|
|
|
2048 |
$result['filesize'] = $fileareainfo['filesize'];
|
|
|
2049 |
$result['filesizewithoutreferences'] = $fileareainfo['filesize_without_references'];
|
|
|
2050 |
$result['warnings'] = $warnings;
|
|
|
2051 |
return $result;
|
|
|
2052 |
}
|
|
|
2053 |
|
|
|
2054 |
/**
|
|
|
2055 |
* Returns description of method result value.
|
|
|
2056 |
*
|
|
|
2057 |
* @return external_description
|
|
|
2058 |
* @since Moodle 3.4
|
|
|
2059 |
*/
|
|
|
2060 |
public static function get_private_files_info_returns() {
|
|
|
2061 |
return new external_single_structure(
|
|
|
2062 |
array(
|
|
|
2063 |
'filecount' => new external_value(PARAM_INT, 'Number of files in the area.'),
|
|
|
2064 |
'foldercount' => new external_value(PARAM_INT, 'Number of folders in the area.'),
|
|
|
2065 |
'filesize' => new external_value(PARAM_INT, 'Total size of the files in the area.'),
|
|
|
2066 |
'filesizewithoutreferences' => new external_value(PARAM_INT, 'Total size of the area excluding file references'),
|
|
|
2067 |
'warnings' => new external_warnings()
|
|
|
2068 |
)
|
|
|
2069 |
);
|
|
|
2070 |
}
|
|
|
2071 |
}
|