Reputation: 4316
Edit: here's a github with the 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;
}
With 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 following 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 a correct image, and the form is correctly saved in database.
However if I submit an incorrect image (for example a .txt file), the form is still saved in database without any error
However if I remove the addModelTransformer
from the Form, then I got the correct validation error
This file is not a valid image
as my transformer does not modify the original imageFile
field, I'm wondering what could cause this problem.
I'm using php7 and symfony3.3.4
Upvotes: 5
Views: 893
Reputation: 4316
The answer was actually pretty stupid
The reason was that I forgot a return in the 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 was causing the whole entity in the form model to be transformed as "null" BUT the entity itself was not destroyed because I had still reference to it in the controller as it was created through the standard
public function createAction(Request $request)
{
$place = new Place();
$form = $this->createForm(AdminPlaceType::class, $place);
$form->handleRequest($request);
}
so the $place
was containing the correct data, and the form having null
it was not triggering validation....
Upvotes: 3
Reputation: 244
To cause a validation error, throw a TransformationFailedException. But the message you pass to this exception won't be shown to the user. You'll set that message with the invalid_message option (see below). https://symfony.com/doc/current/form/data_transformers.html
Upvotes: 0
Reputation: 4468
Your transformer is replacing a UploadFile
or File
object by MyImage
entity. I assume your MyImage
is not extending File
or UploadFile
. This is not the intended use for a transformer. A transformer change one input to another type of input.
I would recommend to remove the transformer and add the code of the transformer into Place->setImageFile
. Then you will have the imageFile validation as expected and every time you change the image by another file you will recreate your MyImage
even when you are not using the form.
If you really want to do that in the form code and not in the Place entity code you should use the FormEvents https://symfony.com/doc/current/form/events.html FormEvents::POST_SET_DATA
Upvotes: 2