diff --git a/composer.lock b/composer.lock index 76a76ad..fa0d56d 100644 --- a/composer.lock +++ b/composer.lock @@ -62,16 +62,16 @@ }, { "name": "phpgt/dom", - "version": "v4.1.4", + "version": "v4.1.6", "source": { "type": "git", "url": "https://github.com/PhpGt/Dom.git", - "reference": "a71e91f18a2f17e7f7dd0db7dab01ceeccf24af6" + "reference": "b3fe4a5054ef0780d663389475972c7b09b70a48" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/PhpGt/Dom/zipball/a71e91f18a2f17e7f7dd0db7dab01ceeccf24af6", - "reference": "a71e91f18a2f17e7f7dd0db7dab01ceeccf24af6", + "url": "https://api.github.com/repos/PhpGt/Dom/zipball/b3fe4a5054ef0780d663389475972c7b09b70a48", + "reference": "b3fe4a5054ef0780d663389475972c7b09b70a48", "shasum": "" }, "require": { @@ -86,7 +86,7 @@ "require-dev": { "phpmd/phpmd": "^2.13", "phpstan/phpstan": "^1.9", - "phpunit/phpunit": "^10.0", + "phpunit/phpunit": "^10.4", "squizlabs/php_codesniffer": "^3.7" }, "type": "library", @@ -147,10 +147,10 @@ "role": "Developer" } ], - "description": "The modern DOM API for PHP projects.", + "description": "Modern DOM API.", "support": { "issues": "https://github.com/PhpGt/Dom/issues", - "source": "https://github.com/PhpGt/Dom/tree/v4.1.4" + "source": "https://github.com/PhpGt/Dom/tree/v4.1.6" }, "funding": [ { @@ -158,7 +158,7 @@ "type": "github" } ], - "time": "2023-07-25T11:59:45+00:00" + "time": "2023-12-31T11:26:08+00:00" }, { "name": "phpgt/propfunc", @@ -328,16 +328,16 @@ }, { "name": "nikic/php-parser", - "version": "v4.17.1", + "version": "v4.18.0", "source": { "type": "git", "url": "https://github.com/nikic/PHP-Parser.git", - "reference": "a6303e50c90c355c7eeee2c4a8b27fe8dc8fef1d" + "reference": "1bcbb2179f97633e98bbbc87044ee2611c7d7999" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/a6303e50c90c355c7eeee2c4a8b27fe8dc8fef1d", - "reference": "a6303e50c90c355c7eeee2c4a8b27fe8dc8fef1d", + "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/1bcbb2179f97633e98bbbc87044ee2611c7d7999", + "reference": "1bcbb2179f97633e98bbbc87044ee2611c7d7999", "shasum": "" }, "require": { @@ -378,9 +378,9 @@ ], "support": { "issues": "https://github.com/nikic/PHP-Parser/issues", - "source": "https://github.com/nikic/PHP-Parser/tree/v4.17.1" + "source": "https://github.com/nikic/PHP-Parser/tree/v4.18.0" }, - "time": "2023-08-13T19:53:39+00:00" + "time": "2023-12-10T21:03:43+00:00" }, { "name": "phar-io/manifest", @@ -495,16 +495,16 @@ }, { "name": "phpstan/phpstan", - "version": "1.10.39", + "version": "1.10.50", "source": { "type": "git", "url": "https://github.com/phpstan/phpstan.git", - "reference": "d9dedb0413f678b4d03cbc2279a48f91592c97c4" + "reference": "06a98513ac72c03e8366b5a0cb00750b487032e4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpstan/zipball/d9dedb0413f678b4d03cbc2279a48f91592c97c4", - "reference": "d9dedb0413f678b4d03cbc2279a48f91592c97c4", + "url": "https://api.github.com/repos/phpstan/phpstan/zipball/06a98513ac72c03e8366b5a0cb00750b487032e4", + "reference": "06a98513ac72c03e8366b5a0cb00750b487032e4", "shasum": "" }, "require": { @@ -553,27 +553,27 @@ "type": "tidelift" } ], - "time": "2023-10-17T15:46:26+00:00" + "time": "2023-12-13T10:59:42+00:00" }, { "name": "phpunit/php-code-coverage", - "version": "10.1.7", + "version": "10.1.11", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-code-coverage.git", - "reference": "355324ca4980b8916c18b9db29f3ef484078f26e" + "reference": "78c3b7625965c2513ee96569a4dbb62601784145" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/355324ca4980b8916c18b9db29f3ef484078f26e", - "reference": "355324ca4980b8916c18b9db29f3ef484078f26e", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/78c3b7625965c2513ee96569a4dbb62601784145", + "reference": "78c3b7625965c2513ee96569a4dbb62601784145", "shasum": "" }, "require": { "ext-dom": "*", "ext-libxml": "*", "ext-xmlwriter": "*", - "nikic/php-parser": "^4.15", + "nikic/php-parser": "^4.18 || ^5.0", "php": ">=8.1", "phpunit/php-file-iterator": "^4.0", "phpunit/php-text-template": "^3.0", @@ -623,7 +623,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/php-code-coverage/issues", "security": "https://github.com/sebastianbergmann/php-code-coverage/security/policy", - "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/10.1.7" + "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/10.1.11" }, "funding": [ { @@ -631,7 +631,7 @@ "type": "github" } ], - "time": "2023-10-04T15:34:17+00:00" + "time": "2023-12-21T15:38:30+00:00" }, { "name": "phpunit/php-file-iterator", @@ -878,16 +878,16 @@ }, { "name": "phpunit/phpunit", - "version": "10.4.1", + "version": "10.5.5", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "62bd7af13d282deeb95650077d28ba3600ca321c" + "reference": "ed21115d505b4b4f7dc7b5651464e19a2c7f7856" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/62bd7af13d282deeb95650077d28ba3600ca321c", - "reference": "62bd7af13d282deeb95650077d28ba3600ca321c", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/ed21115d505b4b4f7dc7b5651464e19a2c7f7856", + "reference": "ed21115d505b4b4f7dc7b5651464e19a2c7f7856", "shasum": "" }, "require": { @@ -927,7 +927,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "10.4-dev" + "dev-main": "10.5-dev" } }, "autoload": { @@ -959,7 +959,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/phpunit/issues", "security": "https://github.com/sebastianbergmann/phpunit/security/policy", - "source": "https://github.com/sebastianbergmann/phpunit/tree/10.4.1" + "source": "https://github.com/sebastianbergmann/phpunit/tree/10.5.5" }, "funding": [ { @@ -975,7 +975,7 @@ "type": "tidelift" } ], - "time": "2023-10-08T05:01:11+00:00" + "time": "2023-12-27T15:13:52+00:00" }, { "name": "sebastian/cli-parser", @@ -1223,20 +1223,20 @@ }, { "name": "sebastian/complexity", - "version": "3.1.0", + "version": "3.2.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/complexity.git", - "reference": "68cfb347a44871f01e33ab0ef8215966432f6957" + "reference": "68ff824baeae169ec9f2137158ee529584553799" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/complexity/zipball/68cfb347a44871f01e33ab0ef8215966432f6957", - "reference": "68cfb347a44871f01e33ab0ef8215966432f6957", + "url": "https://api.github.com/repos/sebastianbergmann/complexity/zipball/68ff824baeae169ec9f2137158ee529584553799", + "reference": "68ff824baeae169ec9f2137158ee529584553799", "shasum": "" }, "require": { - "nikic/php-parser": "^4.10", + "nikic/php-parser": "^4.18 || ^5.0", "php": ">=8.1" }, "require-dev": { @@ -1245,7 +1245,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "3.1-dev" + "dev-main": "3.2-dev" } }, "autoload": { @@ -1269,7 +1269,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/complexity/issues", "security": "https://github.com/sebastianbergmann/complexity/security/policy", - "source": "https://github.com/sebastianbergmann/complexity/tree/3.1.0" + "source": "https://github.com/sebastianbergmann/complexity/tree/3.2.0" }, "funding": [ { @@ -1277,20 +1277,20 @@ "type": "github" } ], - "time": "2023-09-28T11:50:59+00:00" + "time": "2023-12-21T08:37:17+00:00" }, { "name": "sebastian/diff", - "version": "5.0.3", + "version": "5.1.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/diff.git", - "reference": "912dc2fbe3e3c1e7873313cc801b100b6c68c87b" + "reference": "fbf413a49e54f6b9b17e12d900ac7f6101591b7f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/912dc2fbe3e3c1e7873313cc801b100b6c68c87b", - "reference": "912dc2fbe3e3c1e7873313cc801b100b6c68c87b", + "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/fbf413a49e54f6b9b17e12d900ac7f6101591b7f", + "reference": "fbf413a49e54f6b9b17e12d900ac7f6101591b7f", "shasum": "" }, "require": { @@ -1303,7 +1303,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "5.0-dev" + "dev-main": "5.1-dev" } }, "autoload": { @@ -1336,7 +1336,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/diff/issues", "security": "https://github.com/sebastianbergmann/diff/security/policy", - "source": "https://github.com/sebastianbergmann/diff/tree/5.0.3" + "source": "https://github.com/sebastianbergmann/diff/tree/5.1.0" }, "funding": [ { @@ -1344,7 +1344,7 @@ "type": "github" } ], - "time": "2023-05-01T07:48:21+00:00" + "time": "2023-12-22T10:55:06+00:00" }, { "name": "sebastian/environment", @@ -1552,20 +1552,20 @@ }, { "name": "sebastian/lines-of-code", - "version": "2.0.1", + "version": "2.0.2", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/lines-of-code.git", - "reference": "649e40d279e243d985aa8fb6e74dd5bb28dc185d" + "reference": "856e7f6a75a84e339195d48c556f23be2ebf75d0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/lines-of-code/zipball/649e40d279e243d985aa8fb6e74dd5bb28dc185d", - "reference": "649e40d279e243d985aa8fb6e74dd5bb28dc185d", + "url": "https://api.github.com/repos/sebastianbergmann/lines-of-code/zipball/856e7f6a75a84e339195d48c556f23be2ebf75d0", + "reference": "856e7f6a75a84e339195d48c556f23be2ebf75d0", "shasum": "" }, "require": { - "nikic/php-parser": "^4.10", + "nikic/php-parser": "^4.18 || ^5.0", "php": ">=8.1" }, "require-dev": { @@ -1598,7 +1598,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/lines-of-code/issues", "security": "https://github.com/sebastianbergmann/lines-of-code/security/policy", - "source": "https://github.com/sebastianbergmann/lines-of-code/tree/2.0.1" + "source": "https://github.com/sebastianbergmann/lines-of-code/tree/2.0.2" }, "funding": [ { @@ -1606,7 +1606,7 @@ "type": "github" } ], - "time": "2023-08-31T09:25:50+00:00" + "time": "2023-12-21T08:38:20+00:00" }, { "name": "sebastian/object-enumerator", @@ -1894,16 +1894,16 @@ }, { "name": "theseer/tokenizer", - "version": "1.2.1", + "version": "1.2.2", "source": { "type": "git", "url": "https://github.com/theseer/tokenizer.git", - "reference": "34a41e998c2183e22995f158c581e7b5e755ab9e" + "reference": "b2ad5003ca10d4ee50a12da31de12a5774ba6b96" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/theseer/tokenizer/zipball/34a41e998c2183e22995f158c581e7b5e755ab9e", - "reference": "34a41e998c2183e22995f158c581e7b5e755ab9e", + "url": "https://api.github.com/repos/theseer/tokenizer/zipball/b2ad5003ca10d4ee50a12da31de12a5774ba6b96", + "reference": "b2ad5003ca10d4ee50a12da31de12a5774ba6b96", "shasum": "" }, "require": { @@ -1932,7 +1932,7 @@ "description": "A small library for converting tokenized PHP source code into XML and potentially other formats", "support": { "issues": "https://github.com/theseer/tokenizer/issues", - "source": "https://github.com/theseer/tokenizer/tree/1.2.1" + "source": "https://github.com/theseer/tokenizer/tree/1.2.2" }, "funding": [ { @@ -1940,7 +1940,7 @@ "type": "github" } ], - "time": "2021-07-28T10:34:58+00:00" + "time": "2023-11-20T00:12:19+00:00" } ], "aliases": [], diff --git a/src/BindableCache.php b/src/BindableCache.php index 17f45b3..7438cc4 100644 --- a/src/BindableCache.php +++ b/src/BindableCache.php @@ -102,7 +102,7 @@ public function isBindable(object $object):bool { ? $this->nullableStringOrIterable($object->$key) : null; - if(class_exists($refTypeName)) { + if($refTypeName && class_exists($refTypeName)) { $cacheObjectKeys[$bindKey] = $refTypeName; } } diff --git a/src/HTMLAttributeBinder.php b/src/HTMLAttributeBinder.php index 7c98025..f546e0c 100644 --- a/src/HTMLAttributeBinder.php +++ b/src/HTMLAttributeBinder.php @@ -32,6 +32,8 @@ public function bind( $element = $element->documentElement; } + $attributesToRemove = []; + /** * @var string $attrName * @var Attr $attr @@ -69,20 +71,25 @@ public function bind( } } + $bindProperty = substr( + $attrName, + strpos($attrName, ":") + 1 + ); $this->setBindProperty( $element, - substr( - $attrName, - strpos($attrName, ":") + 1 - ), + $bindProperty, $value, $modifier ); if(!$attr->ownerElement->hasAttribute("data-rebind")) { - $attr->ownerElement->removeAttribute($attrName); + array_push($attributesToRemove, $attrName); } } + + foreach($attributesToRemove as $attrName) { + $element->removeAttribute($attrName); + } } public function expandAttributes(Element $element):void { diff --git a/test/phpunit/DocumentBinderTest.php b/test/phpunit/DocumentBinderTest.php index fa25588..aba290b 100644 --- a/test/phpunit/DocumentBinderTest.php +++ b/test/phpunit/DocumentBinderTest.php @@ -1207,6 +1207,25 @@ public function testBindKeyValue_nestedObject():void { ); } + public function testBind_multipleAttributes():void { + $kvp = [ + "key1" => "value1", + "key2" => "value2", + "id" => "abc123", + "name" => "example", + ]; + $document = new HTMLDocument(HTMLPageContent::HTML_MULTIPLE_BINDS_ON_SINGLE_ELEMENT); + $sut = new DocumentBinder($document); + $sut->setDependencies(...$this->documentBinderDependencies($document)); + $sut->bindData($kvp); + $outputElement = $document->querySelector("output"); + self::assertSame($kvp["key1"], $outputElement->dataset->get("attr1")); + self::assertSame($kvp["key2"], $outputElement->dataset->get("attr2")); + self::assertSame($kvp["id"], $outputElement->id); + self::assertSame($kvp["name"], $outputElement->getAttribute("name")); + self::assertSame($kvp["name"], $outputElement->getAttribute("title")); + } + /** For issue #438 (https://github.com/PhpGt/DomTemplate/issues/438) */ public function test_removesUnboundDataElement():void { $document = new HTMLDocument(HTMLPageContent::HTML_REMOVE_UNBOUND); diff --git a/test/phpunit/HTMLAttributeBinderTest.php b/test/phpunit/HTMLAttributeBinderTest.php index e6d4c87..501a7cd 100644 --- a/test/phpunit/HTMLAttributeBinderTest.php +++ b/test/phpunit/HTMLAttributeBinderTest.php @@ -127,4 +127,23 @@ public function testBind_dateTimeInterface():void { $sut->bind(null, $dateTime, $outputElement); self::assertSame("Tue, 05 Apr 1988 17:23:00 GMT", $outputElement->textContent); } + + public function testBind_multipleAttributes():void { + $document = new HTMLDocument(HTMLPageContent::HTML_MULTIPLE_BINDS_ON_SINGLE_ELEMENT); + $outputElement = $document->querySelector("output"); + $sut = new HTMLAttributeBinder(); + $sut->bind("key1", "value1", $outputElement); + $sut->bind("key2", "value2", $outputElement); + $sut->bind("id", "example-id", $outputElement); + $sut->bind("name", "example-name", $outputElement); + + self::assertSame("value1", $outputElement->getAttribute("data-attr1")); + self::assertSame("value2", $outputElement->getAttribute("data-attr2")); + self::assertSame("example-id", $outputElement->getAttribute("id")); + self::assertSame("example-name", $outputElement->getAttribute("name")); + + self::assertSame("existing-value", $outputElement->dataset->get("existingAttr")); + self::assertSame("value1", $outputElement->dataset->get("attr1")); + self::assertSame("value2", $outputElement->dataset->get("attr2")); + } } diff --git a/test/phpunit/TestHelper/HTMLPageContent.php b/test/phpunit/TestHelper/HTMLPageContent.php index 4adfba9..9d27895 100644 --- a/test/phpunit/TestHelper/HTMLPageContent.php +++ b/test/phpunit/TestHelper/HTMLPageContent.php @@ -1099,6 +1099,11 @@ class HTMLPageContent { +HTML; + + const HTML_MULTIPLE_BINDS_ON_SINGLE_ELEMENT = << +Nothing is bound HTML; public static function createHTML(string $html = ""):HTMLDocument {