ZF2: allow an empty set of fields, but check if at least one of them is filled

I defined a set of fields for phone numbers. It contains the fields "type" (private, Office mobile ...) and "number". Input filter for the number "required => true":

``

class PhoneFieldset extends BaseFieldset implements InputFilterProviderInterface { public function __construct() { parent::__construct('phones'); $this->setHydrator(new DoctrineHydrator($this->getEntityManager(), 'HtsBase\Entity\Phone')) ->setObject(new Phone()); $this->add(array( 'type' => 'DoctrineORMModule\Form\Element\EntitySelect', 'name' => 'type', 'options' => array( 'label' => 'Type', 'empty_option' => '', 'object_manager' => $this->getEntityManager(), 'target_class' => 'HtsBase\Entity\OptionlistPhoneType', 'property' => 'name', ), 'attributes' => array( #'id' => 'type', 'class' => 'input-medium', ), )); $this->add(array( 'name' => 'number', 'options' => array( 'label' => 'Number', ), 'attributes' => array( 'type' => 'text', #'id' => 'number', 'class' => 'input-medium', 'maxlength' => '25', 'autocomplete' => 'off', ), )); } public function getInputFilterSpecification() { return array( 'type' => array( 'required' => false, ), 'number' => array( 'required' => true, 'filters' => array( array('name' => 'StringTrim'), ), 'validators' => array( array( 'name' => 'StringLength', 'options' => array( 'encoding' => 'UTF-8', 'max' => 25, ), ), ), ), ); } 

``

Can I attach a validator / filter for the whole set of fields? So, if "type" AND "number" is empty, the field does matter, but checks to see if at least one of them is populated?

+4
source share
1 answer

I found an easy-to-use solution, although I no longer use the form, now I use InputFilter and still need the same stuff. But found an easy solution

AbstractFilterValidator , my own implementation

 abstract class AbstractFilterValidator extends AbstractValidator { /** * Returns true if and only if $value meets the validation requirements * * If $value fails validation, then this method returns false, and * getMessages() will return an array of messages that explain why the * validation failed. * * @param mixed $value * @return bool * @throws Exception\RuntimeException If validation of $value is impossible */ public function isValid($value) { $this->setValue($value); $filter = $this->buildFilter(); $filter->setData($value); if (!$filter->isValid()) { $this->abstractOptions['messages'] = $filter->getMessages(); return false; } return true; } /** * @return array */ public function getMessages() { return $this->abstractOptions['messages']; } /** * @return InputFilter\InputFilter */ abstract protected function buildFilter(); } 

Old answer

Although you used InputFilterProviderInterface , I used Zend\InputFilter\InputFilter and wanted the same thing as you. If the field set has not been filled, check true .

To do this, I replace isValid following text:

 public function isValid() { $values = array_filter($this->getRawValues()); if (empty($values)) { return true; } return parent::isValid(); } 

It just filters the array from all the empty keys of the array, see docs for information on this. Then check if $values empty, and if so, return true . Otherwise, validators are called.


Well, I need something else, but I need a decent solution. I still could not find a good one, so I wrote the following code.

 <?php namespace Application\InputFilter; use Zend\InputFilter as ZFI; class InputFilter extends ZFI\InputFilter { private $required = true; /** * @return boolean */ public function isRequired() { return $this->required; } /** * @param boolean $required * * @return $this */ public function setRequired($required) { $this->required = (bool) $required; return $this; } /** * @return bool */ public function isValid() { if (!$this->isRequired() && empty(array_filter($this->getRawValues()))) { return true; } return parent::isValid(); } } 

github gist

Now you can just call setRequired(false) on the InputFilter

+1
source

Source: https://habr.com/ru/post/1498395/


All Articles