Symfony3 form validation not used for field use by model transformer

Edit: here is github with full code to reproduce the problem

I have the following entity

class Place { use Traits\HasId; /** * Used for form. * * @Assert\Image( * mimeTypes = {"image/png", "image/jpeg"}, * minWidth = 50, * maxWidth = 1000, * minHeight = 50, * maxHeight = 1000, * maxSize = "1M" * ) */ private $imageFile = null; /** * @ORM\OneToOne(targetEntity="MyImage", orphanRemoval=true, cascade={"persist"}) */ protected $image; } 

In the following form

 class AdminPlaceType extends AbstractType { public function buildForm(FormBuilderInterface $builder, array $options) { $transformer = new HasImageTransformer(); $builder->add('imageFile')->addModelTransformer($transformer); } public function configureOptions(OptionsResolver $resolver) { $resolver->setDefaults(['data_class' => 'AppBundle\Entity\Place']); } } 

And the next model transformer

 class HasImageTransformer implements DataTransformerInterface { public function transform($hasImage) { return $hasImage; } /** * reverse transforms. */ public function reverseTransform($hasImage) { $file = $hasImage->getImageFile(); $myImage = new MyImage(); $myImage->setData(file_get_contents($file->getPathName())) $myImage->setMimeType($file->getMimeType()); $hasImage->setImage($myImage); } } 

I can upload the correct image and the form will be saved to the database correctly.

However, if I submit an incorrect image (for example, a .txt file), the form is saved in the database without errors

However, if I remove addModelTransformer from the form, then I got the correct validation error

This file is not a valid image.

since my transformer does not change the original imageFile field, I wonder what might cause this problem.

I am using php7 and symfony3.3.4

+5
source share
3 answers

The answer was really pretty dumb

The reason is that I forgot about returning to reverseTransform

 /** * reverse transforms. */ public function reverseTransform($hasImage) { $file = $hasImage->getImageFile(); $myImage = new MyImage(); $myImage->setData(file_get_contents($file->getPathName())) $myImage->setMimeType($file->getMimeType()); $hasImage->setImage($myImage); // this was missing :( return $hasImage; } 

This led to the fact that the entire object in the form model was transformed as "null", but the object itself was not destroyed, because I still referenced it in the controller, since it was created using the standard

  public function createAction(Request $request) { $place = new Place(); $form = $this->createForm(AdminPlaceType::class, $place); $form->handleRequest($request); } 

therefore, $place contained the correct data, and a form that was null did not cause validation.

+3
source

Your transformer replaces the UploadFile or File object with the MyImage object. I assume that your MyImage does not extend File or UploadFile . It is not intended for a transformer. The transformer changes one input to another type of input.

I would recommend removing the transformer and adding the transformer code to Place->setImageFile . Then you will have the imageFile validation as expected, and each time you change the image with another file, you again create your MyImage , even if you are not using the form.

If you really want to do this in the form code, and not in the code of the Place object, you should use FormEvents https://symfony.com/doc/current/form/events.html FormEvents :: POST_SET_DATA

+2
source

To raise a validation error, throw a TransformationFailedException. But the message you pass to this exception will not be shown to the user. You install this message with the invalid_message option (see below). https://symfony.com/doc/current/form/data_transformers.html

0
source

Source: https://habr.com/ru/post/1269914/


All Articles