diff --git a/course/externallib.php b/course/externallib.php index 290146a4bd3..d10dddb79dd 100644 --- a/course/externallib.php +++ b/course/externallib.php @@ -297,6 +297,7 @@ class core_course_external extends external_api { // now security checks $context = context_course::instance($course->id, IGNORE_MISSING); + $courseformatoptions = course_get_format($course)->get_format_options(); try { self::validate_context($context); } catch (Exception $e) { @@ -316,7 +317,10 @@ class core_course_external extends external_api { external_format_text($course->summary, $course->summaryformat, $context->id, 'course', 'summary', 0); $courseinfo['format'] = $course->format; $courseinfo['startdate'] = $course->startdate; - $courseinfo['numsections'] = $course->numsections; + if (array_key_exists('numsections', $courseformatoptions)) { + // For backward-compartibility + $courseinfo['numsections'] = $courseformatoptions['numsections']; + } //some field should be returned only if the user has update permission $courseadmin = has_capability('moodle/course:update', $context); @@ -328,7 +332,10 @@ class core_course_external extends external_api { $courseinfo['newsitems'] = $course->newsitems; $courseinfo['visible'] = $course->visible; $courseinfo['maxbytes'] = $course->maxbytes; - $courseinfo['hiddensections'] = $course->hiddensections; + if (array_key_exists('hiddensections', $courseformatoptions)) { + // For backward-compartibility + $courseinfo['hiddensections'] = $courseformatoptions['hiddensections']; + } $courseinfo['groupmode'] = $course->groupmode; $courseinfo['groupmodeforce'] = $course->groupmodeforce; $courseinfo['defaultgroupingid'] = $course->defaultgroupingid; @@ -339,6 +346,13 @@ class core_course_external extends external_api { $courseinfo['enablecompletion'] = $course->enablecompletion; $courseinfo['completionstartonenrol'] = $course->completionstartonenrol; $courseinfo['completionnotify'] = $course->completionnotify; + $courseinfo['formatoptions'] = array(); + foreach ($courseformatoptions as $key => $value) { + $courseinfo['formatoptions'][] = array( + 'optionname' => $key, + 'optionvalue' => $value + ); + } } if ($courseadmin or $course->visible @@ -377,7 +391,9 @@ class core_course_external extends external_api { 'number of recent items appearing on the course page', VALUE_OPTIONAL), 'startdate' => new external_value(PARAM_INT, 'timestamp when the course start'), - 'numsections' => new external_value(PARAM_INT, 'number of weeks/topics'), + 'numsections' => new external_value(PARAM_INT, + '(deprecated, use formatsettings) number of weeks/topics', + VALUE_OPTIONAL), 'maxbytes' => new external_value(PARAM_INT, 'largest size of file that can be uploaded into the course', VALUE_OPTIONAL), @@ -386,7 +402,7 @@ class core_course_external extends external_api { 'visible' => new external_value(PARAM_INT, '1: available to student, 0:not available', VALUE_OPTIONAL), 'hiddensections' => new external_value(PARAM_INT, - 'How the hidden sections in the course are displayed to students', + '(deprecated, use formatsettings) How the hidden sections in the course are displayed to students', VALUE_OPTIONAL), 'groupmode' => new external_value(PARAM_INT, 'no group, separate, visible', VALUE_OPTIONAL), @@ -412,6 +428,13 @@ class core_course_external extends external_api { 'forced course language', VALUE_OPTIONAL), 'forcetheme' => new external_value(PARAM_PLUGIN, 'name of the force theme', VALUE_OPTIONAL), + 'formatoptions' => new external_multiple_structure( + new external_single_structure( + array('optionname' => new external_value(PARAM_ALPHANUMEXT, 'course format option name'), + 'optionvalue' => new external_value(PARAM_RAW, 'course format option value') + )), + 'additional options for particular course format', VALUE_OPTIONAL + ), ), 'course' ) ); @@ -447,8 +470,9 @@ class core_course_external extends external_api { VALUE_DEFAULT, $courseconfig->newsitems), 'startdate' => new external_value(PARAM_INT, 'timestamp when the course start', VALUE_OPTIONAL), - 'numsections' => new external_value(PARAM_INT, 'number of weeks/topics', - VALUE_DEFAULT, $courseconfig->numsections), + 'numsections' => new external_value(PARAM_INT, + '(deprecated, use formatsettings) number of weeks/topics', + VALUE_OPTIONAL), 'maxbytes' => new external_value(PARAM_INT, 'largest size of file that can be uploaded into the course', VALUE_DEFAULT, $courseconfig->maxbytes), @@ -458,8 +482,8 @@ class core_course_external extends external_api { 'visible' => new external_value(PARAM_INT, '1: available to student, 0:not available', VALUE_OPTIONAL), 'hiddensections' => new external_value(PARAM_INT, - 'How the hidden sections in the course are displayed to students', - VALUE_DEFAULT, $courseconfig->hiddensections), + '(deprecated, use formatsettings) How the hidden sections in the course are displayed to students', + VALUE_OPTIONAL), 'groupmode' => new external_value(PARAM_INT, 'no group, separate, visible', VALUE_DEFAULT, $courseconfig->groupmode), 'groupmodeforce' => new external_value(PARAM_INT, '1: yes, 0: no', @@ -480,6 +504,12 @@ class core_course_external extends external_api { 'forced course language', VALUE_OPTIONAL), 'forcetheme' => new external_value(PARAM_PLUGIN, 'name of the force theme', VALUE_OPTIONAL), + 'formatoptions' => new external_multiple_structure( + new external_single_structure( + array('optionname' => new external_value(PARAM_ALPHANUMEXT, 'course format option name'), + 'optionvalue' => new external_value(PARAM_RAW, 'course format option value') + )), + 'additional options for particular course format', VALUE_OPTIONAL), ) ), 'courses to create' ) @@ -562,6 +592,12 @@ class core_course_external extends external_api { // Summary format. $course['summaryformat'] = external_validate_format($course['summaryformat']); + if (!empty($course['formatoptions'])) { + foreach ($course['formatoptions'] as $option) { + $course[$option['optionname']] = $option['optionvalue']; + } + } + //Note: create_course() core function check shortname, idnumber, category $course['id'] = create_course((object) $course)->id; diff --git a/course/tests/externallib_test.php b/course/tests/externallib_test.php index 984b9ed3588..3b0470d0f84 100644 --- a/course/tests/externallib_test.php +++ b/course/tests/externallib_test.php @@ -339,6 +339,17 @@ class core_course_external_testcase extends externallib_advanced_testcase { $course2['completionnotify'] = 1; $course2['lang'] = 'en'; $course2['forcetheme'] = 'base'; + $course3['fullname'] = 'Test course 3'; + $course3['shortname'] = 'Testcourse3'; + $course3['categoryid'] = $category->id; + $course3['format'] = 'topics'; + $course3options = array('numsections' => 8, + 'hiddensections' => 1, + 'coursedisplay' => 1); + $course3['formatoptions'] = array(); + foreach ($course3options as $key => $value) { + $course3['formatoptions'][] = array('optionname' => $key, 'optionvalue' => $value); + } $courses = array($course1, $course2); $createdcourses = core_course_external::create_courses($courses); @@ -348,7 +359,7 @@ class core_course_external_testcase extends externallib_advanced_testcase { // Check that the courses were correctly created. foreach ($createdcourses as $createdcourse) { - $dbcourse = $DB->get_record('course', array('id' => $createdcourse['id'])); + $dbcourse = course_get_format($createdcourse['id'])->get_course(); if ($createdcourse['shortname'] == $course2['shortname']) { $this->assertEquals($dbcourse->fullname, $course2['fullname']); @@ -393,13 +404,19 @@ class core_course_external_testcase extends externallib_advanced_testcase { $this->assertEquals($dbcourse->format, $courseconfig->format); $this->assertEquals($dbcourse->showgrades, $courseconfig->showgrades); $this->assertEquals($dbcourse->newsitems, $courseconfig->newsitems); - $this->assertEquals($dbcourse->numsections, $courseconfig->numsections); $this->assertEquals($dbcourse->maxbytes, $courseconfig->maxbytes); $this->assertEquals($dbcourse->showreports, $courseconfig->showreports); - $this->assertEquals($dbcourse->hiddensections, $courseconfig->hiddensections); $this->assertEquals($dbcourse->groupmode, $courseconfig->groupmode); $this->assertEquals($dbcourse->groupmodeforce, $courseconfig->groupmodeforce); $this->assertEquals($dbcourse->defaultgroupingid, 0); + } else if ($createdcourse['shortname'] == $course3['shortname']) { + $this->assertEquals($dbcourse->fullname, $course3['fullname']); + $this->assertEquals($dbcourse->shortname, $course3['shortname']); + $this->assertEquals($dbcourse->category, $course3['categoryid']); + $this->assertEquals($dbcourse->format, $course3['format']); + $this->assertEquals($dbcourse->hiddensections, $course3options['hiddensections']); + $this->assertEquals($dbcourse->numsections, $course3options['numsections']); + $this->assertEquals($dbcourse->coursedisplay, $course3options['coursedisplay']); } else { throw moodle_exception('Unexpected shortname'); } @@ -459,7 +476,7 @@ class core_course_external_testcase extends externallib_advanced_testcase { $generatedcourses[$course1->id] = $course1; $course2 = self::getDataGenerator()->create_course(); $generatedcourses[$course2->id] = $course2; - $course3 = self::getDataGenerator()->create_course(); + $course3 = self::getDataGenerator()->create_course(array('format' => 'topics')); $generatedcourses[$course3->id] = $course3; // Set the required capabilities by the external function. @@ -504,6 +521,13 @@ class core_course_external_testcase extends externallib_advanced_testcase { $this->assertEquals($course['completionstartonenrol'], $dbcourse->completionstartonenrol); $this->assertEquals($course['enablecompletion'], $dbcourse->enablecompletion); $this->assertEquals($course['completionstartonenrol'], $dbcourse->completionstartonenrol); + if ($dbcourse->format === 'topics') { + $this->assertEquals($course['formatoptions'], array( + array('optionname' => 'numsections', 'optionvalue' => $dbcourse->numsections), + array('optionname' => 'hiddensections', 'optionvalue' => $dbcourse->hiddensections), + array('optionname' => 'coursedisplay', 'optionvalue' => $dbcourse->coursedisplay), + )); + } } // Get all courses in the DB