Skip to content
This repository has been archived by the owner on Jan 8, 2020. It is now read-only.

Error on date validation #4619

Closed
claudiasagner opened this issue Jun 10, 2013 · 8 comments
Closed

Error on date validation #4619

claudiasagner opened this issue Jun 10, 2013 · 8 comments

Comments

@claudiasagner
Copy link

I'm not sure if #4592 has the same cause.
I got an error when validating a wrong date in a date field.

Code:

class TestForm extends \Zend\Form\Form{
    public function __construct($name = null)
  {
        parent::__construct($name);
        $this->setAttribute('method', 'post');

        $this->add(array(
                        'name' => 'expiry',
                        'type' => 'Zend\Form\Element\Date',
                        'attributes' => array(
                                'maxlength' => '10',
                        ),
                        'options' => array(
                                'label' => 'expiry_date',
                        ),
        ));  

        $this->add(array(
                'name' => 'submit',
                'attributes' => array(
                        'type'  => 'submit',
                        'value' => 'test',
                ),
        ));                               
  }
}

class TestFilter implements \Zend\InputFilter\InputFilterAwareInterface
{
    public function getInputFilter()
    {
        if (!$this->inputFilter) {
          $this->inputFilter = new \Zend\InputFilter\InputFilter();
        }

        $factory     = new \Zend\InputFilter\Factory();

        $this->inputFilter->add($factory->createInput(array(
                        'name'     => 'expiry',
                        'required' => true,
                        'filters'  => array(
                                        array('name' => 'StringTrim'),
                        ),
                        'validators' => array(
                                          array(
                                              'name'    => 'Date',
                                              'options' => array(
                                                  'format' => 'd.m.Y',
                                              ),
                                        ),
                        ),
        )));            

        return $this->inputFilter;     
    }
}

//controller:
public function testAction()
{
  $form = new TestForm();

  $filter  = new TestFilter();
  $form->setInputFilter($filter->getInputFilter()); //i tested with and without filter. i always got the same error

  $request = $this->getRequest();
  if ($request->isPost()) {
      $form->setData($request->getPost());
      if ($form->isValid()) {     // throws exception on wrong date
        ...
      }
      else{
        ....
      }
  }

  return array(
      'form' => $form,
  );  
}

//view:
<?$form->setAttribute('action', $this->url('test'));?>
<?$form->prepare();?>
<?=$this->form()->openTag($form);?>
<?=$this->formRow($form->get('expiry'));?>
<?=$this->formSubmit($form->get('submit'));?>
<?=$this->form()->closeTag();?>

