merged branch benjamindulau/ImageValidator (PR #1214)

Commits
-------

89f4791 Fixed CS
a348efe Removed trailing whitespaces
135531a Replaced setExpectedException() methods by annotations
6ad83e7 Updated according to PR review
2de243c * Added Fixtures 2x2px test.gif image file * Updated tests for using fixture image instead of imagecreate function
a5a2dfa [ImageValidator] Added dedicated ImageValidator class with min width, max width, min height and max height validations

Discussion
----------

[2.1] [ImageValidator] Improved ImageValidator + tests

Added dedicated ImageValidator class with min width, max width, min height and max height validations

---------------------------------------------------------------------------

by kriswallsmith at 2011/06/04 10:32:56 -0700

This is nice but doesn't belong in the core as it adds a dependency on GD.

---------------------------------------------------------------------------

by benjamindulau at 2011/06/04 10:41:02 -0700

@kriswallsmith i'm not sure, php.net doc says :

    Note:

    This function does not require the GD image library.

Well, that could also be a mistake :)

---------------------------------------------------------------------------

by pborreli at 2011/06/04 11:17:25 -0700

i think @benjamindulau is right

```
$ php -m
[PHP Modules]
bcmath
calendar
com_dotnet
Core
ctype
date
dom
ereg
filter
ftp
hash
iconv
json
libxml
mcrypt
mhash
mysqlnd
odbc
pcre
PDO
Phar
Reflection
session
SimpleXML
SPL
sqlite3
standard
tokenizer
wddx
xdebug
xml
xmlreader
xmlwriter
zip
zlib
```

```
$ php -r "var_dump(getimagesize(__DIR__.'/src/Symfony/Bundle/FrameworkBund
le/Resources/public/images/blue_picto_less.gif'));"
array(7) {
  [0]=>
  int(18)
  [1]=>
  int(18)
  [2]=>
  int(1)
  [3]=>
  string(22) "width="18" height="18""
  ["bits"]=>
  int(5)
  ["channels"]=>
  int(3)
  ["mime"]=>
  string(9) "image/gif"
}
```

---------------------------------------------------------------------------

by benjamindulau at 2011/06/04 11:22:57 -0700

However, the tests use imagejpeg and imagedestroy, that's not valid.
But, i'm not sure how to correctly test the validator then.

---------------------------------------------------------------------------

by benjamindulau at 2011/06/04 11:31:51 -0700

Can i use an image from FrameworkBundle resources ?

---------------------------------------------------------------------------

by pborreli at 2011/06/06 03:47:24 -0700

just add your own image inside Fixture folder (smaller the better, 1x1, 1x2 ..)

---------------------------------------------------------------------------

by stof at 2011/09/04 05:27:42 -0700

@benjamindulau could you rebase your PR and update it according to the comments ?

---------------------------------------------------------------------------

by benjamindulau at 2011/09/04 06:31:34 -0700

Yep, i think i can find some time today to do that

---------------------------------------------------------------------------

by benjamindulau at 2011/09/04 09:27:29 -0700

I've updated the PR.

A big thank to Stof who helped me with my git mess ;-)
This commit is contained in:
Fabien Potencier 2011-09-06 08:18:07 +02:00
commit f75d8ff653
4 changed files with 286 additions and 8 deletions

View File

@ -19,13 +19,15 @@ namespace Symfony\Component\Validator\Constraints;
class Image extends File
{
public $mimeTypes = 'image/*';
public $mimeTypesMessage = 'This file is not a valid image';
public $minWidth = null;
public $maxWidth = null;
public $maxHeight = null;
public $minHeight = null;
/**
* @inheritDoc
*/
public function validatedBy()
{
return __NAMESPACE__.'\FileValidator';
}
public $mimeTypesMessage = 'This file is not a valid image';
public $sizeNotDetectedMessage = 'The size of the image could not be detected';
public $maxWidthMessage = 'The image width is too big ({{ width }}px). Allowed maximum width is {{ max_width }}px';
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 width is {{ max_eight }}px';
public $minHeightMessage = 'The image width is too small ({{ height }}px). Minimum height expected is {{ min_height }}px';
}

View File

