Commit d1787798 authored by Paul Holden's avatar Paul Holden
Browse files

MDL-69625 course: return raw custom field value in external method.

For clients that wish to consume the original value of the custom
field (e.g. timestamps for date fields), rather than the formatted
version, add a new "valueraw" property to the returned data.
parent 87afa4d7
......@@ -611,6 +611,7 @@ class core_course_external extends external_api {
$courseinfo['customfields'][] = [
'type' => $data->get_type(),
'value' => $data->get_value(),
'valueraw' => $data->get_data_controller()->get_value(),
'name' => $data->get_name(),
'shortname' => $data->get_shortname()
];
......@@ -735,6 +736,7 @@ class core_course_external extends external_api {
'shortname' => new external_value(PARAM_ALPHANUMEXT, 'The shortname of the custom field'),
'type' => new external_value(PARAM_COMPONENT,
'The type of the custom field - text, checkbox...'),
'valueraw' => new external_value(PARAM_RAW, 'The raw value of the custom field'),
'value' => new external_value(PARAM_RAW, 'The value of the custom field')]
), 'Custom fields and associated values', VALUE_OPTIONAL),
), 'course'
......@@ -2489,6 +2491,7 @@ class core_course_external extends external_api {
$coursereturns['customfields'][] = [
'type' => $data->get_type(),
'value' => $data->get_value(),
'valueraw' => $data->get_data_controller()->get_value(),
'name' => $data->get_name(),
'shortname' => $data->get_shortname()
];
......@@ -2640,6 +2643,7 @@ class core_course_external extends external_api {
'The shortname of the custom field - to be able to build the field class in the code'),
'type' => new external_value(PARAM_ALPHANUMEXT,
'The type of the custom field - text field, checkbox...'),
'valueraw' => new external_value(PARAM_RAW, 'The raw value of the custom field'),
'value' => new external_value(PARAM_RAW, 'The value of the custom field'),
)
), 'Custom fields', VALUE_OPTIONAL),
......
......@@ -775,8 +775,16 @@ class core_course_externallib_testcase extends externallib_advanced_testcase {
array('name' => 'coursedisplay', 'value' => $dbcourse->coursedisplay),
));
}
if ($dbcourse->id == 4) {
$this->assertEquals($course['customfields'], [array_merge($customfield, $customfieldvalue)]);
// Assert custom field that we previously added to test course 4.
if ($dbcourse->id == $course4->id) {
$this->assertEquals([
'shortname' => $customfield['shortname'],
'name' => $customfield['name'],
'type' => $customfield['type'],
'value' => $customfieldvalue['value'],
'valueraw' => $customfieldvalue['value'],
], $course['customfields'][0]);
}
}
......@@ -789,6 +797,49 @@ class core_course_externallib_testcase extends externallib_advanced_testcase {
$this->assertEquals($DB->count_records('course'), count($courses));
}
/**
* Test retrieving courses returns custom field data
*/
public function test_get_courses_customfields(): void {
$this->resetAfterTest();
$this->setAdminUser();
$fieldcategory = $this->getDataGenerator()->create_custom_field_category([]);
$datefield = $this->getDataGenerator()->create_custom_field([
'categoryid' => $fieldcategory->get('id'),
'shortname' => 'mydate',
'name' => 'My date',
'type' => 'date',
]);
$newcourse = $this->getDataGenerator()->create_course(['customfields' => [
[
'shortname' => $datefield->get('shortname'),
'value' => 1580389200, // 30/01/2020 13:00 GMT.
],
]]);
$courses = external_api::clean_returnvalue(
core_course_external::get_courses_returns(),
core_course_external::get_courses(['ids' => [$newcourse->id]])
);
$this->assertCount(1, $courses);
$course = reset($courses);
$this->assertArrayHasKey('customfields', $course);
$this->assertCount(1, $course['customfields']);
// Assert the received custom field, "value" containing a human-readable version and "valueraw" the unmodified version.
$this->assertEquals([
'name' => $datefield->get('name'),
'shortname' => $datefield->get('shortname'),
'type' => $datefield->get('type'),
'value' => userdate(1580389200),
'valueraw' => 1580389200,
], reset($course['customfields']));
}
/**
* Test get_courses without capability
*/
......@@ -912,6 +963,49 @@ class core_course_externallib_testcase extends externallib_advanced_testcase {
$results = core_course_external::search_courses('blocklist', $blockid);
}
/**
* Test searching for courses returns custom field data
*/
public function test_search_courses_customfields(): void {
$this->resetAfterTest();
$this->setAdminUser();
$fieldcategory = $this->getDataGenerator()->create_custom_field_category([]);
$datefield = $this->getDataGenerator()->create_custom_field([
'categoryid' => $fieldcategory->get('id'),
'shortname' => 'mydate',
'name' => 'My date',
'type' => 'date',
]);
$newcourse = $this->getDataGenerator()->create_course(['customfields' => [
[
'shortname' => $datefield->get('shortname'),
'value' => 1580389200, // 30/01/2020 13:00 GMT.
],
]]);
$result = external_api::clean_returnvalue(
core_course_external::search_courses_returns(),
core_course_external::search_courses('search', $newcourse->shortname)
);
$this->assertCount(1, $result['courses']);
$course = reset($result['courses']);
$this->assertArrayHasKey('customfields', $course);
$this->assertCount(1, $course['customfields']);
// Assert the received custom field, "value" containing a human-readable version and "valueraw" the unmodified version.
$this->assertEquals([
'name' => $datefield->get('name'),
'shortname' => $datefield->get('shortname'),
'type' => $datefield->get('type'),
'value' => userdate(1580389200),
'valueraw' => 1580389200,
], reset($course['customfields']));
}
/**
* Create a course with contents
* @return array A list with the course object and course modules objects
......@@ -2453,8 +2547,13 @@ class core_course_externallib_testcase extends externallib_advanced_testcase {
$this->assertCount(1, $result['courses']);
$this->assertEquals($course2->id, $result['courses'][0]['id']);
// Check custom fields properly returned.
unset($customfield['categoryid']);
$this->assertEquals([array_merge($customfield, $customfieldvalue)], $result['courses'][0]['customfields']);
$this->assertEquals([
'shortname' => $customfield['shortname'],
'name' => $customfield['name'],
'type' => $customfield['type'],
'value' => $customfieldvalue['value'],
'valueraw' => $customfieldvalue['value'],
], $result['courses'][0]['customfields'][0]);
$result = core_course_external::get_courses_by_field('ids', "$course1->id,$course2->id");
$result = external_api::clean_returnvalue(core_course_external::get_courses_by_field_returns(), $result);
......@@ -2583,6 +2682,49 @@ class core_course_externallib_testcase extends externallib_advanced_testcase {
$this->assertCount(0, $result['courses']);
}
/**
* Test retrieving courses by field returns custom field data
*/
public function test_get_courses_by_field_customfields(): void {
$this->resetAfterTest();
$this->setAdminUser();
$fieldcategory = $this->getDataGenerator()->create_custom_field_category([]);
$datefield = $this->getDataGenerator()->create_custom_field([
'categoryid' => $fieldcategory->get('id'),
'shortname' => 'mydate',
'name' => 'My date',
'type' => 'date',
]);
$newcourse = $this->getDataGenerator()->create_course(['customfields' => [
[
'shortname' => $datefield->get('shortname'),
'value' => 1580389200, // 30/01/2020 13:00 GMT.
],
]]);
$result = external_api::clean_returnvalue(
core_course_external::get_courses_by_field_returns(),
core_course_external::get_courses_by_field('id', $newcourse->id)
);
$this->assertCount(1, $result['courses']);
$course = reset($result['courses']);
$this->assertArrayHasKey('customfields', $course);
$this->assertCount(1, $course['customfields']);
// Assert the received custom field, "value" containing a human-readable version and "valueraw" the unmodified version.
$this->assertEquals([
'name' => $datefield->get('name'),
'shortname' => $datefield->get('shortname'),
'type' => $datefield->get('type'),
'value' => userdate(1580389200),
'valueraw' => 1580389200,
], reset($course['customfields']));
}
public function test_get_courses_by_field_invalid_field() {
$this->expectException('invalid_parameter_exception');
$result = core_course_external::get_courses_by_field('zyx', 'x');
......
......@@ -5,6 +5,8 @@ information provided here is intended especially for developers.
* The function make_categories_options() has now been deprecated. Please use \core_course_category::make_categories_list() instead.
* External function core_course_external::get_course_contents now returns a new field contextid with the module context id.
* The core_course_external class methods get_courses(), get_courses_by_field() and search_courses() now return a "valueraw" property
for each custom course field, which contains the original/unformatted version of the custom field value.
=== 3.9 ===
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment