diff --git a/user/externallib.php b/user/externallib.php index 946027a9ab5..8a6e8e0acc2 100644 --- a/user/externallib.php +++ b/user/externallib.php @@ -1149,7 +1149,9 @@ class core_user_external extends \core_external\external_api { new external_single_structure( array( 'type' => new external_value(PARAM_ALPHANUMEXT, 'The type of the custom field - text field, checkbox...'), - 'value' => new external_value(PARAM_RAW, 'The value of the custom field'), + '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), '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'), ) diff --git a/user/lib.php b/user/lib.php index a2022b462c1..2ab18a227cd 100644 --- a/user/lib.php +++ b/user/lib.php @@ -361,19 +361,13 @@ function user_get_user_details($user, $course = null, array $userfields = array( foreach ($fields as $formfield) { if ($formfield->is_visible() and !$formfield->is_empty()) { - // TODO: Part of MDL-50728, this conditional coding must be moved to - // proper profile fields API so they are self-contained. - // We only use display_data in fields that require text formatting. - if ($formfield->field->datatype == 'text' or $formfield->field->datatype == 'textarea') { - $fieldvalue = $formfield->display_data(); - } else { - // Cases: datetime, checkbox and menu. - $fieldvalue = $formfield->data; - } - - $userdetails['customfields'][] = - array('name' => $formfield->field->name, 'value' => $fieldvalue, - 'type' => $formfield->field->datatype, 'shortname' => $formfield->field->shortname); + $userdetails['customfields'][] = [ + 'name' => $formfield->field->name, + 'value' => $formfield->data, + 'displayvalue' => $formfield->display_data(), + 'type' => $formfield->field->datatype, + 'shortname' => $formfield->field->shortname + ]; } } } diff --git a/user/profile/field/menu/field.class.php b/user/profile/field/menu/field.class.php index a304cc4102a..061c791440c 100644 --- a/user/profile/field/menu/field.class.php +++ b/user/profile/field/menu/field.class.php @@ -168,6 +168,24 @@ class profile_field_menu extends profile_field_base { public function get_field_properties() { return array(PARAM_TEXT, NULL_NOT_ALLOWED); } + + /** + * Return the field settings suitable to be exported via an external function. + * + * @return array all the settings + */ + public function get_field_config_for_external() { + + if (isset($this->field->param1) && !empty($this->options)) { + // Remove "Choose" option to make it consisten with the rest of the data. + if (!empty($this->field->required)) { + unset($this->options['']); + } + $this->field->param2 = implode("\n", array_values($this->options)); + } + + return (array) $this->field; + } } diff --git a/user/tests/externallib_test.php b/user/tests/externallib_test.php index d986c4b0e71..e54bc521d35 100644 --- a/user/tests/externallib_test.php +++ b/user/tests/externallib_test.php @@ -184,7 +184,20 @@ class externallib_test extends externallib_advanced_testcase { $this->resetAfterTest(true); - $course = self::getDataGenerator()->create_course(); + $generator = self::getDataGenerator(); + + // Create complex user profile field supporting multi-lang. + filter_set_global_state('multilang', TEXTFILTER_ON); + $statuses = 'UE\nSE\nOtherOtro'; + $generator->create_custom_profile_field( + [ + 'datatype' => 'menu', + 'shortname' => 'employmentstatus', 'name' => 'Employment status', + 'param1' => $statuses + ] + ); + + $course = $generator->create_course(); $user1 = array( 'username' => 'usernametest1', 'idnumber' => 'idnumbertest1', @@ -200,14 +213,16 @@ class externallib_test extends externallib_advanced_testcase { 'descriptionformat' => FORMAT_MOODLE, 'city' => 'Perth', 'country' => 'AU', + 'profile_field_jobposition' => 'Manager', + 'profile_field_employmentstatus' => explode('\n', $statuses)[2], ); - $user1 = self::getDataGenerator()->create_user($user1); + $user1 = $generator->create_user($user1); if (!empty($CFG->usetags)) { require_once($CFG->dirroot . '/user/editlib.php'); $user1->interests = array('Cinema', 'Tennis', 'Dance', 'Guitar', 'Cooking'); useredit_update_interests($user1, $user1->interests); } - $user2 = self::getDataGenerator()->create_user( + $user2 = $generator->create_user( array('username' => 'usernametest2', 'idnumber' => 'idnumbertest2')); $generatedusers = array(); @@ -218,9 +233,9 @@ class externallib_test extends externallib_advanced_testcase { $roleid = $this->assignUserCapability('moodle/user:viewdetails', $context->id); // Enrol the users in the course. - $this->getDataGenerator()->enrol_user($user1->id, $course->id, $roleid, 'manual'); - $this->getDataGenerator()->enrol_user($user2->id, $course->id, $roleid, 'manual'); - $this->getDataGenerator()->enrol_user($USER->id, $course->id, $roleid, 'manual'); + $generator->enrol_user($user1->id, $course->id, $roleid, 'manual'); + $generator->enrol_user($user2->id, $course->id, $roleid, 'manual'); + $generator->enrol_user($USER->id, $course->id, $roleid, 'manual'); // call as admin and receive all possible fields. $this->setAdminUser(); @@ -290,6 +305,13 @@ class externallib_test extends externallib_advanced_testcase { // Default language and no theme were used for the user. $this->assertEquals($CFG->lang, $returneduser['lang']); $this->assertEmpty($returneduser['theme']); + + if ($returneduser['id'] == $user1->id) { + $this->assertCount(1, $returneduser['customfields']); + $dbvalue = explode('\n', $statuses)[2]; + $this->assertEquals($dbvalue, $returneduser['customfields'][0]['value']); + $this->assertEquals('Other', $returneduser['customfields'][0]['displayvalue']); + } } } diff --git a/user/upgrade.txt b/user/upgrade.txt index 9bda89264ba..b113d41bdfa 100644 --- a/user/upgrade.txt +++ b/user/upgrade.txt @@ -15,6 +15,10 @@ This files describes API changes for code that uses the user API. * New `profile_get_user_field` method for returning profile field instance of given type * The `profile_field_base::is_visible` method now accepts an optional `$context` argument * External function core_user_external::add_user_private_files() now returns moodle_exception when the user quota is exceeded +* The `customfields` structure used for returning user profile fields information has been updated to: + * Return in the field `value` the value of the custom field (as stored in the database) + * Return in the field `displayvalue` the value of the custom field for display + External systems displaying user information should always use `displayvalue`. === 4.1 ===