Last Updated: February 25, 2016
·
2.442K
· banu-ioan

Symfony - add a custom form type ( two integers saved as one in database )

Data transformer:

<?php

namespace ibanu\MainBundle\Form\DataTransformer;

use Symfony\Component\Form\DataTransformerInterface;
use Symfony\Component\Form\Exception\TransformationFailedException;

/**
*
* @author ion
*/
class DurationToIntegerTransformer implements DataTransformerInterface
{

public function transform($duration)
{
    if (null === $duration) {
        $duration   = 0;
    }

    $hours      = floor($duration / 60);
    $minutes    = $duration % 60;

    return  array('hours' => $hours, 'minutes' => $minutes);
}


public function reverseTransform($values)
{
    $hours   = isset($values['hours']) ? $values['hours'] : 0 ;
    $minutes = isset($values['minutes']) ? $values['minutes'] : 0 ;

    if (!is_int($hours) && !is_int($minutes)) {
        throw new TransformationFailedException('Expected one integer.');
    }

    return $hours * 60 + $minutes;
}

}

Form type:

<?php

namespace ibanu\MainBundle\Form\Type;

use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;

use ibanu\MainBundle\Form\DataTransformer\DurationToIntegerTransformer;

class DurationType extends AbstractType
{

public function buildForm(FormBuilderInterface $builder, array $options)
{
    $transformer = new DurationToIntegerTransformer();

    $builder->add(
        $builder->create('hours', 'integer', array('error_bubbling' => false, 'empty_data' => 0))
    );
    $builder->add(
        $builder->create('minutes', 'integer', array('error_bubbling' => false, 'empty_data' => 0))
    );

    $builder->addModelTransformer($transformer);
}


public function setDefaultOptions(OptionsResolverInterface $resolver)
{
     $resolver->setDefaults(array(
        'hours'          => range(0, 256),
        'minutes'        => range(0, 59),
        'error_bubbling' => false,
        'compound'       => true,
        'required'       => false
    ));

}

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

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

}

Usage:

$builder
    ->add('estimated', 'duration')