Error:
Code: 0
File: Zend_Framework_2_2/Zend/Filter/DateTimeFormatter.php
Line: 60
Message: Invalid date string provided
Trace: 0 Zend_Framework_2_2/Zend/Filter/AbstractFilter.php(85): Zend\Filter\DateTimeFormatter->filter('fffffff')
1 [internal function]: Zend\Filter\AbstractFilter->__invoke('fffffff')
2 Zend_Framework_2_2/Zend/Filter/FilterChain.php(218): call_user_func(Object(Zend\Filter\DateTimeFormatte r), 'fffffff')
3 Zend_Framework_2_2/Zend/InputFilter/Input.php(262): Zend\Filter\FilterChain->filter('fffffff')
4 Zend_Framework_2_2/Zend/InputFilter/Input.php(307): Zend\InputFilter\Input->getValue()
5 Zend_Framework_2_2/Zend/InputFilter/BaseInputFilter.php(296): Zend\InputFilter\Input->isValid(Array)
6 Zend_Framework_2_2/Zend/InputFilter/BaseInputFilter.php(167): Zend\InputFilter\BaseInputFilter->validateInputs(Array)
7 Zend_Framework_2_2/Zend/Form/Form.php(476): Zend\InputFilter\BaseInputFilter->isValid()
8 myapp/module/Test/src/Test/Controller/TestController.php(479): Zend\Form\Form->isValid()
9 Zend_Framework_2_2/Zend/Mvc/Controller/AbstractActionController.php(83): Test\Controller\TestController->testAction()
10 [internal function]: Zend\Mvc\Controller\AbstractActionController->onDispatch(Object(Zend\Mvc\MvcEvent))
11 Zend_Framework_2_2/Zend/EventManager/EventManager.php(468): call_user_func(Array, Object(Zend\Mvc\MvcEvent))
12 Zend_Framework_2_2/Zend/EventManager/EventManager.php(207): Zend\EventManager\EventManager->triggerListeners('dispatch', Object(Zend\Mvc\MvcEvent), Object(Closure))
13 Zend_Framework_2_2/Zend/Mvc/Controller/AbstractController.php(117): Zend\EventManager\EventManager->trigger('dispatch', Object(Zend\Mvc\MvcEvent), Object(Closure))
14 Zend_Framework_2_2/Zend/Mvc/DispatchListener.php(114): Zend\Mvc\Controller\AbstractController->dispatch(Object(Zend\Http\PhpEnvironment\Request) , Object(Zend\Http\PhpEnvironment\Response))
15 [internal function]: Zend\Mvc\DispatchListener->onDispatch(Object(Zend\Mvc\MvcEvent))
16 Zend_Framework_2_2/Zend/EventManager/EventManager.php(468): call_user_func(Array, Object(Zend\Mvc\MvcEvent))
17 Zend_Framework_2_2/Zend/EventManager/EventManager.php(207): Zend\EventManager\EventManager->triggerListeners('dispatch', Object(Zend\Mvc\MvcEvent), Object(Closure))
18 Zend_Framework_2_2/Zend/Mvc/Application.php(309): Zend\EventManager\EventManager->trigger('dispatch', Object(Zend\Mvc\MvcEvent), Object(Closure))
19 myapp/public/index.php(14): Zend\Mvc\Application->run()
20 {main}

previous
Code: 0
File: Zend_Framework_2_2/Zend/Filter/DateTimeFormatter.php
Line: 79
Message: DateTime::__construct(): Failed to parse time string (fffffff) at position 0 (f): The timezone could not be found in the database
Trace: 0 Zend_Framework_2_2/Zend/Filter/DateTimeFormatter.php(79): DateTime->__construct('fffffff')
1 Zend_Framework_2_2/Zend/Filter/DateTimeFormatter.php(57): Zend\Filter\DateTimeFormatter->normalizeDateTime('fffffff')
2 Zend_Framework_2_2/Zend/Filter/AbstractFilter.php(85): Zend\Filter\DateTimeFormatter->filter('fffffff')
3 [internal function]: Zend\Filter\AbstractFilter->__invoke('fffffff')
4 Zend_Framework_2_2/Zend/Filter/FilterChain.php(218): call_user_func(Object(Zend\Filter\DateTimeFormatte r), 'fffffff')
5 Zend_Framework_2_2/Zend/InputFilter/Input.php(262): Zend\Filter\FilterChain->filter('fffffff')
6 Zend_Framework_2_2/Zend/InputFilter/Input.php(307): Zend\InputFilter\Input->getValue()
7 Zend_Framework_2_2/Zend/InputFilter/BaseInputFilter.php(296): Zend\InputFilter\Input->isValid(Array)
8 Zend_Framework_2_2/Zend/InputFilter/BaseInputFilter.php(167): Zend\InputFilter\BaseInputFilter->validateInputs(Array)
9 Zend_Framework_2_2/Zend/Form/Form.php(476): Zend\InputFilter\BaseInputFilter->isValid()
10 myapp/module/Test/src/Test/Controller/TestController.php(479): Zend\Form\Form->isValid()
11 Zend_Framework_2_2/Zend/Mvc/Controller/AbstractActionController.php(83): Test\Controller\TestController->addAction()
12 [internal function]: Zend\Mvc\Controller\AbstractActionController->onDispatch(Object(Zend\Mvc\MvcEvent))
13 Zend_Framework_2_2/Zend/EventManager/EventManager.php(468): call_user_func(Array, Object(Zend\Mvc\MvcEvent))
14 Zend_Framework_2_2/Zend/EventManager/EventManager.php(207): Zend\EventManager\EventManager->triggerListeners('dispatch', Object(Zend\Mvc\MvcEvent), Object(Closure))
15 Zend_Framework_2_2/Zend/Mvc/Controller/AbstractController.php(117): Zend\EventManager\EventManager->trigger('dispatch', Object(Zend\Mvc\MvcEvent), Object(Closure))
16 Zend_Framework_2_2/Zend/Mvc/DispatchListener.php(114): Zend\Mvc\Controller\AbstractController->dispatch(Object(Zend\Http\PhpEnvironment\Request) , Object(Zend\Http\PhpEnvironment\Response))
17 [internal function]: Zend\Mvc\DispatchListener->onDispatch(Object(Zend\Mvc\MvcEvent))
18 Zend_Framework_2_2/Zend/EventManager/EventManager.php(468): call_user_func(Array, Object(Zend\Mvc\MvcEvent))
19 Zend_Framework_2_2/Zend/EventManager/EventManager.php(207): Zend\EventManager\EventManager->triggerListeners('dispatch', Object(Zend\Mvc\MvcEvent), Object(Closure))
20 Zend_Framework_2_2/Zend/Mvc/Application.php(309): Zend\EventManager\EventManager->trigger('dispatch', Object(Zend\Mvc\MvcEvent), Object(Closure))
21 myapp/public/index.php(14): Zend\Mvc\Application->run()
22 {main}

