diff --git a/src/DefaultValidationRules.php b/src/DefaultValidationRules.php index 6b2e828..d2f7531 100644 --- a/src/DefaultValidationRules.php +++ b/src/DefaultValidationRules.php @@ -3,6 +3,7 @@ use Gt\DomValidation\Rule\Pattern; use Gt\DomValidation\Rule\Required; +use Gt\DomValidation\Rule\SelectElement; use Gt\DomValidation\Rule\TypeDate; use Gt\DomValidation\Rule\TypeEmail; use Gt\DomValidation\Rule\TypeNumber; @@ -17,6 +18,7 @@ protected function setRuleList() { new TypeEmail(), new TypeUrl(), new TypeDate(), + new SelectElement(), ]; } } \ No newline at end of file diff --git a/src/Rule/Rule.php b/src/Rule/Rule.php index a17c1ad..5516bcc 100644 --- a/src/Rule/Rule.php +++ b/src/Rule/Rule.php @@ -10,7 +10,9 @@ abstract class Rule { * equals sign (e.g. "type=email"). For attributes without a value, pass the * attribute name on its own (e.g. "required"). */ - protected $attributes; + protected $attributes = [ + "name" + ]; public function getAttributes():array { return $this->attributes; diff --git a/src/Rule/SelectElement.php b/src/Rule/SelectElement.php new file mode 100644 index 0000000..305a82e --- /dev/null +++ b/src/Rule/SelectElement.php @@ -0,0 +1,44 @@ +tagName !== "select") { + return true; + } + + if($value === "") { + return true; + } + + $optionElementList = $element->getElementsByTagName("option"); + for($i = 0, $len = $optionElementList->length; $i < $len; $i++) { + $option = $optionElementList->item($i); + + if($option->hasAttribute("value")) { + $optionValue = $option->getAttribute("value"); + } + else { + $optionValue = $option->nodeValue; + } + + if($optionValue !== "") { + $availableValues []= $optionValue; + } + } + + if(!in_array($value, $availableValues)) { + return false; + } + + return true; + } + + public function getHint(DOMElement $element, string $value):string { + return "This field's value must match one of the available options"; + } +} \ No newline at end of file diff --git a/src/Validator.php b/src/Validator.php index 7a1edb2..d53590d 100644 --- a/src/Validator.php +++ b/src/Validator.php @@ -33,10 +33,11 @@ public function validate(DOMElement $form, array $input):void { foreach($this->rules->getAttributeRuleList() as $attrString => $ruleArray) { /** @var Rule[] $ruleArray */ - $xpath = new DOMXPath($form->ownerDocument); + $cssSelector = "[$attrString]"; + $xpath = new DOMXPath($form->ownerDocument); $inputElementList = $xpath->query( - new Translator("[$attrString]") + new Translator($cssSelector) ); for($i = 0, $len = $inputElementList->length; $i < $len; $i++) { diff --git a/test/phpunit/Helper/Helper.php b/test/phpunit/Helper/Helper.php index 203552d..66c292c 100644 --- a/test/phpunit/Helper/Helper.php +++ b/test/phpunit/Helper/Helper.php @@ -141,6 +141,37 @@ class Helper { HTML; + const HTML_SELECT = << +
+HTML; } \ No newline at end of file diff --git a/test/phpunit/Rule/SelectElementTest.php b/test/phpunit/Rule/SelectElementTest.php new file mode 100644 index 0000000..20e5543 --- /dev/null +++ b/test/phpunit/Rule/SelectElementTest.php @@ -0,0 +1,136 @@ +validate($form, [ + "currency" => "GBP", + ]); + } + catch(ValidationException $exception) {} + + self::assertNull($exception); + } + + public function testSelectMissingRequired() { + $form = self::getFormFromHtml(Helper::HTML_SELECT); + $validator = new Validator(); + + try { + $validator->validate($form, [ + "currency" => "", + ]); + } + catch(ValidationException $exception) { + $errorArray = iterator_to_array($validator->getLastErrorList()); + self::assertCount(1, $errorArray); + $currencyErrorArray = $errorArray["currency"]; + self::assertContains( + "This field is required", + $currencyErrorArray + ); + } + } + + public function testSelectTextContent() { + $form = self::getFormFromHtml(Helper::HTML_SELECT); + $validator = new Validator(); + + $exception = null; + + try { + $validator->validate($form, [ + "currency" => "USD", + "sort" => "Descending", + ]); + } + catch(ValidationException $exception) {} + + self::assertNull($exception); + } + + public function testSelectTextContentInvalid() { + $form = self::getFormFromHtml(Helper::HTML_SELECT); + $validator = new Validator(); + + try { + $validator->validate($form, [ + "currency" => "USD", + "sort" => "Random", // This