User ma podać dane do analizy przez formularz. Może podać albo za pomocą url'a albo przez wklejenie tekstu do textarea.
I teraz pojawia sę taka prosta logika tego formularza: wymagane jest wypełnienie jednago pola, ale zabronione wypełnienie obu oraz niewypełnienie żadnego. Zresztą to wydaje się dosyć oczywiste, bo analiza ma dotyczyć jednego przypadku, a nie dwóch.
Walidacja obu pól dotyczy tylko długości stringa. Docelowo url ma być walidowany pod względem poprawności, ale przyjąłem na razie walidację tylko długości stringa.
Poniżej przedstawiam moje rozwiązanie, które ma jeden mankament, z którym nie mogę sobie poradzić. Otóż niewypełnienie żadnego pola jest walidowane jako poprawne. A powinna być informacja, że wymagane jest wypełnienie jednego pola. Dzieje się tak mimo, że narzucona jest walidacja długości stringa od 3.
Jak zatem moje rozwiązanie poprawić?
<?php namespace Application\Filter; use Application\Form\Test as Form; use Application\Validator\Text; use Application\Validator\Url; use Zend\InputFilter\InputFilter; class Test extends InputFilter { public function init() { $this->add([ 'name' => Form::TEXT, 'required' => false, 'validators' => [ ['name' => Text::class], ], ]); $this->add([ 'name' => Form::URL, 'required' => false, 'validators' => [ ['name' => Url::class], ], ]); } }
<?php namespace Application\Validator; use Zend\Validator\StringLength; use Zend\Validator\ValidatorInterface; class Text implements ValidatorInterface { protected $stringLength; protected $messages = []; public function __construct() { $this->stringLengthValidator = new StringLength(); } public function isValid($value, $context = null) { $this->stringLengthValidator->setMin(3); $this->stringLengthValidator->setMax(5000); if ($this->stringLengthValidator->isValid($value)) { return true; } $this->messages = $this->stringLengthValidator->getMessages(); return false; } } public function getMessages() { return $this->messages; } }
<?php namespace Application\Validator; use Zend\Validator\StringLength; use Zend\Validator\ValidatorInterface; class Url implements ValidatorInterface { const ERROR_NOT_ALLOWED_STRING = 'string-not-allowed'; protected $stringLength; protected $messages = [ self::ERROR_NOT_ALLOWED_STRING => 'Only one of text and url field may be filled out.', ]; public function __construct() { $this->stringLengthValidator = new StringLength(); } public function isValid($value, $context = null) { $this->stringLengthValidator->setMin(3); $this->stringLengthValidator->setMax(500); if ($this->stringLengthValidator->isValid($value)) { return true; } $this->messages = $this->stringLengthValidator->getMessages(); return false; } } public function getMessages() { return $this->messages; } }
Edit
Jest rozwiązanie!
https://stackoverflow.com/questions/4921668...lidation-in-zf3
W skrócie, dodać 2 pozycje do opcji filtrów w klasie filtra:
'allow_empty' => true, 'continue_if_empty' => true,
I doszły kosmetyczne dodatki, widoczne na SO.