From a5dcaee31ceae84907103f78623bd4778064d5e2 Mon Sep 17 00:00:00 2001 From: Juan Leyva Date: Wed, 30 Sep 2020 11:27:05 +0200 Subject: [PATCH] MDL-69823 mod_quiz: Return question options via WS --- mod/quiz/classes/external.php | 8 +++++++- mod/quiz/tests/external_test.php | 5 +++++ mod/quiz/upgrade.txt | 6 ++++++ question/type/questionbase.php | 25 +++++++++++++++++++++++++ 4 files changed, 43 insertions(+), 1 deletion(-) diff --git a/mod/quiz/classes/external.php b/mod/quiz/classes/external.php index 2c207bdd524..3b6a6f23192 100644 --- a/mod/quiz/classes/external.php +++ b/mod/quiz/classes/external.php @@ -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)) { diff --git a/mod/quiz/tests/external_test.php b/mod/quiz/tests/external_test.php index 0ea6a4eda6f..9d97fce8c15 100644 --- a/mod/quiz/tests/external_test.php +++ b/mod/quiz/tests/external_test.php @@ -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); diff --git a/mod/quiz/upgrade.txt b/mod/quiz/upgrade.txt index d3f6c09585d..3af165d4297 100644 --- a/mod/quiz/upgrade.txt +++ b/mod/quiz/upgrade.txt @@ -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 diff --git a/question/type/questionbase.php b/question/type/questionbase.php index 4e2ea870fae..d045f868059 100644 --- a/question/type/questionbase.php +++ b/question/type/questionbase.php @@ -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; + } } -- 2.17.1