diff --git a/lib/db/services.php b/lib/db/services.php index 167b8c7d16e..2a89989a5ce 100644 --- a/lib/db/services.php +++ b/lib/db/services.php @@ -1025,15 +1025,6 @@ $functions = array( 'type' => 'write', 'services' => array(MOODLE_OFFICIAL_MOBILE_SERVICE), ), - 'core_user_update_user' => array( - 'classname' => 'core_user_external', - 'methodname' => 'update_user', - 'classpath' => 'user/externallib.php', - 'description' => 'Update logged in user', - 'type' => 'write', - 'capabilities' => 'moodle/user:update', - 'ajax' => true, - ), 'core_user_update_users' => array( 'classname' => 'core_user_external', 'methodname' => 'update_users', @@ -1043,6 +1034,15 @@ $functions = array( 'capabilities' => 'moodle/user:update', 'ajax' => true, ), + 'core_user_update_user_preferences' => array( + 'classname' => 'core_user_external', + 'methodname' => 'update_user_preferences', + 'classpath' => 'user/externallib.php', + 'description' => 'Update a user\'s preferences', + 'type' => 'write', + 'capabilities' => 'moodle/user:editownmessageprofile, moodle/user:editmessageprofile', + 'ajax' => true, + ), 'core_user_view_user_list' => array( 'classname' => 'core_user_external', 'methodname' => 'view_user_list', diff --git a/message/amd/src/message_preferences.js b/message/amd/src/message_preferences.js index 1eee287add1..087c3671c41 100644 --- a/message/amd/src/message_preferences.js +++ b/message/amd/src/message_preferences.js @@ -74,16 +74,14 @@ define(['jquery', 'core/ajax', 'core/notification', container.addClass('loading'); var request = { - methodname: 'core_user_update_user', + methodname: 'core_user_update_user_preferences', args: { - user: { - preferences: [ - { - type: checkbox.attr('data-preference-key'), - value: ischecked ? 1 : 0, - } - ] - } + preferences: [ + { + type: checkbox.attr('data-preference-key'), + value: ischecked ? 1 : 0, + } + ] } }; diff --git a/message/amd/src/notification_preference.js b/message/amd/src/notification_preference.js index 88fdc96027a..a260007a019 100644 --- a/message/amd/src/notification_preference.js +++ b/message/amd/src/notification_preference.js @@ -158,22 +158,21 @@ define(['jquery', 'core/ajax', 'core/notification', 'core_message/notification_p } var args = { - user: { - preferences: [ - { - type: this.getLoggedInPreferenceKey(), - value: loggedInValue, - }, - { - type: this.getLoggedOffPreferenceKey(), - value: loggedOffValue, - }, - ], - } + userid : this.userId, + preferences: [ + { + type: this.getLoggedInPreferenceKey(), + value: loggedInValue, + }, + { + type: this.getLoggedOffPreferenceKey(), + value: loggedOffValue, + }, + ], }; var request = { - methodname: 'core_user_update_user', + methodname: 'core_user_update_user_preferences', args: args, }; diff --git a/message/amd/src/preferences_notifications_list_controller.js b/message/amd/src/preferences_notifications_list_controller.js index 854df9cf908..1bbed33d6b4 100644 --- a/message/amd/src/preferences_notifications_list_controller.js +++ b/message/amd/src/preferences_notifications_list_controller.js @@ -98,11 +98,10 @@ define(['jquery', 'core/ajax', 'core/notification', 'core/custom_interaction_eve container.addClass('loading'); var request = { - methodname: 'core_user_update_user', + methodname: 'core_user_update_user_preferences', args: { - user: { - emailstop: ischecked ? 1 : 0, - } + userid: this.userId, + emailstop: ischecked ? 1 : 0, } }; diff --git a/user/externallib.php b/user/externallib.php index e46b9efd28c..2d2ddd64426 100644 --- a/user/externallib.php +++ b/user/externallib.php @@ -323,140 +323,88 @@ class core_user_external extends external_api { } /** - * Returns description of method parameters + * Returns description of method parameters. * * @return external_function_parameters * @since Moodle 3.2 */ - public static function update_user_parameters() { + public static function update_user_preferences_parameters() { return new external_function_parameters( array( - 'user' => new external_single_structure( - array( - 'username' => - new external_value(core_user::get_property_type('username'), 'Username policy is defined in Moodle security config.', - VALUE_OPTIONAL, '', NULL_NOT_ALLOWED), - '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), - 'emailstop' => - new external_value(core_user::get_property_type('emailstop'), 'Enable or disable notifications for this user', VALUE_OPTIONAL, '', - NULL_NOT_ALLOWED), - 'auth' => - new external_value(core_user::get_property_type('auth'), 'Auth plugins include manual, ldap, imap, etc', VALUE_OPTIONAL, '', - NULL_NOT_ALLOWED), - 'idnumber' => - new external_value(core_user::get_property_type('idnumber'), 'An arbitrary ID code number perhaps from the institution', - VALUE_OPTIONAL), - '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), - '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, no HTML', 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), - '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), - 'customfields' => new external_multiple_structure( - new external_single_structure( - array( - '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), - 'preferences' => new external_multiple_structure( - new external_single_structure( - array( - 'type' => new external_value(PARAM_ALPHANUMEXT, 'The name of the preference'), - 'value' => new external_value(PARAM_RAW, 'The value of the preference') - ) - ), 'User preferences', VALUE_OPTIONAL), - ) + '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( + 'type' => new external_value(PARAM_ALPHANUMEXT, 'The name of the preference'), + 'value' => new external_value(PARAM_RAW, 'The value of the preference') + ) + ), 'User preferences', VALUE_DEFAULT, array() ) ) ); } /** - * Update the currently logged in user + * Update the user's preferences. * - * @param array $users + * @param int $userid + * @param bool|null $emailstop + * @param array $preferences * @return null * @since Moodle 3.2 */ - public static function update_user($user) { + public static function update_user_preferences($userid, $emailstop = null, $preferences = array()) { + global $USER, $CFG; - global $USER, $CFG, $DB; - require_once($CFG->dirroot."/user/lib.php"); - require_once($CFG->dirroot."/user/profile/lib.php"); // Required for customfields related function. + require_once($CFG->dirroot . '/user/lib.php'); - $params = self::validate_parameters( - self::update_user_parameters(), - array('user' => $user) - ); - - $user = $params['user']; - $user['id'] = $USER->id; - - $transaction = $DB->start_delegated_transaction(); - - user_update_user($user, true, false); - // Update user 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']; - } - profile_save_data((object) $user); + if (empty($userid)) { + $userid = $USER->id; } - // Trigger event. - \core\event\user_updated::create_from_userid($user['id'])->trigger(); + $systemcontext = context_system::instance(); + self::validate_context($systemcontext); + $params = array( + 'userid' => $userid, + 'emailstop' => $emailstop, + 'preferences' => $preferences + ); + self::validate_parameters(self::update_user_preferences_parameters(), $params); + + if ($userid == $USER->id) { + require_capability('moodle/user:editownmessageprofile', $systemcontext); + } else { + $personalcontext = context_user::instance($userid); + require_capability('moodle/user:editmessageprofile', $personalcontext); + // No editing of guest user account. + if (isguestuser($userid)) { + print_error('guestnoeditmessageother', 'message'); + } + // No editing of admins by non-admins. + if (is_siteadmin($userid) and !is_siteadmin($USER)) { + print_error('useradmineditadmin'); + } + } // Preferences. - if (!empty($user['preferences'])) { - foreach ($user['preferences'] as $preference) { - set_user_preference($preference['type'], $preference['value'], $user['id']); + if (!empty($preferences)) { + foreach ($preferences as $preference) { + set_user_preference($preference['type'], $preference['value'], $userid); } } - $transaction->allow_commit(); + // Check if they want to update the email. + if ($emailstop !== null) { + $user = new stdClass(); + $user->id = $userid; + $user->emailstop = $emailstop; + user_update_user($user); - // Everything went well, update the $USER. - foreach ($user as $property => $value) { - // If the $USER knows about this value. - if (isset($USER, $property)) { - $USER->$property = $value; + // Update the $USER if we should. + if ($userid == $USER->id) { + $USER->emailstop = $emailstop; } } @@ -469,7 +417,7 @@ class core_user_external extends external_api { * @return null * @since Moodle 3.2 */ - public static function update_user_returns() { + public static function update_user_preferences_returns() { return null; } @@ -501,9 +449,6 @@ class core_user_external extends external_api { 'email' => new external_value(core_user::get_property_type('email'), 'A valid and unique email address', VALUE_OPTIONAL, '', NULL_NOT_ALLOWED), - 'emailstop' => - new external_value(core_user::get_property_type('emailstop'), 'Enable or disable notifications for this user', VALUE_OPTIONAL, '', - NULL_NOT_ALLOWED), 'auth' => new external_value(core_user::get_property_type('auth'), 'Auth plugins include manual, ldap, imap, etc', VALUE_OPTIONAL, '', NULL_NOT_ALLOWED),