I'm using the default assert File :
/**
* @Assert\NotBlank()
* @Assert\File(
* mimeTypes={
* "application/pdf",
* "image/jpeg",
* "image/pjpeg",
*
* },
* mimeTypesMessage="The file format is not correct",
* maxSize="1M",
* )
* @var File $file
*/
private $file;
I verify if the file size is less the 1M . But what if i want to create a configuration in a config file like:
//yml file
max_size_file : 1
and use the value in the assertion.
I know that is need to create a custom validation as service and inject the container to get the config value from the parameters or config file .it 's seems something like :
/**
*
*@Assert\myConstraint()
*/
private $file
any help please .
Thank you in advance .
Here is the solution :
first let's make a config value in the parameter file :
//parameters.yml
max_file_size_upload: 2 // the unit is MEGABYTE
the unit value is MB , so check the factorizeSize methd in FileSizeValidator if you wanna custom your own logic
To implement a custom validator , symfony offer you to create a class for the constraint and to other one for the validation of the constraint , so let's first create the constraint class:
<?php
namespace Acme\AppBundleBundle\Service\Validation;
use Symfony\Component\Validator\Constraint;
/**
* the Max file size upload constraint
*
* @Annotation
* Class FileSize
* @package Acme\AppBundle\Service\Validation
*/
class FileSize extends Constraint
{
/**
* @var string the message error if the file {{size}} uploaded is greater than {{limit}}
*
* {{size}} the file upload size
* {{limit}} max_file_size_upload in the parameters.(env).yml
*
* in case of custom the error message, add the maxSizeMessage attribute the the assertion :
* @example :
*
* maxSizeMessage= "you custom message ({{ size }} ). you custom message {{ limit }} ."
*
*/
public $maxSizeMessage = 'The file is too large ({{ size }} M). Allowed maximum size is {{ limit }} M.';
}
the validator class of the constraint :
<?php
namespace Acme\AppBundle\Service\Validation;
use Symfony\Component\HttpFoundation\File\UploadedFile;
use Symfony\Component\Validator\Constraint;
use Symfony\Component\Validator\ConstraintValidator;
use Symfony\Component\Validator\Exception\UnexpectedTypeException;
/**
*
* Class FileSizeValidator
* @package Acme\AppBundle\Service\Validation
*/
class FileSizeValidator extends ConstraintValidator
{
const CONVERT_MB_TO_B = "MBTOB";
const CONVERT_B_TO_MB = "BTOMB";
private $_maxFileSizeUpload;
public function __construct($maxFileSizeUpload)
{
$this->_maxFileSizeUpload = $maxFileSizeUpload;
}
/**
* @param mixed $value
* @param Constraint $constraint
*/
public function validate($value, Constraint $constraint)
{
if (!$constraint instanceof FileSize) {
throw new UnexpectedTypeException($constraint, __NAMESPACE__.'\FileSize');
}
if($value instanceof UploadedFile){
if($this->_maxFileSizeUpload < $this->factorizeSize($value->getClientSize())){
$this->context->buildViolation($constraint->maxSizeMessage)
->setParameter('{{ size }}', $this->factorizeSize($value->getClientSize(),self::CONVERT_B_TO_MB))
->setParameter('{{ limit }}', $this->_maxFileSizeUpload)
->addViolation();
}
}
return;
}
/**
* @param $size
* @param string $convert
* @return float|int
*/
protected function factorizeSize($size,$convert =self::CONVERT_MB_TO_B){
$size = intval($size);
if($convert == self::CONVERT_MB_TO_B){
return $size*pow(10,6);
}
else{
return intval($size/pow(10,6));
}
}
}
The validator should be declared as service to inject the parameter value , so we need to add it in the service.yml :
fileSizeValidator.service:
class: Acme\AppBundle\Service\Validation\FileSizeValidator
arguments: [%max_file_size_upload%]
tags:
- name: validator.constraint_validator
alias: file_size_correct
The alias : file_size_correct is the value tha your method validateBy sould return in the FileSize Class , because your Validator is now service , if not , your constraint can't find the Validator class . see the official doc [here][1]
use the constraint :
/**
* @MyAssert\FileSize()
*
* @var File $file
*/
protected $file;
hope this help you .