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: