diff --git a/completion/classes/external.php b/completion/classes/external.php index dc57b662ffc..dcbad6b9c3c 100644 --- a/completion/classes/external.php +++ b/completion/classes/external.php @@ -377,4 +377,84 @@ class core_completion_external extends external_api { ); } + /** + * Describes the parameters for mark_course_self_completed. + * + * @return external_external_function_parameters + * @since Moodle 3.0 + */ + public static function mark_course_self_completed_parameters() { + return new external_function_parameters ( + array( + 'courseid' => new external_value(PARAM_INT, 'Course ID') + ) + ); + } + + /** + * Update the course completion status for the current user (if course self-completion is enabled). + * + * @param int $courseid Course id + * @return array Result and possible warnings + * @since Moodle 3.0 + * @throws moodle_exception + */ + public static function mark_course_self_completed($courseid) { + global $USER; + + $warnings = array(); + $params = self::validate_parameters(self::mark_course_self_completed_parameters(), + array('courseid' => $courseid)); + + $course = get_course($params['courseid']); + $context = context_course::instance($course->id); + self::validate_context($context); + + // Set up completion object and check it is enabled. + $completion = new completion_info($course); + if (!$completion->is_enabled()) { + throw new moodle_exception('completionnotenabled', 'completion'); + } + + if (!$completion->is_tracked_user($USER->id)) { + throw new moodle_exception('nottracked', 'completion'); + } + + $completion = $completion->get_completion($USER->id, COMPLETION_CRITERIA_TYPE_SELF); + + // Self completion criteria not enabled. + if (!$completion) { + throw new moodle_exception('noselfcompletioncriteria', 'completion'); + } + + // Check if the user has already marked himself as complete. + if ($completion->is_complete()) { + throw new moodle_exception('useralreadymarkedcomplete', 'completion'); + } + + // Mark the course complete. + $completion->mark_complete(); + + $result = array(); + $result['status'] = true; + $result['warnings'] = $warnings; + return $result; + } + + /** + * Describes the mark_course_self_completed return value. + * + * @return external_single_structure + * @since Moodle 3.0 + */ + public static function mark_course_self_completed_returns() { + + return new external_single_structure( + array( + 'status' => new external_value(PARAM_BOOL, 'status, true if success'), + 'warnings' => new external_warnings(), + ) + ); + } + } diff --git a/completion/tests/externallib_test.php b/completion/tests/externallib_test.php index c16b29c2654..ebcedc043ac 100644 --- a/completion/tests/externallib_test.php +++ b/completion/tests/externallib_test.php @@ -317,4 +317,71 @@ class core_completion_externallib_testcase extends externallib_advanced_testcase } + /** + * Test mark_course_self_completed + */ + public function test_mark_course_self_completed() { + global $DB, $CFG; + require_once($CFG->dirroot.'/completion/criteria/completion_criteria_self.php'); + + $this->resetAfterTest(true); + + $CFG->enablecompletion = true; + $student = $this->getDataGenerator()->create_user(); + $teacher = $this->getDataGenerator()->create_user(); + + $course = $this->getDataGenerator()->create_course(array('enablecompletion' => 1)); + + $studentrole = $DB->get_record('role', array('shortname' => 'student')); + $this->getDataGenerator()->enrol_user($student->id, $course->id, $studentrole->id); + + // Set completion rules. + $completion = new completion_info($course); + + $criteriadata = new stdClass(); + $criteriadata->id = $course->id; + $criteriadata->criteria_activity = array(); + + // Self completion. + $criteriadata->criteria_self = COMPLETION_CRITERIA_TYPE_SELF; + $class = 'completion_criteria_self'; + $criterion = new $class(); + $criterion->update_config($criteriadata); + + // Handle overall aggregation. + $aggdata = array( + 'course' => $course->id, + 'criteriatype' => null + ); + $aggregation = new completion_aggregation($aggdata); + $aggregation->setMethod(COMPLETION_AGGREGATION_ALL); + $aggregation->save(); + + $this->setUser($student); + + $result = core_completion_external::mark_course_self_completed($course->id); + // We need to execute the return values cleaning process to simulate the web service server. + $result = external_api::clean_returnvalue( + core_completion_external::mark_course_self_completed_returns(), $result); + + // We expect a valid result. + $this->assertEquals(true, $result['status']); + + $result = core_completion_external::get_course_completion_status($course->id, $student->id); + // We need to execute the return values cleaning process to simulate the web service server. + $result = external_api::clean_returnvalue( + core_completion_external::get_course_completion_status_returns(), $result); + + // Course must be completed. + $this->assertEquals(COMPLETION_COMPLETE, $result['completionstatus']['completions'][0]['complete']); + + try { + $result = core_completion_external::mark_course_self_completed($course->id); + $this->fail('Exception expected due course already self completed.'); + } catch (moodle_exception $e) { + $this->assertEquals('useralreadymarkedcomplete', $e->errorcode); + } + + } + } diff --git a/lib/db/services.php b/lib/db/services.php index 2606f72ca55..381978e07ea 100644 --- a/lib/db/services.php +++ b/lib/db/services.php @@ -1075,6 +1075,13 @@ $functions = array( 'type' => 'write', ), + 'core_completion_mark_course_self_completed' => array( + 'classname' => 'core_completion_external', + 'methodname' => 'mark_course_self_completed', + 'description' => 'Update the course completion status for the current user (if course self-completion is enabled).', + 'type' => 'write', + ), + 'core_completion_get_activities_completion_status' => array( 'classname' => 'core_completion_external', 'methodname' => 'get_activities_completion_status', @@ -1179,6 +1186,7 @@ $services = array( 'core_user_remove_user_device', 'core_course_get_courses', 'core_completion_update_activity_completion_status_manually', + 'core_completion_mark_course_self_completed', 'mod_data_get_databases_by_courses', 'core_comment_get_comments', 'mod_forum_view_forum', diff --git a/version.php b/version.php index 8c22d493c90..c4d349438a3 100644 --- a/version.php +++ b/version.php @@ -29,7 +29,7 @@ defined('MOODLE_INTERNAL') || die(); -$version = 2015091000.02; // YYYYMMDD = weekly release date of this DEV branch. +$version = 2015091000.03; // YYYYMMDD = weekly release date of this DEV branch. // RR = release increments - 00 in DEV branches. // .XX = incremental changes.