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
If you're using the default services.yaml configuration , Symfony will automatically know to pass your TaskType an instance of the IssueToNumberTransformer thanks to autowire and autoconfigure . Otherwise, register the form class as a service and tag it with the form.type tag.
You can also validate all the classes stored in a given directory: The Symfony validator is a powerful tool that can be leveraged to guarantee that the data of any object is "valid". The power behind validation lies in "constraints", which are rules that you can apply to properties or getter methods of your object.
Symfony's validator uses PHP reflection, as well as "getter" methods, to get the value of any property, so they can be public, private or protected (see Validation ). Next, to actually validate an Author object, use the validate () method on the validator service (which implements ValidatorInterface ).
Internally, a data transformer converts the starting DateTime value of the field into the yyyy-MM-dd string to render the form, and then back into a DateTime object on submit. When a form field has the inherit_data option set to true, data transformers are not applied to that field.
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....
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With