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.
<?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 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?
In that case, you can create your own validator and apply it to the entire class.