From 3b214760fb51ae2b0c85bbb2b272b9bc7c164657 Mon Sep 17 00:00:00 2001 From: Simey Lameze Date: Mon, 18 Jan 2016 10:13:11 +0800 Subject: [PATCH] MDL-50705 core_user: introduce new fill_properties_cache() Also the get_property_definition() was created to get the property without retrieve the whole definition cache and unit tests were created to tests those new methods. --- lib/classes/user.php | 103 +++++++++++++++++++++++++++++++++++ lib/phpunit/classes/util.php | 1 + lib/tests/user_test.php | 25 +++++++++ lib/upgrade.txt | 8 +++ 4 files changed, 137 insertions(+) diff --git a/lib/classes/user.php b/lib/classes/user.php index bad53f530f0..34813b16925 100644 --- a/lib/classes/user.php +++ b/lib/classes/user.php @@ -49,6 +49,9 @@ class core_user { /** @var stdClass keep record of support user */ public static $supportuser = false; + /** @var array store user fields properties cache. */ + protected static $propertiescache = null; + /** * Return user object from db or create noreply or support user, * if userid matches corse_user::NOREPLY_USER or corse_user::SUPPORT_USER @@ -238,4 +241,104 @@ class core_user { return true; } } + + /** + * Definition of user profile fields and the expected parameter type for data validation. + * + * @return void + */ + protected static function fill_properties_cache() { + + if (self::$propertiescache !== null) { + return; + } + + // Array of user fields properties and expected parameters. + // Every new field on the user table should be added here otherwise it won't be validated. + $fields = array(); + $fields['id'] = array('type' => PARAM_INT); + $fields['auth'] = array('type' => PARAM_NOTAGS); + $fields['confirmed'] = array('type' => PARAM_BOOL); + $fields['policyagreed'] = array('type' => PARAM_BOOL); + $fields['deleted'] = array('type' => PARAM_BOOL); + $fields['suspended'] = array('type' => PARAM_BOOL); + $fields['mnethostid'] = array('type' => PARAM_BOOL); + $fields['username'] = array('type' => PARAM_USERNAME); + $fields['password'] = array('type' => PARAM_NOTAGS); + $fields['idnumber'] = array('type' => PARAM_NOTAGS); + $fields['firstname'] = array('type' => PARAM_NOTAGS); + $fields['lastname'] = array('type' => PARAM_NOTAGS); + $fields['surname'] = array('type' => PARAM_NOTAGS); + $fields['email'] = array('type' => PARAM_RAW_TRIMMED); + $fields['emailstop'] = array('type' => PARAM_INT); + $fields['icq'] = array('type' => PARAM_NOTAGS); + $fields['skype'] = array('type' => PARAM_NOTAGS); + $fields['aim'] = array('type' => PARAM_NOTAGS); + $fields['yahoo'] = array('type' => PARAM_NOTAGS); + $fields['msn'] = array('type' => PARAM_NOTAGS); + $fields['phone1'] = array('type' => PARAM_NOTAGS); + $fields['phone2'] = array('type' => PARAM_NOTAGS); + $fields['institution'] = array('type' => PARAM_TEXT); + $fields['department'] = array('type' => PARAM_TEXT); + $fields['address'] = array('type' => PARAM_TEXT); + $fields['city'] = array('type' => PARAM_TEXT); + $fields['country'] = array('type' => PARAM_TEXT); + $fields['lang'] = array('type' => PARAM_TEXT); + $fields['calendartype'] = array('type' => PARAM_NOTAGS); + $fields['theme'] = array('type' => PARAM_NOTAGS); + $fields['timezones'] = array('type' => PARAM_TEXT); + $fields['firstaccess'] = array('type' => PARAM_INT); + $fields['lastaccess'] = array('type' => PARAM_INT); + $fields['lastlogin'] = array('type' => PARAM_INT); + $fields['currentlogin'] = array('type' => PARAM_INT); + $fields['lastip'] = array('type' => PARAM_NOTAGS); + $fields['secret'] = array('type' => PARAM_TEXT); + $fields['picture'] = array('type' => PARAM_INT); + $fields['url'] = array('type' => PARAM_URL); + $fields['description'] = array('type' => PARAM_CLEANHTML); + $fields['descriptionformat'] = array('type' => PARAM_INT); + $fields['mailformat'] = array('type' => PARAM_INT); + $fields['maildigest'] = array('type' => PARAM_INT); + $fields['maildisplay'] = array('type' => PARAM_INT); + $fields['autosubscribe'] = array('type' => PARAM_INT); + $fields['trackforums'] = array('type' => PARAM_INT); + $fields['timecreated'] = array('type' => PARAM_INT); + $fields['timemodified'] = array('type' => PARAM_INT); + $fields['trustbitmask'] = array('type' => PARAM_INT); + $fields['imagealt'] = array('type' => PARAM_TEXT); + $fields['lastnamephonetic'] = array('type' => PARAM_NOTAGS); + $fields['firstnamephonetic'] = array('type' => PARAM_NOTAGS); + $fields['middlename'] = array('type' => PARAM_NOTAGS); + $fields['alternatename'] = array('type' => PARAM_NOTAGS); + + self::$propertiescache = $fields; + } + + /** + * Get properties of a user field. + * + * @param string $property property name to be retrieved. + * @throws coding_exception if the requested property name is invalid. + * @return array the property definition. + */ + public static function get_property_definition($property) { + + self::fill_properties_cache(); + + if (!array_key_exists($property, self::$propertiescache)) { + throw new coding_exception('Invalid property requested.'); + } + + return self::$propertiescache[$property]; + } + + /** + * Clean the properties cache. + * + * During unit tests we need to be able to reset all caches so that each new test starts in a known state. + * Intended for use only for testing, phpunit calls this before every test. + */ + public static function reset_caches() { + self::$propertiescache = null; + } } diff --git a/lib/phpunit/classes/util.php b/lib/phpunit/classes/util.php index c6e9baf30b1..3144b932b59 100644 --- a/lib/phpunit/classes/util.php +++ b/lib/phpunit/classes/util.php @@ -204,6 +204,7 @@ class phpunit_util extends testing_util { filter_manager::reset_caches(); // Reset internal users. core_user::reset_internal_users(); + core_user::reset_caches(); //TODO MDL-25290: add more resets here and probably refactor them to new core function diff --git a/lib/tests/user_test.php b/lib/tests/user_test.php index 1a8acdef43e..14b8df7f8b4 100644 --- a/lib/tests/user_test.php +++ b/lib/tests/user_test.php @@ -116,4 +116,29 @@ class core_user_testcase extends advanced_testcase { // Assert that a user not in the db return false. $this->assertFalse(core_user::get_user_by_username('janedoe')); } + + /** + * Test get_property_definition() method. + */ + public function test_get_property_definition() { + // Try to get a existing property. + $properties = core_user::get_property_definition('id'); + $this->assertEquals($properties['type'], PARAM_INT); + $properties = core_user::get_property_definition('username'); + $this->assertEquals($properties['type'], PARAM_USERNAME); + + // Invalid property. + try { + core_user::get_property_definition('fullname'); + } catch (coding_exception $e) { + $this->assertRegExp('/Invalid property requested./', $e->getMessage()); + } + + // Empty parameter. + try { + core_user::get_property_definition(''); + } catch (coding_exception $e) { + $this->assertRegExp('/Invalid property requested./', $e->getMessage()); + } + } } diff --git a/lib/upgrade.txt b/lib/upgrade.txt index 6c06a9bb526..71600a073c3 100644 --- a/lib/upgrade.txt +++ b/lib/upgrade.txt @@ -1,6 +1,14 @@ This files describes API changes in core libraries and APIs, information provided here is intended especially for developers. +=== 2.7.13 === + +* The core_user::fill_properties_cache() static method has been introduced to be a reference + and allow standard user fields data validation. Right now only type validation is supported + checking it against the parameter (PARAM_*) type of the target user field. MDL-52781 is + going to add support to null/not null and choices validation, replacing the existing code to + validate the user fields in different places in a common way. + === 2.7.10 === * In the html_editors (tinyMCE, Atto), the manage files button can be hidden by changing the 'enable_filemanagement' option to false.