Skip to content

Commit 12bd0d7

Browse files
committed
Merge branch 'MDL-57239_37' of https://github.com/timhunt/moodle into MOODLE_37_STABLE
2 parents 01f6eae + 8d4f41b commit 12bd0d7

File tree

3 files changed

+77
-19
lines changed

3 files changed

+77
-19
lines changed

question/behaviour/interactive/behaviour.php

Lines changed: 19 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@
3232
* Question behaviour for the interactive model.
3333
*
3434
* Each question has a submit button next to it which the student can use to
35-
* submit it. Once the qustion is submitted, it is not possible for the
35+
* submit it. Once the question is submitted, it is not possible for the
3636
* student to change their answer any more, but the student gets full feedback
3737
* straight away.
3838
*
@@ -41,14 +41,17 @@
4141
*/
4242
class qbehaviour_interactive extends question_behaviour_with_multiple_tries {
4343
/**
44-
* Special value used for {@link question_display_options::$readonly when
45-
* we are showing the try again button to the student during an attempt.
46-
* The particular number was chosen randomly. PHP will treat it the same
47-
* as true, but in the renderer we reconginse it display the try again
48-
* button enabled even though the rest of the question is disabled.
49-
* @var integer
44+
* Constant used only in {@link adjust_display_options()} below and
45+
* {@link (qbehaviour_interactive_renderer}.
46+
* @var int
5047
*/
51-
const READONLY_EXCEPT_TRY_AGAIN = 23485299;
48+
const TRY_AGAIN_VISIBLE = 0x10;
49+
/**
50+
* Constant used only in {@link adjust_display_options()} below and
51+
* {@link (qbehaviour_interactive_renderer}.
52+
* @var int
53+
*/
54+
const TRY_AGAIN_VISIBLE_READONLY = 0x11;
5255

5356
public function is_compatible_question(question_definition $question) {
5457
return $question instanceof question_automatically_gradable;
@@ -82,6 +85,14 @@ public function adjust_display_options(question_display_options $options) {
8285
return;
8386
}
8487

88+
// The question in in a try-again state. We need the to let the renderer know this.
89+
// The API for question-rendering is defined by the question engine, but we
90+
// don't want to add logic in the renderer, so we are limited in how we can do this.
91+
// However, when the question is in this state, all the question-type controls
92+
// need to be rendered read-only. Therefore, we can conveniently pass this information
93+
// by setting special true-like values in $options->readonly (but this is a bit of a hack).
94+
$options->readonly = $options->readonly ? self::TRY_AGAIN_VISIBLE_READONLY : self::TRY_AGAIN_VISIBLE;
95+
8596
// Let the hint adjust the options.
8697
$hint = $this->get_applicable_hint();
8798
if (!is_null($hint)) {
@@ -93,12 +104,6 @@ public function adjust_display_options(question_display_options $options) {
93104
parent::adjust_display_options($options);
94105
$options->feedback = $save->feedback;
95106
$options->numpartscorrect = $save->numpartscorrect;
96-
97-
// In a try-again state, everything except the try again button
98-
// Should be read-only. This is a mild hack to achieve this.
99-
if (!$options->readonly) {
100-
$options->readonly = self::READONLY_EXCEPT_TRY_AGAIN;
101-
}
102107
}
103108

104109
public function get_applicable_hint() {

question/behaviour/interactive/renderer.php

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,14 +36,19 @@
3636
*/
3737
class qbehaviour_interactive_renderer extends qbehaviour_renderer {
3838
public function controls(question_attempt $qa, question_display_options $options) {
39-
if ($options->readonly === qbehaviour_interactive::READONLY_EXCEPT_TRY_AGAIN) {
39+
if ($options->readonly === qbehaviour_interactive::TRY_AGAIN_VISIBLE ||
40+
$options->readonly === qbehaviour_interactive::TRY_AGAIN_VISIBLE_READONLY) {
41+
// We are in the try again state, so no submit button.
4042
return '';
4143
}
4244
return $this->submit_button($qa, $options);
4345
}
4446

4547
public function feedback(question_attempt $qa, question_display_options $options) {
46-
if (!$qa->get_state()->is_active() || !$options->readonly) {
48+
// Show the Try again button if we are in try-again state.
49+
if (!$qa->get_state()->is_active() ||
50+
($options->readonly !== qbehaviour_interactive::TRY_AGAIN_VISIBLE &&
51+
$options->readonly !== qbehaviour_interactive::TRY_AGAIN_VISIBLE_READONLY)) {
4752
return '';
4853
}
4954

@@ -54,7 +59,8 @@ public function feedback(question_attempt $qa, question_display_options $options
5459
'value' => get_string('tryagain', 'qbehaviour_interactive'),
5560
'class' => 'submit btn',
5661
);
57-
if ($options->readonly !== qbehaviour_interactive::READONLY_EXCEPT_TRY_AGAIN) {
62+
if ($options->readonly === qbehaviour_interactive::TRY_AGAIN_VISIBLE_READONLY) {
63+
// This means the question really was rendered with read-only option.
5864
$attributes['disabled'] = 'disabled';
5965
}
6066
$output = html_writer::empty_tag('input', $attributes);

question/behaviour/interactive/tests/walkthrough_test.php

Lines changed: 49 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,7 @@
1818
* This file contains tests that walks a question through the interactive
1919
* behaviour.
2020
*
21-
* @package qbehaviour
22-
* @subpackage interactive
21+
* @package qbehaviour_interactive
2322
* @copyright 2009 The Open University
2423
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
2524
*/
@@ -483,4 +482,52 @@ public function test_interactive_regrade_changing_num_tries_finished() {
483482
// and I am currently interested in testing regrading here.
484483
$this->check_current_mark(1);
485484
}
485+
486+
public function test_review_of_interactive_questions_before_finished() {
487+
// Create a multichoice multiple question.
488+
$q = test_question_maker::make_question('shortanswer');
489+
$q->hints = array(
490+
new question_hint_with_parts(0, 'This is the first hint.', FORMAT_HTML, true, true),
491+
new question_hint_with_parts(0, 'This is the second hint.', FORMAT_HTML, true, true),
492+
);
493+
$this->start_attempt_at_question($q, 'interactive', 3);
494+
495+
// Check the initial state.
496+
$this->check_current_state(question_state::$todo);
497+
$this->check_current_mark(null);
498+
$this->check_current_output(
499+
$this->get_contains_submit_button_expectation(true),
500+
$this->get_does_not_contain_feedback_expectation(),
501+
$this->get_tries_remaining_expectation(3),
502+
$this->get_does_not_contain_try_again_button_expectation());
503+
504+
// Now check what the teacher sees when they review the question.
505+
$this->displayoptions->readonly = true;
506+
$this->check_current_output(
507+
$this->get_contains_submit_button_expectation(false),
508+
$this->get_does_not_contain_feedback_expectation(),
509+
$this->get_tries_remaining_expectation(3),
510+
$this->get_does_not_contain_try_again_button_expectation());
511+
$this->displayoptions->readonly = false;
512+
513+
// Submit a wrong answer.
514+
$this->process_submission(array('answer' => 'cat', '-submit' => 1));
515+
516+
// Check the Try again button now shows up correctly.
517+
$this->check_current_state(question_state::$todo);
518+
$this->check_current_mark(null);
519+
$this->check_current_output(
520+
$this->get_does_not_contain_submit_button_expectation(),
521+
$this->get_contains_hint_expectation('This is the first hint.'),
522+
$this->get_tries_remaining_expectation(2),
523+
$this->get_contains_try_again_button_expectation(true));
524+
525+
// And check that a disabled Try again button shows up when the question is reviewed.
526+
$this->displayoptions->readonly = true;
527+
$this->check_current_output(
528+
$this->get_does_not_contain_submit_button_expectation(),
529+
$this->get_contains_hint_expectation('This is the first hint.'),
530+
$this->get_tries_remaining_expectation(2),
531+
$this->get_contains_try_again_button_expectation(false));
532+
}
486533
}

0 commit comments

Comments
 (0)