How to use Assert\File and Assert\Image at the same time in Symfony?

Viewed 2855

I'm trying to validate a file upload with 2 conditions:

  1. Only allowed to upload image file or PDF file

  2. Max width with Image file is 160px and no requirement with PDF file

I used "Constraints" of Symfony but when I upload a PDF file, it said that

This file is not a valid image.

Because I used both Assert\Image and Assert\File at the same time, so it will check whether the file is image or not first.

But What I want is that when I upload a file, it will check Assert\File first. If it's an image, then it will check Assert\Image. How can I do?

Here is my code at Entity:

   /**
     * @Vich\UploadableField(mapping="ad", fileNameProperty="imageFile")
     * @var File
     * @Assert\File(
     *     mimeTypes = {"application/pdf", "application/x-pdf", "image/png", "image/jpeg", "image/svg+xml"},
     *     mimeTypesMessage = "You can only be allowed to upload Image file or PDF file"
     * )
     * @Assert\Image(
     *     maxWidth = 160
     * )
     */
    private $image;
2 Answers

Another approach could be to check this in an form-event

use Symfony\Component\Validator\ConstraintViolation;
use Symfony\Component\Validator\Validator\ValidatorInterface;
use Symfony\Component\Validator\Constraints as Assert;

private $validator;

public function __construct(ValidatorInterface $validator)
{
    $this->validator = $validator;
}

public function buildForm(FormBuilderInterface $builder, array $options)
{
    // Add the fields

    $builder->addEventListener(FormEvents::PRE_SUBMIT, function (FormEvent $event) {
        $data = $event->getData();

        if (// check mimetype of $data['image'] is an image) {
            $imageConstraint = new Assert\Image(['maxWidth' => 160]);

            $errors = $this->validator->validate($data['image'], $imageConstraint);

            if ($errors) {
                /** @var ConstraintViolation $error */
                foreach ($errors as $error) {
                    $event->getForm()->get('image')->addError(new FormError($error->getMessage()));
                }
            }
        }
    });
}
Related