@Gounlaf
Copy link

Gounlaf commented Oct 7, 2013

I have same issue, without settings filters (so it use natives filter provided by the element)

class TestForm extends Form
{
    public function __construct($name = null, $options = array())
    {
        parent::__construct($name, $options);

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

        $this->createElements();
    }

    public function createElements(array $options)
    {
        $date = new Element\Date('date', array(
            'format' => 'Y-m-d',
            'label' => 'Date :',
        ));

        $this->add($date);
    }
}

#0 Project/vendor/zendframework/zendframework/library/Zend/Filter/AbstractFilter.php(85): Zend\Filter\DateTimeFormatter->filter('aaaaa')
#1 [internal function]: Zend\Filter\AbstractFilter->__invoke('aaaaa')
#2 Project/vendor/zendframework/zendframework/library/Zend/Filter/FilterChain.php(224): call_user_func(Object(Zend\Filter\DateTimeFormatter), 'aaaaa')
#3 Project/vendor/zendframework/zendframework/library/Zend/InputFilter/Input.php(263): Zend\Filter\FilterChain->filter('aaaaa')
#4 Project/vendor/zendframework/zendframework/library/Zend/InputFilter/Input.php(309): Zend\InputFilter\Input->getValue()
#5 Project/vendor/zendframework/zendframework/library/Zend/InputFilter/BaseInputFilter.php(299): Zend\InputFilter\Input->isValid(Array)
#6 Project/vendor/zendframework/zendframework/library/Zend/InputFilter/BaseInputFilter.php(169): Zend\InputFilter\BaseInputFilter->validateInputs(Array)
#7 Project/vendor/zendframework/zendframework/library/Zend/Form/Form.php(498): Zend\InputFilter\BaseInputFilter->isValid()
#8 Project/module/Trigger/src/Trigger/Controller/TriggerController.php(309): Zend\Form\Form->isValid()
#9 Project/vendor/zendframework/zendframework/library/Zend/Mvc/Controller/AbstractActionController.php(83): Trigger\Controller\TriggerController->step2DateAction()
#10 [internal function]: Zend\Mvc\Controller\AbstractActionController->onDispatch(Object(Zend\Mvc\MvcEvent))
#11 Project/vendor/zendframework/zendframework/library/Zend/EventManager/EventManager.php(468): call_user_func(Array, Object(Zend\Mvc\MvcEvent))
#12 Project/vendor/zendframework/zendframework/library/Zend/EventManager/EventManager.php(207): Zend\EventManager\EventManager->triggerListeners('dispatch', Object(Zend\Mvc\MvcEvent), Object(Closure))
#13 Project/vendor/zendframework/zendframework/library/Zend/Mvc/Controller/AbstractController.php(117): Zend\EventManager\EventManager->trigger('dispatch', Object(Zend\Mvc\MvcEvent), Object(Closure))
#14 Project/vendor/zendframework/zendframework/library/Zend/Mvc/DispatchListener.php(114): Zend\Mvc\Controller\AbstractController->dispatch(Object(Zend\Http\PhpEnvironment\Request), Object(Zend\Http\PhpEnvironment\Response))
#15 [internal function]: Zend\Mvc\DispatchListener->onDispatch(Object(Zend\Mvc\MvcEvent))
#16 Project/vendor/zendframework/zendframework/library/Zend/EventManager/EventManager.php(468): call_user_func(Array, Object(Zend\Mvc\MvcEvent))
#17 Project/vendor/zendframework/zendframework/library/Zend/EventManager/EventManager.php(207): Zend\EventManager\EventManager->triggerListeners('dispatch', Object(Zend\Mvc\MvcEvent), Object(Closure))
#18 Project/vendor/zendframework/zendframework/library/Zend/Mvc/Application.php(309): Zend\EventManager\EventManager->trigger('dispatch', Object(Zend\Mvc\MvcEvent), Object(Closure))
#19 Project/public/index.php(11): Zend\Mvc\Application->run()
#20 {main}

