Php DataTransformer-将DateTime拆分为两个字段

Php DataTransformer-将DateTime拆分为两个字段,php,forms,symfony,Php,Forms,Symfony,我最近构建了一个DataTransformer,它最终将接受各种不同的日期格式(如2012年12月12日或2012年12月12日或2012-12-12) 我的问题是:在我将日期和时间分为两个不同的字段之前: $builder->add('date\u end','datetime',数组( “标签”=>“日期/时间”, 'date_widget'=>'single_text', “时间小部件”=>“单一文本”, “日期格式”=>“年月日”, '带_秒'=>假, “必需”=>false, ) )

我最近构建了一个
DataTransformer
,它最终将接受各种不同的日期格式(如2012年12月12日或2012年12月12日或2012-12-12)

我的问题是:在我将日期和时间分为两个不同的字段之前:

$builder->add('date\u end','datetime',数组(
“标签”=>“日期/时间”,
'date_widget'=>'single_text',
“时间小部件”=>“单一文本”,
“日期格式”=>“年月日”,
'带_秒'=>假,
“必需”=>false,
) )
效果很好。如何使用新的
数据转换器

在我的实体类型中:
公共函数buildForm(FormBuilder$builder,数组$options){
生成器->添加('date\u end','dateTime',数组(
“标签”=>“日期/时间”,
“必需”=>false,
) )
}
我创建的相应DateTimeType:
类DateTimeType扩展了AbstractType{
私人$om;
公共函数构造(ObjectManager$om){
$this->om=$om;
}
公共函数buildForm(FormBuilder$builder,数组$options){
$transformer=newdatetimetransformer($this->om);
$builder->appendClientTransformer($transformer);
}
公共函数getDefaultOptions(数组$options){
返回数组(
“无效消息”=>“TODO invalid”,
);
}
公共函数getParent(数组$options){
返回“文本”;
}
公共函数getName(){
返回“日期时间”;
}
}
到目前为止,我的变压器:
/**
*@param\DateTime | null$DateTime
*@返回字符串|空
*/
公共函数转换($dateTime){
如果(null==$dateTime){
返回null;
}
返回$dateTime->format('Y-m-dh:i');
}
/**
*@param字符串$value
*@返回字符串|空
*/
公共函数反向转换($value)
{
如果((null==$value)| |空($value)){
返回null;
}
返回new\DateTime($value);
}

我假设您使用的是Symfony 2.0。我已经了解到表单组件在2.1中有所改变

我有一个类似的问题——我想有一个datetime字段,它使用单独的小部件来输入日期和时间(小时)

首先,您必须为这个字段创建一个单独的表单类型(实际上它本身就是一个表单)

我的代码与此类似(针对本例进行了修改):

正如您所看到的,它是一个表单(不要让它迷惑您),但我们将使用它作为单个逻辑字段。这就是数据转换器的用武之地。在显示表单时,它必须将单个
DateTime
实例拆分为日期和时间,以获取两个子字段的数据,在提交表单时,反之亦然

error_冒泡设置确保子字段生成的错误附加到新的子字段,并且不会传播到顶级表单,但您可能有不同的目标

我的数据转换器如下所示:

class DateTimeToDateTimeArrayTransformer implements DataTransformerInterface
{
    public function transform($datetime)
    {
        if(null !== $datetime)
        {
            $date = clone $datetime;
            $date->setTime(12, 0, 0);

            $time = clone $datetime;
            $time->setDate(1970, 1, 1);
        }
        else
        {
            $date = null;
            $time = null;
        }

        $result = array(
            'date' => $date,
            'time' => $time
        );

        return $result;
    }

    public function reverseTransform($array)
    {
        $date = $array['date'];
        $time = $array['time'];

        if(null == $date || null == $time)
            return null;

        $date->setTime($time->format('G'), $time->format('i'));

        return $date;
    }
}
最后,您可以这样使用它:

$builder->add('startDate', 'my_datetime', array(
       'label' => 'label.form.date'
));
您必须通过别名使用它,否则直接实例化它(
newmydatetimetype()


这可能不是最漂亮的解决方案,但Symfony 2.0中的表单组件也是如此。

您是否只需要将原始的$builder->add(…)调用放入新的buildForm()方法中,并向其追加->appendClientTransformer($transformer)?我不确定我是否完全理解这个问题。当我使用
appendClientTransformer
时,整个表单都会传递给转换器,实际上我只希望传递所需的字段。当我试图保留选项时,比如它们是如何的,我得到了一个例外:`选项“date_widget”,“time_widget”,“date_format”,“with_seconds”不存在“。我还更新了关于如何调用转换器的问题。因此,根据您上面的代码,转换被正确应用,只是您的日期字段没有显示为两个小部件?是的,这正是我的问题。您需要一个特定的表单类型,您知道吗?似乎您只关心DataTransformer,但没有显示表单类型。如果你已经有了它,你可以用它更新问题。
$builder->add('startDate', 'my_datetime', array(
       'label' => 'label.form.date'
));