From 0e527d56788dc753d10d25240a43415f8b1430d6 Mon Sep 17 00:00:00 2001 From: Charles Sarrazin Date: Fri, 16 May 2014 16:52:36 +0200 Subject: [PATCH] Added option for specifying the size format for the file validator This lets someone choose between binary (multiples of 1024) and decimal (multiple of 1000) formats for specifying the size --- .../Component/Validator/Constraints/File.php | 1 + .../Validator/Constraints/FileValidator.php | 22 +++++++++++++---- .../Tests/Constraints/FileValidatorTest.php | 24 +++++++++++++++---- 3 files changed, 39 insertions(+), 8 deletions(-) diff --git a/src/Symfony/Component/Validator/Constraints/File.php b/src/Symfony/Component/Validator/Constraints/File.php index 80527171ecbef..9951f07230d58 100644 --- a/src/Symfony/Component/Validator/Constraints/File.php +++ b/src/Symfony/Component/Validator/Constraints/File.php @@ -25,6 +25,7 @@ class File extends Constraint { public $maxSize = null; public $mimeTypes = array(); + public $sizeFormat = FileValidator::SIZE_FORMAT_DECIMAL; public $notFoundMessage = 'The file could not be found.'; public $notReadableMessage = 'The file is not readable.'; public $maxSizeMessage = 'The file is too large ({{ size }} {{ suffix }}). Allowed maximum size is {{ limit }} {{ suffix }}.'; diff --git a/src/Symfony/Component/Validator/Constraints/FileValidator.php b/src/Symfony/Component/Validator/Constraints/FileValidator.php index 5f499810e6517..f98979406845b 100644 --- a/src/Symfony/Component/Validator/Constraints/FileValidator.php +++ b/src/Symfony/Component/Validator/Constraints/FileValidator.php @@ -25,6 +25,14 @@ */ class FileValidator extends ConstraintValidator { + const SIZE_FORMAT_BINARY = 'binary'; + const SIZE_FORMAT_DECIMAL = 'decimal'; + + private $sizeFormats = array( + self::SIZE_FORMAT_BINARY => 1024, + self::SIZE_FORMAT_DECIMAL => 1000, + ); + /** * {@inheritdoc} */ @@ -34,6 +42,12 @@ public function validate($value, Constraint $constraint) return; } + if (!array_key_exists($constraint->sizeFormat, $this->sizeFormats)) { + throw new ConstraintDefinitionException(sprintf('"%s" is not a valid size format', $constraint->sizeFormat)); + } + + $formatSize = $this->sizeFormats[$constraint->sizeFormat]; + if ($value instanceof UploadedFile && !$value->isValid()) { switch ($value->getError()) { case UPLOAD_ERR_INI_SIZE: @@ -41,9 +55,9 @@ public function validate($value, Constraint $constraint) if (ctype_digit((string) $constraint->maxSize)) { $maxSize = (int) $constraint->maxSize; } elseif (preg_match('/^\d++k$/', $constraint->maxSize)) { - $maxSize = $constraint->maxSize * 1024; + $maxSize = $constraint->maxSize * $formatSize; } elseif (preg_match('/^\d++M$/', $constraint->maxSize)) { - $maxSize = $constraint->maxSize * 1048576; + $maxSize = $constraint->maxSize * pow($formatSize, 2); } else { throw new ConstraintDefinitionException(sprintf('"%s" is not a valid maximum size', $constraint->maxSize)); } @@ -113,11 +127,11 @@ public function validate($value, Constraint $constraint) $limit = (int) $constraint->maxSize; $suffix = 'bytes'; } elseif (preg_match('/^\d++k$/', $constraint->maxSize)) { - $size = round(filesize($path) / 1000, 2); + $size = round(filesize($path) / $formatSize, 2); $limit = (int) $constraint->maxSize; $suffix = 'kB'; } elseif (preg_match('/^\d++M$/', $constraint->maxSize)) { - $size = round(filesize($path) / 1000000, 2); + $size = round(filesize($path) / pow($formatSize, 2), 2); $limit = (int) $constraint->maxSize; $suffix = 'MB'; } else { diff --git a/src/Symfony/Component/Validator/Tests/Constraints/FileValidatorTest.php b/src/Symfony/Component/Validator/Tests/Constraints/FileValidatorTest.php index 0ca98067d324d..237338905d1f0 100644 --- a/src/Symfony/Component/Validator/Tests/Constraints/FileValidatorTest.php +++ b/src/Symfony/Component/Validator/Tests/Constraints/FileValidatorTest.php @@ -107,13 +107,17 @@ public function testTooLargeBytes() $this->validator->validate($this->getFile($this->path), $constraint); } - public function testTooLargeKiloBytes() + /** + * @dataProvider sizeFormatProvider + */ + public function testTooLargeKiloBytes($sizeFormat, $size) { - fwrite($this->file, str_repeat('0', 1400)); + fwrite($this->file, str_repeat('0', 1.4 * $size)); $constraint = new File(array( 'maxSize' => '1k', 'maxSizeMessage' => 'myMessage', + 'sizeFormat' => $sizeFormat, )); $this->context->expects($this->once()) @@ -128,13 +132,17 @@ public function testTooLargeKiloBytes() $this->validator->validate($this->getFile($this->path), $constraint); } - public function testTooLargeMegaBytes() + /** + * @dataProvider sizeFormatProvider + */ + public function testTooLargeMegaBytes($sizeFormat, $size) { - fwrite($this->file, str_repeat('0', 1400000)); + fwrite($this->file, str_repeat('0', 1.4 * pow($size, 2))); $constraint = new File(array( 'maxSize' => '1M', 'maxSizeMessage' => 'myMessage', + 'sizeFormat' => $sizeFormat, )); $this->context->expects($this->once()) @@ -305,6 +313,14 @@ public function testUploadedFileError($error, $message, array $params = array(), } + public function sizeFormatProvider() + { + return array( + array('binary', 1024), + array('decimal', 1000), + ); + } + public function uploadedFileErrorProvider() { $tests = array(