Skip to content

Commit

Permalink
feature: detect cyclic recursion in partials (#347)
Browse files Browse the repository at this point in the history
closes #242
  • Loading branch information
g105b authored Jun 10, 2022
1 parent ebba1b0 commit e787874
Show file tree
Hide file tree
Showing 4 changed files with 50 additions and 0 deletions.
4 changes: 4 additions & 0 deletions src/CyclicRecursionException.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
<?php
namespace Gt\DomTemplate;

class CyclicRecursionException extends DomTemplateException {}
3 changes: 3 additions & 0 deletions src/PartialExpander.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@ public function expand(Element $context = null):array {
}

$partialDocument = $this->partialContent->getHTMLDocument($extends);
if(isset($partialDocumentArray[$extends])) {
throw new CyclicRecursionException("Partial '$extends' has already been expanded in this document, expanding again would cause cyclic recursion.");
}
$partialDocumentArray[$extends] = $partialDocument;
$context = $partialDocument;
}
Expand Down
16 changes: 16 additions & 0 deletions test/phpunit/PartialExpanderTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
use Gt\Dom\Element;
use Gt\Dom\HTMLDocument;
use Gt\DomTemplate\CommentIni;
use Gt\DomTemplate\CyclicRecursionException;
use Gt\DomTemplate\PartialContent;
use Gt\DomTemplate\PartialContentFileNotFoundException;
use Gt\DomTemplate\PartialExpander;
Expand Down Expand Up @@ -119,4 +120,19 @@ public function testExpand_multipleDataPartialElements():void {
self::expectExceptionMessage("The current view extends the partial \"base-page\", but there is more than one element marked with `data-partial`.");
$sut->expand();
}

public function testExpand_detectCyclicRecursion():void {
$document = DocumentTestFactory::createHTML(DocumentTestFactory::HTML_EXTENDS_PARTIAL_CYCLIC_RECURSION);
$partialContent = self::mockPartialContent(
"_partial", [
"extended-page-1" => DocumentTestFactory::HTML_EXTENDS_PARTIAL_CYCLIC_RECURSION_1,
"extended-page-2" => DocumentTestFactory::HTML_EXTENDS_PARTIAL_CYCLIC_RECURSION_2,
"partial-base" => DocumentTestFactory::HTML_PARTIAL_VIEW,
]
);
$sut = new PartialExpander($document, $partialContent);

self::expectException(CyclicRecursionException::class);
$sut->expand();
}
}
27 changes: 27 additions & 0 deletions test/phpunit/TestFactory/DocumentTestFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -747,6 +747,33 @@ class DocumentTestFactory {
</main>
HTML;

const HTML_EXTENDS_PARTIAL_CYCLIC_RECURSION = <<<HTML
<!-- extends=extended-page-1 -->
<div>
This is the deepest part of the cyclic recursion.
</div>
HTML;


const HTML_EXTENDS_PARTIAL_CYCLIC_RECURSION_1 = <<<HTML
<!--
extends=extended-page-2
-->
<div>
This HTML extends page 2.
</div>
<div data-partial>Extended page is injected here</div>
HTML;

const HTML_EXTENDS_PARTIAL_CYCLIC_RECURSION_2 = <<<HTML
<!--
extends=extended-page-1
-->
<div>
This HTML extends page 1.
</div>
<div data-partial>Extended page is injected here</div>
HTML;

public static function createHTML(string $html = ""):HTMLDocument {
return HTMLDocumentFactory::create($html);
Expand Down

0 comments on commit e787874

Please sign in to comment.