MDL-79295 quiz: Add proper WS support for sequential nav.
This commit is contained in:
@@ -968,41 +968,18 @@ class mod_quiz_external extends external_api {
|
||||
$qattempt = $attemptobj->get_question_attempt($slot);
|
||||
$questiondef = $qattempt->get_question(true);
|
||||
|
||||
// Get response files (for questions like essay that allows attachments).
|
||||
$responsefileareas = [];
|
||||
foreach (question_bank::get_qtype($qtype)->response_file_areas() as $area) {
|
||||
if ($files = $attemptobj->get_question_attempt($slot)->get_last_qt_files($area, $contextid)) {
|
||||
$responsefileareas[$area]['area'] = $area;
|
||||
$responsefileareas[$area]['files'] = [];
|
||||
|
||||
foreach ($files as $file) {
|
||||
$responsefileareas[$area]['files'][] = [
|
||||
'filename' => $file->get_filename(),
|
||||
'fileurl' => $qattempt->get_response_file_url($file),
|
||||
'filesize' => $file->get_filesize(),
|
||||
'filepath' => $file->get_filepath(),
|
||||
'mimetype' => $file->get_mimetype(),
|
||||
'timemodified' => $file->get_timemodified(),
|
||||
];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Check display settings for question.
|
||||
$settings = $questiondef->get_question_definition_for_external_rendering($qattempt, $displayoptions);
|
||||
|
||||
// Navigation information.
|
||||
$question = [
|
||||
'slot' => $slot,
|
||||
'type' => $qtype,
|
||||
'page' => $attemptobj->get_question_page($slot),
|
||||
'questionnumber' => $attemptobj->get_question_number($slot),
|
||||
'flagged' => $attemptobj->is_question_flagged($slot),
|
||||
'html' => $attemptobj->render_question($slot, $review, $renderer) . $PAGE->requires->get_end_code(),
|
||||
'responsefileareas' => $responsefileareas,
|
||||
'sequencecheck' => $qattempt->get_sequence_check_count(),
|
||||
'lastactiontime' => $qattempt->get_last_step()->get_timecreated(),
|
||||
'hasautosavedstep' => $qattempt->has_autosaved_step(),
|
||||
'settings' => !empty($settings) ? json_encode($settings) : null,
|
||||
];
|
||||
|
||||
if ($question['questionnumber'] === (string) (int) $question['questionnumber']) {
|
||||
@@ -1023,9 +1000,44 @@ class mod_quiz_external extends external_api {
|
||||
if ($displayoptions->marks >= question_display_options::MARK_AND_MAX) {
|
||||
$question['mark'] = $attemptobj->get_question_mark($slot);
|
||||
}
|
||||
if ($attemptobj->check_page_access($attemptobj->get_question_page($slot), false)) {
|
||||
$questions[] = $question;
|
||||
|
||||
// Check access. This is needed especially when sequential navigation is enforced. To prevent the student see "future" questions.
|
||||
$haveaccess = $attemptobj->check_page_access($attemptobj->get_question_page($slot), false);
|
||||
if (!$haveaccess) {
|
||||
$question['type'] = '';
|
||||
$question['html'] = '';
|
||||
}
|
||||
|
||||
// For visited pages/questions it is ok to keep data the user already saw.
|
||||
$questionalreadyseen = $attemptobj->get_currentpage() >= $attemptobj->get_question_page($slot);
|
||||
|
||||
// Information when only the user has access to the question at any moment (free navigation) or already seen.
|
||||
if ($haveaccess || $questionalreadyseen) {
|
||||
// Get response files (for questions like essay that allows attachments).
|
||||
$responsefileareas = [];
|
||||
foreach (question_bank::get_qtype($qtype)->response_file_areas() as $area) {
|
||||
if ($files = $attemptobj->get_question_attempt($slot)->get_last_qt_files($area, $contextid)) {
|
||||
$responsefileareas[$area]['area'] = $area;
|
||||
$responsefileareas[$area]['files'] = [];
|
||||
|
||||
foreach ($files as $file) {
|
||||
$responsefileareas[$area]['files'][] = [
|
||||
'filename' => $file->get_filename(),
|
||||
'fileurl' => $qattempt->get_response_file_url($file),
|
||||
'filesize' => $file->get_filesize(),
|
||||
'filepath' => $file->get_filepath(),
|
||||
'mimetype' => $file->get_mimetype(),
|
||||
'timemodified' => $file->get_timemodified(),
|
||||
];
|
||||
}
|
||||
}
|
||||
}
|
||||
$question['type'] = $qtype;
|
||||
$question['html'] = $attemptobj->render_question($slot, $review, $renderer) . $PAGE->requires->get_end_code();
|
||||
$question['responsefileareas'] = $responsefileareas;
|
||||
$question['settings'] = !empty($settings) ? json_encode($settings) : null;
|
||||
}
|
||||
$questions[] = $question;
|
||||
}
|
||||
return $questions;
|
||||
}
|
||||
|
||||
+8
-4
@@ -2074,17 +2074,20 @@ class external_test extends externallib_advanced_testcase {
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that a sequential navigation quiz is not allowing to see questions in advance for a student
|
||||
* Test that a sequential navigation quiz is not allowing to see questions content in advance for a student.
|
||||
*/
|
||||
public function test_sequential_navigation_attempt_summary() {
|
||||
// Test user with full capabilities.
|
||||
$quiz = $this->prepare_sequential_quiz();
|
||||
$attemptobj = $this->create_quiz_attempt_object($quiz);
|
||||
$this->setUser($this->student);
|
||||
// Check that we do not return other questions than the one currently viewed.
|
||||
// Check that we do not return content from other questions except than the ones currently viewed.
|
||||
$result = mod_quiz_external::get_attempt_summary($attemptobj->get_attemptid());
|
||||
$this->assertCount(1, $result['questions']);
|
||||
$this->assertStringContainsString('Question (1)', $result['questions'][0]['html']);
|
||||
$this->assertStringContainsString('Question (1)', $result['questions'][0]['html']); // Current question.
|
||||
$this->assertEmpty($result['questions'][1]['html']); // Next question.
|
||||
$this->assertEmpty($result['questions'][2]['html']); // And more.
|
||||
$this->assertEmpty($result['questions'][3]['html']); // And more.
|
||||
$this->assertEmpty($result['questions'][4]['html']); // And more.
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2137,6 +2140,7 @@ class external_test extends externallib_advanced_testcase {
|
||||
$data = [
|
||||
'course' => $this->course->id,
|
||||
'sumgrades' => 2,
|
||||
'questionsperpage' => 1,
|
||||
'preferredbehaviour' => 'deferredfeedback',
|
||||
'navmethod' => QUIZ_NAVMETHOD_SEQ
|
||||
];
|
||||
|
||||
Reference in New Issue
Block a user