MDL-20625 fixed transaction related todos
[moodle.git] / user / externallib.php
CommitLineData
ef22c1b6 1<?php
2
3// This file is part of Moodle - http://moodle.org/
4//
5// Moodle is free software: you can redistribute it and/or modify
6// it under the terms of the GNU General Public License as published by
7// the Free Software Foundation, either version 3 of the License, or
8// (at your option) any later version.
9//
10// Moodle is distributed in the hope that it will be useful,
11// but WITHOUT ANY WARRANTY; without even the implied warranty of
12// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13// GNU General Public License for more details.
14//
15// You should have received a copy of the GNU General Public License
16// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
17
18/**
19 * External user API
20 *
21 * @package moodlecore
22 * @subpackage webservice
551f4420 23 * @copyright 2009 Moodle Pty Ltd (http://moodle.com)
ef22c1b6 24 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
25 */
26
27require_once("$CFG->libdir/externallib.php");
28
29class moodle_user_external extends external_api {
30
7b472b32
PS
31 /**
32 * Returns description of method parameters
33 * @return external_function_parameters
34 */
d4e13355 35 public static function create_users_parameters() {
667b496a
PS
36 global $CFG;
37
35b9a80a 38 return new external_function_parameters(
39 array(
40 'users' => new external_multiple_structure(
41 new external_single_structure(
42 array(
7b472b32 43 'username' => new external_value(PARAM_RAW, 'Username policy is defined in Moodle security config'),
667b496a 44 'password' => new external_value(PARAM_RAW, 'Plain text password consisting of any characters'),
7b472b32
PS
45 'firstname' => new external_value(PARAM_NOTAGS, 'The first name(s) of the user'),
46 'lastname' => new external_value(PARAM_NOTAGS, 'The family name of the user'),
47 'email' => new external_value(PARAM_EMAIL, 'A valid and unique email address'),
667b496a 48 'auth' => new external_value(PARAM_SAFEDIR, 'Auth plugins include manual, ldap, imap, etc', false, 'manual', false),
7b472b32
PS
49 'idnumber' => new external_value(PARAM_RAW, 'An arbitrary ID code number perhaps from the institution', false),
50 'emailstop' => new external_value(PARAM_NUMBER, 'Email is blocked: 1 is blocked and 0 otherwise', false),
667b496a 51 'lang' => new external_value(PARAM_SAFEDIR, 'Language code such as "en_utf8", must exist on server', false, $CFG->lang, false),
7b472b32
PS
52 'theme' => new external_value(PARAM_SAFEDIR, 'Theme name such as "standard", must exist on server', false),
53 'timezone' => new external_value(PARAM_ALPHANUMEXT, 'Timezone code such as Australia/Perth, or 99 for default', false),
54 'mailformat' => new external_value(PARAM_INTEGER, 'Mail format code is 0 for plain text, 1 for HTML etc', false),
35b9a80a 55 'description' => new external_value(PARAM_TEXT, 'User profile description, as HTML', false),
7b472b32
PS
56 'city' => new external_value(PARAM_NOTAGS, 'Home city of the user', false),
57 'country' => new external_value(PARAM_ALPHA, 'Home country code of the user, such as AU or CZ', false),
35b9a80a 58 'preferences' => new external_multiple_structure(
59 new external_single_structure(
60 array(
7b472b32 61 'type' => new external_value(PARAM_ALPHANUMEXT, 'The name of the preference'),
35b9a80a 62 'value' => new external_value(PARAM_RAW, 'The value of the preference')
63 )
64 ), 'User preferences', false),
65 'customfields' => new external_multiple_structure(
66 new external_single_structure(
67 array(
7b472b32 68 'type' => new external_value(PARAM_ALPHANUMEXT, 'The name of the custom field'),
35b9a80a 69 'value' => new external_value(PARAM_RAW, 'The value of the custom field')
70 )
71 ), 'User custom fields', false)
72 )
73 )
74 )
75 )
76 );
625f0a24 77 }
78
d4e13355 79 /**
5de592b1 80 * Create one or more users
81 *
71864f15
PS
82 * @param array $users An array of users to create.
83 * @return array An array of arrays
5de592b1 84 */
7b472b32 85 public static function create_users($users) {
ef22c1b6 86 global $CFG, $DB;
7b472b32 87
5de592b1 88 // Ensure the current user is allowed to run this function
ef22c1b6 89 $context = get_context_instance(CONTEXT_SYSTEM);
5de592b1 90 require_capability('moodle/user:create', $context);
ef22c1b6 91 self::validate_context($context);
92
5de592b1 93 // Do basic automatic PARAM checks on incoming data, using params description
94 // This checks to make sure that:
95 // 1) No extra data was sent
d4e13355 96 // 2) All required items were sent
5de592b1 97 // 3) All data passes clean_param without changes (yes this is strict)
98 // If any problems are found then exceptions are thrown with helpful error messages
7b472b32
PS
99 $params = self::validate_parameters(self::create_users_parameters(), array('users'=>$users));
100
667b496a
PS
101 $availableauths = get_plugin_list('auth');
102 unset($availableauths['mnet']); // these would need mnethostid too
103 unset($availableauths['webservice']); // we do not want new webservice users for now
104
105 $availablethemes = get_plugin_list('theme');
106 $availablelangs = get_list_of_languages();
5de592b1 107
667b496a 108 // TODO start delegated transaction
5de592b1 109
ef22c1b6 110 $users = array();
7b472b32 111 foreach ($params['users'] as $user) {
667b496a
PS
112 // Make sure that the username doesn't already exist
113 if ($DB->record_exists('user', array('username'=>$user['username'], 'mnethostid'=>$CFG->mnet_localhost_id))) {
114 throw new invalid_parameter_exception('Username already exists: '.$user['username']);
ef22c1b6 115 }
ef22c1b6 116
667b496a
PS
117 // Make sure auth is valid
118 if (empty($availableauths[$user['auth']])) {
119 throw new invalid_parameter_exception('Invalid authentication type: '.$user['auth']);
ef22c1b6 120 }
121
667b496a
PS
122 // Make sure lang is valid
123 if (empty($availablelangs[$user['lang']])) {
124 throw new invalid_parameter_exception('Invalid language code: '.$user['lang']);
ef22c1b6 125 }
126
667b496a
PS
127 // Make sure lang is valid
128 if (empty($availablethemes[$user['theme']])) {
129 throw new invalid_parameter_exception('Invalid theme: '.$user['theme']);
ef22c1b6 130 }
5de592b1 131
7b472b32 132 //TODO: validate username, auth, lang and theme
5de592b1 133
7b472b32 134 // finally create user
ef22c1b6 135 $record = create_user_record($user['username'], $user['password'], $user['auth']);
ef22c1b6 136
667b496a
PS
137 // update using given data
138 $user['confirmed'] = 1;
139
140 unset($user['username']);
141 unset($user['password']);
142 unset($user['auth']);
143
144 $preferences = $user['preferences'];
145 unset($user['preferences']);
146
147 $customfields = $user['customfields'];
148 unset($custom['customfields']);
149
150 foreach ($user as $key=>$value) {
151 if (is_null($value)) {
152 //ignore missing fields
153 continue;
154 }
155 $record->$key = $value;
156 }
157 $DB->update_record('user', $record);
158
d4e13355 159 //TODO: preferences and custom fields
160
7b472b32 161 $users[] = array('id'=>$record->id, 'username'=>$record->username);
ef22c1b6 162 }
163
667b496a
PS
164 // TODO allow commit of delegated transaction
165
7b472b32 166 return $users;
ef22c1b6 167 }
168
7b472b32
PS
169 /**
170 * Returns description of method result value
171 * @return external_description
172 */
173 public static function create_users_returns() {
174 return new external_multiple_structure(
175 new external_single_structure(
176 array(
177 'id' => new external_value(PARAM_INT, 'user id'),
178 'username' => new external_value(PARAM_RAW, 'user name'),
179 )
180 )
181 );
d4e13355 182 }
183
184
930680cb
PS
185 /**
186 * Returns description of method parameters
187 * @return external_function_parameters
188 */
d4e13355 189 public static function delete_users_parameters() {
930680cb
PS
190 return new external_function_parameters(
191 array(
192 'userids' => new external_multiple_structure(new external_value(PARAM_INT, 'user ID')),
193 )
194 );
d4e13355 195 }
930680cb 196
ef22c1b6 197 public static function delete_users($params) {
198 //TODO
199 }
930680cb
PS
200
201 /**
202 * Returns description of method result value
203 * @return external_description
204 */
d4e13355 205 public static function delete_users_returns() {
930680cb 206 return null;
d4e13355 207 }
ef22c1b6 208
209
930680cb
PS
210 /**
211 * Returns description of method parameters
212 * @return external_function_parameters
213 */
d4e13355 214 public static function update_users_parameters() {
215 //TODO
216 }
ef22c1b6 217 public static function update_users($params) {
218 //TODO
219 }
930680cb
PS
220
221 /**
222 * Returns description of method result value
223 * @return external_description
224 */
d4e13355 225 public static function update_users_returns() {
930680cb 226 return null;
d4e13355 227 }
228
7b472b32
PS
229 /**
230 * Returns description of method parameters
231 * @return external_function_parameters
232 */
d4e13355 233 public static function get_users_parameters() {
71864f15
PS
234 return new external_function_parameters(
235 array(
236 'userids' => new external_multiple_structure(new external_value(PARAM_INT, 'user ID')),
237 )
238 );
d4e13355 239 }
7b472b32 240
930680cb 241
71864f15
PS
242 /**
243 * Get user information
244 *
245 * @param array $userids array of user ids
246 * @return array An array of arrays describing users
247 */
248 public static function get_users($userids) {
5de592b1 249 $context = get_context_instance(CONTEXT_SYSTEM);
250 require_capability('moodle/user:viewdetails', $context);
251 self::validate_context($context);
252
71864f15 253 $params = self::validate_parameters(self::get_users_parameters(), array('userids'=>$userids));
5de592b1 254
255 //TODO: this search is probably useless for external systems because it is not exact
256 // 1/ we should specify multiple search parameters including the mnet host id
d4e13355 257 // 2/ custom profile fileds not included
258
259 $result = array();
71864f15 260/*
d4e13355 261 $users = get_users(true, $params['search'], false, null, 'firstname ASC','', '', '', 1000, 'id, mnethostid, auth, confirmed, username, idnumber, firstname, lastname, email, emailstop, lang, theme, timezone, mailformat, city, description, country');
262 foreach ($users as $user) {
263 $result[] = (array)$user;
71864f15
PS
264 }*/
265
266 return $result;
d4e13355 267 }
7b472b32
PS
268
269 /**
270 * Returns description of method result value
271 * @return external_description
272 */
d4e13355 273 public static function get_users_returns() {
71864f15
PS
274 return new external_multiple_structure(
275 new external_single_structure(
276 array(
277 'username' => new external_value(PARAM_RAW, 'Username policy is defined in Moodle security config'),
278 'firstname' => new external_value(PARAM_NOTAGS, 'The first name(s) of the user'),
279 'lastname' => new external_value(PARAM_NOTAGS, 'The family name of the user'),
280 'email' => new external_value(PARAM_EMAIL, 'A valid and unique email address'),
281 'auth' => new external_value(PARAM_SAFEDIR, 'Auth plugins include manual, ldap, imap, etc', false),
282 'confirmed' => new external_value(PARAM_NUMBER, 'Active user: 1 if confirmed, 0 otherwise', false),
283 'idnumber' => new external_value(PARAM_RAW, 'An arbitrary ID code number perhaps from the institution', false),
284 'emailstop' => new external_value(PARAM_NUMBER, 'Email is blocked: 1 is blocked and 0 otherwise', false),
285 'lang' => new external_value(PARAM_SAFEDIR, 'Language code such as "en_utf8", must exist on server', false),
286 'theme' => new external_value(PARAM_SAFEDIR, 'Theme name such as "standard", must exist on server', false),
287 'timezone' => new external_value(PARAM_ALPHANUMEXT, 'Timezone code such as Australia/Perth, or 99 for default', false),
288 'mailformat' => new external_value(PARAM_INTEGER, 'Mail format code is 0 for plain text, 1 for HTML etc', false),
289 'description' => new external_value(PARAM_TEXT, 'User profile description, as HTML', false),
290 'city' => new external_value(PARAM_NOTAGS, 'Home city of the user', false),
291 'country' => new external_value(PARAM_ALPHA, 'Home country code of the user, such as AU or CZ', false),
292 'customfields' => new external_multiple_structure(
293 new external_single_structure(
294 array(
295 'type' => new external_value(PARAM_ALPHANUMEXT, 'The name of the custom field'),
296 'value' => new external_value(PARAM_RAW, 'The value of the custom field')
297 )
298 ), 'User custom fields', false)
299 )
300 )
301 );
5de592b1 302 }
5de592b1 303}