0

I am trying to read a \DateInterval from 2 input fields, as follows :

public function buildForm(FormBuilderInterface $builder, array $options)
{
    $builder
        ->add('name', TextType::class, ['label' => "Name"])
        ->add('duration', DateIntervalType::class, ['label' => false])
    ;
}

public function configureOptions(OptionsResolver $resolver)
{
    $resolver->setDefaults(['data_class' => NamedInterval::class]);
}

Here's my DateIntervalType::buildForm :

public function buildForm(FormBuilderInterface $builder, array $options)
{
    $builder
        ->add('amount', IntegerType::class)
        ->add('kind', ChoiceType::class, ['choices' => ['Year' => 'Y', 'Month' => 'M', 'Week' => 'W']])
    ;
}

And here is the transformer I attempted :

$builder->get('duration')->addModelTransformer(new CallbackTransformer(
    function ($property) {
        return new \DateInterval('P' . $property['amount'] . $property['kind']);
    },
    function ($property) {
        /* compute $specString from $property assuming it's a \DateInterval */
        /* ... */
        return ['amount' => 1, 'kind' => 'W'];
    }
));

Hence this is not working, my $property is always null after validating the form when transforming from form data to \DateInterval and I'm not even sure that I ever used the transformer from \DateInterval to form data, what I am doing wrong?

1 Answer 1

2

It appears that the CallbackTransformer is inversed :

$builder->get('duration')->addModelTransformer(new CallbackTransformer(
    function ($property) {
        /* compute specString from $property assuming it's a \DateInterval */
        /* ... */
        return ['amount' => 1, 'kind' => 'W'];
    },
    function ($property) {
        if (!$property) return null;
        return new \DateInterval('P' . $property['amount'] . $property['kind']);
    }
));

Now it works like a charm !

EDIT: as \DateInterval converts weeks to days, there also should be an option 'Day' => 'D' in the options list.

Sign up to request clarification or add additional context in comments.

1 Comment

A model transformer transforms from the model format to the norm format (in your case that's from a DateInterval object to an array). This is done using the transform() method. The CallbackTransformer calls the first callback here. To do the transformation from the norm data back to the model data the reverseTransform() method is used (i.e. the second callback passed to the CallbackTransformer).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.