From 649777fb8d489ac6abc3c933f67ba814eabebfa2 Mon Sep 17 00:00:00 2001 From: Juan Leyva Date: Thu, 1 Sep 2016 13:47:13 +0200 Subject: [PATCH] MDL-55347 user: New WS core_user_set_users_preferences --- lib/db/services.php | 9 +++ user/externallib.php | 106 ++++++++++++++++++++++++++++++++ user/tests/externallib_test.php | 106 ++++++++++++++++++++++++++++++++ version.php | 2 +- 4 files changed, 222 insertions(+), 1 deletion(-) diff --git a/lib/db/services.php b/lib/db/services.php index 9ba895e6c45..df735aa7ad9 100644 --- a/lib/db/services.php +++ b/lib/db/services.php @@ -905,6 +905,15 @@ $functions = array( 'capabilities' => 'moodle/user:editownprofile, moodle/user:editprofile', 'services' => array(MOODLE_OFFICIAL_MOBILE_SERVICE), ), + 'core_user_set_user_preferences' => array( + 'classname' => 'core_user_external', + 'methodname' => 'set_user_preferences', + 'classpath' => 'user/externallib.php', + 'description' => 'Set user preferences.', + 'type' => 'write', + 'capabilities' => 'moodle/site:config', + ), + // Competencies functions. 'core_competency_create_competency_framework' => array( 'classname' => 'core_competency\external', diff --git a/user/externallib.php b/user/externallib.php index 933b6da06ea..19abcd04071 100644 --- a/user/externallib.php +++ b/user/externallib.php @@ -1554,4 +1554,110 @@ class core_user_external extends external_api { ) ); } + + /** + * 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'), + 'userid' => new external_value(PARAM_INT, 'Id of the user to set the preference'), + ) + ) + ) + ) + ); + } + + /** + * 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); + require_capability('moodle/site:config', $context); + + $userscache = array(); + foreach ($params['preferences'] as $pref) { + // Check to which user set the preference. + if (!empty($userscache[$pref['userid']])) { + $user = $userscache[$pref['userid']]; + } else { + try { + $user = core_user::get_user($pref['userid'], '*', MUST_EXIST); + core_user::require_active_user($user); + $userscache[$pref['userid']] = $user; + } catch (Exception $e) { + $warnings[] = array( + 'item' => 'user', + 'itemid' => $pref['userid'], + 'warningcode' => 'invaliduser', + 'message' => $e->getMessage() + ); + continue; + } + } + + try { + set_user_preference($pref['name'], $pref['value'], $user); + $saved[] = array( + 'name' => $pref['name'], + 'userid' => $user->id, + ); + } 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() + ) + ); + } } diff --git a/user/tests/externallib_test.php b/user/tests/externallib_test.php index e0920b74a4f..a7b48d799c6 100644 --- a/user/tests/externallib_test.php +++ b/user/tests/externallib_test.php @@ -919,4 +919,110 @@ class core_user_externallib_testcase extends externallib_advanced_testcase { $this->expectException('moodle_exception'); core_user_external::update_picture(0); } + + /** + * Test set_user_preferences + */ + public function test_set_user_preferences_save() { + global $DB; + $this->resetAfterTest(true); + + $user1 = self::getDataGenerator()->create_user(); + $user2 = self::getDataGenerator()->create_user(); + + // Save users preferences. + $this->setAdminUser(); + $preferences = array( + array( + 'name' => 'some_random_pref', + 'value' => 'abc', + 'userid' => $user1->id, + ), + array( + 'name' => 'some_random_pref', + 'value' => 'def', + 'userid' => $user2->id, + ) + ); + + $result = core_user_external::set_user_preferences($preferences); + $result = external_api::clean_returnvalue(core_user_external::set_user_preferences_returns(), $result); + $this->assertCount(0, $result['warnings']); + $this->assertCount(2, $result['saved']); + + // Get preference from DB to avoid cache. + $this->assertEquals('abc', $DB->get_field('user_preferences', 'value', + array('userid' => $user1->id, 'name' => 'some_random_pref'))); + $this->assertEquals('def', $DB->get_field('user_preferences', 'value', + array('userid' => $user2->id, 'name' => 'some_random_pref'))); + } + + /** + * Test set_user_preferences for an invalid user + */ + public function test_set_user_preferences_invalid_user() { + $this->resetAfterTest(true); + + $this->setAdminUser(); + $preferences = array( + array( + 'name' => 'calendar_maxevents', + 'value' => 4, + 'userid' => -2 + ) + ); + + $result = core_user_external::set_user_preferences($preferences); + $result = external_api::clean_returnvalue(core_user_external::set_user_preferences_returns(), $result); + $this->assertCount(1, $result['warnings']); + $this->assertCount(0, $result['saved']); + $this->assertEquals('invaliduser', $result['warnings'][0]['warningcode']); + $this->assertEquals(-2, $result['warnings'][0]['itemid']); + } + + /** + * Test set_user_preferences using an invalid preference + */ + public function test_set_user_preferences_invalid_preference() { + global $USER; + + $this->resetAfterTest(true); + // Create a very long value. + $this->setAdminUser(); + $preferences = array( + array( + 'name' => 'calendar_maxevents', + 'value' => str_repeat('a', 1334), + 'userid' => $USER->id + ) + ); + + $result = core_user_external::set_user_preferences($preferences); + $result = external_api::clean_returnvalue(core_user_external::set_user_preferences_returns(), $result); + $this->assertCount(1, $result['warnings']); + $this->assertCount(0, $result['saved']); + $this->assertEquals('errorsavingpreference', $result['warnings'][0]['warningcode']); + } + + /** + * Test set_user_preferences for other user not being admin + */ + public function test_set_user_preferences_other_user_not_being_admin() { + $this->resetAfterTest(true); + + $user1 = self::getDataGenerator()->create_user(); + $user2 = self::getDataGenerator()->create_user(); + + $this->setUser($user1); + $preferences = array( + array( + 'name' => 'calendar_maxevents', + 'value' => 4, + 'userid' => $user2->id + ) + ); + + $this->expectException('required_capability_exception'); + $result = core_user_external::set_user_preferences($preferences); + } } diff --git a/version.php b/version.php index 3c09cea3d01..0ab7567123c 100644 --- a/version.php +++ b/version.php @@ -29,7 +29,7 @@ defined('MOODLE_INTERNAL') || die(); -$version = 2016092900.00; // YYYYMMDD = weekly release date of this DEV branch. +$version = 2016092900.01; // YYYYMMDD = weekly release date of this DEV branch. // RR = release increments - 00 in DEV branches. // .XX = incremental changes.