Skip to content

Commit 2e0df6c

Browse files
authored
Fix segfault! (#386)
* fix: bind placeholders using regex for #385 * fix: bind keyless placeholders using new method fixes #385 * maintenance: remove unused class * maintenance: remove commented out code * maintenance: remove unused variable
1 parent 9ecc381 commit 2e0df6c

File tree

5 files changed

+72
-105
lines changed

5 files changed

+72
-105
lines changed

src/PlaceholderBinder.php

+20-17
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@ public function bind(
2828
$context
2929
);
3030

31-
$placeholderTextList = [];
3231
foreach($xpathResult as $attributeOrText) {
3332
/** @var Text|Attr $text */
3433
$text = $attributeOrText;
@@ -37,24 +36,28 @@ public function bind(
3736
$text = $text->lastChild;
3837
}
3938

40-
$placeholder = $text->splitText(
41-
strpos($text->data, "{{")
42-
);
43-
$placeholder->splitText(
44-
strpos($placeholder->data, "}}") + 2
45-
);
46-
47-
$placeholderText = new PlaceholderText($placeholder);
48-
if((string)$key !== $placeholderText->getBindKey()) {
49-
$text->parentNode->nodeValue = $text->wholeText;
50-
continue;
51-
}
39+
$nodeValue = $text->nodeValue;
5240

53-
array_push($placeholderTextList, $placeholderText);
54-
}
41+
$regex = "/{{ *(?P<KEY>$key) *(\?\? ?(?P<DEFAULT>\w+))? ?}}/";
42+
preg_match_all($regex, $nodeValue, $matches);
43+
44+
foreach($matches[0] as $i => $subjectToReplace) {
45+
if($key != $matches["KEY"][$i]) {
46+
continue;
47+
}
5548

56-
foreach($placeholderTextList as $placeholderText) {
57-
$placeholderText->setValue($value);
49+
$valueToUse = $matches["DEFAULT"][$i];
50+
if(!is_null($value) && $value !== "") {
51+
$valueToUse = $value;
52+
}
53+
54+
$nodeValue = str_replace(
55+
$subjectToReplace,
56+
$valueToUse,
57+
$nodeValue
58+
);
59+
}
60+
$text->nodeValue = $nodeValue;
5861
}
5962
}
6063
}

src/PlaceholderText.php

-87
This file was deleted.

test.php

+41
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
<?php
2+
use Gt\Dom\HTMLDocument;
3+
use Gt\DomTemplate\ListBinder;
4+
use Gt\DomTemplate\TemplateCollection;
5+
use Gt\DomTemplate\TemplateElement;
6+
7+
require "vendor/autoload.php";
8+
9+
$html = <<<HTML
10+
<!doctype html>
11+
<ul>
12+
13+
<li data-template>
14+
<a href="/orders/{{userId}}/{{username??defaultUser}}/">view</a>
15+
</li>
16+
17+
</ul>
18+
HTML;
19+
20+
$kvpList = [
21+
(object)["userId" => 543, "username" => "win95", "orderCount" => 55],
22+
(object)["userId" => 559, "username" => "seafoam", "orderCount" => 30],
23+
(object)["userId" => 274, "username" => "hammatime", "orderCount" => 23],
24+
];
25+
26+
$string = "";
27+
for($iteration = 0; $iteration < 1000; $iteration++) {
28+
$document = new HTMLDocument($html);
29+
$orderList = $document->querySelector("ul");
30+
31+
$templateElement = new TemplateElement($document->querySelector("ul li[data-template]"));
32+
$templateCollection = new TemplateCollection($document);
33+
$templateElement->removeOriginalElement();
34+
35+
$sut = new ListBinder($templateCollection);
36+
$sut->bindListData($kvpList, $orderList);
37+
$string .= $document;
38+
echo memory_get_usage(), PHP_EOL;
39+
}
40+
41+
echo $document;

test/phpunit/TestFactory/DocumentTestFactory.php

+10
Original file line numberDiff line numberDiff line change
@@ -331,6 +331,16 @@ class DocumentTestFactory {
331331
<p><a href="https://github.com/sponsors/{{org}}/sponsorships?tier_id={{tierId}}">Sponsor via GitHub.</a></p>
332332
</main>
333333
HTML;
334+
335+
const HTML_PLACEHOLDER_LIST = <<<HTML
336+
<!doctype html>
337+
<h1>A list with placeholders</h1>
338+
339+
<ul>
340+
<li data-template id="user-{{userId}}">Username: {{username}}</li>
341+
</ul>
342+
HTML;
343+
334344
const HTML_MUSIC_EXPLICIT_TEMPLATE_NAMES = <<<HTML
335345
<!doctype html>
336346
<h1>Music library</h1>

test/phpunit/phpunit.xml

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<?xml version="1.0"?>
2-
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" colors="true" xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/9.3/phpunit.xsd" processIsolation="true">
2+
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" colors="true" xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/9.3/phpunit.xsd">
33
<coverage>
44
<include>
55
<directory suffix=".php">../../src</directory>

0 commit comments

Comments
 (0)