Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DateTime min/max validators are not working when using costum format #7

Open
weierophinney opened this issue Dec 31, 2019 · 3 comments

Comments

@weierophinney
Copy link
Member

given this input definition

        $this->add([
            'type' => DateTime::class,
            'name' => 'dutyDate',
            'options' => [
                'label' => 'duty date',
                'format' => 'd.m.Y H:i'
            ],
            'attributes' => [
                'min' => '01.01.2000 00:00',
                'max' => '31.12.2099 00:00',
            ]
        ]);

when you now enter '2.2.2199 12:43' it is accepted without causing the validator to fail

from what i have seen is that to the GreaterThan and LessThan validator the raw string is passed and compared with the raw string from the input definition. i suggest to fill the validator with real DateTime objects for 'value' and also 'min' and 'max'


Originally posted by @BigMichi1 at zendframework/zend-form#190

@weierophinney
Copy link
Member Author

the documentation clearly states that greaterThan etc validators only support numbers
https://docs.zendframework.com/zend-validator/validators/greater-than/#only-supports-numbers
building a custom isBefore validator should be quite easy


Originally posted by @ghost at zendframework/zend-form#190 (comment)

@weierophinney
Copy link
Member Author

that is completly right but if these validators are added automatically if you specifiy min or max in the supported options. i implemented a new Element that replaces that validators but this is only workaround from my pointof view because if these validators are added automatically the should be added in the right way, i thunk.

namespace Administration\Element;

use Administration\Filter\ToDateTime;
use Zend\Filter\StringTrim;
use Zend\InputFilter\InputProviderInterface;
use Zend\Validator\GreaterThan;
use Zend\Validator\LessThan;

/**
 * Class DateTime.
 *
 * @package Administration\Element
 */
class DateTime extends \Zend\Form\Element\DateTime implements InputProviderInterface
{
    /**
     * @inheritdoc
     */
    public function getInputSpecification()
    {
        $validators = $this->getValidators();
        foreach ($validators as $validator) {
            if ($validator instanceof LessThan) {
                /** @var LessThan $validator */
                $validator->setMax(\DateTime::createFromFormat($this->getFormat(), $validator->getMax()));
            } elseif ($validator instanceof GreaterThan) {
                /** @var GreaterThan $validator */
                $validator->setMin(\DateTime::createFromFormat($this->getFormat(), $validator->getMin()));
            }
        }

        return [
            'name' => $this->getName(),
            'required' => true,
            'filters' => [
                ['name' => StringTrim::class],
                [
                    'name' => ToDateTime::class,
                    'options' => [
                        'format' => $this->getFormat(),
                    ],
                ],
            ],
            'validators' => $validators,
        ];
    }
}

and

namespace Administration\Filter;

use Zend\Filter\AbstractFilter;
use Zend\Filter\FilterInterface;

/**
 * Class ToDateTime
 *
 * @package Administration\Filter
 */
class ToDateTime extends AbstractFilter implements FilterInterface
{
    /**
     * @var string
     */
    protected $format = \DateTime::ISO8601;

    /**
     * @param array|\Traversable $options
     */
    public function __construct($options = null)
    {
        if ($options) {
            $this->setOptions($options);
        }
    }

    /**
     * @see \Zend\Filter\FilterInterface::filter()
     * @param  string $value
     * @return \DateTime
     */
    public function filter($value)
    {
        try {
            $date = (is_int($value)) ? new \DateTime($value) : \DateTime::createFromFormat($this->getFormat(), $value);
        } catch (\Exception $e) {
            $date = $value;
        }

        return $date;
    }

    /**
     * @return string
     */
    public function getFormat()
    {
        return $this->format;
    }

    /**
     * @param string $format
     * @return ToDateTime
     */
    public function setFormat($format)
    {
        $this->format = $format;
        return $this;
    }
}

Originally posted by @BigMichi1 at zendframework/zend-form#190 (comment)

@weierophinney
Copy link
Member Author

TL;DR
your are completely right. Since there are added automagically, they should probably handle date objects. a "nice to have"...


Originally posted by @ghost at zendframework/zend-form#190 (comment)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant