0

Appointment オブジェクトが Reminder オブジェクトと OneToMany 関係を持つモデルがあります。予約フォームにリマインダー フォームのコレクションを埋め込みたい。Appointment オブジェクトにはプロパティ Appointment.Date があります。Reminder オブジェクトには、Reminder.Date プロパティもあります。

Reminder.Date入力に使用する「数値」ドロップダウンと「単位」ドロップダウンで構成される「IntervalType」というカスタムタイプを作成しました。アイデアは、ユーザーが数値と単位 (「1 時間」、「2 日」など) を選択することです。

次に、「2 日」を、Appointment.Date より 2 日前の Reminder.Date の DateTime 値に変換する必要があります。「IntervalToDateTransformer」と呼ばれるカスタム DataTransformer を使用してこれを行う方法を見つけようとしています。データ トランスフォーマーをリマインダー フォームや IntervalType 入力などに追加することはできますが、リマインダーの親である Appointment.Date が何であるかをトランスフォーマーに認識させるにはどうすればよいでしょうか。

4

1 に答える 1

0

最初は、この問題について以前に行ったいくつかの調査のために、それは不可能だと思いました. 私はそれを試してみることにしました。基本的に、Issue と Option の 2 つのフィールドを持つカスタム フォーム タイプを作成しました。次に、変換に使用できるデータ変換クラスでこれらの 2 つの値を取得することができました。ここにファイルがあります。

Note that the 'option' field is not used, but I did verify 
it was accessible from the data transformer.

Also, I could not manage to render the validation messages declared 
on the data transform class when transformation fails. I stopped 
there, but if you manage to do it let me know.

最初のフォーム タイプ

class IssueSelectorType extends AbstractType
{

    /**
     * @var ObjectManager
     */
    private $om;

    /**
     * @param ObjectManager $om
     */
    public function __construct(ObjectManager $om)
    {
        $this->om = $om;
    }

    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder->add('number', 'text', array(
                // 'mapped' => false
        ));
        $builder->add('option', 'choice', array(
                // 'mapped' => false
        ));

          $transformer = new IssueToNumberTransformer($this->om);
          $builder->addViewTransformer($transformer);
    }

    public function setDefaultOptions(OptionsResolverInterface $resolver)
    {
        $resolver->setDefaults(array(
            'invalid_message' => 'The selected issue does not exist',
        ));
    }

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

    public function getParent()
    {
        return 'field';
    }

}

データ変換クラス:

class IssueToNumberTransformer implements DataTransformerInterface
{

    /**
     * @var ObjectManager
     */
    private $om;

    /**
     * @param ObjectManager $om
     */
    public function __construct(ObjectManager $om)
    {
        $this->om = $om;
    }

    /**
     * Transforms an object (issue) to a array .
     *
     * @param  Issue|null $issue
     * @return array
     */
    public function transform($issue)
    {
        if (null === $issue)
        {

            return array(
                'number' => 0,
                'option' => 0
                    );
        }

        return array(
            'number' => $issue->id,
            'option' => 0
        );
    }

    /**
     * Transforms a array  to an object (issue).
     *
     * @param  array $value
     * @return Issue|null
     * @throws TransformationFailedException if object (issue) is not found.
     */
    public function reverseTransform($value)
    {
        if (null === $value)
        {
            return null;
        }

        if (!is_array($value))
        {
            throw new UnexpectedTypeException($value, 'array');
        }
        $number = $value['number'] ;
        $option = $value['option'] ;

        $issue = $this->om
                ->getRepository('AcmeTransformerBundle:Issue')
                ->findOneBy(array('id' => $number))
        ;

        if (null === $issue)
        {
            throw new TransformationFailedException(sprintf(
                            'An issue with number "%s" does not exist!', $number
            ));
        }

        return $issue;
    }
}
于 2012-10-31T05:33:14.450 に答える