From 79265f94a90e450c6d8c2e6dfdc935a625913620 Mon Sep 17 00:00:00 2001 From: John Beedell Date: Mon, 17 Dec 2018 12:34:31 +0000 Subject: [PATCH] MDL-64404 qtype: gapselect currency like options dont show --- question/type/gapselect/renderer.php | 3 +- question/type/gapselect/rendererbase.php | 6 +++- question/type/gapselect/tests/helper.php | 35 +++++++++++++++++++ .../type/gapselect/tests/walkthrough_test.php | 18 ++++++++++ 4 files changed, 59 insertions(+), 3 deletions(-) diff --git a/question/type/gapselect/renderer.php b/question/type/gapselect/renderer.php index 386a687606f..177e0e58812 100644 --- a/question/type/gapselect/renderer.php +++ b/question/type/gapselect/renderer.php @@ -57,8 +57,7 @@ class qtype_gapselect_renderer extends qtype_elements_embedded_in_question_text_ $orderedchoices = $question->get_ordered_choices($group); $selectoptions = array(); foreach ($orderedchoices as $orderedchoicevalue => $orderedchoice) { - $selectoptions[$orderedchoicevalue] = $question->format_text($orderedchoice->text, - $question->questiontextformat, $qa, 'question', 'questiontext', $question->id); + $selectoptions[$orderedchoicevalue] = $orderedchoice->text; } $feedbackimage = ''; diff --git a/question/type/gapselect/rendererbase.php b/question/type/gapselect/rendererbase.php index 3bca12b1c77..d19efb444a1 100644 --- a/question/type/gapselect/rendererbase.php +++ b/question/type/gapselect/rendererbase.php @@ -47,7 +47,11 @@ abstract class qtype_elements_embedded_in_question_text_renderer foreach ($question->textfragments as $i => $fragment) { if ($i > 0) { $questiontext .= $placeholders[$i]; - $embeddedelements[$placeholders[$i]] = $this->embedded_element($qa, $i, $options); + // There is a preg_replace 11 lines ahead where the $embeddedelements is used as the replace. + // If there are currency like options ($4) in the select then the preg_replace treats them as backreferences. + // So we need to escape the backreferences here. + $embeddedelements[$placeholders[$i]] = + preg_replace('/\$(\d)/', '\\\$$1', $this->embedded_element($qa, $i, $options)); } $questiontext .= $fragment; } diff --git a/question/type/gapselect/tests/helper.php b/question/type/gapselect/tests/helper.php index 6c1b2a2606a..faa98ebe07d 100644 --- a/question/type/gapselect/tests/helper.php +++ b/question/type/gapselect/tests/helper.php @@ -146,4 +146,39 @@ class qtype_gapselect_test_helper { return $gapselect; } + + /** + * This examples includes choices with currency like options. + * @return qtype_gapselect_question + */ + public static function make_a_currency_gapselect_question() { + question_bank::load_question_definition_classes('gapselect'); + $gapselect = new qtype_gapselect_question(); + + test_question_maker::initialise_a_question($gapselect); + + $gapselect->name = 'Selection from currency like choices'; + $gapselect->questiontext = 'The price of the ball is [[1]] approx.'; + $gapselect->generalfeedback = 'The choice is yours'; + $gapselect->qtype = question_bank::get_qtype('gapselect'); + + $gapselect->shufflechoices = true; + + test_question_maker::set_standard_combined_feedback_fields($gapselect); + + $gapselect->choices = [ + 1 => [ + 1 => new qtype_gapselect_choice('$2', 1), + 2 => new qtype_gapselect_choice('$3', 1), + 3 => new qtype_gapselect_choice('$4.99', 1), + 4 => new qtype_gapselect_choice('-1', 1) + ] + ]; + + $gapselect->places = array(1 => 1); + $gapselect->rightchoices = array(1 => 1); + $gapselect->textfragments = array('The price of the ball is ', ' approx.'); + + return $gapselect; + } } diff --git a/question/type/gapselect/tests/walkthrough_test.php b/question/type/gapselect/tests/walkthrough_test.php index 67752b2896c..085b0b118de 100644 --- a/question/type/gapselect/tests/walkthrough_test.php +++ b/question/type/gapselect/tests/walkthrough_test.php @@ -166,4 +166,22 @@ class qtype_gapselect_walkthrough_test extends qbehaviour_walkthrough_test_base $this->get_contains_select_expectation('p2', array('' => get_string('choosedots'), '1' => 'mat', '2' => 'bat'), null, true)); } + + public function test_choices_containing_dollars() { + + // Choices with a currency like entry (e.g. $3) should display. + $q = qtype_gapselect_test_helper::make_a_currency_gapselect_question(); + $q->shufflechoices = false; + $this->start_attempt_at_question($q, 'interactive', 1); + + // Check the initial state. + $this->check_current_state(question_state::$todo); + $this->check_current_mark(null); + $html = $this->quba->render_question($this->slot, $this->displayoptions); + preg_match_all('/