Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

[Validator] improved image validator

  • Loading branch information...
commit b0306242cc9bb9f28b2eaa69b1529e9f41daee53 1 parent 63e6368
@lmammino lmammino authored fabpot committed
View
5 src/Symfony/Component/Validator/CHANGELOG.md
@@ -1,6 +1,11 @@
CHANGELOG
=========
+2.4.0
+-----
+
+ * added `minRatio`, `maxRatio`, `allowSquare`, `allowLandscape`, and `allowPortrait` to Image validator
+
2.3.0
-----
View
10 src/Symfony/Component/Validator/Constraints/Image.php
@@ -23,6 +23,11 @@ class Image extends File
public $maxWidth = null;
public $maxHeight = null;
public $minHeight = null;
+ public $maxRatio = null;
+ public $minRatio = null;
+ public $allowSquare = true;
+ public $allowLandscape = true;
+ public $allowPortrait = true;
public $mimeTypesMessage = 'This file is not a valid image.';
public $sizeNotDetectedMessage = 'The size of the image could not be detected.';
@@ -30,4 +35,9 @@ class Image extends File
public $minWidthMessage = 'The image width is too small ({{ width }}px). Minimum width expected is {{ min_width }}px.';
public $maxHeightMessage = 'The image height is too big ({{ height }}px). Allowed maximum height is {{ max_height }}px.';
public $minHeightMessage = 'The image height is too small ({{ height }}px). Minimum height expected is {{ min_height }}px.';
+ public $maxRatioMessage = 'The image ratio is too big ({{ ratio }}). Allowed maximum ratio is {{ max_ratio }}.';
+ public $minRatioMessage = 'The image ratio is too small ({{ ratio }}). Minimum ratio expected is {{ min_ratio }}.';
+ public $allowSquareMessage = 'The image is square ({{ width }}x{{ height }}px). Square images are not allowed.';
+ public $allowLandscapeMessage = 'The image is landscape oriented ({{ width }}x{{ height }}px). Landscape oriented images are not allowed.';
+ public $allowPortraitMessage = 'The image is portrait oriented ({{ width }}x{{ height }}px). Portrait oriented images are not allowed.';
}
View
54 src/Symfony/Component/Validator/Constraints/ImageValidator.php
@@ -38,7 +38,9 @@ public function validate($value, Constraint $constraint)
}
if (null === $constraint->minWidth && null === $constraint->maxWidth
- && null === $constraint->minHeight && null === $constraint->maxHeight) {
+ && null === $constraint->minHeight && null === $constraint->maxHeight
+ && null === $constraint->minRatio && null === $constraint->maxRatio
+ && $constraint->allowSquare && $constraint->allowLandscape && $constraint->allowPortrait) {
return;
}
@@ -109,5 +111,55 @@ public function validate($value, Constraint $constraint)
));
}
}
+
+ $ratio = $width / $height;
+
+ if (null !== $constraint->minRatio) {
+ if (!is_numeric((string) $constraint->minRatio)) {
+ throw new ConstraintDefinitionException(sprintf('"%s" is not a valid minimum ratio', $constraint->minRatio));
+ }
+
+ if ($ratio < $constraint->minRatio) {
+ $this->context->addViolation($constraint->minRatioMessage, array(
+ '{{ ratio }}' => $ratio,
+ '{{ min_ratio }}' => $constraint->minRatio
+ ));
+ }
+ }
+
+ if (null !== $constraint->maxRatio) {
+ if (!is_numeric((string) $constraint->maxRatio)) {
+ throw new ConstraintDefinitionException(sprintf('"%s" is not a valid maximum ratio', $constraint->maxRatio));
+ }
+
+ if ($ratio > $constraint->maxRatio) {
+ $this->context->addViolation($constraint->maxRatioMessage, array(
+ '{{ ratio }}' => $ratio,
+ '{{ max_ratio }}' => $constraint->maxRatio
+ ));
+ }
+ }
+
+ if (!$constraint->allowSquare && $width == $height) {
+ $this->context->addViolation($constraint->allowSquareMessage, array(
+ '{{ width }}' => $width,
+ '{{ height }}' => $height
+ ));
+ }
+
+ if (!$constraint->allowLandscape && $width > $height) {
+ $this->context->addViolation($constraint->allowLandscapeMessage, array(
+ '{{ width }}' => $width,
+ '{{ height }}' => $height
+ ));
+ }
+
+ if (!$constraint->allowPortrait && $width < $height) {
+ $this->context->addViolation($constraint->allowPortraitMessage, array(
+ '{{ width }}' => $width,
+ '{{ height }}' => $height
+ ));
+ }
+
}
}
View
BIN  src/Symfony/Component/Validator/Tests/Constraints/Fixtures/test_landscape.gif
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
BIN  src/Symfony/Component/Validator/Tests/Constraints/Fixtures/test_portrait.gif
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
141 src/Symfony/Component/Validator/Tests/Constraints/ImageValidatorTest.php
@@ -20,6 +20,8 @@ class ImageValidatorTest extends \PHPUnit_Framework_TestCase
protected $validator;
protected $path;
protected $image;
+ protected $imageLandscape;
+ protected $imagePortrait;
protected function setUp()
{
@@ -27,6 +29,8 @@ protected function setUp()
$this->validator = new ImageValidator();
$this->validator->initialize($this->context);
$this->image = __DIR__.'/Fixtures/test.gif';
+ $this->imageLandscape = __DIR__.'/Fixtures/test_landscape.gif';
+ $this->imagePortrait = __DIR__.'/Fixtures/test_portrait.gif';
}
public function testNullIsValid()
@@ -223,4 +227,141 @@ public function testInvalidMaxHeight()
$this->validator->validate($this->image, $constraint);
}
+
+ public function testRatioTooSmall()
+ {
+ if (!class_exists('Symfony\Component\HttpFoundation\File\File')) {
+ $this->markTestSkipped('The "HttpFoundation" component is not available');
+ }
+
+ $constraint = new Image(array(
+ 'minRatio' => 2,
+ 'minRatioMessage' => 'myMessage',
+ ));
+
+ $this->context->expects($this->once())
+ ->method('addViolation')
+ ->with('myMessage', array(
+ '{{ ratio }}' => 1,
+ '{{ min_ratio }}' => 2,
+ ));
+
+ $this->validator->validate($this->image, $constraint);
+ }
+
+ public function testRatioTooBig()
+ {
+ if (!class_exists('Symfony\Component\HttpFoundation\File\File')) {
+ $this->markTestSkipped('The "HttpFoundation" component is not available');
+ }
+
+ $constraint = new Image(array(
+ 'maxRatio' => 0.5,
+ 'maxRatioMessage' => 'myMessage',
+ ));
+
+ $this->context->expects($this->once())
+ ->method('addViolation')
+ ->with('myMessage', array(
+ '{{ ratio }}' => 1,
+ '{{ max_ratio }}' => 0.5,
+ ));
+
+ $this->validator->validate($this->image, $constraint);
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Validator\Exception\ConstraintDefinitionException
+ */
+ public function testInvalidMinRatio()
+ {
+ if (!class_exists('Symfony\Component\HttpFoundation\File\File')) {
+ $this->markTestSkipped('The "HttpFoundation" component is not available');
+ }
+
+ $constraint = new Image(array(
+ 'minRatio' => '1abc',
+ ));
+
+ $this->validator->validate($this->image, $constraint);
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Validator\Exception\ConstraintDefinitionException
+ */
+ public function testInvalidMaxRatio()
+ {
+ if (!class_exists('Symfony\Component\HttpFoundation\File\File')) {
+ $this->markTestSkipped('The "HttpFoundation" component is not available');
+ }
+
+ $constraint = new Image(array(
+ 'maxRatio' => '1abc',
+ ));
+
+ $this->validator->validate($this->image, $constraint);
+ }
+
+ public function testSquareNotAllowed()
+ {
+ if (!class_exists('Symfony\Component\HttpFoundation\File\File')) {
+ $this->markTestSkipped('The "HttpFoundation" component is not available');
+ }
+
+ $constraint = new Image(array(
+ 'allowSquare' => false,
+ 'allowSquareMessage' => 'myMessage',
+ ));
+
+ $this->context->expects($this->once())
+ ->method('addViolation')
+ ->with('myMessage', array(
+ '{{ width }}' => 2,
+ '{{ height }}' => 2,
+ ));
+
+ $this->validator->validate($this->image, $constraint);
+ }
+
+ public function testLandscapeNotAllowed()
+ {
+ if (!class_exists('Symfony\Component\HttpFoundation\File\File')) {
+ $this->markTestSkipped('The "HttpFoundation" component is not available');
+ }
+
+ $constraint = new Image(array(
+ 'allowLandscape' => false,
+ 'allowLandscapeMessage' => 'myMessage',
+ ));
+
+ $this->context->expects($this->once())
+ ->method('addViolation')
+ ->with('myMessage', array(
+ '{{ width }}' => 2,
+ '{{ height }}' => 1,
+ ));
+
+ $this->validator->validate($this->imageLandscape, $constraint);
+ }
+
+ public function testPortraitNotAllowed()
+ {
+ if (!class_exists('Symfony\Component\HttpFoundation\File\File')) {
+ $this->markTestSkipped('The "HttpFoundation" component is not available');
+ }
+
+ $constraint = new Image(array(
+ 'allowPortrait' => false,
+ 'allowPortraitMessage' => 'myMessage',
+ ));
+
+ $this->context->expects($this->once())
+ ->method('addViolation')
+ ->with('myMessage', array(
+ '{{ width }}' => 1,
+ '{{ height }}' => 2,
+ ));
+
+ $this->validator->validate($this->imagePortrait, $constraint);
+ }
}
Please sign in to comment.
Something went wrong with that request. Please try again.