MDL-69823 mod_quiz: Return question options via WS
authorJuan Leyva <juanleyvadelgado@gmail.com>
Wed, 30 Sep 2020 09:27:05 +0000 (11:27 +0200)
committerJuan Leyva <juanleyvadelgado@gmail.com>
Tue, 10 Nov 2020 18:16:24 +0000 (19:16 +0100)
mod/quiz/classes/external.php
mod/quiz/tests/external_test.php
mod/quiz/upgrade.txt
question/type/questionbase.php

index 2c207bd..3b6a6f2 100644 (file)
@@ -902,6 +902,7 @@ class mod_quiz_external extends external_api {
                     It will be returned only if the user is allowed to see it.', VALUE_OPTIONAL),
                 'maxmark' => new external_value(PARAM_FLOAT, 'the maximum mark possible for this question attempt.
                     It will be returned only if the user is allowed to see it.', VALUE_OPTIONAL),
+                'settings' => new external_value(PARAM_RAW, 'Question settings (JSON encoded).', VALUE_OPTIONAL),
             ),
             'The question data. Some fields may not be returned depending on the quiz display settings.'
         );
@@ -927,6 +928,7 @@ class mod_quiz_external extends external_api {
         foreach ($attemptobj->get_slots($page) as $slot) {
             $qtype = $attemptobj->get_question_type_name($slot);
             $qattempt = $attemptobj->get_question_attempt($slot);
+            $questiondef = $qattempt->get_question(true);
 
             // Get response files (for questions like essay that allows attachments).
             $responsefileareas = [];
@@ -948,6 +950,9 @@ class mod_quiz_external extends external_api {
                 }
             }
 
+            // Check display settings for question.
+            $settings = $questiondef->get_question_definition_for_external_rendering($qattempt, $displayoptions);
+
             $question = array(
                 'slot' => $slot,
                 'type' => $qtype,
@@ -957,7 +962,8 @@ class mod_quiz_external extends external_api {
                 'responsefileareas' => $responsefileareas,
                 'sequencecheck' => $qattempt->get_sequence_check_count(),
                 'lastactiontime' => $qattempt->get_last_step()->get_timecreated(),
-                'hasautosavedstep' => $qattempt->has_autosaved_step()
+                'hasautosavedstep' => $qattempt->has_autosaved_step(),
+                'settings' => !empty($settings) ? json_encode($settings) : null,
             );
 
             if ($attemptobj->is_real_question($slot)) {
index 0ea6a4e..9d97fce 100644 (file)
@@ -1034,6 +1034,11 @@ class mod_quiz_external_testcase extends externallib_advanced_testcase {
         $this->assertEquals(false, $result['questions'][0]['hasautosavedstep']);
         $this->assertEquals(false, $result['questions'][1]['hasautosavedstep']);
 
+        // Check question options.
+        $this->assertNotEmpty(5, $result['questions'][0]['settings']);
+        // Check at least some settings returned.
+        $this->assertCount(4, (array) json_decode($result['questions'][0]['settings']));
+
         // Submit a response for the first question.
         $tosubmit = array(1 => array('answer' => '3.14'));
         $attemptobj->process_submitted_actions(time(), false, $tosubmit);
index d3f6c09..3af165d 100644 (file)
@@ -1,5 +1,11 @@
 This files describes API changes in the quiz code.
 
+=== 3.10.1 ===
+
+* External functions mod_quiz_external::get_attempt_data, mod_quiz_external::get_attempt_summary
+  and mod_quiz_external::get_attempt_review now return a new additional optional field:
+   - settings: Containing the question definition settings for displaying the question in an external system.
+
 === 3.10 ===
 
 * External functions mod_quiz_external::get_attempt_data, mod_quiz_external::get_attempt_summary
index 4e2ea87..d045f86 100644 (file)
@@ -427,6 +427,31 @@ abstract class question_definition {
             return false;
         }
     }
+
+    /**
+     * Return the question settings that define this question as structured data.
+     *
+     * This is used by external systems such as the Moodle mobile app, which want to display the question themselves,
+     * rather than using the renderer provided.
+     *
+     * This method should only return the data that the student is allowed to see or know, given the current state of
+     * the question. For example, do not include the 'General feedback' until the student has completed the question,
+     * and even then, only include it if the question_display_options say it should be visible.
+     *
+     * But, within those rules, it is recommended that you return all the settings for the question,
+     * to give maximum flexibility to the external system providing its own rendering of the question.
+     *
+     * @param question_attempt $qa the current attempt for which we are exporting the settings.
+     * @param question_display_options $options the question display options which say which aspects of the question
+     * should be visible.
+     * @return mixed structure representing the question settings. In web services, this will be JSON-encoded.
+     */
+    public function get_question_definition_for_external_rendering(question_attempt $qa, question_display_options $options) {
+
+        debugging('This question does not implement the get_question_definition_for_external_rendering() method yet.',
+            DEBUG_DEVELOPER);
+        return null;
+    }
 }