3

私は最近DataTransformer、さまざまな異なる日付形式(2012年12月12日、2012年12月12日、2012年12月12日など)を受け入れるaを作成しました。

私の質問は:日付と時刻を2つの異なるフィールドに分割する前に:

$builder->add('date_end', 'datetime', array(
        'label' => 'Date/Time',
        'date_widget' => 'single_text',
        'time_widget' => 'single_text',
        'date_format' => 'dd.MM.yyyy',
        'with_seconds' => false,
        'required' => false,
    ) )

これはうまくいきました。新しいものでこれをどのように達成できDataTransformerますか?

私のエンティティタイプ内:

public function buildForm(FormBuilder $builder, array $options) {

    builder->add('date_end', 'dateTime', array(
        'label' => 'Date/Time',
        'required' => false,
    ) )
}

私が作成した対応するDateTimeType:

class DateTimeType extends AbstractType {
    private $om;

    public function __construct(ObjectManager $om) {
        $this->om = $om;
    }

    public function buildForm(FormBuilder $builder, array $options) {
        $transformer = new DateTimeTransformer($this->om);
        $builder->appendClientTransformer($transformer);
    }

    public function getDefaultOptions(array $options) {
        return array(
            'invalid_message' => 'TODO INVALID',
        );
    }

    public function getParent(array $options) {
        return 'text';
    }

    public function getName(){
        return 'dateTime';
    }
}

これまでの私の変圧器:

/**
 * @param  \DateTime|null $dateTime
 * @return string|null
 */
public function transform($dateTime) {
    if (null === $dateTime) {
        return null;
    }

    return $dateTime->format('Y-m-d H:i');
}

/**
 * @param  string $value
 * @return string|null
 */
public function reverseTransform($value)
{
    if ( (null === $value) || empty($value) ) {
        return null;
    }
    return new \DateTime( $value );

}
4

1 に答える 1

2

Symfony 2.0 を使用していると仮定しています。フォーム コンポーネントが 2.1 で多少変更されたことを読みました。

同様の問題がありました-日付と時刻(時間)の入力に別々のウィジェットを使用する日時フィールドが必要でした。

まず、このフィールド用に別のフォーム タイプを作成する必要があります (実際にはそれ自体がフォームです)。

私のコードは次のようになります (この例では変更されています):

class MyDateTimeType extends AbstractType
{
    public function buildForm(FormBuilder $builder, array $options)
    {
        $builder
        ->add('date', 'date', array(
            'label'  => 'label.form.date',
            'input'  => 'datetime',
            'widget' => 'single_text',
            'format' => 'yyyy-MM-dd',
            'error_bubbling' => true
        ))
        ->add('time', 'time', array(
            'label'  => 'label.form.time',
            'input'  => 'datetime',
            'widget' => 'choice',
            'error_bubbling' => true
        ));

        $builder->appendClientTransformer(new DateTimeToDateTimeArrayTransformer());
    }

    public function getDefaultOptions(array $options)
    {
        return array(
            'label' => 'label.form.date',
            'error_bubbling' => false
        );
    }

    public function getParent(array $options)
    {
        return 'form';
    }

    public function getName()
    {
        return 'my_datetime';
    }
}

ご覧のとおり、これはフォームですが (混乱しないようにしてください)、単一の論理フィールドとして使用します。ここでデータ トランスフォーマーの出番です。フォームを表示するときに 2 つのサブフィールドのデータを取得するために、単一のDateTimeインスタンスを日付と時刻に分割する必要があり、フォームが送信されるときにその逆を行う必要があります。

error_bubbling 設定により、サブフィールドによって生成されたエラーが新しいサブフィールドにアタッチされ、最上位のフォームに伝播されないようになりますが、別の目標がある場合があります。

私のデータトランスフォーマーは次のようになります。

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'
));

エイリアスで使用するには、サービスとして登録する必要があります。それ以外の場合は、直接インスタンス化します ( new MyDateTimeType())。

これは最善の解決策ではないかもしれませんが、Symfony 2.0 のフォーム コンポーネントも同様です。

于 2012-12-03T20:42:32.707 に答える