-
+
- + + + + +
diff --git a/src/Bindable.php b/src/Bindable.php index 377fed2..e76d8bb 100644 --- a/src/Bindable.php +++ b/src/Bindable.php @@ -79,11 +79,8 @@ protected function setData(BaseElement $element, iterable $data):void { continue; } - $key = $this->getKeyFromAttribute($element, $attr); - if(!isset($data[$key])) { - throw new BoundDataNotSetException($key); - } - $dataValue = $data[$key]; + $dataKeyMatch = $this->getKeyFromAttribute($element, $attr); + $dataValue = $dataKeyMatch->getValue($data) ?? ""; switch($matches[1]) { case "html": @@ -104,9 +101,15 @@ protected function setData(BaseElement $element, iterable $data):void { } } - protected function getKeyFromAttribute(BaseElement $element, Attr $attr):string { + protected function getKeyFromAttribute(BaseElement $element, Attr $attr):DataKeyMatch { + $required = true; $key = $attr->value; + if($key[0] === "?") { + $required = false; + $key = substr($key, 1); + } + if($key[0] === "@") { $key = substr($key, 1); $attributeValue = $element->getAttribute($key); @@ -114,10 +117,10 @@ protected function getKeyFromAttribute(BaseElement $element, Attr $attr):string throw new BoundAttributeDoesNotExistException($attr->name); } - return $attributeValue; + $key = $attributeValue; } - return $key; + return new DataKeyMatch($key, $required); } protected function wrapData(iterable $data):iterable { diff --git a/src/DataKeyMatch.php b/src/DataKeyMatch.php new file mode 100644 index 0000000..ecf7b86 --- /dev/null +++ b/src/DataKeyMatch.php @@ -0,0 +1,24 @@ +key = $key; + $this->required = $required; + } + + public function checkDataExists(iterable $data) { + if(!$this->required) { + return; + } + + if(!isset($data[$this->key])) { + throw new BoundDataNotSetException($this->key); + } + } + + public function getValue(iterable $data):?string { + $this->checkDataExists($data); + return $data[$this->key] ?? null; + } +} \ No newline at end of file diff --git a/test/unit/BindableTest.php b/test/unit/BindableTest.php index 42f12dc..3bc2995 100644 --- a/test/unit/BindableTest.php +++ b/test/unit/BindableTest.php @@ -1,6 +1,7 @@ innerHTML); self::assertNotContains("Use the other template instead!", $todoListElement->innerHTML); } + + public function testBindWithNonOptionalKey() { + $document = new HTMLDocument(Helper::HTML_TODO_LIST); + $todoData = [ + ["title" => "Write tests", "complete" => true], + ["title" => "Implement features", "complete" => false], + ["title" => "Pass tests", "complete" => false], + ]; + $document->extractTemplates(); + $todoListElement = $document->getElementById("todo-list"); + + self::expectException(BoundDataNotSetException::class); + $todoListElement->bind($todoData); + } + + public function testBindWithOptionalKey() { + $document = new HTMLDocument(Helper::HTML_TODO_LIST_OPTIONAL_ID); + $todoData = [ + ["title" => "Write tests", "complete" => true], + ["title" => "Implement features", "complete" => false], + ["title" => "Pass tests", "complete" => false], + ]; + $document->extractTemplates(); + $todoListElement = $document->getElementById("todo-list"); + + $todoListElement->bind($todoData); + $items = $todoListElement->querySelectorAll("li"); + self::assertCount(3, $items); + + self::assertEquals( + "Implement features", + $items[1]->querySelector("input[name=title]")->value + ); + self::assertNull( + $items[1]->querySelector("input[name=id]")->value + ); + } } \ No newline at end of file diff --git a/test/unit/Helper/Helper.php b/test/unit/Helper/Helper.php index c4877b6..908f94e 100644 --- a/test/unit/Helper/Helper.php +++ b/test/unit/Helper/Helper.php @@ -188,5 +188,35 @@ class Helper { +HTML; + + const HTML_TODO_LIST_OPTIONAL_ID = << + +