DateTime::__construct(): Failed to parse time string (aaaaa) at position 0 (a): The timezone could not be found in the database

#0 Project/vendor/zendframework/zendframework/library/Zend/Filter/DateTimeFormatter.php(79): DateTime->__construct('aaaaa')
#1 Project/vendor/zendframework/zendframework/library/Zend/Filter/DateTimeFormatter.php(57): Zend\Filter\DateTimeFormatter->normalizeDateTime('aaaaa')
#2 Project/vendor/zendframework/zendframework/library/Zend/Filter/AbstractFilter.php(85): Zend\Filter\DateTimeFormatter->filter('aaaaa')
#3 [internal function]: Zend\Filter\AbstractFilter->__invoke('aaaaa')
#4 Project/vendor/zendframework/zendframework/library/Zend/Filter/FilterChain.php(224): call_user_func(Object(Zend\Filter\DateTimeFormatter), 'aaaaa')
#5 Project/vendor/zendframework/zendframework/library/Zend/InputFilter/Input.php(263): Zend\Filter\FilterChain->filter('aaaaa')
#6 Project/vendor/zendframework/zendframework/library/Zend/InputFilter/Input.php(309): Zend\InputFilter\Input->getValue()
#7 Project/vendor/zendframework/zendframework/library/Zend/InputFilter/BaseInputFilter.php(299): Zend\InputFilter\Input->isValid(Array)
#8 Project/vendor/zendframework/zendframework/library/Zend/InputFilter/BaseInputFilter.php(169): Zend\InputFilter\BaseInputFilter->validateInputs(Array)
#9 Project/vendor/zendframework/zendframework/library/Zend/Form/Form.php(498): Zend\InputFilter\BaseInputFilter->isValid()
#10 Project/module/Trigger/src/Trigger/Controller/TriggerController.php(309): Zend\Form\Form->isValid()
#11 Project/vendor/zendframework/zendframework/library/Zend/Mvc/Controller/AbstractActionController.php(83): Trigger\Controller\TriggerController->step2DateAction()
#12 [internal function]: Zend\Mvc\Controller\AbstractActionController->onDispatch(Object(Zend\Mvc\MvcEvent))
#13 Project/vendor/zendframework/zendframework/library/Zend/EventManager/EventManager.php(468): call_user_func(Array, Object(Zend\Mvc\MvcEvent))
#14 Project/vendor/zendframework/zendframework/library/Zend/EventManager/EventManager.php(207): Zend\EventManager\EventManager->triggerListeners('dispatch', Object(Zend\Mvc\MvcEvent), Object(Closure))
#15 Project/vendor/zendframework/zendframework/library/Zend/Mvc/Controller/AbstractController.php(117): Zend\EventManager\EventManager->trigger('dispatch', Object(Zend\Mvc\MvcEvent), Object(Closure))
#16 Project/vendor/zendframework/zendframework/library/Zend/Mvc/DispatchListener.php(114): Zend\Mvc\Controller\AbstractController->dispatch(Object(Zend\Http\PhpEnvironment\Request), Object(Zend\Http\PhpEnvironment\Response))
#17 [internal function]: Zend\Mvc\DispatchListener->onDispatch(Object(Zend\Mvc\MvcEvent))
#18 Project/vendor/zendframework/zendframework/library/Zend/EventManager/EventManager.php(468): call_user_func(Array, Object(Zend\Mvc\MvcEvent))
#19 Project/vendor/zendframework/zendframework/library/Zend/EventManager/EventManager.php(207): Zend\EventManager\EventManager->triggerListeners('dispatch', Object(Zend\Mvc\MvcEvent), Object(Closure))
#20 Project/vendor/zendframework/zendframework/library/Zend/Mvc/Application.php(309): Zend\EventManager\EventManager->trigger('dispatch', Object(Zend\Mvc\MvcEvent), Object(Closure))
#21 Project/public/index.php(11): Zend\Mvc\Application->run()
#22 {main}

