Differences Between: [Versions 310 and 402] [Versions 311 and 402] [Versions 39 and 402] [Versions 400 and 402] [Versions 401 and 402]
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 /** 18 * Auth e-mail external API 19 * 20 * @package auth_email 21 * @category external 22 * @copyright 2016 Juan Leyva <juan@moodle.com> 23 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 24 * @since Moodle 3.2 25 */ 26 27 use core_external\external_api; 28 use core_external\external_format_value; 29 use core_external\external_function_parameters; 30 use core_external\external_multiple_structure; 31 use core_external\external_single_structure; 32 use core_external\external_value; 33 use core_external\external_warnings; 34 35 defined('MOODLE_INTERNAL') || die; 36 37 require_once($CFG->libdir . '/authlib.php'); 38 require_once($CFG->dirroot . '/user/editlib.php'); 39 require_once($CFG->dirroot . '/user/profile/lib.php'); 40 41 /** 42 * Auth e-mail external functions 43 * 44 * @package auth_email 45 * @category external 46 * @copyright 2016 Juan Leyva <juan@moodle.com> 47 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 48 * @since Moodle 3.2 49 */ 50 class auth_email_external extends external_api { 51 52 /** 53 * Check if registration is enabled in this site. 54 * 55 * @throws moodle_exception 56 * @since Moodle 3.2 57 */ 58 protected static function check_signup_enabled() { 59 global $CFG; 60 61 if (empty($CFG->registerauth) or $CFG->registerauth != 'email') { 62 throw new moodle_exception('registrationdisabled', 'error'); 63 } 64 } 65 66 /** 67 * Describes the parameters for get_signup_settings. 68 * 69 * @return external_function_parameters 70 * @since Moodle 3.2 71 */ 72 public static function get_signup_settings_parameters() { 73 return new external_function_parameters(array()); 74 } 75 76 /** 77 * Get the signup required settings and profile fields. 78 * 79 * @return array settings and possible warnings 80 * @since Moodle 3.2 81 * @throws moodle_exception 82 */ 83 public static function get_signup_settings() { 84 global $CFG, $PAGE; 85 86 $context = context_system::instance(); 87 // We need this to make work the format text functions. 88 $PAGE->set_context($context); 89 90 self::check_signup_enabled(); 91 92 $result = array(); 93 $result['namefields'] = useredit_get_required_name_fields(); 94 95 if (!empty($CFG->passwordpolicy)) { 96 $result['passwordpolicy'] = print_password_policy(); 97 } 98 $manager = new \core_privacy\local\sitepolicy\manager(); 99 if ($sitepolicy = $manager->get_embed_url()) { 100 $result['sitepolicy'] = $sitepolicy->out(false); 101 } 102 if (!empty($CFG->sitepolicyhandler)) { 103 $result['sitepolicyhandler'] = $CFG->sitepolicyhandler; 104 } 105 if (!empty($CFG->defaultcity)) { 106 $result['defaultcity'] = $CFG->defaultcity; 107 } 108 if (!empty($CFG->country)) { 109 $result['country'] = $CFG->country; 110 } 111 112 if ($fields = profile_get_signup_fields()) { 113 $result['profilefields'] = array(); 114 foreach ($fields as $field) { 115 $fielddata = $field->object->get_field_config_for_external(); 116 $fielddata['categoryname'] = \core_external\util::format_string($field->categoryname, $context->id); 117 $fielddata['name'] = \core_external\util::format_string($fielddata['name'], $context->id); 118 list($fielddata['defaultdata'], $fielddata['defaultdataformat']) = 119 \core_external\util::format_text($fielddata['defaultdata'], $fielddata['defaultdataformat'], $context->id); 120 121 $result['profilefields'][] = $fielddata; 122 } 123 } 124 125 if (signup_captcha_enabled()) { 126 // With reCAPTCHA v2 the captcha will be rendered by the mobile client using just the publickey. 127 $result['recaptchapublickey'] = $CFG->recaptchapublickey; 128 } 129 130 $result['warnings'] = array(); 131 return $result; 132 } 133 134 /** 135 * Describes the get_signup_settings return value. 136 * 137 * @return external_single_structure 138 * @since Moodle 3.2 139 */ 140 public static function get_signup_settings_returns() { 141 142 return new external_single_structure( 143 array( 144 'namefields' => new external_multiple_structure( 145 new external_value(PARAM_NOTAGS, 'The order of the name fields') 146 ), 147 'passwordpolicy' => new external_value(PARAM_RAW, 'Password policy', VALUE_OPTIONAL), 148 'sitepolicy' => new external_value(PARAM_RAW, 'Site policy', VALUE_OPTIONAL), 149 'sitepolicyhandler' => new external_value(PARAM_PLUGIN, 'Site policy handler', VALUE_OPTIONAL), 150 'defaultcity' => new external_value(PARAM_NOTAGS, 'Default city', VALUE_OPTIONAL), 151 'country' => new external_value(PARAM_ALPHA, 'Default country', VALUE_OPTIONAL), 152 'profilefields' => new external_multiple_structure( 153 new external_single_structure( 154 array( 155 'id' => new external_value(PARAM_INT, 'Profile field id', VALUE_OPTIONAL), 156 'shortname' => new external_value(PARAM_ALPHANUMEXT, 'Profile field shortname', VALUE_OPTIONAL), 157 'name' => new external_value(PARAM_RAW, 'Profield field name', VALUE_OPTIONAL), 158 'datatype' => new external_value(PARAM_ALPHANUMEXT, 'Profield field datatype', VALUE_OPTIONAL), 159 'description' => new external_value(PARAM_RAW, 'Profield field description', VALUE_OPTIONAL), 160 'descriptionformat' => new external_format_value('description'), 161 'categoryid' => new external_value(PARAM_INT, 'Profield field category id', VALUE_OPTIONAL), 162 'categoryname' => new external_value(PARAM_RAW, 'Profield field category name', VALUE_OPTIONAL), 163 'sortorder' => new external_value(PARAM_INT, 'Profield field sort order', VALUE_OPTIONAL), 164 'required' => new external_value(PARAM_INT, 'Profield field required', VALUE_OPTIONAL), 165 'locked' => new external_value(PARAM_INT, 'Profield field locked', VALUE_OPTIONAL), 166 'visible' => new external_value(PARAM_INT, 'Profield field visible', VALUE_OPTIONAL), 167 'forceunique' => new external_value(PARAM_INT, 'Profield field unique', VALUE_OPTIONAL), 168 'signup' => new external_value(PARAM_INT, 'Profield field in signup form', VALUE_OPTIONAL), 169 'defaultdata' => new external_value(PARAM_RAW, 'Profield field default data', VALUE_OPTIONAL), 170 'defaultdataformat' => new external_format_value('defaultdata'), 171 'param1' => new external_value(PARAM_RAW, 'Profield field settings', VALUE_OPTIONAL), 172 'param2' => new external_value(PARAM_RAW, 'Profield field settings', VALUE_OPTIONAL), 173 'param3' => new external_value(PARAM_RAW, 'Profield field settings', VALUE_OPTIONAL), 174 'param4' => new external_value(PARAM_RAW, 'Profield field settings', VALUE_OPTIONAL), 175 'param5' => new external_value(PARAM_RAW, 'Profield field settings', VALUE_OPTIONAL), 176 ) 177 ), 'Required profile fields', VALUE_OPTIONAL 178 ), 179 'recaptchapublickey' => new external_value(PARAM_RAW, 'Recaptcha public key', VALUE_OPTIONAL), 180 'recaptchachallengehash' => new external_value(PARAM_RAW, 'Recaptcha challenge hash', VALUE_OPTIONAL), 181 'recaptchachallengeimage' => new external_value(PARAM_URL, 'Recaptcha challenge noscript image', VALUE_OPTIONAL), 182 'recaptchachallengejs' => new external_value(PARAM_URL, 'Recaptcha challenge js url', VALUE_OPTIONAL), 183 'warnings' => new external_warnings(), 184 ) 185 ); 186 } 187 188 /** 189 * Describes the parameters for signup_user. 190 * 191 * @return external_function_parameters 192 * @since Moodle 3.2 193 */ 194 public static function signup_user_parameters() { 195 return new external_function_parameters( 196 array( 197 'username' => new external_value(core_user::get_property_type('username'), 'Username'), 198 'password' => new external_value(core_user::get_property_type('password'), 'Plain text password'), 199 'firstname' => new external_value(core_user::get_property_type('firstname'), 'The first name(s) of the user'), 200 'lastname' => new external_value(core_user::get_property_type('lastname'), 'The family name of the user'), 201 'email' => new external_value(core_user::get_property_type('email'), 'A valid and unique email address'), 202 'city' => new external_value(core_user::get_property_type('city'), 'Home city of the user', VALUE_DEFAULT, ''), 203 'country' => new external_value(core_user::get_property_type('country'), 'Home country code', VALUE_DEFAULT, ''), 204 'recaptchachallengehash' => new external_value(PARAM_RAW, 'Recaptcha challenge hash', VALUE_DEFAULT, ''), 205 'recaptcharesponse' => new external_value(PARAM_NOTAGS, 'Recaptcha response', VALUE_DEFAULT, ''), 206 'customprofilefields' => new external_multiple_structure( 207 new external_single_structure( 208 array( 209 'type' => new external_value(PARAM_ALPHANUMEXT, 'The type of the custom field'), 210 'name' => new external_value(PARAM_ALPHANUMEXT, 'The name of the custom field'), 211 'value' => new external_value(PARAM_RAW, 'Custom field value, can be an encoded json if required') 212 ) 213 ), 'User custom fields (also known as user profile fields)', VALUE_DEFAULT, array() 214 ), 215 'redirect' => new external_value(PARAM_LOCALURL, 'Redirect the user to this site url after confirmation.', 216 VALUE_DEFAULT, ''), 217 ) 218 ); 219 } 220 221 /** 222 * Get the signup required settings and profile fields. 223 * 224 * @param string $username username 225 * @param string $password plain text password 226 * @param string $firstname the first name(s) of the user 227 * @param string $lastname the family name of the user 228 * @param string $email a valid and unique email address 229 * @param string $city home city of the user 230 * @param string $country home country code 231 * @param string $recaptchachallengehash recaptcha challenge hash 232 * @param string $recaptcharesponse recaptcha response 233 * @param array $customprofilefields user custom fields (also known as user profile fields) 234 * @param string $redirect Site url to redirect the user after confirmation 235 * @return array settings and possible warnings 236 * @since Moodle 3.2 237 * @throws moodle_exception 238 * @throws invalid_parameter_exception 239 */ 240 public static function signup_user($username, $password, $firstname, $lastname, $email, $city = '', $country = '', 241 $recaptchachallengehash = '', $recaptcharesponse = '', $customprofilefields = array(), 242 $redirect = '') { 243 global $CFG, $PAGE; 244 245 $warnings = array(); 246 $params = self::validate_parameters( 247 self::signup_user_parameters(), 248 array( 249 'username' => $username, 250 'password' => $password, 251 'firstname' => $firstname, 252 'lastname' => $lastname, 253 'email' => $email, 254 'city' => $city, 255 'country' => $country, 256 'recaptchachallengehash' => $recaptchachallengehash, 257 'recaptcharesponse' => $recaptcharesponse, 258 'customprofilefields' => $customprofilefields, 259 'redirect' => $redirect, 260 ) 261 ); 262 263 // We need this to make work the format text functions. 264 $context = context_system::instance(); 265 $PAGE->set_context($context); 266 267 self::check_signup_enabled(); 268 269 // Validate profile fields param types. 270 $allowedfields = profile_get_signup_fields(); 271 $fieldproperties = array(); 272 $fieldsrequired = array(); 273 foreach ($allowedfields as $field) { 274 $fieldproperties[$field->object->inputname] = $field->object->get_field_properties(); 275 if ($field->object->is_required()) { 276 $fieldsrequired[$field->object->inputname] = true; 277 } 278 } 279 280 foreach ($params['customprofilefields'] as $profilefield) { 281 if (!array_key_exists($profilefield['name'], $fieldproperties)) { 282 throw new invalid_parameter_exception('Invalid field' . $profilefield['name']); 283 } 284 list($type, $allownull) = $fieldproperties[$profilefield['name']]; 285 validate_param($profilefield['value'], $type, $allownull); 286 // Remove from the potential required list. 287 if (isset($fieldsrequired[$profilefield['name']])) { 288 unset($fieldsrequired[$profilefield['name']]); 289 } 290 } 291 if (!empty($fieldsrequired)) { 292 throw new invalid_parameter_exception('Missing required parameters: ' . implode(',', array_keys($fieldsrequired))); 293 } 294 295 // Validate the data sent. 296 $data = $params; 297 $data['email2'] = $data['email']; 298 // Force policy agreed if a site policy is set. The client is responsible of implementing the interface check. 299 $manager = new \core_privacy\local\sitepolicy\manager(); 300 if ($manager->is_defined()) { 301 $data['policyagreed'] = 1; 302 } 303 unset($data['recaptcharesponse']); 304 unset($data['customprofilefields']); 305 // Add profile fields data. 306 foreach ($params['customprofilefields'] as $profilefield) { 307 // First, check if the value is a json (some profile fields like text area uses an array for sending data). 308 $datadecoded = json_decode($profilefield['value'], true); 309 if (is_array($datadecoded) && (json_last_error() == JSON_ERROR_NONE)) { 310 $data[$profilefield['name']] = $datadecoded; 311 } else { 312 $data[$profilefield['name']] = $profilefield['value']; 313 } 314 } 315 316 $errors = signup_validate_data($data, array()); 317 318 // Validate recaptcha. 319 if (signup_captcha_enabled()) { 320 require_once($CFG->libdir . '/recaptchalib_v2.php'); 321 $response = recaptcha_check_response(RECAPTCHA_VERIFY_URL, $CFG->recaptchaprivatekey, 322 getremoteaddr(), $params['recaptcharesponse']); 323 if (!$response['isvalid']) { 324 $errors['recaptcharesponse'] = $response['error']; 325 } 326 } 327 328 if (!empty($errors)) { 329 foreach ($errors as $itemname => $message) { 330 $warnings[] = array( 331 'item' => $itemname, 332 'itemid' => 0, 333 'warningcode' => 'fielderror', 334 'message' => s($message) 335 ); 336 } 337 $result = array( 338 'success' => false, 339 'warnings' => $warnings, 340 ); 341 } else { 342 // Save the user. 343 $user = signup_setup_new_user((object) $data); 344 345 $authplugin = get_auth_plugin('email'); 346 347 // Check if we should redirect the user once the user is confirmed. 348 $confirmationurl = null; 349 if (!empty($params['redirect'])) { 350 // Pass via moodle_url to fix thinks like admin links. 351 $redirect = new moodle_url($params['redirect']); 352 353 $confirmationurl = new moodle_url('/login/confirm.php', array('redirect' => $redirect->out())); 354 } 355 $authplugin->user_signup_with_confirmation($user, false, $confirmationurl); 356 357 $result = array( 358 'success' => true, 359 'warnings' => array(), 360 ); 361 } 362 return $result; 363 } 364 365 /** 366 * Describes the signup_user return value. 367 * 368 * @return external_single_structure 369 * @since Moodle 3.2 370 */ 371 public static function signup_user_returns() { 372 373 return new external_single_structure( 374 array( 375 'success' => new external_value(PARAM_BOOL, 'True if the user was created false otherwise'), 376 'warnings' => new external_warnings(), 377 ) 378 ); 379 } 380 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body