From b197da877061ab04f03b953d9c54dce72c7f78e4 Mon Sep 17 00:00:00 2001 From: Marina Glancy Date: Fri, 6 Apr 2018 17:27:56 +0800 Subject: [PATCH] MDL-61876 question: apply format_text to input only --- question/type/gapselect/renderer.php | 3 +- question/type/gapselect/rendererbase.php | 42 ++++++++++++++++++++++-- question/type/upgrade.txt | 3 ++ 3 files changed, 44 insertions(+), 4 deletions(-) diff --git a/question/type/gapselect/renderer.php b/question/type/gapselect/renderer.php index 177e0e5881264..386a687606f16 100644 --- a/question/type/gapselect/renderer.php +++ b/question/type/gapselect/renderer.php @@ -57,7 +57,8 @@ protected function embedded_element(question_attempt $qa, $place, $orderedchoices = $question->get_ordered_choices($group); $selectoptions = array(); foreach ($orderedchoices as $orderedchoicevalue => $orderedchoice) { - $selectoptions[$orderedchoicevalue] = $orderedchoice->text; + $selectoptions[$orderedchoicevalue] = $question->format_text($orderedchoice->text, + $question->questiontextformat, $qa, 'question', 'questiontext', $question->id); } $feedbackimage = ''; diff --git a/question/type/gapselect/rendererbase.php b/question/type/gapselect/rendererbase.php index dc619fa65895b..0577a21925188 100644 --- a/question/type/gapselect/rendererbase.php +++ b/question/type/gapselect/rendererbase.php @@ -40,16 +40,26 @@ public function formulation_and_controls(question_attempt $qa, $question = $qa->get_question(); $questiontext = ''; + // Glue question fragments together using unique placeholders, apply format_text to the result + // and then substitute each placeholder with the embedded element. + // This will ensure that format_text() is applied to the whole question but not to the embedded elements. + $placeholders = $this->get_fragments_glue_placeholders($question->textfragments); foreach ($question->textfragments as $i => $fragment) { if ($i > 0) { - $questiontext .= $this->embedded_element($qa, $i, $options); + $questiontext .= $placeholders[$i]; + $embeddedelements[$placeholders[$i]] = $this->embedded_element($qa, $i, $options); } $questiontext .= $fragment; } + $questiontext = $question->format_text($questiontext, + $question->questiontextformat, $qa, 'question', 'questiontext', $question->id); + foreach ($placeholders as $i => $placeholder) { + $questiontext = preg_replace('/'. preg_quote($placeholder, '/') . '/', + $embeddedelements[$placeholder], $questiontext); + } $result = ''; - $result .= html_writer::tag('div', $question->format_text($questiontext, - $question->questiontextformat, $qa, 'question', 'questiontext', $question->id), + $result .= html_writer::tag('div', $questiontext, array('class' => $this->qtext_classname(), 'id' => $this->qtext_id($qa))); $result .= $this->post_qtext_elements($qa, $options); @@ -63,6 +73,32 @@ public function formulation_and_controls(question_attempt $qa, return $result; } + /** + * Find strings that we can use to glue the fragments with + * + * These strings have to be all different and neither of them can be present in the text + * + * @param array $fragments + * @return array array with indexes from 1 to count($fragments)-1 + */ + protected function get_fragments_glue_placeholders($fragments) { + $fragmentscount = count($fragments); + if ($fragmentscount <= 1) { + return []; + } + $prefix = '[[$'; + $postfix = ']]'; + $text = join('', $fragments); + while (preg_match('/' . preg_quote($prefix, '/') . '\\d+' . preg_quote($postfix, '/') . '/', $text)) { + $prefix .= '$'; + } + $glues = []; + for ($i = 1; $i < $fragmentscount; $i++) { + $glues[$i] = $prefix . $i . $postfix; + } + return $glues; + } + protected function qtext_classname() { return 'qtext'; } diff --git a/question/type/upgrade.txt b/question/type/upgrade.txt index c9a70f3f73e3f..f7fd3cb93e08d 100644 --- a/question/type/upgrade.txt +++ b/question/type/upgrade.txt @@ -8,6 +8,9 @@ This files describes API changes for question type plugins. question_manually_gradable. + The default implementation of is_gradable_response has been moved from question_graded_automatically to question_with_responses. + + Note that format_text() is no longer applied to the results of + qtype_elements_embedded_in_question_text_renderer::embedded_element(). If question type overrides + this method make sure you apply format_text() to any text that came from a user. === 3.1.5, 3.2.2, 3.3 ===