@steverhoades
Copy link
Contributor

@claudiasagner @Gounlaf Can you please update the status of this issue? I am unable to replicate this with the following unit test

/**
 * @group 4619
 */
public function testValidatorReturnsBooleanOnFormatError()
{
    $validator = $this->validator;
    try {
        $validator->isValid("asdf");
    } catch (Exception $e) {
        $this->fail($e->getMessage());
    }        
}

It appears to me this issue has already been resolved.

@Gounlaf
Copy link

Gounlaf commented Feb 24, 2014

Hi @steverhoades,

the problem is still here for me ;
I have a form and i have tested with both Zend\Form\Element\Date and Zend\Form\Element\DateTime
I setted the filter "required" to false ; the elements are displayed with view plugins formDate($fieldDate) and formDateTime($fieldDateTime)
The version installed with composer is 2.2.5
Simple form

class ChangeData extends Form
{
    public function __construct($name = null, $options = array())
    {
        parent::__construct($name, $options);

        $this->add(new Element\DateTime('birthday', array(
            'label' => _('Birthday')
        )))
        //->add(new Element\Date('birthday', array(
        //    'label' => _('Birthday')
        //)))
        ;
    }
}

In the view

<?php echo $this->formDateTime($form->get('birthday')); ?>

Maybe a missconfig ? I'm on OS-X, using Mamp (PHP 5.4.19) ;

@steverhoades
Copy link
Contributor

@Gounlaf can you take a look at the unit test I am running and help me reproduce the issue you are describing? I've run that test on 2.2.5 and it still passed.

@Gounlaf
Copy link

Gounlaf commented Feb 24, 2014

