2009-09-15 22:52:49 +00:00
< ? php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
2022-12-16 11:00:58 +08:00
use core_external\external_description ;
use core_external\external_value ;
use core_external\external_format_value ;
use core_external\external_single_structure ;
use core_external\external_multiple_structure ;
use core_external\external_function_parameters ;
use core_external\external_warnings ;
2009-09-15 22:52:49 +00:00
2011-10-18 12:57:33 +08:00
/**
2012-01-18 10:52:25 +08:00
* User external functions
*
* @ package core_user
* @ category external
* @ copyright 2011 Jerome Mouneyrac
* @ license http :// www . gnu . org / copyleft / gpl . html GNU GPL v3 or later
* @ since Moodle 2.2
2011-10-18 12:57:33 +08:00
*/
2022-12-16 11:00:58 +08:00
class core_user_external extends \core_external\external_api {
2009-09-15 22:52:49 +00:00
2009-11-05 22:54:48 +00:00
/**
* Returns description of method parameters
2012-01-18 10:52:25 +08:00
*
2009-11-05 22:54:48 +00:00
* @ return external_function_parameters
2012-01-18 10:52:25 +08:00
* @ since Moodle 2.2
2009-11-05 22:54:48 +00:00
*/
2009-09-16 19:00:12 +00:00
public static function create_users_parameters () {
2009-11-06 12:28:50 +00:00
global $CFG ;
2018-06-25 13:51:11 +08:00
$userfields = [
'createpassword' => new external_value ( PARAM_BOOL , 'True if password should be created and mailed to user.' ,
VALUE_OPTIONAL ),
// General.
'username' => new external_value ( core_user :: get_property_type ( 'username' ),
'Username policy is defined in Moodle security config.' ),
'auth' => new external_value ( core_user :: get_property_type ( 'auth' ), 'Auth plugins include manual, ldap, etc' ,
VALUE_DEFAULT , 'manual' , core_user :: get_property_null ( 'auth' )),
'password' => new external_value ( core_user :: get_property_type ( 'password' ),
'Plain text password consisting of any characters' , VALUE_OPTIONAL ),
'firstname' => new external_value ( core_user :: get_property_type ( 'firstname' ), 'The first name(s) of the user' ),
'lastname' => new external_value ( core_user :: get_property_type ( 'lastname' ), 'The family name of the user' ),
'email' => new external_value ( core_user :: get_property_type ( 'email' ), 'A valid and unique email address' ),
2023-01-06 11:02:33 +08:00
'maildisplay' => new external_value ( core_user :: get_property_type ( 'maildisplay' ), 'Email visibility' , VALUE_OPTIONAL ),
2018-06-25 13:51:11 +08:00
'city' => new external_value ( core_user :: get_property_type ( 'city' ), 'Home city of the user' , VALUE_OPTIONAL ),
'country' => new external_value ( core_user :: get_property_type ( 'country' ),
'Home country code of the user, such as AU or CZ' , VALUE_OPTIONAL ),
'timezone' => new external_value ( core_user :: get_property_type ( 'timezone' ),
'Timezone code such as Australia/Perth, or 99 for default' , VALUE_OPTIONAL ),
'description' => new external_value ( core_user :: get_property_type ( 'description' ), 'User profile description, no HTML' ,
VALUE_OPTIONAL ),
// Additional names.
'firstnamephonetic' => new external_value ( core_user :: get_property_type ( 'firstnamephonetic' ),
'The first name(s) phonetically of the user' , VALUE_OPTIONAL ),
'lastnamephonetic' => new external_value ( core_user :: get_property_type ( 'lastnamephonetic' ),
'The family name phonetically of the user' , VALUE_OPTIONAL ),
'middlename' => new external_value ( core_user :: get_property_type ( 'middlename' ), 'The middle name of the user' ,
VALUE_OPTIONAL ),
'alternatename' => new external_value ( core_user :: get_property_type ( 'alternatename' ), 'The alternate name of the user' ,
VALUE_OPTIONAL ),
// Interests.
'interests' => new external_value ( PARAM_TEXT , 'User interests (separated by commas)' , VALUE_OPTIONAL ),
// Optional.
'idnumber' => new external_value ( core_user :: get_property_type ( 'idnumber' ),
'An arbitrary ID code number perhaps from the institution' , VALUE_DEFAULT , '' ),
'institution' => new external_value ( core_user :: get_property_type ( 'institution' ), 'institution' , VALUE_OPTIONAL ),
'department' => new external_value ( core_user :: get_property_type ( 'department' ), 'department' , VALUE_OPTIONAL ),
'phone1' => new external_value ( core_user :: get_property_type ( 'phone1' ), 'Phone 1' , VALUE_OPTIONAL ),
'phone2' => new external_value ( core_user :: get_property_type ( 'phone2' ), 'Phone 2' , VALUE_OPTIONAL ),
'address' => new external_value ( core_user :: get_property_type ( 'address' ), 'Postal address' , VALUE_OPTIONAL ),
// Other user preferences stored in the user table.
'lang' => new external_value ( core_user :: get_property_type ( 'lang' ), 'Language code such as "en", must exist on server' ,
VALUE_DEFAULT , core_user :: get_property_default ( 'lang' ), core_user :: get_property_null ( 'lang' )),
'calendartype' => new external_value ( core_user :: get_property_type ( 'calendartype' ),
'Calendar type such as "gregorian", must exist on server' , VALUE_DEFAULT , $CFG -> calendartype , VALUE_OPTIONAL ),
'theme' => new external_value ( core_user :: get_property_type ( 'theme' ),
'Theme name such as "standard", must exist on server' , VALUE_OPTIONAL ),
'mailformat' => new external_value ( core_user :: get_property_type ( 'mailformat' ),
'Mail format code is 0 for plain text, 1 for HTML etc' , VALUE_OPTIONAL ),
// Custom user profile fields.
'customfields' => new external_multiple_structure (
new external_single_structure (
[
'type' => new external_value ( PARAM_ALPHANUMEXT , 'The name of the custom field' ),
'value' => new external_value ( PARAM_RAW , 'The value of the custom field' )
]
), 'User custom fields (also known as user profil fields)' , VALUE_OPTIONAL ),
// User preferences.
'preferences' => new external_multiple_structure (
new external_single_structure (
[
'type' => new external_value ( PARAM_RAW , 'The name of the preference' ),
'value' => new external_value ( PARAM_RAW , 'The value of the preference' )
]
), 'User preferences' , VALUE_OPTIONAL ),
];
2009-10-09 09:57:07 +00:00
return new external_function_parameters (
2018-06-25 13:51:11 +08:00
[
2009-10-09 09:57:07 +00:00
'users' => new external_multiple_structure (
2018-06-25 13:51:11 +08:00
new external_single_structure ( $userfields )
2009-10-09 09:57:07 +00:00
)
2018-06-25 13:51:11 +08:00
]
2009-10-09 09:57:07 +00:00
);
2009-09-16 07:22:22 +00:00
}
2009-09-16 19:00:12 +00:00
/**
2014-02-18 10:12:42 +13:00
* Create one or more users .
2009-09-16 06:50:31 +00:00
*
2014-02-18 10:12:42 +13:00
* @ throws invalid_parameter_exception
2012-01-18 10:52:25 +08:00
* @ param array $users An array of users to create .
2009-11-05 23:03:33 +00:00
* @ return array An array of arrays
2012-01-18 10:52:25 +08:00
* @ since Moodle 2.2
2009-09-16 06:50:31 +00:00
*/
2009-11-05 22:54:48 +00:00
public static function create_users ( $users ) {
2009-09-15 22:52:49 +00:00
global $CFG , $DB ;
2012-02-21 15:23:57 +08:00
require_once ( $CFG -> dirroot . " /lib/weblib.php " );
2010-02-11 04:02:04 +00:00
require_once ( $CFG -> dirroot . " /user/lib.php " );
2017-11-15 11:43:19 +08:00
require_once ( $CFG -> dirroot . " /user/editlib.php " );
2014-02-18 10:12:42 +13:00
require_once ( $CFG -> dirroot . " /user/profile/lib.php " ); // Required for customfields related function.
2010-07-27 09:07:24 +00:00
2014-02-18 10:12:42 +13:00
// Ensure the current user is allowed to run this function.
2012-07-26 11:38:02 +08:00
$context = context_system :: instance ();
2009-09-15 22:52:49 +00:00
self :: validate_context ( $context );
2010-02-11 04:02:04 +00:00
require_capability ( 'moodle/user:create' , $context );
2010-07-08 08:40:21 +00:00
2014-02-18 10:12:42 +13:00
// Do basic automatic PARAM checks on incoming data, using params description.
// If any problems are found then exceptions are thrown with helpful error messages.
$params = self :: validate_parameters ( self :: create_users_parameters (), array ( 'users' => $users ));
2010-07-27 09:07:24 +00:00
2013-07-16 22:36:11 +02:00
$availableauths = core_component :: get_plugin_list ( 'auth' );
2014-02-18 10:12:42 +13:00
unset ( $availableauths [ 'mnet' ]); // These would need mnethostid too.
unset ( $availableauths [ 'webservice' ]); // We do not want new webservice users for now.
2009-11-06 12:28:50 +00:00
2013-07-16 22:36:11 +02:00
$availablethemes = core_component :: get_plugin_list ( 'theme' );
2010-04-14 09:45:49 +00:00
$availablelangs = get_string_manager () -> get_list_of_translations ();
2009-09-16 06:50:31 +00:00
2009-11-08 21:57:01 +00:00
$transaction = $DB -> start_delegated_transaction ();
2009-09-16 06:50:31 +00:00
2010-02-11 04:02:04 +00:00
$userids = array ();
2009-11-05 22:54:48 +00:00
foreach ( $params [ 'users' ] as $user ) {
2018-08-17 12:33:25 +02:00
// Make sure that the username, firstname and lastname are not blank.
foreach ( array ( 'username' , 'firstname' , 'lastname' ) as $fieldname ) {
if ( trim ( $user [ $fieldname ]) === '' ) {
throw new invalid_parameter_exception ( 'The field ' . $fieldname . ' cannot be blank' );
}
}
2014-02-18 10:12:42 +13:00
// Make sure that the username doesn't already exist.
if ( $DB -> record_exists ( 'user' , array ( 'username' => $user [ 'username' ], 'mnethostid' => $CFG -> mnet_localhost_id ))) {
2009-11-06 12:28:50 +00:00
throw new invalid_parameter_exception ( 'Username already exists: ' . $user [ 'username' ]);
2009-09-15 22:52:49 +00:00
}
2014-02-18 10:12:42 +13:00
// Make sure auth is valid.
2009-11-06 12:28:50 +00:00
if ( empty ( $availableauths [ $user [ 'auth' ]])) {
throw new invalid_parameter_exception ( 'Invalid authentication type: ' . $user [ 'auth' ]);
2009-09-15 22:52:49 +00:00
}
2014-02-18 10:12:42 +13:00
// Make sure lang is valid.
2009-11-06 12:28:50 +00:00
if ( empty ( $availablelangs [ $user [ 'lang' ]])) {
throw new invalid_parameter_exception ( 'Invalid language code: ' . $user [ 'lang' ]);
2009-09-15 22:52:49 +00:00
}
2014-02-18 10:12:42 +13:00
// Make sure lang is valid.
if ( ! empty ( $user [ 'theme' ]) && empty ( $availablethemes [ $user [ 'theme' ]])) { // Theme is VALUE_OPTIONAL,
// so no default value
2010-02-11 04:02:04 +00:00
// We need to test if the client sent it
2014-02-18 10:12:42 +13:00
// => !empty($user['theme']).
2009-11-06 12:28:50 +00:00
throw new invalid_parameter_exception ( 'Invalid theme: ' . $user [ 'theme' ]);
2009-09-15 22:52:49 +00:00
}
2009-09-16 06:50:31 +00:00
2015-08-21 11:36:38 -03:00
// Make sure we have a password or have to create one.
2018-10-18 15:24:46 +08:00
$authplugin = get_auth_plugin ( $user [ 'auth' ]);
if ( $authplugin -> is_internal () && empty ( $user [ 'password' ]) && empty ( $user [ 'createpassword' ])) {
2015-09-23 14:48:59 +08:00
throw new invalid_parameter_exception ( 'Invalid password: you must provide a password, or set createpassword.' );
2015-08-21 11:36:38 -03:00
}
2010-02-11 04:02:04 +00:00
$user [ 'confirmed' ] = true ;
2010-07-05 06:01:08 +00:00
$user [ 'mnethostid' ] = $CFG -> mnet_localhost_id ;
2010-05-25 03:44:29 +00:00
2012-02-21 15:23:57 +08:00
// Start of user info validation.
2014-02-18 10:12:42 +13:00
// Make sure we validate current user info as handled by current GUI. See user/editadvanced_form.php func validation().
2012-02-21 15:23:57 +08:00
if ( ! validate_email ( $user [ 'email' ])) {
throw new invalid_parameter_exception ( 'Email address is invalid: ' . $user [ 'email' ]);
2019-02-21 15:24:56 +08:00
} else if ( empty ( $CFG -> allowaccountssameemail )) {
// Make a case-insensitive query for the given email address.
$select = $DB -> sql_equal ( 'email' , ':email' , false ) . ' AND mnethostid = :mnethostid' ;
$params = array (
'email' => $user [ 'email' ],
'mnethostid' => $user [ 'mnethostid' ]
);
// If there are other user(s) that already have the same email, throw an error.
if ( $DB -> record_exists_select ( 'user' , $select , $params )) {
throw new invalid_parameter_exception ( 'Email address already exists: ' . $user [ 'email' ]);
}
2012-02-21 15:23:57 +08:00
}
// End of user info validation.
2015-08-21 11:36:38 -03:00
$createpassword = ! empty ( $user [ 'createpassword' ]);
unset ( $user [ 'createpassword' ]);
2018-10-18 15:24:46 +08:00
$updatepassword = false ;
if ( $authplugin -> is_internal ()) {
if ( $createpassword ) {
$user [ 'password' ] = '' ;
} else {
$updatepassword = true ;
}
2015-08-21 11:36:38 -03:00
} else {
2018-10-18 15:24:46 +08:00
$user [ 'password' ] = AUTH_PASSWORD_NOT_CACHED ;
2015-08-21 11:36:38 -03:00
}
2014-02-18 10:12:42 +13:00
// Create the user data now!
2015-08-21 11:36:38 -03:00
$user [ 'id' ] = user_create_user ( $user , $updatepassword , false );
2012-02-21 15:23:57 +08:00
2018-06-25 13:51:11 +08:00
$userobject = ( object ) $user ;
// Set user interests.
if ( ! empty ( $user [ 'interests' ])) {
$trimmedinterests = array_map ( 'trim' , explode ( ',' , $user [ 'interests' ]));
$interests = array_filter ( $trimmedinterests , function ( $value ) {
return ! empty ( $value );
});
useredit_update_interests ( $userobject , $interests );
}
2014-02-18 10:12:42 +13:00
// Custom fields.
if ( ! empty ( $user [ 'customfields' ])) {
foreach ( $user [ 'customfields' ] as $customfield ) {
// Profile_save_data() saves profile file it's expecting a user with the correct id,
// and custom field to be named profile_field_"shortname".
$user [ " profile_field_ " . $customfield [ 'type' ]] = $customfield [ 'value' ];
2010-05-25 03:44:29 +00:00
}
profile_save_data (( object ) $user );
}
2009-11-06 12:28:50 +00:00
2015-08-21 11:36:38 -03:00
if ( $createpassword ) {
setnew_password_and_mail ( $userobject );
unset_user_preference ( 'create_password' , $userobject );
set_user_preference ( 'auth_forcepasswordchange' , 1 , $userobject );
}
2014-05-23 11:40:31 +08:00
// Trigger event.
\core\event\user_created :: create_from_userid ( $user [ 'id' ]) -> trigger ();
2014-02-18 10:12:42 +13:00
// Preferences.
2010-07-08 08:40:21 +00:00
if ( ! empty ( $user [ 'preferences' ])) {
2017-03-05 13:20:03 +08:00
$userpref = ( object ) $user ;
2014-02-18 10:12:42 +13:00
foreach ( $user [ 'preferences' ] as $preference ) {
2017-03-05 13:20:03 +08:00
$userpref -> { 'preference_' . $preference [ 'type' ]} = $preference [ 'value' ];
2010-07-08 08:40:21 +00:00
}
2017-03-05 13:20:03 +08:00
useredit_update_user_preference ( $userpref );
2010-07-08 08:40:21 +00:00
}
2009-09-16 19:00:12 +00:00
2014-02-18 10:12:42 +13:00
$userids [] = array ( 'id' => $user [ 'id' ], 'username' => $user [ 'username' ]);
2009-09-15 22:52:49 +00:00
}
2009-11-08 21:57:01 +00:00
$transaction -> allow_commit ();
2009-11-06 12:28:50 +00:00
2010-02-11 04:02:04 +00:00
return $userids ;
2009-09-15 22:52:49 +00:00
}
2014-02-18 10:12:42 +13:00
/**
2009-11-05 22:54:48 +00:00
* Returns description of method result value
2012-01-18 10:52:25 +08:00
*
2009-11-05 22:54:48 +00:00
* @ return external_description
2012-01-18 10:52:25 +08:00
* @ since Moodle 2.2
2009-11-05 22:54:48 +00:00
*/
public static function create_users_returns () {
return new external_multiple_structure (
new external_single_structure (
array (
2016-04-11 12:16:09 +08:00
'id' => new external_value ( core_user :: get_property_type ( 'id' ), 'user id' ),
'username' => new external_value ( core_user :: get_property_type ( 'username' ), 'user name' ),
2009-11-05 22:54:48 +00:00
)
)
);
2009-09-16 19:00:12 +00:00
}
2009-11-05 23:05:26 +00:00
/**
* Returns description of method parameters
2012-01-18 10:52:25 +08:00
*
2009-11-05 23:05:26 +00:00
* @ return external_function_parameters
2012-01-18 10:52:25 +08:00
* @ since Moodle 2.2
2009-11-05 23:05:26 +00:00
*/
2009-09-16 19:00:12 +00:00
public static function delete_users_parameters () {
2009-11-05 23:05:26 +00:00
return new external_function_parameters (
array (
2016-04-11 12:16:09 +08:00
'userids' => new external_multiple_structure ( new external_value ( core_user :: get_property_type ( 'id' ), 'user ID' )),
2009-11-05 23:05:26 +00:00
)
);
2009-09-16 19:00:12 +00:00
}
2009-11-05 23:05:26 +00:00
2011-10-18 12:57:33 +08:00
/**
* Delete users
2012-01-18 10:52:25 +08:00
*
2014-02-18 10:12:42 +13:00
* @ throws moodle_exception
2011-10-18 12:57:33 +08:00
* @ param array $userids
2011-10-25 15:28:52 +13:00
* @ return null
2012-01-18 10:52:25 +08:00
* @ since Moodle 2.2
2011-10-18 12:57:33 +08:00
*/
2009-11-08 21:57:01 +00:00
public static function delete_users ( $userids ) {
2010-08-12 08:12:46 +00:00
global $CFG , $DB , $USER ;
2010-02-11 04:02:04 +00:00
require_once ( $CFG -> dirroot . " /user/lib.php " );
2009-11-08 21:57:01 +00:00
2014-02-18 10:12:42 +13:00
// Ensure the current user is allowed to run this function.
2012-07-26 11:38:02 +08:00
$context = context_system :: instance ();
2009-11-08 21:57:01 +00:00
require_capability ( 'moodle/user:delete' , $context );
self :: validate_context ( $context );
2014-02-18 10:12:42 +13:00
$params = self :: validate_parameters ( self :: delete_users_parameters (), array ( 'userids' => $userids ));
2009-11-08 21:57:01 +00:00
$transaction = $DB -> start_delegated_transaction ();
foreach ( $params [ 'userids' ] as $userid ) {
2014-02-18 10:12:42 +13:00
$user = $DB -> get_record ( 'user' , array ( 'id' => $userid , 'deleted' => 0 ), '*' , MUST_EXIST );
// Must not allow deleting of admins or self!!!
2010-08-12 09:44:28 +00:00
if ( is_siteadmin ( $user )) {
throw new moodle_exception ( 'useradminodelete' , 'error' );
}
if ( $USER -> id == $user -> id ) {
throw new moodle_exception ( 'usernotdeletederror' , 'error' );
2010-08-12 08:12:46 +00:00
}
2010-02-11 04:02:04 +00:00
user_delete_user ( $user );
2009-11-08 21:57:01 +00:00
}
$transaction -> allow_commit ();
return null ;
2009-09-15 22:52:49 +00:00
}
2009-11-05 23:05:26 +00:00
2014-02-18 10:12:42 +13:00
/**
2009-11-05 23:05:26 +00:00
* Returns description of method result value
2012-01-18 10:52:25 +08:00
*
* @ return null
* @ since Moodle 2.2
2009-11-05 23:05:26 +00:00
*/
2009-09-16 19:00:12 +00:00
public static function delete_users_returns () {
2009-11-05 23:05:26 +00:00
return null ;
2009-09-16 19:00:12 +00:00
}
2009-09-15 22:52:49 +00:00
2016-06-23 02:53:58 +00:00
/**
2016-09-21 12:06:22 +08:00
* Returns description of method parameters .
2016-06-23 02:53:58 +00:00
*
* @ return external_function_parameters
* @ since Moodle 3.2
*/
2016-09-21 12:06:22 +08:00
public static function update_user_preferences_parameters () {
2016-06-23 02:53:58 +00:00
return new external_function_parameters (
array (
2016-09-21 12:06:22 +08:00
'userid' => new external_value ( PARAM_INT , 'id of the user, default to current user' , VALUE_DEFAULT , 0 ),
'emailstop' => new external_value ( core_user :: get_property_type ( 'emailstop' ),
'Enable or disable notifications for this user' , VALUE_DEFAULT , null ),
'preferences' => new external_multiple_structure (
new external_single_structure (
array (
2017-09-06 13:01:37 +02:00
'type' => new external_value ( PARAM_RAW , 'The name of the preference' ),
2018-11-08 15:02:12 +01:00
'value' => new external_value ( PARAM_RAW , ' The value of the preference , do not set this field if you
want to remove ( unset ) the current value . ' , VALUE_DEFAULT , null ),
2016-09-21 12:06:22 +08:00
)
), 'User preferences' , VALUE_DEFAULT , array ()
2016-06-23 02:53:58 +00:00
)
)
);
}
/**
2016-09-21 12:06:22 +08:00
* Update the user ' s preferences .
2016-06-23 02:53:58 +00:00
*
2016-09-21 12:06:22 +08:00
* @ param int $userid
* @ param bool | null $emailstop
* @ param array $preferences
2016-06-23 02:53:58 +00:00
* @ return null
* @ since Moodle 3.2
*/
2018-11-08 15:02:12 +01:00
public static function update_user_preferences ( $userid = 0 , $emailstop = null , $preferences = array ()) {
2016-09-21 12:06:22 +08:00
global $USER , $CFG ;
2016-06-23 02:53:58 +00:00
2016-09-21 12:06:22 +08:00
require_once ( $CFG -> dirroot . '/user/lib.php' );
2017-03-05 13:20:03 +08:00
require_once ( $CFG -> dirroot . '/user/editlib.php' );
require_once ( $CFG -> dirroot . '/message/lib.php' );
2016-06-23 02:53:58 +00:00
2016-09-21 12:06:22 +08:00
if ( empty ( $userid )) {
$userid = $USER -> id ;
}
2016-06-23 02:53:58 +00:00
2016-09-21 12:06:22 +08:00
$systemcontext = context_system :: instance ();
self :: validate_context ( $systemcontext );
$params = array (
'userid' => $userid ,
'emailstop' => $emailstop ,
'preferences' => $preferences
);
2018-11-08 15:02:12 +01:00
$params = self :: validate_parameters ( self :: update_user_preferences_parameters (), $params );
$preferences = $params [ 'preferences' ];
2016-09-21 12:06:22 +08:00
2016-06-23 02:53:58 +00:00
// Preferences.
2016-09-21 12:06:22 +08:00
if ( ! empty ( $preferences )) {
2017-03-05 13:20:03 +08:00
$userpref = [ 'id' => $userid ];
2016-09-21 12:06:22 +08:00
foreach ( $preferences as $preference ) {
2021-12-10 12:40:38 +01:00
/*
* Rename user message provider preferences to avoid orphan settings on old app versions .
* @ todo Remove this " translation " block on MDL - 73284.
*/
if ( preg_match ( '/message_provider_.*_loggedin/' , $preference [ 'type' ]) ||
preg_match ( '/message_provider_.*_loggedoff/' , $preference [ 'type' ])) {
$nameparts = explode ( '_' , $preference [ 'type' ]);
array_pop ( $nameparts );
$preference [ 'type' ] = implode ( '_' , $nameparts ) . '_enabled' ;
}
2017-03-05 13:20:03 +08:00
$userpref [ 'preference_' . $preference [ 'type' ]] = $preference [ 'value' ];
2016-06-23 02:53:58 +00:00
}
2017-03-05 13:20:03 +08:00
useredit_update_user_preference ( $userpref );
2016-06-23 02:53:58 +00:00
}
2016-09-21 12:06:22 +08:00
// Check if they want to update the email.
if ( $emailstop !== null ) {
2017-03-05 13:20:03 +08:00
$otheruser = ( $userid == $USER -> id ) ? $USER : core_user :: get_user ( $userid , '*' , MUST_EXIST );
core_user :: require_active_user ( $otheruser );
if ( core_message_can_edit_message_profile ( $otheruser ) && $otheruser -> emailstop != $emailstop ) {
$user = new stdClass ();
$user -> id = $userid ;
$user -> emailstop = $emailstop ;
user_update_user ( $user );
// Update the $USER if we should.
if ( $userid == $USER -> id ) {
$USER -> emailstop = $emailstop ;
}
2016-08-01 06:51:30 +00:00
}
}
2016-06-23 02:53:58 +00:00
return null ;
}
/**
* Returns description of method result value
*
* @ return null
* @ since Moodle 3.2
*/
2016-09-21 12:06:22 +08:00
public static function update_user_preferences_returns () {
2016-06-23 02:53:58 +00:00
return null ;
}
2009-09-15 22:52:49 +00:00
2009-11-05 23:05:26 +00:00
/**
* Returns description of method parameters
2012-01-18 10:52:25 +08:00
*
2009-11-05 23:05:26 +00:00
* @ return external_function_parameters
2012-01-18 10:52:25 +08:00
* @ since Moodle 2.2
2009-11-05 23:05:26 +00:00
*/
2009-09-16 19:00:12 +00:00
public static function update_users_parameters () {
2018-06-25 13:51:11 +08:00
$userfields = [
'id' => new external_value ( core_user :: get_property_type ( 'id' ), 'ID of the user' ),
// General.
'username' => new external_value ( core_user :: get_property_type ( 'username' ),
'Username policy is defined in Moodle security config.' , VALUE_OPTIONAL , '' , NULL_NOT_ALLOWED ),
'auth' => new external_value ( core_user :: get_property_type ( 'auth' ), 'Auth plugins include manual, ldap, etc' ,
VALUE_OPTIONAL , '' , NULL_NOT_ALLOWED ),
'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 ),
'password' => new external_value ( core_user :: get_property_type ( 'password' ),
'Plain text password consisting of any characters' , VALUE_OPTIONAL , '' , NULL_NOT_ALLOWED ),
'firstname' => new external_value ( core_user :: get_property_type ( 'firstname' ), 'The first name(s) of the user' ,
VALUE_OPTIONAL , '' , NULL_NOT_ALLOWED ),
'lastname' => new external_value ( core_user :: get_property_type ( 'lastname' ), 'The family name of the user' ,
VALUE_OPTIONAL ),
'email' => new external_value ( core_user :: get_property_type ( 'email' ), 'A valid and unique email address' , VALUE_OPTIONAL ,
'' , NULL_NOT_ALLOWED ),
2023-01-06 11:02:33 +08:00
'maildisplay' => new external_value ( core_user :: get_property_type ( 'maildisplay' ), 'Email visibility' , VALUE_OPTIONAL ),
2018-06-25 13:51:11 +08:00
'city' => new external_value ( core_user :: get_property_type ( 'city' ), 'Home city of the user' , VALUE_OPTIONAL ),
'country' => new external_value ( core_user :: get_property_type ( 'country' ),
'Home country code of the user, such as AU or CZ' , VALUE_OPTIONAL ),
'timezone' => new external_value ( core_user :: get_property_type ( 'timezone' ),
'Timezone code such as Australia/Perth, or 99 for default' , VALUE_OPTIONAL ),
'description' => new external_value ( core_user :: get_property_type ( 'description' ), 'User profile description, no HTML' ,
VALUE_OPTIONAL ),
// User picture.
'userpicture' => new external_value ( PARAM_INT ,
'The itemid where the new user picture has been uploaded to, 0 to delete' , VALUE_OPTIONAL ),
// Additional names.
'firstnamephonetic' => new external_value ( core_user :: get_property_type ( 'firstnamephonetic' ),
'The first name(s) phonetically of the user' , VALUE_OPTIONAL ),
'lastnamephonetic' => new external_value ( core_user :: get_property_type ( 'lastnamephonetic' ),
'The family name phonetically of the user' , VALUE_OPTIONAL ),
'middlename' => new external_value ( core_user :: get_property_type ( 'middlename' ), 'The middle name of the user' ,
VALUE_OPTIONAL ),
'alternatename' => new external_value ( core_user :: get_property_type ( 'alternatename' ), 'The alternate name of the user' ,
VALUE_OPTIONAL ),
// Interests.
'interests' => new external_value ( PARAM_TEXT , 'User interests (separated by commas)' , VALUE_OPTIONAL ),
// Optional.
'idnumber' => new external_value ( core_user :: get_property_type ( 'idnumber' ),
'An arbitrary ID code number perhaps from the institution' , VALUE_OPTIONAL ),
'institution' => new external_value ( core_user :: get_property_type ( 'institution' ), 'Institution' , VALUE_OPTIONAL ),
'department' => new external_value ( core_user :: get_property_type ( 'department' ), 'Department' , VALUE_OPTIONAL ),
'phone1' => new external_value ( core_user :: get_property_type ( 'phone1' ), 'Phone' , VALUE_OPTIONAL ),
'phone2' => new external_value ( core_user :: get_property_type ( 'phone2' ), 'Mobile phone' , VALUE_OPTIONAL ),
'address' => new external_value ( core_user :: get_property_type ( 'address' ), 'Postal address' , VALUE_OPTIONAL ),
// Other user preferences stored in the user table.
'lang' => new external_value ( core_user :: get_property_type ( 'lang' ), 'Language code such as "en", must exist on server' ,
VALUE_OPTIONAL , '' , NULL_NOT_ALLOWED ),
'calendartype' => new external_value ( core_user :: get_property_type ( 'calendartype' ),
'Calendar type such as "gregorian", must exist on server' , VALUE_OPTIONAL , '' , NULL_NOT_ALLOWED ),
'theme' => new external_value ( core_user :: get_property_type ( 'theme' ),
'Theme name such as "standard", must exist on server' , VALUE_OPTIONAL ),
'mailformat' => new external_value ( core_user :: get_property_type ( 'mailformat' ),
'Mail format code is 0 for plain text, 1 for HTML etc' , VALUE_OPTIONAL ),
// Custom user profile fields.
'customfields' => new external_multiple_structure (
new external_single_structure (
[
'type' => new external_value ( PARAM_ALPHANUMEXT , 'The name of the custom field' ),
'value' => new external_value ( PARAM_RAW , 'The value of the custom field' )
]
), 'User custom fields (also known as user profil fields)' , VALUE_OPTIONAL ),
// User preferences.
'preferences' => new external_multiple_structure (
new external_single_structure (
[
'type' => new external_value ( PARAM_RAW , 'The name of the preference' ),
'value' => new external_value ( PARAM_RAW , 'The value of the preference' )
]
), 'User preferences' , VALUE_OPTIONAL ),
];
2011-10-25 11:43:53 +13:00
return new external_function_parameters (
2018-06-25 13:51:11 +08:00
[
2010-02-11 04:02:04 +00:00
'users' => new external_multiple_structure (
2018-06-25 13:51:11 +08:00
new external_single_structure ( $userfields )
2010-02-11 04:02:04 +00:00
)
2018-06-25 13:51:11 +08:00
]
2010-02-11 04:02:04 +00:00
);
2009-09-16 19:00:12 +00:00
}
2009-11-08 21:57:01 +00:00
2011-10-18 12:57:33 +08:00
/**
* Update users
2012-01-18 10:52:25 +08:00
*
2011-10-18 12:57:33 +08:00
* @ param array $users
2011-10-25 15:28:52 +13:00
* @ return null
2012-01-18 10:52:25 +08:00
* @ since Moodle 2.2
2011-10-18 12:57:33 +08:00
*/
2009-11-08 21:57:01 +00:00
public static function update_users ( $users ) {
2016-09-22 10:52:11 +01:00
global $CFG , $DB , $USER ;
2010-02-11 04:02:04 +00:00
require_once ( $CFG -> dirroot . " /user/lib.php " );
2014-02-18 10:12:42 +13:00
require_once ( $CFG -> dirroot . " /user/profile/lib.php " ); // Required for customfields related function.
2017-03-05 13:20:03 +08:00
require_once ( $CFG -> dirroot . '/user/editlib.php' );
2009-11-08 21:57:01 +00:00
2014-02-18 10:12:42 +13:00
// Ensure the current user is allowed to run this function.
2012-07-26 11:38:02 +08:00
$context = context_system :: instance ();
2009-11-08 21:57:01 +00:00
require_capability ( 'moodle/user:update' , $context );
self :: validate_context ( $context );
2014-02-18 10:12:42 +13:00
$params = self :: validate_parameters ( self :: update_users_parameters (), array ( 'users' => $users ));
2009-11-08 21:57:01 +00:00
2015-10-15 19:34:58 +11:00
$filemanageroptions = array ( 'maxbytes' => $CFG -> maxbytes ,
'subdirs' => 0 ,
'maxfiles' => 1 ,
2020-08-11 14:50:06 +02:00
'accepted_types' => 'optimised_image' );
2015-10-15 19:34:58 +11:00
2020-08-17 15:45:53 +03:00
$warnings = array ();
2009-11-08 21:57:01 +00:00
foreach ( $params [ 'users' ] as $user ) {
2020-08-17 15:45:53 +03:00
// Catch any exception while updating a user and return it as a warning.
try {
$transaction = $DB -> start_delegated_transaction ();
// First check the user exists.
if ( ! $existinguser = core_user :: get_user ( $user [ 'id' ])) {
2021-04-08 00:44:17 +00:00
throw new moodle_exception ( 'invaliduserid' , '' , '' , null ,
'Invalid user ID' );
2020-08-17 15:45:53 +03:00
}
// Check if we are trying to update an admin.
if ( $existinguser -> id != $USER -> id and is_siteadmin ( $existinguser ) and ! is_siteadmin ( $USER )) {
2021-04-08 00:44:17 +00:00
throw new moodle_exception ( 'usernotupdatedadmin' , '' , '' , null ,
'Cannot update admin accounts' );
2020-08-17 15:45:53 +03:00
}
// Other checks (deleted, remote or guest users).
if ( $existinguser -> deleted ) {
2021-04-08 00:44:17 +00:00
throw new moodle_exception ( 'usernotupdateddeleted' , '' , '' , null ,
'User is a deleted user' );
2020-08-17 15:45:53 +03:00
}
if ( is_mnet_remote_user ( $existinguser )) {
2021-04-08 00:44:17 +00:00
throw new moodle_exception ( 'usernotupdatedremote' , '' , '' , null ,
'User is a remote user' );
2020-08-17 15:45:53 +03:00
}
if ( isguestuser ( $existinguser -> id )) {
2021-04-08 00:44:17 +00:00
throw new moodle_exception ( 'usernotupdatedguest' , '' , '' , null ,
'Cannot update guest account' );
2020-08-17 15:45:53 +03:00
}
// Check duplicated emails.
if ( isset ( $user [ 'email' ]) && $user [ 'email' ] !== $existinguser -> email ) {
if ( ! validate_email ( $user [ 'email' ])) {
2021-04-08 00:44:17 +00:00
throw new moodle_exception ( 'useremailinvalid' , '' , '' , null ,
'Invalid email address' );
2020-08-17 15:45:53 +03:00
} else if ( empty ( $CFG -> allowaccountssameemail )) {
// Make a case-insensitive query for the given email address
// and make sure to exclude the user being updated.
$select = $DB -> sql_equal ( 'email' , ':email' , false ) . ' AND mnethostid = :mnethostid AND id <> :userid' ;
$params = array (
'email' => $user [ 'email' ],
'mnethostid' => $CFG -> mnet_localhost_id ,
'userid' => $user [ 'id' ]
);
// Skip if there are other user(s) that already have the same email.
if ( $DB -> record_exists_select ( 'user' , $select , $params )) {
2021-04-08 00:44:17 +00:00
throw new moodle_exception ( 'useremailduplicate' , '' , '' , null ,
'Duplicate email address' );
2020-08-17 15:45:53 +03:00
}
2019-02-21 15:24:56 +08:00
}
2017-10-30 17:42:03 +01:00
}
2020-08-17 15:45:53 +03:00
user_update_user ( $user , true , false );
2015-10-15 19:34:58 +11:00
2020-08-17 15:45:53 +03:00
$userobject = ( object ) $user ;
2018-06-25 13:51:11 +08:00
2020-08-17 15:45:53 +03:00
// Update user picture if it was specified for this user.
if ( empty ( $CFG -> disableuserimages ) && isset ( $user [ 'userpicture' ])) {
$userobject -> deletepicture = null ;
2015-10-15 19:34:58 +11:00
2020-08-17 15:45:53 +03:00
if ( $user [ 'userpicture' ] == 0 ) {
$userobject -> deletepicture = true ;
} else {
$userobject -> imagefile = $user [ 'userpicture' ];
}
2015-10-15 19:34:58 +11:00
2020-08-17 15:45:53 +03:00
core_user :: update_picture ( $userobject , $filemanageroptions );
}
2015-10-15 19:34:58 +11:00
2020-08-17 15:45:53 +03:00
// Update user interests.
if ( ! empty ( $user [ 'interests' ])) {
$trimmedinterests = array_map ( 'trim' , explode ( ',' , $user [ 'interests' ]));
$interests = array_filter ( $trimmedinterests , function ( $value ) {
return ! empty ( $value );
});
useredit_update_interests ( $userobject , $interests );
}
2018-06-25 13:51:11 +08:00
2020-08-17 15:45:53 +03:00
// Update user custom fields.
if ( ! empty ( $user [ 'customfields' ])) {
2010-02-15 08:56:51 +00:00
2020-08-17 15:45:53 +03:00
foreach ( $user [ 'customfields' ] as $customfield ) {
// Profile_save_data() saves profile file it's expecting a user with the correct id,
// and custom field to be named profile_field_"shortname".
$user [ " profile_field_ " . $customfield [ 'type' ]] = $customfield [ 'value' ];
}
profile_save_data (( object ) $user );
2010-02-15 08:56:51 +00:00
}
2010-07-08 08:40:21 +00:00
2020-08-17 15:45:53 +03:00
// Trigger event.
\core\event\user_updated :: create_from_userid ( $user [ 'id' ]) -> trigger ();
2014-05-23 11:40:31 +08:00
2020-08-17 15:45:53 +03:00
// Preferences.
if ( ! empty ( $user [ 'preferences' ])) {
$userpref = clone ( $existinguser );
foreach ( $user [ 'preferences' ] as $preference ) {
$userpref -> { 'preference_' . $preference [ 'type' ]} = $preference [ 'value' ];
}
useredit_update_user_preference ( $userpref );
}
if ( isset ( $user [ 'suspended' ]) and $user [ 'suspended' ]) {
\core\session\manager :: kill_user_sessions ( $user [ 'id' ]);
}
$transaction -> allow_commit ();
} catch ( Exception $e ) {
try {
$transaction -> rollback ( $e );
} catch ( Exception $e ) {
$warning = [];
$warning [ 'item' ] = 'user' ;
$warning [ 'itemid' ] = $user [ 'id' ];
if ( $e instanceof moodle_exception ) {
$warning [ 'warningcode' ] = $e -> errorcode ;
} else {
$warning [ 'warningcode' ] = $e -> getCode ();
}
$warning [ 'message' ] = $e -> getMessage ();
$warnings [] = $warning ;
2010-07-08 08:40:21 +00:00
}
2016-10-09 21:50:49 +00:00
}
2009-11-08 21:57:01 +00:00
}
2020-08-17 15:45:53 +03:00
return [ 'warnings' => $warnings ];
2009-09-15 22:52:49 +00:00
}
2009-11-05 23:05:26 +00:00
2014-02-18 10:12:42 +13:00
/**
2009-11-05 23:05:26 +00:00
* Returns description of method result value
2012-01-18 10:52:25 +08:00
*
2020-08-17 15:45:53 +03:00
* @ return external_description
2012-01-18 10:52:25 +08:00
* @ since Moodle 2.2
2009-11-05 23:05:26 +00:00
*/
2009-09-16 19:00:12 +00:00
public static function update_users_returns () {
2020-08-17 15:45:53 +03:00
return new external_single_structure (
array (
'warnings' => new external_warnings ()
)
);
2009-09-16 19:00:12 +00:00
}
2014-02-18 10:12:42 +13:00
/**
* Returns description of method parameters
*
* @ return external_function_parameters
* @ since Moodle 2.4
*/
2012-10-30 11:36:29 +08:00
public static function get_users_by_field_parameters () {
2012-05-07 12:09:09 +01:00
return new external_function_parameters (
array (
2012-10-30 11:36:29 +08:00
'field' => new external_value ( PARAM_ALPHA , ' the search field can be
\ 'id\' or \'idnumber\' or \'username\' or \'email\'' ),
'values' => new external_multiple_structure (
new external_value ( PARAM_RAW , 'the value to match' ))
2012-05-07 12:09:09 +01:00
)
);
}
/**
2012-10-30 11:36:29 +08:00
* Get user information for a unique field .
2012-05-07 12:09:09 +01:00
*
2014-02-18 10:12:42 +13:00
* @ throws coding_exception
* @ throws invalid_parameter_exception
2012-10-30 11:36:29 +08:00
* @ param string $field
* @ param array $values
* @ return array An array of arrays containg user profiles .
* @ since Moodle 2.4
2012-05-07 12:09:09 +01:00
*/
2012-10-30 11:36:29 +08:00
public static function get_users_by_field ( $field , $values ) {
2012-05-07 12:09:09 +01:00
global $CFG , $USER , $DB ;
require_once ( $CFG -> dirroot . " /user/lib.php " );
2012-10-30 11:36:29 +08:00
$params = self :: validate_parameters ( self :: get_users_by_field_parameters (),
array ( 'field' => $field , 'values' => $values ));
// This array will keep all the users that are allowed to be searched,
// according to the current user's privileges.
$cleanedvalues = array ();
switch ( $field ) {
case 'id' :
2016-04-11 12:16:09 +08:00
$paramtype = core_user :: get_property_type ( 'id' );
2012-10-30 11:36:29 +08:00
break ;
case 'idnumber' :
2016-04-11 12:16:09 +08:00
$paramtype = core_user :: get_property_type ( 'idnumber' );
2012-10-30 11:36:29 +08:00
break ;
case 'username' :
2016-04-11 12:16:09 +08:00
$paramtype = core_user :: get_property_type ( 'username' );
2012-10-30 11:36:29 +08:00
break ;
case 'email' :
2016-04-11 12:16:09 +08:00
$paramtype = core_user :: get_property_type ( 'email' );
2012-10-30 11:36:29 +08:00
break ;
default :
throw new coding_exception ( 'invalid field parameter' ,
'The search field \'' . $field . '\' is not supported, look at the web service documentation' );
2012-05-07 12:09:09 +01:00
}
2014-02-18 10:12:42 +13:00
// Clean the values.
2012-10-30 11:36:29 +08:00
foreach ( $values as $value ) {
$cleanedvalue = clean_param ( $value , $paramtype );
if ( $value != $cleanedvalue ) {
throw new invalid_parameter_exception ( 'The field \'' . $field .
'\' value is invalid: ' . $value . '(cleaned value: ' . $cleanedvalue . ')' );
}
$cleanedvalues [] = $cleanedvalue ;
2012-05-07 12:09:09 +01:00
}
2014-02-18 10:12:42 +13:00
// Retrieve the users.
2012-10-30 11:36:29 +08:00
$users = $DB -> get_records_list ( 'user' , $field , $cleanedvalues , 'id' );
2012-05-07 12:09:09 +01:00
2016-04-13 14:27:23 +08:00
$context = context_system :: instance ();
self :: validate_context ( $context );
2014-02-18 10:12:42 +13:00
// Finally retrieve each users information.
2012-10-30 11:36:29 +08:00
$returnedusers = array ();
2012-05-07 12:09:09 +01:00
foreach ( $users as $user ) {
$userdetails = user_get_user_details_courses ( $user );
2014-02-18 10:12:42 +13:00
// Return the user only if the searched field is returned.
// Otherwise it means that the $USER was not allowed to search the returned user.
2012-10-30 11:36:29 +08:00
if ( ! empty ( $userdetails ) and ! empty ( $userdetails [ $field ])) {
$returnedusers [] = $userdetails ;
2012-05-07 12:09:09 +01:00
}
}
2012-10-30 11:36:29 +08:00
return $returnedusers ;
2012-05-07 12:09:09 +01:00
}
/**
* Returns description of method result value
*
2012-10-30 11:36:29 +08:00
* @ return external_multiple_structure
* @ since Moodle 2.4
2012-05-07 12:09:09 +01:00
*/
2012-10-30 11:36:29 +08:00
public static function get_users_by_field_returns () {
2013-02-15 11:03:13 +08:00
return new external_multiple_structure ( self :: user_description ());
2013-01-23 18:02:31 +08:00
}
/**
2013-02-06 17:18:09 +08:00
* Returns description of get_users () parameters .
2013-01-23 18:02:31 +08:00
*
* @ return external_function_parameters
2013-02-06 17:18:09 +08:00
* @ since Moodle 2.5
2013-01-23 18:02:31 +08:00
*/
public static function get_users_parameters () {
return new external_function_parameters (
array (
'criteria' => new external_multiple_structure (
new external_single_structure (
array (
2013-02-06 17:18:09 +08:00
'key' => new external_value ( PARAM_ALPHA , ' the user column to search , expected keys ( value format ) are :
" id " ( int ) matching user id ,
" lastname " ( string ) user last name ( Note : you can use % for searching but it may be considerably slower ! ),
" firstname " ( string ) user first name ( Note : you can use % for searching but it may be considerably slower ! ),
" idnumber " ( string ) matching user idnumber ,
" username " ( string ) matching user username ,
" email " ( string ) user email ( Note : you can use % for searching but it may be considerably slower ! ),
" auth " ( string ) matching user auth plugin ' ),
'value' => new external_value ( PARAM_RAW , 'the value to search' )
2013-01-23 18:02:31 +08:00
)
), ' the key / value pairs to be considered in user search . Values can not be empty .
2013-02-06 17:18:09 +08:00
Specify different keys only once ( fullname => \ ' user1\ ' , auth => \ ' manual\ ' , ... ) -
2013-02-15 11:03:13 +08:00
key occurences are forbidden .
2013-02-11 13:57:50 +08:00
The search is executed with AND operator on the criterias . Invalid criterias ( keys ) are ignored ,
2013-02-15 11:03:13 +08:00
the search is still executed on the valid criterias .
You can search without criteria , but the function is not designed for it .
It could very slow or timeout . The function is designed to search some specific users . '
2012-05-07 12:09:09 +01:00
)
)
);
}
2013-01-23 18:02:31 +08:00
/**
2013-02-06 17:18:09 +08:00
* Retrieve matching user .
2013-01-23 18:02:31 +08:00
*
2014-02-18 10:12:42 +13:00
* @ throws moodle_exception
2013-02-06 17:18:09 +08:00
* @ param array $criteria the allowed array keys are id / lastname / firstname / idnumber / username / email / auth .
* @ return array An array of arrays containing user profiles .
* @ since Moodle 2.5
2013-01-23 18:02:31 +08:00
*/
public static function get_users ( $criteria = array ()) {
global $CFG , $USER , $DB ;
require_once ( $CFG -> dirroot . " /user/lib.php " );
$params = self :: validate_parameters ( self :: get_users_parameters (),
array ( 'criteria' => $criteria ));
2013-02-06 17:18:09 +08:00
// Validate the criteria and retrieve the users.
2013-01-23 18:02:31 +08:00
$users = array ();
$warnings = array ();
$sqlparams = array ();
2013-02-15 11:03:13 +08:00
$usedkeys = array ();
// Do not retrieve deleted users.
$sql = ' deleted = 0' ;
2013-01-23 18:02:31 +08:00
2013-02-11 13:57:50 +08:00
foreach ( $params [ 'criteria' ] as $criteriaindex => $criteria ) {
2013-02-15 11:03:13 +08:00
// Check that the criteria has never been used.
if ( array_key_exists ( $criteria [ 'key' ], $usedkeys )) {
throw new moodle_exception ( 'keyalreadyset' , '' , '' , null , 'The key ' . $criteria [ 'key' ] . ' can only be sent once' );
} else {
$usedkeys [ $criteria [ 'key' ]] = true ;
}
2013-02-11 13:57:50 +08:00
$invalidcriteria = false ;
2013-02-06 17:18:09 +08:00
// Clean the parameters.
2013-01-23 18:02:31 +08:00
$paramtype = PARAM_RAW ;
switch ( $criteria [ 'key' ]) {
case 'id' :
2016-04-11 12:16:09 +08:00
$paramtype = core_user :: get_property_type ( 'id' );
2013-01-23 18:02:31 +08:00
break ;
case 'idnumber' :
2016-04-11 12:16:09 +08:00
$paramtype = core_user :: get_property_type ( 'idnumber' );
2013-01-23 18:02:31 +08:00
break ;
case 'username' :
2016-04-11 12:16:09 +08:00
$paramtype = core_user :: get_property_type ( 'username' );
2013-01-23 18:02:31 +08:00
break ;
case 'email' :
2013-02-06 17:18:09 +08:00
// We use PARAM_RAW to allow searches with %.
2016-04-11 12:16:09 +08:00
$paramtype = core_user :: get_property_type ( 'email' );
2013-01-23 18:02:31 +08:00
break ;
case 'auth' :
2016-04-11 12:16:09 +08:00
$paramtype = core_user :: get_property_type ( 'auth' );
2013-01-23 18:02:31 +08:00
break ;
case 'lastname' :
case 'firstname' :
2016-04-11 12:16:09 +08:00
$paramtype = core_user :: get_property_type ( 'firstname' );
2013-01-23 18:02:31 +08:00
break ;
default :
2013-02-06 17:18:09 +08:00
// Send back a warning that this search key is not supported in this version.
// This warning will make the function extandable without breaking clients.
2013-01-23 18:02:31 +08:00
$warnings [] = array (
2013-02-11 13:57:50 +08:00
'item' => $criteria [ 'key' ],
2013-01-23 18:02:31 +08:00
'warningcode' => 'invalidfieldparameter' ,
2014-02-18 10:12:42 +13:00
'message' =>
'The search key \'' . $criteria [ 'key' ] . '\' is not supported, look at the web service documentation'
2013-01-23 18:02:31 +08:00
);
2013-02-11 13:57:50 +08:00
// Do not add this invalid criteria to the created SQL request.
$invalidcriteria = true ;
unset ( $params [ 'criteria' ][ $criteriaindex ]);
break ;
2013-01-23 18:02:31 +08:00
}
2013-02-11 13:57:50 +08:00
if ( ! $invalidcriteria ) {
$cleanedvalue = clean_param ( $criteria [ 'value' ], $paramtype );
2013-01-23 18:02:31 +08:00
2013-02-15 11:03:13 +08:00
$sql .= ' AND ' ;
2013-02-11 13:57:50 +08:00
// Create the SQL.
switch ( $criteria [ 'key' ]) {
case 'id' :
case 'idnumber' :
case 'username' :
case 'auth' :
$sql .= $criteria [ 'key' ] . ' = :' . $criteria [ 'key' ];
$sqlparams [ $criteria [ 'key' ]] = $cleanedvalue ;
break ;
case 'email' :
case 'lastname' :
case 'firstname' :
$sql .= $DB -> sql_like ( $criteria [ 'key' ], ':' . $criteria [ 'key' ], false );
$sqlparams [ $criteria [ 'key' ]] = $cleanedvalue ;
break ;
default :
break ;
}
2013-01-23 18:02:31 +08:00
}
}
$users = $DB -> get_records_select ( 'user' , $sql , $sqlparams , 'id ASC' );
2013-02-06 17:18:09 +08:00
// Finally retrieve each users information.
2013-01-23 18:02:31 +08:00
$returnedusers = array ();
foreach ( $users as $user ) {
$userdetails = user_get_user_details_courses ( $user );
// Return the user only if all the searched fields are returned.
// Otherwise it means that the $USER was not allowed to search the returned user.
if ( ! empty ( $userdetails )) {
$validuser = true ;
2014-02-18 10:12:42 +13:00
foreach ( $params [ 'criteria' ] as $criteria ) {
2013-01-23 18:02:31 +08:00
if ( empty ( $userdetails [ $criteria [ 'key' ]])) {
$validuser = false ;
}
}
if ( $validuser ) {
$returnedusers [] = $userdetails ;
}
}
}
return array ( 'users' => $returnedusers , 'warnings' => $warnings );
}
/**
2013-02-06 17:18:09 +08:00
* Returns description of get_users result value .
2013-01-23 18:02:31 +08:00
*
* @ return external_description
2013-02-06 17:18:09 +08:00
* @ since Moodle 2.5
2013-01-23 18:02:31 +08:00
*/
public static function get_users_returns () {
return new external_single_structure (
array ( 'users' => new external_multiple_structure (
2013-02-15 11:03:13 +08:00
self :: user_description ()
2013-01-23 18:02:31 +08:00
),
2013-02-06 17:18:09 +08:00
'warnings' => new external_warnings ( 'always set to \'key\'' , 'faulty key name' )
2013-01-23 18:02:31 +08:00
)
);
}
2009-11-05 22:54:48 +00:00
/**
* Returns description of method parameters
2012-01-18 10:52:25 +08:00
*
2009-11-05 22:54:48 +00:00
* @ return external_function_parameters
2012-01-18 10:52:25 +08:00
* @ since Moodle 2.2
2011-06-20 13:46:47 +08:00
*/
2011-10-18 12:57:33 +08:00
public static function get_course_user_profiles_parameters () {
2011-06-20 13:46:47 +08:00
return new external_function_parameters (
array (
'userlist' => new external_multiple_structure (
new external_single_structure (
array (
2016-04-11 12:16:09 +08:00
'userid' => new external_value ( core_user :: get_property_type ( 'id' ), 'userid' ),
2011-06-20 13:46:47 +08:00
'courseid' => new external_value ( PARAM_INT , 'courseid' ),
2010-07-27 09:07:24 +00:00
)
2011-06-20 13:46:47 +08:00
)
2009-11-05 23:03:33 +00:00
)
2011-06-20 13:46:47 +08:00
)
);
}
/**
* Get course participant ' s details
2012-01-18 10:52:25 +08:00
*
2011-06-20 13:46:47 +08:00
* @ param array $userlist array of user ids and according course ids
* @ return array An array of arrays describing course participants
2012-01-18 10:52:25 +08:00
* @ since Moodle 2.2
2011-06-20 13:46:47 +08:00
*/
2011-10-18 12:57:33 +08:00
public static function get_course_user_profiles ( $userlist ) {
2011-06-20 13:46:47 +08:00
global $CFG , $USER , $DB ;
require_once ( $CFG -> dirroot . " /user/lib.php " );
2014-02-18 10:12:42 +13:00
$params = self :: validate_parameters ( self :: get_course_user_profiles_parameters (), array ( 'userlist' => $userlist ));
2011-06-20 13:46:47 +08:00
$userids = array ();
$courseids = array ();
foreach ( $params [ 'userlist' ] as $value ) {
$userids [] = $value [ 'userid' ];
$courseids [ $value [ 'userid' ]] = $value [ 'courseid' ];
}
2014-02-18 10:12:42 +13:00
// Cache all courses.
2011-06-20 13:46:47 +08:00
$courses = array ();
2013-07-17 09:45:42 +08:00
list ( $sqlcourseids , $params ) = $DB -> get_in_or_equal ( array_unique ( $courseids ), SQL_PARAMS_NAMED );
2013-07-05 13:02:00 +08:00
$cselect = ', ' . context_helper :: get_preload_record_columns_sql ( 'ctx' );
$cjoin = " LEFT JOIN { context} ctx ON (ctx.instanceid = c.id AND ctx.contextlevel = :contextlevel) " ;
$params [ 'contextlevel' ] = CONTEXT_COURSE ;
2012-01-21 16:08:25 +01:00
$coursesql = " SELECT c.* $cselect
2011-06-20 13:46:47 +08:00
FROM { course } c $cjoin
WHERE c . id $sqlcourseids " ;
$rs = $DB -> get_recordset_sql ( $coursesql , $params );
foreach ( $rs as $course ) {
2014-02-18 10:12:42 +13:00
// Adding course contexts to cache.
2013-07-05 11:48:36 +08:00
context_helper :: preload_from_record ( $course );
2014-02-18 10:12:42 +13:00
// Cache courses.
2011-06-20 13:46:47 +08:00
$courses [ $course -> id ] = $course ;
}
$rs -> close ();
2013-07-17 09:45:42 +08:00
list ( $sqluserids , $params ) = $DB -> get_in_or_equal ( $userids , SQL_PARAMS_NAMED );
2013-07-05 13:02:00 +08:00
$uselect = ', ' . context_helper :: get_preload_record_columns_sql ( 'ctx' );
$ujoin = " LEFT JOIN { context} ctx ON (ctx.instanceid = u.id AND ctx.contextlevel = :contextlevel) " ;
$params [ 'contextlevel' ] = CONTEXT_USER ;
2011-06-20 13:46:47 +08:00
$usersql = " SELECT u.* $uselect
FROM { user } u $ujoin
WHERE u . id $sqluserids " ;
$users = $DB -> get_recordset_sql ( $usersql , $params );
$result = array ();
foreach ( $users as $user ) {
if ( ! empty ( $user -> deleted )) {
continue ;
}
2013-07-05 11:48:36 +08:00
context_helper :: preload_from_record ( $user );
2011-06-20 13:46:47 +08:00
$course = $courses [ $courseids [ $user -> id ]];
2012-07-26 11:38:02 +08:00
$context = context_course :: instance ( $courseids [ $user -> id ], IGNORE_MISSING );
2011-06-20 13:46:47 +08:00
self :: validate_context ( $context );
2011-06-29 15:41:31 +08:00
if ( $userarray = user_get_user_details ( $user , $course )) {
$result [] = $userarray ;
2011-06-20 13:46:47 +08:00
}
2011-06-29 15:41:31 +08:00
}
2011-06-20 13:46:47 +08:00
2011-06-29 15:41:31 +08:00
$users -> close ();
2011-06-20 13:46:47 +08:00
2011-06-29 15:41:31 +08:00
return $result ;
}
2011-06-20 13:46:47 +08:00
2011-06-29 15:41:31 +08:00
/**
* Returns description of method result value
2012-01-18 10:52:25 +08:00
*
2011-06-29 15:41:31 +08:00
* @ return external_description
2012-01-18 10:52:25 +08:00
* @ since Moodle 2.2
2011-06-29 15:41:31 +08:00
*/
2011-10-18 12:57:33 +08:00
public static function get_course_user_profiles_returns () {
2013-01-23 18:02:31 +08:00
$additionalfields = array (
2014-02-18 10:12:42 +13:00
'groups' => new external_multiple_structure (
new external_single_structure (
array (
'id' => new external_value ( PARAM_INT , 'group id' ),
'name' => new external_value ( PARAM_RAW , 'group name' ),
'description' => new external_value ( PARAM_RAW , 'group description' ),
'descriptionformat' => new external_format_value ( 'description' ),
)
), 'user groups' , VALUE_OPTIONAL ),
'roles' => new external_multiple_structure (
new external_single_structure (
array (
'roleid' => new external_value ( PARAM_INT , 'role id' ),
'name' => new external_value ( PARAM_RAW , 'role name' ),
'shortname' => new external_value ( PARAM_ALPHANUMEXT , 'role shortname' ),
'sortorder' => new external_value ( PARAM_INT , 'role sortorder' )
)
), 'user roles' , VALUE_OPTIONAL ),
'enrolledcourses' => new external_multiple_structure (
new external_single_structure (
array (
'id' => new external_value ( PARAM_INT , 'Id of the course' ),
'fullname' => new external_value ( PARAM_RAW , 'Fullname of the course' ),
'shortname' => new external_value ( PARAM_RAW , 'Shortname of the course' )
)
), 'Courses where the user is enrolled - limited by which courses the user is able to see' , VALUE_OPTIONAL )
);
2013-01-23 18:02:31 +08:00
2013-02-15 11:03:13 +08:00
return new external_multiple_structure ( self :: user_description ( $additionalfields ));
2013-01-23 18:02:31 +08:00
}
/**
* Create user return value description .
*
2013-02-06 17:18:09 +08:00
* @ param array $additionalfields some additional field
2023-02-28 13:13:42 +00:00
* @ return external_description
2013-01-23 18:02:31 +08:00
*/
2013-02-06 17:18:09 +08:00
public static function user_description ( $additionalfields = array ()) {
2013-01-23 18:02:31 +08:00
$userfields = array (
2016-04-11 12:16:09 +08:00
'id' => new external_value ( core_user :: get_property_type ( 'id' ), 'ID of the user' ),
'username' => new external_value ( core_user :: get_property_type ( 'username' ), 'The username' , VALUE_OPTIONAL ),
'firstname' => new external_value ( core_user :: get_property_type ( 'firstname' ), 'The first name(s) of the user' , VALUE_OPTIONAL ),
'lastname' => new external_value ( core_user :: get_property_type ( 'lastname' ), 'The family name of the user' , VALUE_OPTIONAL ),
'fullname' => new external_value ( core_user :: get_property_type ( 'firstname' ), 'The fullname of the user' ),
'email' => new external_value ( core_user :: get_property_type ( 'email' ), 'An email address - allow email as root@localhost' , VALUE_OPTIONAL ),
'address' => new external_value ( core_user :: get_property_type ( 'address' ), 'Postal address' , VALUE_OPTIONAL ),
'phone1' => new external_value ( core_user :: get_property_type ( 'phone1' ), 'Phone 1' , VALUE_OPTIONAL ),
'phone2' => new external_value ( core_user :: get_property_type ( 'phone2' ), 'Phone 2' , VALUE_OPTIONAL ),
'department' => new external_value ( core_user :: get_property_type ( 'department' ), 'department' , VALUE_OPTIONAL ),
'institution' => new external_value ( core_user :: get_property_type ( 'institution' ), 'institution' , VALUE_OPTIONAL ),
'idnumber' => new external_value ( core_user :: get_property_type ( 'idnumber' ), 'An arbitrary ID code number perhaps from the institution' , VALUE_OPTIONAL ),
2014-02-18 10:12:42 +13:00
'interests' => new external_value ( PARAM_TEXT , 'user interests (separated by commas)' , VALUE_OPTIONAL ),
2016-04-11 12:16:09 +08:00
'firstaccess' => new external_value ( core_user :: get_property_type ( 'firstaccess' ), 'first access to the site (0 if never)' , VALUE_OPTIONAL ),
'lastaccess' => new external_value ( core_user :: get_property_type ( 'lastaccess' ), 'last access to the site (0 if never)' , VALUE_OPTIONAL ),
2017-07-14 08:11:45 +08:00
'auth' => new external_value ( core_user :: get_property_type ( 'auth' ), 'Auth plugins include manual, ldap, etc' , VALUE_OPTIONAL ),
2016-10-09 21:50:49 +00:00
'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 ),
2016-04-11 12:16:09 +08:00
'confirmed' => new external_value ( core_user :: get_property_type ( 'confirmed' ), 'Active user: 1 if confirmed, 0 otherwise' , VALUE_OPTIONAL ),
'lang' => new external_value ( core_user :: get_property_type ( 'lang' ), 'Language code such as "en", must exist on server' , VALUE_OPTIONAL ),
'calendartype' => new external_value ( core_user :: get_property_type ( 'calendartype' ), 'Calendar type such as "gregorian", must exist on server' , VALUE_OPTIONAL ),
'theme' => new external_value ( core_user :: get_property_type ( 'theme' ), 'Theme name such as "standard", must exist on server' , VALUE_OPTIONAL ),
'timezone' => new external_value ( core_user :: get_property_type ( 'timezone' ), 'Timezone code such as Australia/Perth, or 99 for default' , VALUE_OPTIONAL ),
'mailformat' => new external_value ( core_user :: get_property_type ( 'mailformat' ), 'Mail format code is 0 for plain text, 1 for HTML etc' , VALUE_OPTIONAL ),
'description' => new external_value ( core_user :: get_property_type ( 'description' ), 'User profile description' , VALUE_OPTIONAL ),
'descriptionformat' => new external_format_value ( core_user :: get_property_type ( 'descriptionformat' ), VALUE_OPTIONAL ),
'city' => new external_value ( core_user :: get_property_type ( 'city' ), 'Home city of the user' , VALUE_OPTIONAL ),
'country' => new external_value ( core_user :: get_property_type ( 'country' ), 'Home country code of the user, such as AU or CZ' , VALUE_OPTIONAL ),
2014-02-18 10:12:42 +13:00
'profileimageurlsmall' => new external_value ( PARAM_URL , 'User image profile URL - small version' ),
'profileimageurl' => new external_value ( PARAM_URL , 'User image profile URL - big version' ),
'customfields' => new external_multiple_structure (
new external_single_structure (
array (
'type' => new external_value ( PARAM_ALPHANUMEXT , 'The type of the custom field - text field, checkbox...' ),
2023-03-23 18:00:46 +01:00
'value' => new external_value ( PARAM_RAW , 'The value of the custom field (as stored in the database)' ),
'displayvalue' => new external_value ( PARAM_RAW , 'The value of the custom field for display' ,
VALUE_OPTIONAL ),
2014-02-18 10:12:42 +13:00
'name' => new external_value ( PARAM_RAW , 'The name of the custom field' ),
'shortname' => new external_value ( PARAM_RAW , 'The shortname of the custom field - to be able to build the field class in the code' ),
)
), 'User custom fields (also known as user profile fields)' , VALUE_OPTIONAL ),
'preferences' => new external_multiple_structure (
new external_single_structure (
array (
2017-09-06 13:01:37 +02:00
'name' => new external_value ( PARAM_RAW , 'The name of the preferences' ),
'value' => new external_value ( PARAM_RAW , 'The value of the preference' ),
2014-02-18 10:12:42 +13:00
)
), 'Users preferences' , VALUE_OPTIONAL )
);
2013-01-23 18:02:31 +08:00
if ( ! empty ( $additionalfields )) {
$userfields = array_merge ( $userfields , $additionalfields );
}
return new external_single_structure ( $userfields );
2011-06-29 15:41:31 +08:00
}
2013-01-23 18:02:31 +08:00
2013-08-08 12:05:40 +08:00
/**
* Returns description of method parameters
*
* @ return external_function_parameters
* @ since Moodle 2.6
*/
public static function add_user_private_files_parameters () {
return new external_function_parameters (
array (
'draftid' => new external_value ( PARAM_INT , 'draft area id' )
)
);
}
/**
* Copy files from a draft area to users private files area .
*
2014-02-18 10:12:42 +13:00
* @ throws invalid_parameter_exception
2023-03-16 16:56:07 +01:00
* @ throws moodle_exception
2013-08-08 12:05:40 +08:00
* @ param int $draftid Id of a draft area containing files .
* @ return array An array of warnings
* @ since Moodle 2.6
*/
public static function add_user_private_files ( $draftid ) {
2016-06-29 16:41:25 +01:00
global $CFG , $USER ;
require_once ( $CFG -> libdir . " /filelib.php " );
2013-08-08 12:05:40 +08:00
2014-02-18 10:12:42 +13:00
$params = self :: validate_parameters ( self :: add_user_private_files_parameters (), array ( 'draftid' => $draftid ));
2013-08-08 12:05:40 +08:00
if ( isguestuser ()) {
throw new invalid_parameter_exception ( 'Guest users cannot upload files' );
}
$context = context_user :: instance ( $USER -> id );
require_capability ( 'moodle/user:manageownfiles' , $context );
$maxbytes = $CFG -> userquota ;
$maxareabytes = $CFG -> userquota ;
if ( has_capability ( 'moodle/user:ignoreuserquota' , $context )) {
$maxbytes = USER_CAN_IGNORE_FILE_SIZE_LIMITS ;
$maxareabytes = FILE_AREA_MAX_BYTES_UNLIMITED ;
2023-03-16 16:56:07 +01:00
} else {
2023-05-10 17:16:18 +02:00
// Get current used space for this user (private files only).
$fileareainfo = file_get_file_area_info ( $context -> id , 'user' , 'private' );
$usedspace = $fileareainfo [ 'filesize_without_references' ];
2023-03-16 16:56:07 +01:00
// Get the total size of the new files we want to add to private files.
$newfilesinfo = file_get_draft_area_info ( $params [ 'draftid' ]);
if (( $newfilesinfo [ 'filesize_without_references' ] + $usedspace ) > $maxareabytes ) {
throw new moodle_exception ( 'maxareabytes' );
}
2013-08-08 12:05:40 +08:00
}
$options = array ( 'subdirs' => 1 ,
'maxbytes' => $maxbytes ,
'maxfiles' => - 1 ,
'areamaxbytes' => $maxareabytes );
2016-06-29 16:41:25 +01:00
file_merge_files_from_draft_area_into_filearea ( $draftid , $context -> id , 'user' , 'private' , 0 , $options );
2013-08-08 12:05:40 +08:00
return null ;
}
/**
* Returns description of method result value
*
* @ return external_description
* @ since Moodle 2.2
*/
public static function add_user_private_files_returns () {
return null ;
}
2013-10-04 11:43:45 +02:00
/**
* Returns description of method parameters .
*
* @ return external_function_parameters
* @ since Moodle 2.6
*/
public static function add_user_device_parameters () {
return new external_function_parameters (
array (
'appid' => new external_value ( PARAM_NOTAGS , 'the app id, usually something like com.moodle.moodlemobile' ),
'name' => new external_value ( PARAM_NOTAGS , 'the device name, \'occam\' or \'iPhone\' etc.' ),
'model' => new external_value ( PARAM_NOTAGS , 'the device model \'Nexus4\' or \'iPad1,1\' etc.' ),
'platform' => new external_value ( PARAM_NOTAGS , 'the device platform \'iOS\' or \'Android\' etc.' ),
'version' => new external_value ( PARAM_NOTAGS , 'the device version \'6.1.2\' or \'4.2.2\' etc.' ),
'pushid' => new external_value ( PARAM_RAW , 'the device PUSH token/key/identifier/registration id' ),
2023-04-17 11:03:15 +02:00
'uuid' => new external_value ( PARAM_RAW , 'the device UUID' ),
'publickey' => new external_value ( PARAM_RAW , 'the app generated public key' , VALUE_DEFAULT , null ),
2013-10-04 11:43:45 +02:00
)
);
}
/**
* Add a user device in Moodle database ( for PUSH notifications usually ) .
*
2014-02-18 10:12:42 +13:00
* @ throws moodle_exception
2013-10-04 11:43:45 +02:00
* @ param string $appid The app id , usually something like com . moodle . moodlemobile .
* @ param string $name The device name , occam or iPhone etc .
* @ param string $model The device model Nexus4 or iPad1 . 1 etc .
* @ param string $platform The device platform iOs or Android etc .
* @ param string $version The device version 6.1 . 2 or 4.2 . 2 etc .
* @ param string $pushid The device PUSH token / key / identifier / registration id .
* @ param string $uuid The device UUID .
2023-04-17 11:03:15 +02:00
* @ param string $publickey The app generated public key
2013-10-04 11:43:45 +02:00
* @ return array List of possible warnings .
* @ since Moodle 2.6
*/
2023-04-17 11:03:15 +02:00
public static function add_user_device ( $appid , $name , $model , $platform , $version , $pushid , $uuid , $publickey = null ) {
2013-10-04 11:43:45 +02:00
global $CFG , $USER , $DB ;
require_once ( $CFG -> dirroot . " /user/lib.php " );
$params = self :: validate_parameters ( self :: add_user_device_parameters (),
array ( 'appid' => $appid ,
'name' => $name ,
'model' => $model ,
'platform' => $platform ,
'version' => $version ,
'pushid' => $pushid ,
2023-04-17 11:03:15 +02:00
'uuid' => $uuid ,
'publickey' => $publickey ,
2013-10-04 11:43:45 +02:00
));
$warnings = array ();
// Prevent duplicate keys for users.
if ( $DB -> get_record ( 'user_devices' , array ( 'pushid' => $params [ 'pushid' ], 'userid' => $USER -> id ))) {
$warnings [ 'warning' ][] = array (
'item' => $params [ 'pushid' ],
'warningcode' => 'existingkeyforthisuser' ,
'message' => 'This key is already stored for this user'
);
return $warnings ;
}
2015-02-26 12:07:08 +01:00
// Notice that we can have multiple devices because previously it was allowed to have repeated ones.
// Since we don't have a clear way to decide which one is the more appropiate, we update all.
if ( $userdevices = $DB -> get_records ( 'user_devices' , array ( 'uuid' => $params [ 'uuid' ],
'appid' => $params [ 'appid' ], 'userid' => $USER -> id ))) {
foreach ( $userdevices as $userdevice ) {
$userdevice -> version = $params [ 'version' ]; // Maybe the user upgraded the device.
$userdevice -> pushid = $params [ 'pushid' ];
2023-04-17 11:03:15 +02:00
$userdevice -> publickey = $params [ 'publickey' ];
2015-02-26 12:07:08 +01:00
$userdevice -> timemodified = time ();
$DB -> update_record ( 'user_devices' , $userdevice );
}
} else {
$userdevice = new stdclass ;
$userdevice -> userid = $USER -> id ;
$userdevice -> appid = $params [ 'appid' ];
$userdevice -> name = $params [ 'name' ];
$userdevice -> model = $params [ 'model' ];
$userdevice -> platform = $params [ 'platform' ];
$userdevice -> version = $params [ 'version' ];
$userdevice -> pushid = $params [ 'pushid' ];
$userdevice -> uuid = $params [ 'uuid' ];
2023-04-17 11:03:15 +02:00
$userdevice -> publickey = $params [ 'publickey' ];
2015-02-26 12:07:08 +01:00
$userdevice -> timecreated = time ();
$userdevice -> timemodified = $userdevice -> timecreated ;
if ( ! $DB -> insert_record ( 'user_devices' , $userdevice )) {
throw new moodle_exception ( " There was a problem saving in the database the device with key: " . $params [ 'pushid' ]);
}
2013-10-04 11:43:45 +02:00
}
return $warnings ;
}
/**
* Returns description of method result value .
*
* @ return external_multiple_structure
* @ since Moodle 2.6
*/
public static function add_user_device_returns () {
return new external_multiple_structure (
new external_warnings ()
);
}
2015-02-09 18:06:10 +01:00
/**
* Returns description of method parameters .
*
* @ return external_function_parameters
* @ since Moodle 2.9
*/
public static function remove_user_device_parameters () {
return new external_function_parameters (
array (
'uuid' => new external_value ( PARAM_RAW , 'the device UUID' ),
'appid' => new external_value ( PARAM_NOTAGS ,
'the app id, if empty devices matching the UUID for the user will be removed' ,
VALUE_DEFAULT , '' ),
)
);
}
/**
* Remove a user device from the Moodle database ( for PUSH notifications usually ) .
*
* @ param string $uuid The device UUID .
* @ param string $appid The app id , opitonal parameter . If empty all the devices fmatching the UUID or the user will be removed .
* @ return array List of possible warnings and removal status .
* @ since Moodle 2.9
*/
public static function remove_user_device ( $uuid , $appid = " " ) {
global $CFG ;
require_once ( $CFG -> dirroot . " /user/lib.php " );
$params = self :: validate_parameters ( self :: remove_user_device_parameters (), array ( 'uuid' => $uuid , 'appid' => $appid ));
$context = context_system :: instance ();
self :: validate_context ( $context );
// Warnings array, it can be empty at the end but is mandatory.
$warnings = array ();
$removed = user_remove_user_device ( $params [ 'uuid' ], $params [ 'appid' ]);
if ( ! $removed ) {
$warnings [] = array (
'item' => $params [ 'uuid' ],
'warningcode' => 'devicedoesnotexist' ,
'message' => 'The device doesn\'t exists in the database'
);
}
$result = array (
'removed' => $removed ,
'warnings' => $warnings
);
return $result ;
}
/**
* Returns description of method result value .
*
* @ return external_multiple_structure
* @ since Moodle 2.9
*/
public static function remove_user_device_returns () {
return new external_single_structure (
array (
'removed' => new external_value ( PARAM_BOOL , 'True if removed, false if not removed because it doesn\'t exists' ),
'warnings' => new external_warnings (),
)
);
}
2015-03-30 12:06:01 +02:00
/**
* Returns description of method parameters
*
* @ return external_function_parameters
* @ since Moodle 2.9
*/
public static function view_user_list_parameters () {
return new external_function_parameters (
array (
'courseid' => new external_value ( PARAM_INT , 'id of the course, 0 for site' )
)
);
}
/**
2015-07-14 11:30:55 +02:00
* Trigger the user_list_viewed event .
2015-03-30 12:06:01 +02:00
*
* @ param int $courseid id of course
* @ return array of warnings and status result
* @ since Moodle 2.9
* @ throws moodle_exception
*/
public static function view_user_list ( $courseid ) {
global $CFG ;
require_once ( $CFG -> dirroot . " /user/lib.php " );
2017-08-30 15:11:20 +08:00
require_once ( $CFG -> dirroot . '/course/lib.php' );
2015-03-30 12:06:01 +02:00
$params = self :: validate_parameters ( self :: view_user_list_parameters (),
array (
'courseid' => $courseid
));
$warnings = array ();
if ( empty ( $params [ 'courseid' ])) {
$params [ 'courseid' ] = SITEID ;
}
$course = get_course ( $params [ 'courseid' ]);
if ( $course -> id == SITEID ) {
$context = context_system :: instance ();
} else {
$context = context_course :: instance ( $course -> id );
}
self :: validate_context ( $context );
2017-08-30 15:11:20 +08:00
course_require_view_participants ( $context );
2015-03-30 12:06:01 +02:00
user_list_view ( $course , $context );
$result = array ();
$result [ 'status' ] = true ;
$result [ 'warnings' ] = $warnings ;
return $result ;
}
/**
* Returns description of method result value
*
* @ return external_description
* @ since Moodle 2.9
*/
public static function view_user_list_returns () {
return new external_single_structure (
array (
'status' => new external_value ( PARAM_BOOL , 'status: true if success' ),
'warnings' => new external_warnings ()
)
);
}
2015-03-30 14:11:20 +02:00
/**
* Returns description of method parameters
*
* @ return external_function_parameters
* @ since Moodle 2.9
*/
public static function view_user_profile_parameters () {
return new external_function_parameters (
array (
'userid' => new external_value ( PARAM_INT , 'id of the user, 0 for current user' , VALUE_REQUIRED ),
'courseid' => new external_value ( PARAM_INT , 'id of the course, default site course' , VALUE_DEFAULT , 0 )
)
);
}
/**
2015-07-14 11:30:55 +02:00
* Trigger the user profile viewed event .
2015-03-30 14:11:20 +02:00
*
* @ param int $userid id of user
* @ param int $courseid id of course
* @ return array of warnings and status result
* @ since Moodle 2.9
* @ throws moodle_exception
*/
public static function view_user_profile ( $userid , $courseid = 0 ) {
global $CFG , $USER ;
require_once ( $CFG -> dirroot . " /user/profile/lib.php " );
$params = self :: validate_parameters ( self :: view_user_profile_parameters (),
array (
'userid' => $userid ,
'courseid' => $courseid
));
$warnings = array ();
if ( empty ( $params [ 'userid' ])) {
$params [ 'userid' ] = $USER -> id ;
}
if ( empty ( $params [ 'courseid' ])) {
$params [ 'courseid' ] = SITEID ;
}
$course = get_course ( $params [ 'courseid' ]);
$user = core_user :: get_user ( $params [ 'userid' ], '*' , MUST_EXIST );
2015-09-23 11:00:32 +02:00
core_user :: require_active_user ( $user );
2015-03-30 14:11:20 +02:00
if ( $course -> id == SITEID ) {
$coursecontext = context_system :: instance ();;
} else {
$coursecontext = context_course :: instance ( $course -> id );
}
self :: validate_context ( $coursecontext );
$currentuser = $USER -> id == $user -> id ;
$usercontext = context_user :: instance ( $user -> id );
if ( ! $currentuser and
! has_capability ( 'moodle/user:viewdetails' , $coursecontext ) and
! has_capability ( 'moodle/user:viewdetails' , $usercontext )) {
throw new moodle_exception ( 'cannotviewprofile' );
}
// Case like user/profile.php.
if ( $course -> id == SITEID ) {
profile_view ( $user , $usercontext );
} else {
// Case like user/view.php.
2015-09-22 15:29:49 +02:00
if ( ! $currentuser and ! can_access_course ( $course , $user , '' , true )) {
2015-03-30 14:11:20 +02:00
throw new moodle_exception ( 'notenrolledprofile' );
}
profile_view ( $user , $coursecontext , $course );
}
$result = array ();
$result [ 'status' ] = true ;
$result [ 'warnings' ] = $warnings ;
return $result ;
}
/**
* Returns description of method result value
*
* @ return external_description
* @ since Moodle 2.9
*/
public static function view_user_profile_returns () {
return new external_single_structure (
array (
'status' => new external_value ( PARAM_BOOL , 'status: true if success' ),
'warnings' => new external_warnings ()
)
);
}
2016-07-21 15:42:58 +01:00
/**
* Returns description of method parameters
*
* @ return external_function_parameters
* @ since Moodle 3.2
*/
public static function get_user_preferences_parameters () {
return new external_function_parameters (
array (
'name' => new external_value ( PARAM_RAW , 'preference name, empty for all' , VALUE_DEFAULT , '' ),
'userid' => new external_value ( PARAM_INT , 'id of the user, default to current user' , VALUE_DEFAULT , 0 )
)
);
}
/**
* Return user preferences .
*
* @ param string $name preference name , empty for all
* @ param int $userid id of the user , 0 for current user
* @ return array of warnings and preferences
* @ since Moodle 3.2
* @ throws moodle_exception
*/
public static function get_user_preferences ( $name = '' , $userid = 0 ) {
global $USER ;
$params = self :: validate_parameters ( self :: get_user_preferences_parameters (),
array (
'name' => $name ,
'userid' => $userid
));
$preferences = array ();
$warnings = array ();
$context = context_system :: instance ();
self :: validate_context ( $context );
if ( empty ( $params [ 'name' ])) {
$name = null ;
}
if ( empty ( $params [ 'userid' ])) {
$user = null ;
} else {
$user = core_user :: get_user ( $params [ 'userid' ], '*' , MUST_EXIST );
core_user :: require_active_user ( $user );
if ( $user -> id != $USER -> id ) {
// Only admins can retrieve other users preferences.
require_capability ( 'moodle/site:config' , $context );
}
}
$userpreferences = get_user_preferences ( $name , null , $user );
// Check if we received just one preference.
if ( ! is_array ( $userpreferences )) {
$userpreferences = array ( $name => $userpreferences );
}
foreach ( $userpreferences as $name => $value ) {
$preferences [] = array (
'name' => $name ,
'value' => $value ,
);
}
$result = array ();
$result [ 'preferences' ] = $preferences ;
$result [ 'warnings' ] = $warnings ;
return $result ;
}
/**
* Returns description of method result value
*
* @ return external_description
* @ since Moodle 3.2
*/
public static function get_user_preferences_returns () {
return new external_single_structure (
array (
'preferences' => new external_multiple_structure (
new external_single_structure (
array (
'name' => new external_value ( PARAM_RAW , 'The name of the preference' ),
'value' => new external_value ( PARAM_RAW , 'The value of the preference' ),
)
),
'User custom fields (also known as user profile fields)'
),
'warnings' => new external_warnings ()
)
);
}
2016-09-21 21:28:08 +01:00
/**
* Returns description of method parameters
*
* @ return external_function_parameters
* @ since Moodle 3.2
*/
public static function update_picture_parameters () {
return new external_function_parameters (
array (
'draftitemid' => new external_value ( PARAM_INT , 'Id of the user draft file to use as image' ),
'delete' => new external_value ( PARAM_BOOL , 'If we should delete the user picture' , VALUE_DEFAULT , false ),
'userid' => new external_value ( PARAM_INT , 'Id of the user, 0 for current user' , VALUE_DEFAULT , 0 )
)
);
}
/**
* Update or delete the user picture in the site
*
* @ param int $draftitemid id of the user draft file to use as image
* @ param bool $delete if we should delete the user picture
* @ param int $userid id of the user , 0 for current user
* @ return array warnings and success status
* @ since Moodle 3.2
* @ throws moodle_exception
*/
public static function update_picture ( $draftitemid , $delete = false , $userid = 0 ) {
global $CFG , $USER , $PAGE ;
$params = self :: validate_parameters (
self :: update_picture_parameters (),
array (
'draftitemid' => $draftitemid ,
'delete' => $delete ,
'userid' => $userid
)
);
$context = context_system :: instance ();
self :: validate_context ( $context );
if ( ! empty ( $CFG -> disableuserimages )) {
throw new moodle_exception ( 'userimagesdisabled' , 'admin' );
}
if ( empty ( $params [ 'userid' ]) or $params [ 'userid' ] == $USER -> id ) {
$user = $USER ;
require_capability ( 'moodle/user:editownprofile' , $context );
} else {
$user = core_user :: get_user ( $params [ 'userid' ], '*' , MUST_EXIST );
core_user :: require_active_user ( $user );
$personalcontext = context_user :: instance ( $user -> id );
require_capability ( 'moodle/user:editprofile' , $personalcontext );
if ( is_siteadmin ( $user ) and ! is_siteadmin ( $USER )) { // Only admins may edit other admins.
throw new moodle_exception ( 'useradmineditadmin' );
}
}
// Load the appropriate auth plugin.
$userauth = get_auth_plugin ( $user -> auth );
if ( is_mnet_remote_user ( $user ) or ! $userauth -> can_edit_profile () or $userauth -> edit_profile_url ()) {
throw new moodle_exception ( 'noprofileedit' , 'auth' );
}
2020-08-11 14:50:06 +02:00
$filemanageroptions = array (
'maxbytes' => $CFG -> maxbytes ,
'subdirs' => 0 ,
'maxfiles' => 1 ,
'accepted_types' => 'optimised_image'
);
2016-09-21 21:28:08 +01:00
$user -> deletepicture = $params [ 'delete' ];
$user -> imagefile = $params [ 'draftitemid' ];
$success = core_user :: update_picture ( $user , $filemanageroptions );
$result = array (
'success' => $success ,
'warnings' => array (),
);
if ( $success ) {
$userpicture = new user_picture ( core_user :: get_user ( $user -> id ));
$userpicture -> size = 1 ; // Size f1.
$result [ 'profileimageurl' ] = $userpicture -> get_url ( $PAGE ) -> out ( false );
}
return $result ;
}
/**
* Returns description of method result value
*
* @ return external_description
* @ since Moodle 3.2
*/
public static function update_picture_returns () {
return new external_single_structure (
array (
'success' => new external_value ( PARAM_BOOL , 'True if the image was updated, false otherwise.' ),
'profileimageurl' => new external_value ( PARAM_URL , 'New profile user image url' , VALUE_OPTIONAL ),
'warnings' => new external_warnings ()
)
);
}
2016-09-01 13:47:13 +02:00
/**
* Returns description of method parameters
*
* @ return external_function_parameters
* @ since Moodle 3.2
*/
public static function set_user_preferences_parameters () {
return new external_function_parameters (
array (
'preferences' => new external_multiple_structure (
new external_single_structure (
array (
'name' => new external_value ( PARAM_RAW , 'The name of the preference' ),
'value' => new external_value ( PARAM_RAW , 'The value of the preference' ),
2023-01-11 13:59:04 +00:00
'userid' => new external_value ( PARAM_INT ,
'Id of the user to set the preference (default to current user)' , VALUE_DEFAULT , 0 ),
2016-09-01 13:47:13 +02:00
)
)
)
)
);
}
/**
* Set user preferences .
*
* @ param array $preferences list of preferences including name , value and userid
* @ return array of warnings and preferences saved
* @ since Moodle 3.2
* @ throws moodle_exception
*/
public static function set_user_preferences ( $preferences ) {
global $USER ;
$params = self :: validate_parameters ( self :: set_user_preferences_parameters (), array ( 'preferences' => $preferences ));
$warnings = array ();
$saved = array ();
$context = context_system :: instance ();
self :: validate_context ( $context );
$userscache = array ();
foreach ( $params [ 'preferences' ] as $pref ) {
2023-01-11 13:59:04 +00:00
$userid = $pref [ 'userid' ] ? : $USER -> id ;
2016-09-01 13:47:13 +02:00
// Check to which user set the preference.
2023-01-11 13:59:04 +00:00
if ( ! empty ( $userscache [ $userid ])) {
$user = $userscache [ $userid ];
2016-09-01 13:47:13 +02:00
} else {
try {
2023-01-11 13:59:04 +00:00
$user = core_user :: get_user ( $userid , '*' , MUST_EXIST );
2016-09-01 13:47:13 +02:00
core_user :: require_active_user ( $user );
2023-01-11 13:59:04 +00:00
$userscache [ $userid ] = $user ;
2016-09-01 13:47:13 +02:00
} catch ( Exception $e ) {
$warnings [] = array (
'item' => 'user' ,
2023-01-11 13:59:04 +00:00
'itemid' => $userid ,
2016-09-01 13:47:13 +02:00
'warningcode' => 'invaliduser' ,
'message' => $e -> getMessage ()
);
continue ;
}
}
try {
2017-03-05 13:20:03 +08:00
if ( core_user :: can_edit_preference ( $pref [ 'name' ], $user )) {
$value = core_user :: clean_preference ( $pref [ 'value' ], $pref [ 'name' ]);
set_user_preference ( $pref [ 'name' ], $value , $user -> id );
$saved [] = array (
'name' => $pref [ 'name' ],
'userid' => $user -> id ,
);
} else {
$warnings [] = array (
'item' => 'user' ,
'itemid' => $user -> id ,
'warningcode' => 'nopermission' ,
'message' => 'You are not allowed to change the preference ' . s ( $pref [ 'name' ]) . ' for user ' . $user -> id
);
}
2016-09-01 13:47:13 +02:00
} catch ( Exception $e ) {
$warnings [] = array (
'item' => 'user' ,
'itemid' => $user -> id ,
'warningcode' => 'errorsavingpreference' ,
'message' => $e -> getMessage ()
);
}
}
$result = array ();
$result [ 'saved' ] = $saved ;
$result [ 'warnings' ] = $warnings ;
return $result ;
}
/**
* Returns description of method result value
*
* @ return external_description
* @ since Moodle 3.2
*/
public static function set_user_preferences_returns () {
return new external_single_structure (
array (
'saved' => new external_multiple_structure (
new external_single_structure (
array (
'name' => new external_value ( PARAM_RAW , 'The name of the preference' ),
'userid' => new external_value ( PARAM_INT , 'The user the preference was set for' ),
)
), 'Preferences saved'
),
'warnings' => new external_warnings ()
)
);
}
2016-09-27 11:10:51 +01:00
/**
* Returns description of method parameters .
*
* @ return external_function_parameters
* @ since Moodle 3.2
*/
public static function agree_site_policy_parameters () {
return new external_function_parameters ( array ());
}
/**
* Agree the site policy for the current user .
*
* @ return array of warnings and status result
* @ since Moodle 3.2
* @ throws moodle_exception
*/
public static function agree_site_policy () {
global $CFG , $DB , $USER ;
$warnings = array ();
$context = context_system :: instance ();
try {
// We expect an exception here since the user didn't agree the site policy yet.
self :: validate_context ( $context );
} catch ( Exception $e ) {
// We are expecting only a sitepolicynotagreed exception.
if ( ! ( $e instanceof moodle_exception ) or $e -> errorcode != 'sitepolicynotagreed' ) {
// In case we receive a different exception, throw it.
throw $e ;
}
}
2018-03-12 09:33:43 +08:00
$manager = new \core_privacy\local\sitepolicy\manager ();
if ( ! empty ( $USER -> policyagreed )) {
2016-09-27 11:10:51 +01:00
$status = false ;
$warnings [] = array (
'item' => 'user' ,
'itemid' => $USER -> id ,
2018-03-12 09:33:43 +08:00
'warningcode' => 'alreadyagreed' ,
'message' => 'The user already agreed the site policy.'
2016-09-27 11:10:51 +01:00
);
2018-03-12 09:33:43 +08:00
} else if ( ! $manager -> is_defined ()) {
2016-09-27 11:10:51 +01:00
$status = false ;
$warnings [] = array (
'item' => 'user' ,
'itemid' => $USER -> id ,
2018-03-12 09:33:43 +08:00
'warningcode' => 'nositepolicy' ,
'message' => 'The site does not have a site policy configured.'
2016-09-27 11:10:51 +01:00
);
} else {
2018-03-12 09:33:43 +08:00
$status = $manager -> accept ();
2016-09-27 11:10:51 +01:00
}
$result = array ();
$result [ 'status' ] = $status ;
$result [ 'warnings' ] = $warnings ;
return $result ;
}
/**
* Returns description of method result value .
*
* @ return external_description
* @ since Moodle 3.2
*/
public static function agree_site_policy_returns () {
return new external_single_structure (
array (
'status' => new external_value ( PARAM_BOOL , 'Status: true only if we set the policyagreed to 1 for the user' ),
'warnings' => new external_warnings ()
)
);
}
2017-06-13 11:56:19 +01:00
/**
* Returns description of method parameters .
*
* @ return external_function_parameters
* @ since Moodle 3.4
*/
public static function get_private_files_info_parameters () {
return new external_function_parameters (
array (
'userid' => new external_value ( PARAM_INT , 'Id of the user, default to current user.' , VALUE_DEFAULT , 0 )
)
);
}
/**
* Returns general information about files in the user private files area .
*
* @ param int $userid Id of the user , default to current user .
* @ return array of warnings and file area information
* @ since Moodle 3.4
* @ throws moodle_exception
*/
public static function get_private_files_info ( $userid = 0 ) {
global $CFG , $USER ;
require_once ( $CFG -> libdir . '/filelib.php' );
$params = self :: validate_parameters ( self :: get_private_files_info_parameters (), array ( 'userid' => $userid ));
$warnings = array ();
$context = context_system :: instance ();
self :: validate_context ( $context );
if ( empty ( $params [ 'userid' ]) || $params [ 'userid' ] == $USER -> id ) {
$usercontext = context_user :: instance ( $USER -> id );
require_capability ( 'moodle/user:manageownfiles' , $usercontext );
} else {
$user = core_user :: get_user ( $params [ 'userid' ], '*' , MUST_EXIST );
core_user :: require_active_user ( $user );
// Only admins can retrieve other users information.
require_capability ( 'moodle/site:config' , $context );
$usercontext = context_user :: instance ( $user -> id );
}
$fileareainfo = file_get_file_area_info ( $usercontext -> id , 'user' , 'private' );
$result = array ();
$result [ 'filecount' ] = $fileareainfo [ 'filecount' ];
$result [ 'foldercount' ] = $fileareainfo [ 'foldercount' ];
$result [ 'filesize' ] = $fileareainfo [ 'filesize' ];
$result [ 'filesizewithoutreferences' ] = $fileareainfo [ 'filesize_without_references' ];
$result [ 'warnings' ] = $warnings ;
return $result ;
}
/**
* Returns description of method result value .
*
* @ return external_description
* @ since Moodle 3.4
*/
public static function get_private_files_info_returns () {
return new external_single_structure (
array (
'filecount' => new external_value ( PARAM_INT , 'Number of files in the area.' ),
'foldercount' => new external_value ( PARAM_INT , 'Number of folders in the area.' ),
'filesize' => new external_value ( PARAM_INT , 'Total size of the files in the area.' ),
'filesizewithoutreferences' => new external_value ( PARAM_INT , 'Total size of the area excluding file references' ),
'warnings' => new external_warnings ()
)
);
}
2011-10-18 12:57:33 +08:00
}