如何为doctrine Date水化器添加自定义水化器策略

时间:2015-04-28 08:19:46

标签: php date doctrine-orm zend-framework2

我有一个表单,其中包含3个类型文本字段和一个日期验证程序。

此代码位于使用doctrine hydrator(与教义实体相关)

的字段集中
$this->add(
        array(
            'name' => 'endDate',
            'type' => 'Zend\Form\Element\Text',
            'options' => array(
                'label' => 'end_date_label',
                'label_attributes' => array(
                    'class'  => 'control-label col-xs-3'
                ),
            ),
            'attributes' => array(
                'class' => 'form-control col-xs-3 datepicker-end-date',
            )
        )
    );


'endDate' => array(
        'required'   => true,
        'allow_empty' => false,
        'filters'    => array(
            array('name' => 'StripTags'),
            array('name' => 'StringTrim'),
        ),
        'validators' => array(
            array(
                'name' => 'Date',
                'options' => array(
                    'format' => 'd/m/Y',
                ),
            ),
        ),
    ),

我使用法语日期格式。如果我将格式更改为m / d / Y,当我将格式更改为有效但当我的表单无效时,我的日期选择器会得到错误的日期(月份和日期被反转)。

我想要的是有效的法语日期格式,并以m / d / Y格式保存到数据库中。

使用这种格式我得到错误:

DateTime::__construct(): Failed to parse time string (29/04/2015) at position 0 (2): Unexpected character

我在Stack上看到很多关于教条水合的自定义策略的帖子,但我对它们并不了解。我应该一步一步做什么?

我尝试为我的字段endDate添加策略,但它从未被调用过......这段代码在我的字段声明之前的fieldset类中:

$this->setHydrator(new DoctrineHydrator($this->getObjectManager(), 'TodoList\Entity\TodoQuestion'))
            ->setObject(new TodoQuestion());
        $this->getHydrator()->addStrategy('endDate', new \Application\Strategy\DateTimeStrategy());

我的日期时间策略实现了策略界面。

<?php

namespace Application\Strategy;

use Zend\Stdlib\Hydrator\Strategy\StrategyInterface;

class DateTimeStrategy implements StrategyInterface
{
    public function hydrate($value)
    {
        if (is_string($value)) {
            $value = new DateTime($value);
        }
        return $value->format('d/m/Y');
    }

    public function extract($value)
    {
        return;
    }
}

如果有人能详细解释我做错了什么,并帮助我理解这一切......

2 个答案:

答案 0 :(得分:0)

您应该从策略中返回一个DateTime对象。

namespace Application\Strategy;

use Zend\Stdlib\Hydrator\Strategy\StrategyInterface;

class DateTimeStrategy implements StrategyInterface
{
    public function hydrate($value)
    {
        if (is_string($value)) {
            $value = \DateTime::createFormFormat('d/m/Y', $value);
        }
        return $value;
    }

    public function extract($value)
    {
        return $value;
    }
}

<击>

由于在水化器的类型转换后调用策略,因此上述功能不起作用。

您最好使用回调过滤器。

'endDate' => array(
    'required'   => true,
    'allow_empty' => false,
    'filters'    => array(
        array('name' => 'StripTags'),
        array('name' => 'StringTrim'),
        array(
            'name' => 'Callback',
            'options' => array(
                'callback' => function($value) {
                    if (is_string($value)) {
                        $value = \DateTime::createFromFormat('d/m/Y', $value);
                    }
                    return $value;

                },
            ),
    ),
    'validators' => array(
        array(
            'name' => 'Date',
            'options' => array(
                'format' => 'd/m/Y',
            ),
        ),
    ),
),

你正在使用的学说保湿器似乎已经过时了。当前版本不需要将实体指定为第二个参数。

答案 1 :(得分:0)

意外地偶然发现了这个问题。虽然它已经相当陈旧,但我最近在ZF2表格中与Dates合作。我已经完成了如下所示的格式化,没有使用回调。

也许它将来会帮助某人;)

以下是使用ZF2 2.5.3

完成的
    $this->add([
        'name' => 'startDate',
        'required' => true,
        'filters' => [
            [
                'name' => DateTimeFormatter::class,
                'options' => [
                    'format' => 'Y-m-d', // or d/m/Y
                ],
            ],
        ],
        'validators' => [
            [
                'name' => Date::class,
                'options' => [
                    'format' => 'Y-m-d', // or d/m/Y
                ],
            ],
        ],
    ]);