2013-08-22 1 views
4

Я определил набор полей для телефонных номеров. Он содержит поля «type» (частный, Office mobile ...) и «number». Входной фильтр для номера "требуется => правды":ZF2: разрешить пустой набор полей, но подтвердить, если хотя бы один заполнен

``

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, 
        ), 
       ), 
      ), 
     ), 
    ); 
    } 

``

Может ли я прикрепить валидатор/фильтр для всей FIELDSET? Итак, если «тип» И «число» пуст, поле имеет значение, но проверяет, заполняется ли хотя бы один из них?

+0

вам удалось заставить его работать? –

ответ

1

Я нашел простую в использовании решение, хотя я больше не использую форму. Сейчас я сильно использую InputFilter и все еще нуждаюсь в том же материале. Но нашел простое решение

AbstractFilterValidator, моей собственной реализацию

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(); 
} 

Старого ответ

Хотя вы использовали InputFilterProviderInterface, я использовал Zend\InputFilter\InputFilter и хотел такое же, как ты. Если набор полей не был заполнен, проверьте true.

Для этого я заменяю isValid следующим:

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

    return parent::isValid(); 
} 

Это просто фильтрует массив из всех пустых ключей массива, см docs для получения информации об этом. Затем проверьте, является ли $values пустым, и если да, верните true. Иначе вызываются валидаторы.


Ну, мне нужно что-то снова, но нужно достойное решение. Еще не удавалось найти хороший, поэтому я написал следующий код.

<?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

Теперь вы можете просто позвонить setRequired(false) на InputFilter

+0

Спасибо за ваш последний бит :-) Как ваше решение AbstractFilterValidator держится против вашего класса InputFilter? Предполагая, что вы заменили последнего на прежнее, как лучшее/более эффективное? – Nukeface

+0

Мы шагнули от ZF2 в пользу других библиотек, поскольку для проверки мы создали собственную библиотеку, которая поддерживает такое поведение и многое другое. Так что не могу сказать, что лучше – MKroeders