Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Automatically binding nested array iterators #487

Merged
merged 33 commits into from
Feb 29, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
00d1189
build: upgrade dom requirement and loosen version range
g105b Jul 24, 2022
3fcbcb9
Merge branch 'master' of github.com:/PhpGt/DomTemplate
g105b Aug 14, 2022
2a79afb
Merge branch 'master' of github.com:/PhpGt/DomTemplate
g105b Aug 18, 2022
5d58fc4
docs: update examples
g105b Aug 18, 2022
e3957a8
Merge branch 'master' of github.com:/PhpGt/DomTemplate
g105b Aug 26, 2022
73d0b85
Merge branch 'master' of github.com:/PhpGt/DomTemplate
g105b Sep 21, 2022
3cbb825
Merge branch 'master' of github.com:/PhpGt/DomTemplate
g105b Oct 5, 2022
fadbba7
Merge branch 'master' of github.com:/PhpGt/DomTemplate
g105b Oct 8, 2022
5403158
Merge branch 'master' of github.com:/PhpGt/DomTemplate
g105b Oct 31, 2022
224999b
Merge branch 'master' of github.com:/PhpGt/DomTemplate
g105b Jan 10, 2023
3def753
Merge branch 'master' of github.com:/PhpGt/DomTemplate
g105b Jan 17, 2023
3dbda21
feature: trim whitespace when there are only template children
g105b Jan 17, 2023
a28c12c
Merge branch 'master' of github.com:/PhpGt/DomTemplate
g105b Jan 17, 2023
da35c48
Merge branch 'master' of github.com:/PhpGt/DomTemplate
g105b Jan 23, 2023
b2f8fa5
Merge branch 'master' of github.com:/PhpGt/DomTemplate
g105b Jan 26, 2023
2f51576
Merge branch 'master' of github.com:/PhpGt/DomTemplate
g105b Jan 30, 2023
9655705
Merge branch 'master' of github.com:/PhpGt/DomTemplate
g105b Jan 31, 2023
7745df0
maintenance: phpstorm analysis improvements
g105b Jan 31, 2023
5ab8d14
Merge branch 'master' of github.com:/PhpGt/DomTemplate
g105b Feb 15, 2023
14029b2
Merge branch 'master' of github.com:/PhpGt/DomTemplate
g105b Feb 15, 2023
fa5c45b
Merge branch 'master' of github.com:/PhpGt/DomTemplate
g105b Mar 2, 2023
45007a4
Merge branch 'master' of github.com:/PhpGt/DomTemplate
g105b Jul 19, 2023
b47f5b2
tweak: remove data-element attribute
g105b Jul 19, 2023
5f0bbdf
Merge branch 'master' of github.com:/PhpGt/DomTemplate
g105b Jul 20, 2023
28f4cee
Merge branch 'master' of github.com:/PhpGt/DomTemplate
g105b Jul 28, 2023
9c98cd8
Merge branch 'master' of github.com:/PhpGt/DomTemplate
g105b Oct 12, 2023
acfca16
Merge branch 'master' of github.com:/PhpGt/DomTemplate
g105b Oct 25, 2023
afc9a52
Merge branch 'master' of github.com:/PhpGt/DomTemplate
g105b Nov 10, 2023
5ab216b
Merge branch 'master' of github.com:/PhpGt/DomTemplate
g105b Dec 12, 2023
b026d9a
Merge branch 'master' of github.com:/PhpGt/DomTemplate
g105b Jan 13, 2024
5099b0a
Merge branch 'master' of github.com:/PhpGt/DomTemplate
g105b Feb 4, 2024
fe62f74
Merge branch 'master' of github.com:/PhpGt/DomTemplate
g105b Feb 14, 2024
01541ae
fix: recursive call to bindList if value is itself a list
g105b Feb 14, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions src/ListBinder.php
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,10 @@ public function bindListData(
// If the $listValue's first value is iterable, then treat this as a nested list.
if($this->isNested($listValue)) {
$elementBinder->bind(null, $listKey, $t);
$this->bindListData(
$listValue,
$t,
);
foreach($this->bindableCache->convertToKvp($listValue) as $key => $value) {
$elementBinder->bind($key, $value, $t);
}
Expand Down
34 changes: 34 additions & 0 deletions test/phpunit/DocumentBinderTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
use Gt\DomTemplate\Test\TestHelper\HTMLPageContent;
use Gt\DomTemplate\Test\TestHelper\ExampleClass;
use Gt\DomTemplate\Test\TestHelper\Model\Address;
use Gt\DomTemplate\Test\TestHelper\Model\ArrayIterator\Product\ProductList;
use Gt\DomTemplate\Test\TestHelper\Model\Country;
use Gt\DomTemplate\Test\TestHelper\Model\Customer;
use PHPUnit\Framework\TestCase;
Expand Down Expand Up @@ -1366,6 +1367,39 @@ public function getIterator():Traversable {
self::assertCount(1, $ol->children);
}

public function testBindList_arrayIterator():void {
$document = new HTMLDocument(HTMLPageContent::HTML_SHOP_PRODUCTS);
$sut = new DocumentBinder($document);
$sut->setDependencies(...$this->documentBinderDependencies($document));

$categoryNameList = ["Category 1", "Category 2"];
$productNameList = [
["Product 1 in cat 1", "Product 2 in cat 1"],
["Product 3 in cat 2", "Product 4 in cat 2", "Product 5 in cat 2"],
];

$obj = new ProductList(
$categoryNameList,
$productNameList,
);
$sut->bindList($obj);

$categoryList = $document->querySelector("ul.categoryList");
self::assertCount(count($categoryNameList), $categoryList->children);

$productCount = 0;
foreach($categoryList->children as $categoryIndex => $categoryLi) {
self::assertSame("Category " . ($categoryIndex + 1), $categoryLi->querySelector("h2")->innerText);

self::assertCount(count($productNameList[$categoryIndex]), $categoryLi->querySelector("ul")->children);

foreach($categoryLi->querySelectorAll("ul li") as $productIndex => $productLi) {
self::assertSame("Product " . ($productCount + 1) . " in cat " . ($categoryIndex + 1), $productLi->textContent);
$productCount++;
}
}
}

private function documentBinderDependencies(HTMLDocument $document, mixed...$otherObjectList):array {
$htmlAttributeBinder = new HTMLAttributeBinder();
$htmlAttributeCollection = new HTMLAttributeCollection();
Expand Down
16 changes: 16 additions & 0 deletions test/phpunit/TestHelper/HTMLPageContent.php
Original file line number Diff line number Diff line change
Expand Up @@ -1034,6 +1034,22 @@ class HTMLPageContent {
</customer-list>
HTML;

const HTML_SHOP_PRODUCTS = <<<HTML
<!doctype html>
<h1>Categorised shop items</h1>

<ul class="categoryList">
<li data-list>
<h2 data-bind:text>Category name</h2>

<ul class="productList">
<li data-list data-bind:text="name">Product name</li>
</ul>
</li>
</ul>
HTML;


const HTML_REMOVE_UNBOUND = <<<HTML
<!doctype html>
<h1>Log in to the system</h1>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<?php
namespace Gt\DomTemplate\Test\TestHelper\Model\ArrayIterator\Product;

class Product {
public function __construct(
public readonly string $name
) {}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<?php
namespace Gt\DomTemplate\Test\TestHelper\Model\ArrayIterator\Product;

use ArrayIterator;

class ProductList extends ArrayIterator {
/**
* @param array<string> $categoryNameList
* @param array<array<string>> $productNameList
*/
public function __construct(array $categoryNameList, array $productNameList) {
/** @var array<string, array<Product>> $categorisedProducts */
$categorisedProducts = [];

foreach($categoryNameList as $i => $categoryName) {
$categorisedProducts[$categoryName] = [];

foreach($productNameList[$i] as $productName) {
array_push($categorisedProducts[$categoryName], new Product($productName));
}
}

parent::__construct($categorisedProducts);
}
}
Loading