Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Symfony2 form field constraints validation before Data Transformer

I have created form which requires data transformer, but got myself into single problem: I transform data by exploding string (string should be be exploded to 3 parts), everything works, if I supply correct format string, but otherwise it throws error inside data transformer, because transformation cannot occur if wrong string format is supplied (this is expected behavior).

So the question is is there a way to validate form field for correct string before data transformation? I know that data transformation by default occurs before validation, but maybe there's a way to do it other way around?

I found one solution that might work on this thread: Combine constraints and data transformers , but it's looks like rough solution, besides I need to translate validation message, and I would really like to do it using default translation methods for symfony forms (without using translation service)

I thought, and also someone from symfony IRC (Iltar) suggested do it by using events, but I'm not sure how to go about this - how to attach data transformer dynamically to form field? Or maybe there's other way?

like image 778
antanas_sepikas Avatar asked Jul 15 '14 07:07

antanas_sepikas


1 Answers

It's maybe too late but I eventually manage to do it. Maybe it will help you.

Here is my FormType:

class PersonType extends AbstractType{

    public function buildForm(FormBuilderInterface $builder, array $options){
        $builder->add('mother', 'personSelector', array('personEntity' => $options['personEntity']));

    }
}

Here is my customField where are validations:

class PersonSelectorType extends AbstractType{

    public function buildForm(FormBuilderInterface $builder, array $options){
        $transformer = new PersonByFirstnameAndLastnameTransformer($this->entityManager,$options);
        $builder->addModelTransformer($transformer);
        $builder->addEventListener(FormEvents::PRE_SUBMIT, array($this, 'onPreSubmitForm'));
    }

    public function onPreSubmitForm(FormEvent $event){
        $mother     = $event->getData();
        $form       = $event->getForm();
        $options    = $form->getConfig()->getOptions();
        if (!empty($mother)){
            preg_match('#(.*) (.*)#', $mother, $personInformations);
            if (count($personInformations) != 3){
                $form->addError(new FormError('[Format incorrect] Le format attendu est "Prénom Nom".'));
            }else{
                $person = $this->entityManager->getRepository($options['personEntity'])->findOneBy(array('firstname' => $personInformations[1],'lastname' =>$personInformations[2]));
                if ($person === null) {
                    $form->addError(new FormError('Il n\'existe pas de person '.$personInformations[1].' '.$personInformations[2].'.'));
                }
            }
        }
    }
}

Here is my transformer:

class PersonByFirstnameAndLastnameTransformer implements DataTransformerInterface{

    public function reverseTransform($firstnameAndLastname) {
        if (empty($firstnameAndLastname)) { return null; }
        preg_match('#(.*) (.*)#', $firstnameAndLastname, $personInformations);
        $person = $this->entityManager->getRepository($this->options['personEntity'])->findOneBy(array('firstname' =>$personInformations[1],'lastname' =>$personInformations[2]));
        if (count($personInformations) == 3){
            $person = $this->entityManager->getRepository($this->options['personEntity'])->findOneBy(array('firstname' =>$personInformations[1],'lastname' =>$personInformations[2]));
        }
        return $person;
    }

    public function transform($person) {
        if ($person === null) { return ''; }
        return $person->getFirstname().' '.$person->getLastname();
    }
}
like image 69
emottet Avatar answered Oct 15 '22 22:10

emottet