Validate uploaded file with Symfony Constraints

Table of Content

Symfony is a flexible framework and not always is possible to find the best solution for your task, but sometimes there is no "the best" solution and you should choose what suits you.

I spent some time to figure out how to validate the uploaded file with Symfony Constraints. There is a lot of information on the Internet but leave it here to simplify the search in the future.

Create action

Variant A

use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\File\UploadedFile;
use Symfony\Component\Validator\Validator\ValidatorInterface;
// ...
public function editPhotoAction(Request $request, ValidatorInterface $validator)
{
    /** @var UploadedFile $file */
    $file = $request->files->get('file');

    $dto = new PhotoDto();
    $dto->file = $file;
    if (count($errors = $validator->validate($dto))) {
        throw new ValidationException($errors);
    }

    // custom logic here
    // $this->getPhotoService()->uploadPhoto($dto->file);

    return new Respose(/* your content */);
}

Variant B

use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\File\UploadedFile;
use Symfony\Component\Validator\Validator\ValidatorInterface;
use Symfony\Component\Validator\Constraints\Image;
// ...
public function editPhotoAction(Request $request, ValidatorInterface $validator)
{
    /** @var UploadedFile $file */
    $file = $request->files->get('file');

    $errors = $validator->validate($file, new Image([
        'maxSize' => "10M",
        'minWidth' => 200,
        'maxWidth' => 5000,
        'minHeight' => 200,
        'maxHeight' => 5000,
        'mimeTypes' => [
            "image/jpeg",
            "image/jpg",
            "image/png",
            "image/gif",
        ],
    ]));

    if (count($errors)) {
        throw new ValidationException($errors);
    }

    // custom logic here
    // $this->getPhotoService()->uploadPhoto($file);

    return new Respose(/* your content */);
}

This variant is not flexible and not recommended to use, but I thought it was correct to describe possible solutions for this task.

Create PhotoDto

Domain Transfer Object (DTO) helps us to simplify validation logic and reuse it somewhere else. Why Syfmon\Form is not the best solution for it, especially in Restful API, you can read in Trading Symfony’s Form Component for Data Transfer Objects

use Symfony\Component\Validator\Constraints as Assert;

class PhotoDto
{
    /**
     * @Assert\Image(
     *     maxSize = "10M",
     *     minWidth = 200,
     *     maxWidth = 5000,
     *     minHeight = 200,
     *     maxHeight = 5000,
     *     mimeTypes = {
     *      "image/jpeg",
     *      "image/jpg",
     *      "image/png",
     *      "image/gif"
     *     }
     * )
     */
    public $file;
}

Note: You can use constant in annotations as well.

Leave a Reply

Your email address will not be published. Required fields are marked *