validating date in zendframework2

2019-05-11 17:03发布

问题:

Hiho, I would like to validate a date field from an zf2 form. I set the 'format' option to get the format I need. But at every time I validate it i get an error. The validator looks like this:

            $inputFilter->add($factory->createInput(array(
            'name' => 'user_data_birth',
            'required' => false,
            'validators' => array(
                array(
                'name' => 'Date',
                'options' => array(
                    'format' => 'd.m.Y',
                    'locale' => 'de',
                    'messages' => array(
                        \Zend\Validator\Date::INVALID => 'Das scheint kein gültiges Datum zu sein.',
                        \Zend\Validator\Date::INVALID_DATE => 'Das scheint kein gültiges Datum zu sein. (Invalid Date)',
                        \Zend\Validator\Date::FALSEFORMAT => 'Das Datum ist nicht im richtigen Format.',
                        ),
                    ),
                ),
                array(
                    'name' => 'NotEmpty',
                    'options' => array(
                    'messages' => array(
                        \Zend\Validator\NotEmpty::IS_EMPTY => 'Bitte geben Sie das Datum an'
                        ),
                    ),
                )
            ),
        )));

But I get every time an error that the date is in the wrong format.

回答1:

You can solve the problem of, start date should be less than end date validation, using the Callback function as below:

          $inputFilter->add($factory->createInput(array(
                'name' => 'end_date',
                'required' => true,                 
                'filters' => array(
                        array('name' => 'StripTags'),
                        array('name' => 'StringTrim'),
                ),
                'validators' => array(
                    array(
                        'name' => 'Callback',
                        'options' => array(
                            'messages' => array(
                                    \Zend\Validator\Callback::INVALID_VALUE => 'The end date should be greater than start date',
                            ),
                            'callback' => function($value, $context = array()) {                                    
                                $startDate = \DateTime::createFromFormat('d-m-Y', $context['start_date']);
                                $endDate = \DateTime::createFromFormat('d-m-Y', $value);
                                return $endDate >= $startDate;
                            },
                        ),
                    ),                          
                ),
        )));

Using the above code, I have solved my problem. I hope this helps.



回答2:

need to change validator which is in date element. If you pass format into the element you will be fine. You can take validator from element too.

$date = new Element\DateTime('test');
$date->setFormat('d.m.Y');

or

$validators = $date->getValidators()
// apply you changes


回答3:

Did you try with another format like the basic: 'Y-m-d' ? What is the result?



回答4:

CallBack function is a very convenient way if we need to use this only in one form. Most times we will need to use this in more than one place. I did some research and wrote this custom validator. This validator compares two strings; I have added another trick to see if we need these strings to be different or same.

If we are changing the password; then the old password and the new password to be different at the same time we need the new password verification to be the same as the new password. This validator can be used be used for both cases just by changing the different parameter to be "true" or "false".

Form Fields
user_password
new_user_password
new_user_password_verify

create a new validator StringCompare.php in Application\src\Application\Validator

<?php

namespace Application\Validator;

class StringCompare extends \Zend\Validator\AbstractValidator {

    const SAME = 'same';
    const DIFFERENT = 'different';

    protected $messageTemplates = array(
        self::SAME => "Both the words are the same",
        self::DIFFERENT => "Both the words are different",
    );

    protected $messageVariables = array(
        'compareWith' => array( 'options' => 'compareWith' ),
        'different' => array( 'options' => 'different' ),
    );

    protected $options = array(
        'compareWith' => "",
        'different' => true,
        'encoding' => 'UTF-8',
    );

    public function __construct( $options = array( ) ) {
        parent::__construct( $options );
    }

    public function getCompareWith( ) {
        return $this->options[ 'compareWith' ];
    }

    public function getDifferent( ) {
        return $this->options[ 'different' ];
    }

    public function isValid( $value, $context=array( ) ) {

        $compareWith = $this->getCompareWith( );
        $different = $this->getDifferent( );

        $returnValue =  $value == $context[$compareWith];
        if ( $different ) {
            $returnValue = !$returnValue;
       if ( !$returnValue ) {
          $this->error( self::SAME );
           }
        } else {
        if ( !$returnValue ) {
        $this->error( self::DIFFERENT );
        }
    }
        return $returnValue;


    }

}

Add the following to the Form filter

$this->add ( array (
    'name'  => 'new_user_password',
    'required' => true,
    'filters' => array (
        array ( 
            'name' => 'StringTrim',
        ),
    ),
    'validators' => array (
        array (
            'name' => 'StringLength',
            'options' => array (
                'min' => 8,
                'max' => 20,
            )
        ),
        array (
            'name' => 'Application\Validator\StringCompare',
            'options' => array (
                'compareWith' => 'user_password',
                'different' => true,
            ),
        ),
    )
) );

Perform the form validation in your controller and we are through. If we use different = 'true' the validation routine ensures the two values are different, if we use 'false', then it ensures that the strings are the same.