【问题标题】:How to validate null date values in zf2如何验证 zf2 中的空日期值
【发布时间】:2015-01-23 18:37:24
【问题描述】:

我有一个包含日期字段的数据集。在数据库中,添加新行时,该字段默认为 0000-00-00。在我的字段集中,元素定义如下:

$this->add(array(
    'name' => 'memberBirthDate',
    'type' => 'Zend\Form\Element\Date',
    'attributes' => array(
        'type'  => 'date',
    ),
    'options' => array(
        'label' => 'birth date',
        'format' => 'n/j/y'
    ),
));

我不希望表单验证需要该元素。但是,如果没有输入日期,表单验证会给出错误The input does not appear to be a valid date

此外,'n/j/y' 格式将空值呈现为11/30/-1。如果在输入中输入0,表单验证会给出错误The input does not appear to be a valid date,如果输入类似0/0/00,验证会同时给出The input does not appear to be a valid dateThe input does not fit the date format 'n/j/y'

有没有办法让验证器接受空日期值或跳过未更改输入的验证?

编辑

allow_empty 不起作用。我已经设置了它并且还设置了'required' -> false。我什至通过回显所有错误和属性来检查以确保验证属性一直传递到控制器和视图。以下代码:

// enumerate message
$messages = $form->getMessages();
if($messages) {
  echo "<h4>error messages:</h4>";
  print_r ($messages);
}
echo "<br/>";
echo "allow_empty: " . $memberBirthDate->getAttribute('allow_empty') . "<br/>";
echo "required: " . $memberBirthDate->getAttribute('required') . "<br/>";

产生:

Array ( [member-fieldset] => Array ( [memberBirthDate] => Array ( [isEmpty] => Value is required and can't be empty ) ) ) 
allow_empty: 1
required:

编辑 2

我确实在字段集中指定了一个过滤器。我项目的这一部分遵循http://framework.zend.com/manual/current/en/modules/zend.form.collections.html 提供的格式,它没有任何关于使用工厂的建议。我的过滤器是这样的:

namespace AdminMembers\Form;

use Doctrine\Common\Persistence\ObjectManager;
use DoctrineModule\Stdlib\Hydrator\DoctrineObject as DoctrineHydrator;
use Zend\Form\Fieldset;
use Zend\InputFilter\InputFilterProviderInterface;

use AdminMembers\Entity\Member;

class MemberFieldset extends Fieldset implements InputFilterProviderInterface
{
    public function __construct(ObjectManager $objectManager)
    {
        parent::__construct('member-fieldset');

        $this->setHydrator(new DoctrineHydrator($objectManager, 'AdminMembers\Entity\Member'))
             ->setObject(new Member());

            // ...

        $this->add(array(
            'name' => 'memberBirthDate',
            'type' => 'Zend\Form\Element\Date',
                'required' => false,
                'allow_empty' => true,
            'attributes' => array(
                'type'  => 'date',
                'required' => false,
                'allow_empty' => true,
            ),
            'options' => array(
                'label' => 'birth date',
                'format' => 'n/j/y'
            ),
        ));

            // ...

    }

    public function getInputFilterSpecification()
    {

            // ...

        return array(
            'memberBirthDate' => array(
                'required' => false,
                'allow_empty' => true,
            ),
        );

            // ...

    }

}

namespace AdminMembers\Form;

use Zend\InputFilter\InputFilter;
use Doctrine\Common\Persistence\ObjectManager;
use DoctrineModule\Stdlib\Hydrator\DoctrineObject as DoctrineHydrator;
use Zend\Form\Form;

class AddMemberForm extends Form
{
    public function __construct(ObjectManager $objectManager)
    {
        parent::__construct('add_member_form');

        $this->setHydrator(new DoctrineHydrator($objectManager, 'AdminMembers\Entity\Member'));

        $adminMemberFieldset = new MemberFieldset($objectManager);
        $adminMemberFieldset->setUseAsBaseFieldset(true);
        $this->add($adminMemberFieldset);

        $this->setAttribute('method', 'post');
        $this->setInputFilter(new InputFilter());

          // ...

        $this->setValidationGroup(array(
            'member-fieldset' => array(
                'memberID',
                    // ...
                'memberBirthDate',
                    // ...
            ),
        ));

    }

}

【问题讨论】:

    标签: forms validation zend-framework2


    【解决方案1】:

    你需要给它添加一个过滤器。

    过滤器示例:

    namespace YourNamespace\Filter;
    
    use Zend\InputFilter\InputFilter;
    use Zend\InputFilter\InputFilterAwareInterface;
    use Zend\InputFilter\InputFilterInterface;
    
    class YourFilter extends InputFilter
    {
        public function getInputFilter()
        {
            $this->add(
                array(
                    'name' => 'memberBirthDate',
                    'required' => true,
                )
            );
        }
    }
    

    示例工厂:

    namespace YourNamespace\Factory;
    
    use Zend\ServiceManager\ServiceLocatorAwareInterface;
    use Zend\ServiceManager\ServiceLocatorInterface;
    use Zend\ServiceManager\FactoryInterface;
    
    class YourFactory extends FactoryInterface
    {
        public function createService(ServiceLocatorInterface $serviceLocator)
        {  
            $form = new \YourNamespace\Form\YourForm();
    
            $filter = new \YourNamespace\Filter\YourFilter();
    
            $form->setInputFilter($filter->getInputFilter());
    
            return $form;
        }
    }
    

    在 module.config.php 的 servicemanager 键上注册工厂: 您可能应该与旧配置合并:

    'service_manager' => array(
        'factories' => array(
            'YourNamespace\Factory\YourFactoryFinalName' => 'YourNamespace\Factory\YourFactory'
        ),
    )
    

    在任何服务管理器可用的地方调用,带有过滤器的表单,您可以自己添加更多过滤器规则。

    $this->getServiceLocator()->get('YourNamespace\Factory\YourFactoryFinalName');
    

    额外:创建 get/set 以便在您需要此工厂时通过特征轻松使用:

    namespace YourNamespace\Factory;
    
    use YourNamespace\Factory\YourFactory
    
    trait YourFactoryTrait {
    
        protected $yourFactory;
    
        public function getYourFactory()
        {
            if (!isset($this->yourFactory)) {
                $this->yourFactory = this->getServiceLocator()->get('YourNamespace\Factory\YourFactoryFinalName');
            }
            return $this->yourFactory;
        }
    
        public function setYourFactory(YourFactory $yourFactory)
        {
            $this->yourFactory = $yourFactory;
            return $this;
        }
    }
    

    您打算使用的类的属性:

    use YourNamespace\Factory\YourFactoryTrait;
    

    在方法体中:

    $factory = $this->getYourFactory();
    $factory->setData($data);
    
    if ($factory->isValid()) {
    }
    

    【讨论】:

    • 我确实指定了一个过滤器。见编辑 2。
    【解决方案2】:

    您可以配置字段以通过输入过滤器允许空值。在allow_empty 上查看 Rob Allen (akrabat) 的这篇文章:http://akrabat.com/zend-framework-2/setting-up-required-fields-that-can-be-empty-with-zendinputfilter/

    【讨论】:

    • 你把它放在元素的输入过滤器上吗?如果你把它放在元素本身上它不会起作用
    猜你喜欢
    • 2022-12-09
    • 2011-10-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-12-19
    • 1970-01-01
    • 1970-01-01
    • 2011-12-20
    相关资源
    最近更新 更多