MDL-63522 course: Return completion info in get_course_content WS
authorJuan Leyva <juanleyvadelgado@gmail.com>
Wed, 10 Oct 2018 12:01:57 +0000 (14:01 +0200)
committerJuan Leyva <juanleyvadelgado@gmail.com>
Mon, 29 Oct 2018 10:11:38 +0000 (11:11 +0100)
course/externallib.php
course/tests/externallib_test.php
course/upgrade.txt

index 6b1ff34..acc1198 100644 (file)
@@ -85,6 +85,7 @@ class core_course_external extends external_api {
     public static function get_course_contents($courseid, $options = array()) {
         global $CFG, $DB;
         require_once($CFG->dirroot . "/course/lib.php");
+        require_once($CFG->libdir . '/completionlib.php');
 
         //validate parameter
         $params = self::validate_parameters(self::get_course_contents_parameters(),
@@ -168,6 +169,8 @@ class core_course_external extends external_api {
             $coursenumsections = course_get_format($course)->get_last_section_number();
             $stealthmodules = array();   // Array to keep all the modules available but not visible in a course section/topic.
 
+            $completioninfo = new completion_info($course);
+
             //for each sections (first displayed to last displayed)
             $modinfosections = $modinfo->get_sections();
             foreach ($sections as $key => $section) {
@@ -264,6 +267,18 @@ class core_course_external extends external_api {
                         $module['onclick'] = $cm->onclick;
                         $module['afterlink'] = $cm->afterlink;
                         $module['customdata'] = json_encode($cm->customdata);
+                        $module['completion'] = $cm->completion;
+
+                        // Check module completion.
+                        $completion = $completioninfo->is_enabled($cm);
+                        if ($completion != COMPLETION_DISABLED) {
+                            $completiondata = $completioninfo->get_data($cm, true);
+                            $module['completiondata'] = array(
+                                'state'         => $completiondata->completionstate,
+                                'timecompleted' => $completiondata->timemodified,
+                                'overrideby'    => $completiondata->overrideby
+                            );
+                        }
 
                         if (!empty($cm->showdescription) or $cm->modname == 'label') {
                             // We want to use the external format. However from reading get_formatted_content(), $cm->content format is always FORMAT_HTML.
@@ -415,6 +430,17 @@ class core_course_external extends external_api {
                                     'afterlink' => new external_value(PARAM_RAW, 'After link info to be displayed.',
                                         VALUE_OPTIONAL),
                                     'customdata' => new external_value(PARAM_RAW, 'Custom data (JSON encoded).', VALUE_OPTIONAL),
+                                    'completion' => new external_value(PARAM_INT, 'Type of completion tracking:
+                                        0 means none, 1 manual, 2 automatic.', VALUE_OPTIONAL),
+                                    'completiondata' => new external_single_structure(
+                                        array(
+                                            'state' => new external_value(PARAM_INT, 'Completion state value:
+                                                0 means incomplete, 1 complete, 2 complete pass, 3 complete fail'),
+                                            'timecompleted' => new external_value(PARAM_INT, 'Timestamp for completion status.'),
+                                            'overrideby' => new external_value(PARAM_INT, 'The user id who has overriden the
+                                                status.'),
+                                        ), 'Module completion data.', VALUE_OPTIONAL
+                                    ),
                                     'contents' => new external_multiple_structure(
                                           new external_single_structure(
                                               array(
index 5981b0c..fe759d3 100644 (file)
@@ -1140,6 +1140,50 @@ class core_course_externallib_testcase extends externallib_advanced_testcase {
         $this->assertEquals($pagecm->instance, $sections[0]['modules'][0]["instance"]);
     }
 
+    /**
+     * Test get course contents completion
+     */
+    public function test_get_course_contents_completion() {
+        global $CFG;
+        $this->resetAfterTest(true);
+
+        list($course, $forumcm, $datacm, $pagecm, $labelcm, $urlcm) = $this->prepare_get_course_contents_test();
+
+        // Test activity not completed yet.
+        $result = core_course_external::get_course_contents($course->id, array(
+            array("name" => "modname", "value" => "forum"), array("name" => "modid", "value" => $forumcm->instance)));
+        // We need to execute the return values cleaning process to simulate the web service server.
+        $result = external_api::clean_returnvalue(core_course_external::get_course_contents_returns(), $result);
+
+        $this->assertCount(1, $result[0]['modules']);
+        $this->assertEquals("forum", $result[0]['modules'][0]["modname"]);
+        $this->assertEquals(COMPLETION_TRACKING_MANUAL, $result[0]['modules'][0]["completion"]);
+        $this->assertEquals(0, $result[0]['modules'][0]["completiondata"]['state']);
+        $this->assertEquals(0, $result[0]['modules'][0]["completiondata"]['timecompleted']);
+        $this->assertEmpty($result[0]['modules'][0]["completiondata"]['overrideby']);
+
+        // Set activity completed.
+        core_completion_external::update_activity_completion_status_manually($forumcm->id, true);
+
+        $result = core_course_external::get_course_contents($course->id, array(
+            array("name" => "modname", "value" => "forum"), array("name" => "modid", "value" => $forumcm->instance)));
+        // We need to execute the return values cleaning process to simulate the web service server.
+        $result = external_api::clean_returnvalue(core_course_external::get_course_contents_returns(), $result);
+
+        $this->assertEquals(COMPLETION_COMPLETE, $result[0]['modules'][0]["completiondata"]['state']);
+        $this->assertNotEmpty($result[0]['modules'][0]["completiondata"]['timecompleted']);
+        $this->assertEmpty($result[0]['modules'][0]["completiondata"]['overrideby']);
+
+        // Disable completion.
+        $CFG->enablecompletion = 0;
+        $result = core_course_external::get_course_contents($course->id, array(
+            array("name" => "modname", "value" => "forum"), array("name" => "modid", "value" => $forumcm->instance)));
+        // We need to execute the return values cleaning process to simulate the web service server.
+        $result = external_api::clean_returnvalue(core_course_external::get_course_contents_returns(), $result);
+
+        $this->assertArrayNotHasKey('completiondata', $result[0]['modules'][0]);
+    }
+
     /**
      * Test duplicate_course
      */
index a1fa8ba..c46cfaf 100644 (file)
@@ -9,6 +9,8 @@ information provided here is intended especially for developers.
    - onclick (onclick javascript action code)
    - afterlink (after link info to be displayed)
    - customdata (module custom data (JSON encoded))
+   - completion (to indicate if completion is enabled or not)
+   - completiondata (completion status for the current user in the module)
 
 === 3.5 ===