@steverhoades I will try to
Any "step order" or something else ? (I don't know how to run unit test on a big project like this :x)

Edit : i think i tell you something wrong >< ; the error "Invalid date string provided..." is no more here ; but my form is validated

I setted a InputFilter on the form

class ChangeDataFilter extends InputFilter
{
    public function __construct()
    {
        $birthday = new Input('birthday');
        $birthday->setRequired(true);

        $this->add($birthday);
    }
}

// I use this because I see in sources that the inputFilter is merged with defaults filters 
// is it correct ?
$changeDataForm->setInputFilter(new ChangeDataFilter());


  // Somewhere in Zend\Form\Form class
/**
 * Set the input filter used by this form
 *
 * @param  InputFilterInterface $inputFilter
 * @return FormInterface
 */
public function setInputFilter(InputFilterInterface $inputFilter)
{
    $this->hasValidated                = false;
    $this->hasAddedInputFilterDefaults = false;
    $this->filter                      = $inputFilter;
    return $this;
}

With this, the form is validated ;
without, the "correct error" is displayed and form is invalidated ;

@steverhoades
Copy link
Contributor

@Gounlaf I see my error, I was testing the date validator, not the date filter. Looking at the exception triggered above, that seems to be the proper behavior (based on design).

Running the following test:

/**
 * @group 4619
 */
public function testZfIssue4619()
{       
    date_default_timezone_set('UTC');
    $filter = new DateTimeFormatter();
    $result = $filter->filter('aaaaaaa');

}  

returns the following unit test output:

1) ZendTest\Filter\DateTimeFormatterTest::testZfIssue4619
Zend\Filter\Exception\InvalidArgumentException: Invalid date string provided

/usr/local/zend/apache2/htdocs/zendframework/zf2/library/Zend/Filter/DateTimeFormatter.php:60
/usr/local/zend/apache2/htdocs/zendframework/zf2/library/Zend/Filter/DateTimeFormatter.php:79
/usr/local/zend/apache2/htdocs/zendframework/zf2/library/Zend/Filter/DateTimeFormatter.php:57
/usr/local/zend/apache2/htdocs/zendframework/zf2/tests/ZendTest/Filter/DateTimeFormatterTest.php:125
/usr/local/zend/share/pear/PHPUnit/TextUI/Command.php:176
/usr/local/zend/share/pear/PHPUnit/TextUI/Command.php:129

Caused by
Exception: DateTime::__construct(): Failed to parse time string (aaaaaaa) at position 0 (a): The timezone could not be found in the database

/usr/local/zend/apache2/htdocs/zendframework/zf2/library/Zend/Filter/DateTimeFormatter.php:79
/usr/local/zend/apache2/htdocs/zendframework/zf2/library/Zend/Filter/DateTimeFormatter.php:57
/usr/local/zend/apache2/htdocs/zendframework/zf2/tests/ZendTest/Filter/DateTimeFormatterTest.php:125
/usr/local/zend/share/pear/PHPUnit/TextUI/Command.php:176
/usr/local/zend/share/pear/PHPUnit/TextUI/Command.php:129

That is inline with an existing test checking for invalid arguments. This was tested on 2.2.5 -

It would appear to me that you need to put your code in a try block and listen for the Zend\Filter\Exception\InvalidArgumentException.

To see the line triggering this exception see:
https://github.com/zendframework/zf2/blob/release-2.2.5/library/Zend/Filter/DateTimeFormatter.php#L54

Updating that test to follow the one preceeding it results in passed unit test

/**
 * @group 4619
 */
public function testZfIssue4619()
{       
    $this->setExpectedException('Zend\Filter\Exception\InvalidArgumentException');

    date_default_timezone_set('UTC');
    $filter = new DateTimeFormatter();
    $result = $filter->filter('aaaaaaa');
}  

@Gounlaf
Copy link

Gounlaf commented Feb 25, 2014

Hi @steverhoades,
I made some manuals tests ; the formater works correctly like you said ; so, this issue is fixed ^^

The problem was else where : i don't use InputFilters correctly =/

I thank Form::setInputFilter() method was merging the "default input specifications" with the one provided (calling attachInputFilterDefaults), but it's not the case (https://gist.github.com/Gounlaf/9204709) ; any idea were I'm wrong ?

@GeeH
Copy link

GeeH commented Jun 27, 2016

This issue has been closed as part of the bug migration program as outlined here - http://framework.zend.com/blog/2016-04-11-issue-closures.html

@GeeH GeeH closed this as completed Jun 27, 2016
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

4 participants