reverseTransform в DataTransformer не работи

Създадох персонализирано поле за формуляр тип „продължителност“ и 2 полета „час“ и „минути“

class DurationType extends AbstractType
{

    public function setDefaultOptions(OptionsResolverInterface $resolver)
    {
        $resolver->setDefaults([]);
    }

    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('hours', new DurationSmallType(), [])
            ->add('minutes', new DurationSmallType(), [])
        ;
    }

    public function finishView(FormView $view, FormInterface $form, array $options)
    {
    }

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

DurationSmallType:

class DurationSmallType extends AbstractType
{

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

Шаблон и за двата типа:

{% block duration_small_widget -%}
<div class="input-group" style="display: inline-block;width:100px;height: 34px;margin-right: 20px;">
    <input type="text" {{ block('widget_attributes') }} class="form-control" style="width:50px;" {% if value is not empty %}value="{{ value }}" {% endif %}>
    <span class="input-group-addon" style="height: 34px;"></span>
</div>
{%- endblock duration_small_widget %}

{% block duration_widget -%}

    {{ form_widget(form.hours) }}
    {{ form_widget(form.minutes) }}

{%- endblock duration_widget %}

В Продължителността на обекта се записва в минути (като цяло число) и създавам DataTransformer в конструктора на формуляри:

class EventType extends AbstractType
    {
    /**
     * @param FormBuilderInterface $builder
     * @param array $options
     */
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $dataTransformer = new DurationToMinutesTransformer();

        $builder
            ->add('name', NULL, array('label' => 'Название'))
            ->add('type', NULL, array('label' => 'Раздел'))
            ->add($builder
                ->create('duration', new DurationType(), array('label' => 'Продолжительность'))
                ->addModelTransformer($dataTransformer)
            )
        ->add('enabled', NULL, array('label' => 'Включено'));
    }

    /**
     * @param OptionsResolverInterface $resolver
     */
    public function setDefaultOptions(OptionsResolverInterface $resolver)
    {
        $resolver->setDefaults(array(
            'data_class' => 'TourConstructor\MainBundle\Entity\Event',
            'csrf_protection' => true,
            'csrf_field_name' => '_token',
            'intention' => 'events_token'
        ));
    }

    /**
     * @return string
     */
    public function getName()
    {
        return 'mybundle_event';
    }
}

Трансформатор на DurationToMinutes:

class DurationToMinutesTransformer implements DataTransformerInterface
{
    public function transform($value)
    {

        if (!$value) {
            return null;
        }

        $hours = ceil($value / 60);
        $minutes = $value % 60;

        return [
            "hours" => $hours,
            "minutes" => $minutes
        ];
    }

    public function reverseTransform($value)
    {
        if (!$value) {
            return null;
        }

        return $value["hours"]*60 + $value["minutes"];
    }
}

Transform - работа, имам часове и минути в полето за редактиране, но reverseTransform не работи, след изпращане имам поле за продължителност като масив.

Грешка в Symfony:

Symfony\Component\Validator\ConstraintViolation
Object(Symfony\Component\Form\Form).children[duration].children[hours] = 3

Caused by:

Symfony\Component\Form\Exception\TransformationFailedException
Compound forms expect an array or NULL on submission.

Symfony\Component\Validator\ConstraintViolation
Object(Symfony\Component\Form\Form).children[duration].children[minutes] = 0

Caused by:

Symfony\Component\Form\Exception\TransformationFailedException
Compound forms expect an array or NULL on submission.

Моля, помогни ми.


person Alexey Ivanov    schedule 18.01.2015    source източник
comment
какво се предава на метода reverseTransform? отстранете грешки и вижте какво ще се случи   -  person Peter Popelyshko    schedule 18.01.2015
comment
Не знам, не е изключение, грешка в раздела на формуляра на Profiler.   -  person Alexey Ivanov    schedule 18.01.2015


Отговори (1)


Намирам грешка, DurationSmallType се нуждае от опция за съединение=false, по подразбиране е true и symfony се опитва да използва моето поле 2 като вътрешна форма. И премахвам modelTransformer от формата на обект и го поставям в DurationType.

Накрая код на моите създатели на формуляри:

Тип събитие:

class EventType extends AbstractType
    {
    /**
     * @param FormBuilderInterface $builder
     * @param array $options
     */
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $dataTransformer = new DurationToMinutesTransformer();

        $builder
            ->add('name', NULL, array('label' => 'Название'))
            ->add('type', NULL, array('label' => 'Раздел'))
            ->add($builder
                ->create('duration', new DurationType(), array('label' => 'Продолжительность'))
                ->addModelTransformer($dataTransformer)
            )
        ->add('enabled', NULL, array('label' => 'Включено'));
    }

    /**
     * @param OptionsResolverInterface $resolver
     */
    public function setDefaultOptions(OptionsResolverInterface $resolver)
    {
        $resolver->setDefaults(array(
            'data_class' => 'TourConstructor\MainBundle\Entity\Event',
            'csrf_protection' => true,
            'csrf_field_name' => '_token',
            'intention' => 'events_token'
        ));
    }

    /**
     * @return string
     */
    public function getName()
    {
        return 'mybundle_event';
    }
}

DurationType:

class DurationType extends AbstractType
{

    public function setDefaultOptions(OptionsResolverInterface $resolver)
    {

        $resolver->setDefaults(array(
            'html5' => true,
            'error_bubbling' => false,
            'compound' => true,
        ));
    }

    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('hours', new DurationSmallType(), [
                "label"=>"ч."
            ])
            ->add('minutes', new DurationSmallType(), [
                "label"=>"мин."
            ])
            ->addViewTransformer(new DurationToMinutesTransformer())
        ;
    }

    public function finishView(FormView $view, FormInterface $form, array $options)
    {

    }

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

DurationSmallType:

class DurationSmallType extends AbstractType
{

    /**
     * {@inheritdoc}
     */
    public function setDefaultOptions(OptionsResolverInterface $resolver)
    {
        $resolver->setDefaults(array(
            'compound' => false,
        ));
    }

    public function getName()
    {
        return 'duration_small';
    }
}
person Alexey Ivanov    schedule 18.01.2015
comment
задаване на съединение на false реши този проблем и за мен. Благодаря ! - person Sébastien; 27.09.2015