Search code examples
phpsymfonysymfony-formsmultifile-uploader

Symfony multiple Files total max size constraint


The task

The situation is quite typical: I want to allow user to upload multiple files in one form, but total size of all files should not exceed 50 MB.

The code

<?php

namespace Acme\SiteBundle\Form;

use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\FileType;
use Symfony\Component\Form\FormBuilderInterface;

class UploadFilesType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('attachedFiles', FileType::class, [
                'multiple' => true,
                'attr' => [
                    'accept' => '*/*',
                    'multiple' => 'multiple',
                ],
            ])
            ->setMethod('POST');
    }

    public function getBlockPrefix()
    {
        return 'uploadFilesForm';
    }
}

And the corresponding Form Data class.

<?php

namespace Acme\SiteBundle\Form;

use Symfony\Component\HttpFoundation\File\UploadedFile;
use Symfony\Component\Validator\Constraints as Assert;

class UploadFilesDataType
{

    /**
     * @Assert\All({
     *      @Assert\File(maxSize="50M", maxSizeMessage="File size limit exceeds 50 MB")
     * })
     */
    private $attachedFiles;

    /**
     * @return UploadedFile[]
     */
    public function getAttachedFiles()
    {
        return $this->attachedFiles;
    }

    /**
     * @param UploadedFile[] $attachedFiles
     */
    public function setAttachedFiles($attachedFiles)
    {
        $this->attachedFiles = $attachedFiles;
    }

    /**
     * @param UploadedFile $attachedFile
     */
    public function addAttachedFile($attachedFile)
    {
        $this->attachedFiles[] = $attachedFile;
    }
}

Constraints are defined through FormData class' annotations, but could be obviously rewritten to be included in the Form class buildForm() method.

The problem

The File constraint, which contains maxSize facet can be applied directly to single uploaded file field, but when it goes to multiple uploaded files, then one has to use the All constraint. However, with the All constraint one can only define constraint per each element in collection of files (e.g. size of individual uploaded file).

How can one verify total files size? Is there some combination of existing constraints provided by Symfony? Should one resort to writing her own field validation callback?


Solution

  • In that case, you can create your own validator and apply it to the entire class.