@ -0,0 +1,113 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\Validator\Constraints;
use Symfony\Component\Validator\Constraint;
use Symfony\Component\Validator\Exception\ConstraintDefinitionException;
/**
* Validates whether a value is a valid image file and is valid
* against minWidth, maxWidth, minHeight and maxHeight constraints
*
* @author Benjamin Dulau <benjamin.dulau@gmail.com>
*/
class ImageValidator extends FileValidator
{
public function isValid($value, Constraint $constraint)
{
$isValid = parent::isValid($value, $constraint);
if (!$isValid) {
return false;
}
if (null === $value || '' === $value) {
return true;
}
if (null === $constraint->minWidth && null === $constraint->maxWidth
&& null === $constraint->minHeight && null === $constraint->maxHeight) {
return true;
}
$size = @getimagesize($value);
if (empty($size) || ($size[0] === 0) || ($size[1] === 0)) {
$this->setMessage($constraint->sizeNotDetectedMessage);
return false;
}
$width = $size[0];
$height = $size[1];
if ($constraint->minWidth) {
if (!ctype_digit((string) $constraint->minWidth)) {
throw new ConstraintDefinitionException(sprintf('"%s" is not a valid minimum width', $constraint->minWidth));
}
if ($width < $constraint->minWidth) {
$this->setMessage($constraint->minWidthMessage, array(
'{{ width }}' => $width,
'{{ min_width }}' => $constraint->minWidth
));
return false;
}
}
if ($constraint->maxWidth) {
if (!ctype_digit((string) $constraint->maxWidth)) {
throw new ConstraintDefinitionException(sprintf('"%s" is not a valid maximum width', $constraint->maxWidth));
}
if ($width > $constraint->maxWidth) {
$this->setMessage($constraint->maxWidthMessage, array(
'{{ width }}' => $width,
'{{ max_width }}' => $constraint->maxWidth
));
return false;
}
}
if ($constraint->minHeight) {
if (!ctype_digit((string) $constraint->minHeight)) {
throw new ConstraintDefinitionException(sprintf('"%s" is not a valid minimum height', $constraint->minHeight));
}
if ($height < $constraint->minHeight) {
$this->setMessage($constraint->minHeightMessage, array(
'{{ height }}' => $height,
'{{ min_height }}' => $constraint->minHeight
));
return false;
}
}
if ($constraint->maxHeight) {
if (!ctype_digit((string) $constraint->maxHeight)) {
throw new ConstraintDefinitionException(sprintf('"%s" is not a valid maximum height', $constraint->maxHeight));
}
if ($height > $constraint->maxHeight) {
$this->setMessage($constraint->maxHeightMessage, array(
'{{ height }}' => $height,
'{{ max_height }}' => $constraint->maxHeight
));
return false;
}
}
return true;
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 801 B

View File

@ -0,0 +1,163 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Tests\Component\Validator\Constraints;
use Symfony\Component\Validator\Constraints\Image;
use Symfony\Component\Validator\Constraints\ImageValidator;
class ImageValidatorTest extends \PHPUnit_Framework_TestCase
{
protected $validator;
protected $path;
protected $image;
protected function setUp()
{
$this->validator = new ImageValidator();
$this->image = __DIR__.'/Fixtures/test.gif';
}
public function testNullIsValid()
{
$this->assertTrue($this->validator->isValid(null, new Image()));
}
public function testEmptyStringIsValid()
{
$this->assertTrue($this->validator->isValid('', new Image()));
}
public function testValidImage()
{
$this->assertTrue($this->validator->isValid($this->image, new Image()));
}
public function testValidSize()
{
$constraint = new Image(array(
'minWidth' => 1,
'maxWidth' => 2,
'minHeight' => 1,
'maxHeight' => 2,
));
$this->assertTrue($this->validator->isValid($this->image, $constraint));
}
public function testWidthTooSmall()
{
$constraint = new Image(array(
'minWidth' => 3,
'minWidthMessage' => 'myMessage',
));
$this->assertFalse($this->validator->isValid($this->image, $constraint));
$this->assertEquals('myMessage', $this->validator->getMessageTemplate());
$this->assertEquals(array(
'{{ width }}' => '2',
'{{ min_width }}' => '3',
), $this->validator->getMessageParameters());
}
public function testWidthTooBig()
{
$constraint = new Image(array(
'maxWidth' => 1,
'maxWidthMessage' => 'myMessage',
));
$this->assertFalse($this->validator->isValid($this->image, $constraint));
$this->assertEquals('myMessage', $this->validator->getMessageTemplate());
$this->assertEquals(array(
'{{ width }}' => '2',
'{{ max_width }}' => '1',
), $this->validator->getMessageParameters());
}
public function testHeightTooSmall()
{
$constraint = new Image(array(
'minHeight' => 3,
'minHeightMessage' => 'myMessage',
));
$this->assertFalse($this->validator->isValid($this->image, $constraint));
$this->assertEquals('myMessage', $this->validator->getMessageTemplate());
$this->assertEquals(array(
'{{ height }}' => '2',
'{{ min_height }}' => '3',
), $this->validator->getMessageParameters());
}
public function testHeightTooBig()
{
$constraint = new Image(array(
'maxHeight' => 1,
'maxHeightMessage' => 'myMessage',
));
$this->assertFalse($this->validator->isValid($this->image, $constraint));
$this->assertEquals('myMessage', $this->validator->getMessageTemplate());
$this->assertEquals(array(
'{{ height }}' => '2',
'{{ max_height }}' => '1',
), $this->validator->getMessageParameters());
}
/**
* @expectedException \Symfony\Component\Validator\Exception\ConstraintDefinitionException
*/
public function testInvalidMinWidth()
{
$constraint = new Image(array(
'minWidth' => '1abc',
));
$this->validator->isValid($this->image, $constraint);
}
/**
* @expectedException \Symfony\Component\Validator\Exception\ConstraintDefinitionException
*/
public function testInvalidMaxWidth()
{
$constraint = new Image(array(
'maxWidth' => '1abc',
));
$this->validator->isValid($this->image, $constraint);
}
/**
* @expectedException \Symfony\Component\Validator\Exception\ConstraintDefinitionException
*/
public function testInvalidMinHeight()
{
$constraint = new Image(array(
'minHeight' => '1abc',
));
$this->validator->isValid($this->image, $constraint);
}
/**
* @expectedException \Symfony\Component\Validator\Exception\ConstraintDefinitionException
*/
public function testInvalidMaxHeight()
{
$constraint = new Image(array(
'maxHeight' => '1abc',
));
$this->validator->isValid($this->image, $constraint);
}
}