Skip to content

Commit

Permalink
feat: optionally clean placeholder values
Browse files Browse the repository at this point in the history
  • Loading branch information
MHajoha committed Oct 10, 2023
1 parent 5d8376f commit f0be361
Show file tree
Hide file tree
Showing 3 changed files with 29 additions and 13 deletions.
25 changes: 16 additions & 9 deletions classes/question_ui_renderer.php
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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);
}
}

Expand Down Expand Up @@ -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);
}
}
}
Expand Down
12 changes: 9 additions & 3 deletions tests/question_ui_renderer_test.php
Original file line number Diff line number Diff line change
Expand Up @@ -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 <b>one</b>",
"param" => "Value of param <b>one</b>.<script>'Oh no, danger!'</script>",
], mt_rand());

$result = $ui->render_formulation($qa, new \question_display_options());

$this->assertXmlStringEqualsXmlString(<<<EXPECTED
<div xmlns="http://www.w3.org/1999/xhtml">
<span>Parameter: Value of param <b>one</b></span>
<span>By default cleaned parameter: Value of param <b>one</b>.</span>
<span>Explicitly cleaned parameter: Value of param <b>one</b>.</span>
<span>Noclean parameter: Value of param <b>one</b>.<script>'Oh no, danger!'</script></span>
<span>Plain parameter: <![CDATA[Value of param <b>one</b>.<script>'Oh no, danger!'</script>]]></span>
</div>
EXPECTED, $result);
}
Expand All @@ -315,7 +318,10 @@ public function test_should_remove_placeholders_when_no_corresponding_value() {

$this->assertXmlStringEqualsXmlString(<<<EXPECTED
<div xmlns="http://www.w3.org/1999/xhtml">
<span>Parameter: </span>
<span>By default cleaned parameter: </span>
<span>Explicitly cleaned parameter: </span>
<span>Noclean parameter: </span>
<span>Plain parameter: </span>
</div>
EXPECTED, $result);
}
Expand Down
5 changes: 4 additions & 1 deletion tests/question_uis/placeholder.xhtml
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
<qpy:question xmlns:qpy="http://questionpy.org/ns/question">
<qpy:formulation>
<span>Parameter: <?p param?></span>
<span>By default cleaned parameter: <?p param?></span>
<span>Explicitly cleaned parameter: <?p param clean?></span>
<span>Noclean parameter: <?p param noclean?></span>
<span>Plain parameter: <?p param plain?></span>
</qpy:formulation>
</qpy:question>

0 comments on commit f0be361

Please sign in to comment.