diff --git a/classes/question_ui_renderer.php b/classes/question_ui_renderer.php index 6d0ace2f..516a6b10 100644 --- a/classes/question_ui_renderer.php +++ b/classes/question_ui_renderer.php @@ -19,12 +19,12 @@ use coding_exception; use DOMAttr; use DOMDocument; -use DOMDocumentFragment; use DOMElement; use DOMException; use DOMNameSpaceNode; use DOMNode; use DOMProcessingInstruction; +use DOMText; use DOMXPath; use question_attempt; use question_display_options; @@ -328,7 +328,7 @@ private function replace_shuffled_indices(DOMXPath $xpath, DOMNode $element, int break; } - $indexelement->parentNode->replaceChild(new \DOMText($indexstr), $indexelement); + $indexelement->parentNode->replaceChild(new DOMText($indexstr), $indexelement); } } @@ -441,17 +441,24 @@ private function clean_up(DOMXPath $xpath): void { private function resolve_placeholders(DOMXPath $xpath): void { /** @var DOMProcessingInstruction $pi */ foreach ($xpath->query("//processing-instruction('p')") as $pi) { - $key = trim($pi->data); + $parts = preg_split("/\s+/", trim($pi->data)); + $key = $parts[0]; + $cleanoption = $parts[1] ?? "clean"; if (!isset($this->placeholders[$key])) { $pi->parentNode->removeChild($pi); } else { - /** @var DOMDocumentFragment $frag */ - $frag = $xpath->document->createDocumentFragment(); - /* TODO: This always interprets the parameter value as XHTML. - While supporting markup here is important, perhaps we should allow placeholders to opt out? */ - $frag->appendXML($this->placeholders[$key]); - $pi->parentNode->replaceChild($frag, $pi); + $rawvalue = $this->placeholders[$key]; + if (strcasecmp($cleanoption, "clean") == 0) { + $element = $xpath->document->createDocumentFragment(); + $element->appendXML(clean_text($rawvalue)); + } else if (strcasecmp($cleanoption, "noclean") == 0) { + $element = $xpath->document->createDocumentFragment(); + $element->appendXML($rawvalue); + } else { + $element = new DOMText($rawvalue); + } + $pi->parentNode->replaceChild($element, $pi); } } } diff --git a/tests/question_ui_renderer_test.php b/tests/question_ui_renderer_test.php index a1a74eba..12844e59 100644 --- a/tests/question_ui_renderer_test.php +++ b/tests/question_ui_renderer_test.php @@ -285,14 +285,17 @@ public function test_should_resolve_placeholders() { $qa = $this->createStub(\question_attempt::class); $ui = new question_ui_renderer($input, [ - "param" => "Value of param one", + "param" => "Value of param one.", ], mt_rand()); $result = $ui->render_formulation($qa, new \question_display_options()); $this->assertXmlStringEqualsXmlString(<< - Parameter: Value of param one + By default cleaned parameter: Value of param one. + Explicitly cleaned parameter: Value of param one. + Noclean parameter: Value of param one. + Plain parameter: one.]]> EXPECTED, $result); } @@ -315,7 +318,10 @@ public function test_should_remove_placeholders_when_no_corresponding_value() { $this->assertXmlStringEqualsXmlString(<< - Parameter: + By default cleaned parameter: + Explicitly cleaned parameter: + Noclean parameter: + Plain parameter: EXPECTED, $result); } diff --git a/tests/question_uis/placeholder.xhtml b/tests/question_uis/placeholder.xhtml index 0426cf46..d763c770 100644 --- a/tests/question_uis/placeholder.xhtml +++ b/tests/question_uis/placeholder.xhtml @@ -1,5 +1,8 @@ - Parameter: + By default cleaned parameter: + Explicitly cleaned parameter: + Noclean parameter: + Plain parameter: