mirror of
https://github.com/Respect/Validation.git
synced 2024-06-29 02:30:06 +02:00
Fix Symfony validation rule.
The API of Symfony\Component\Validator changed more than 2 years ago, so this validation rule wasn't working for quite a long time. This fixes the validator to work with versions >= 2.1 of Symfony/Validation as the change on composer shows us. Although a bug fix, this breaks compatibility with people already using this validator. I was astonished to not find any tests for that validator also. :( With those tests we can ensure that any change on the component API will be noticed by us.
This commit is contained in:
parent
d1a2f18a80
commit
c2850055bc
|
@ -17,7 +17,7 @@
|
|||
}],
|
||||
"require-dev": {
|
||||
"zendframework/zend-validator": "2.*",
|
||||
"symfony/validator": "2.*",
|
||||
"symfony/validator": ">=2.1.0",
|
||||
"phpunit/phpunit": "3.7.*"
|
||||
},
|
||||
"suggest": {
|
||||
|
|
|
@ -2,51 +2,65 @@
|
|||
namespace Respect\Validation\Rules;
|
||||
|
||||
use ReflectionClass;
|
||||
use ReflectionException;
|
||||
use Respect\Validation\Exceptions\ComponentException;
|
||||
use Symfony\Component\Validator\Validation;
|
||||
use Symfony\Component\Validator\Constraint;
|
||||
use Symfony\Component\Validator\ConstraintViolation;
|
||||
|
||||
class Sf extends AbstractRule
|
||||
{
|
||||
const SYMFONY_CONSTRAINT_NAMESPACE = 'Symfony\Component\Validator\Constraints\%s';
|
||||
public $name;
|
||||
protected $constraint;
|
||||
protected $messages = array();
|
||||
protected $validator;
|
||||
private $constraint;
|
||||
|
||||
public function __construct($name, $params=array())
|
||||
{
|
||||
$this->name = ucfirst($name);
|
||||
$sfMirrorConstraint = new ReflectionClass(
|
||||
'Symfony\Component\Validator\Constraints\\' . $this->name
|
||||
);
|
||||
if ($sfMirrorConstraint->hasMethod('__construct')) {
|
||||
$this->constraint = $sfMirrorConstraint->newInstanceArgs($params);
|
||||
} else {
|
||||
$this->constraint = $sfMirrorConstraint->newInstance();
|
||||
$this->constraint = $this->createSymfonyConstraint($this->name, $params);
|
||||
}
|
||||
|
||||
private function createSymfonyConstraint($constraintName, $constraintConstructorParameters=array())
|
||||
{
|
||||
$fullClassName = sprintf(self::SYMFONY_CONSTRAINT_NAMESPACE, $constraintName);
|
||||
try {
|
||||
$constraintReflection = new ReflectionClass($fullClassName);
|
||||
} catch (ReflectionException $previousException) {
|
||||
$baseExceptionMessage = 'Symfony/Validator constraint "%s" does not exist.';
|
||||
$exceptionMessage = sprintf($baseExceptionMessage, $constraintName);
|
||||
throw new ComponentException($exceptionMessage, 0, $previousException);
|
||||
}
|
||||
if ($constraintReflection->hasMethod('__construct')) {
|
||||
return $constraintReflection->newInstanceArgs($constraintConstructorParameters);
|
||||
}
|
||||
|
||||
return $constraintReflection->newInstance();
|
||||
}
|
||||
|
||||
private function returnViolationsForConstraint($valueToValidate, Constraint $symfonyConstraint)
|
||||
{
|
||||
$validator = Validation::createValidator(); // You gotta love those Symfony namings
|
||||
return $validator->validateValue($valueToValidate, $symfonyConstraint);
|
||||
}
|
||||
|
||||
public function assert($input)
|
||||
{
|
||||
if (!$this->validate($input)) {
|
||||
$violation = new ConstraintViolation(
|
||||
$this->validator->getMessageTemplate(),
|
||||
$this->validator->getMessageParameters(),
|
||||
'',
|
||||
'',
|
||||
$input
|
||||
);
|
||||
throw $this->reportError($violation->getMessage());
|
||||
$violations = $this->returnViolationsForConstraint($input, $this->constraint);
|
||||
if (count($violations) == 0) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return true;
|
||||
throw $this->reportError((string) $violations);
|
||||
}
|
||||
|
||||
public function validate($input)
|
||||
{
|
||||
$validatorName = 'Symfony\Component\Validator\Constraints\\'
|
||||
. $this->name . 'Validator';
|
||||
$this->validator = new $validatorName;
|
||||
$violations = $this->returnViolationsForConstraint($input, $this->constraint);
|
||||
if (count($violations)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return $this->validator->isValid($input, $this->constraint);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
78
tests/library/Respect/Validation/Rules/SfTest.php
Normal file
78
tests/library/Respect/Validation/Rules/SfTest.php
Normal file
|
@ -0,0 +1,78 @@
|
|||
<?php
|
||||
|
||||
namespace Respect\Validation\Rules;
|
||||
|
||||
use Respect\Validation\Validator as v;
|
||||
|
||||
class SfTest extends \PHPUnit_Framework_TestCase
|
||||
{
|
||||
public function assertPreConditions()
|
||||
{
|
||||
if (false === class_exists('Symfony\Component\Validator\Constraints\Time')) {
|
||||
$this->markTestSkipped('Expected Symfony\Validator installed.');
|
||||
}
|
||||
}
|
||||
|
||||
public function testValidationWithAnExistingValidationConstraint()
|
||||
{
|
||||
$constraintName = 'Time';
|
||||
$validConstraintValue = '04:20:00';
|
||||
$invalidConstraintValue = 'yada';
|
||||
$this->assertTrue(
|
||||
v::sf($constraintName)->validate($validConstraintValue),
|
||||
sprintf('"%s" should be valid under "%s" constraint.', $validConstraintValue, $constraintName)
|
||||
);
|
||||
$this->assertFalse(
|
||||
v::sf($constraintName)->validate($invalidConstraintValue),
|
||||
sprintf('"%s" should be invalid under "%s" constraint.', $invalidConstraintValue, $constraintName)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @depends testValidationWithAnExistingValidationConstraint
|
||||
*/
|
||||
public function testAssertionWithAnExistingValidationConstraint()
|
||||
{
|
||||
$constraintName = 'Time';
|
||||
$validConstraintValue = '04:20:00';
|
||||
$this->assertTrue(
|
||||
v::sf($constraintName)->assert($validConstraintValue),
|
||||
sprintf('"%s" should be valid under "%s" constraint.', $validConstraintValue, $constraintName)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @depends testAssertionWithAnExistingValidationConstraint
|
||||
*/
|
||||
public function testAssertionMessageWithAnExistingValidationConstraint()
|
||||
{
|
||||
$constraintName = 'Time';
|
||||
$invalidConstraintValue = '34:90:70';
|
||||
try {
|
||||
v::sf($constraintName)->assert($invalidConstraintValue);
|
||||
} catch (\Respect\Validation\Exceptions\AllOfException $exception) {
|
||||
$fullValidationMessage = $exception->getFullMessage();
|
||||
$expectedValidationException = <<<EOF
|
||||
\-These rules must pass for "34:90:70"
|
||||
\-Time
|
||||
EOF;
|
||||
return $this->assertEquals(
|
||||
$expectedValidationException,
|
||||
$fullValidationMessage,
|
||||
'Exception message is different from the one expected.'
|
||||
);
|
||||
}
|
||||
$this->fail('Validation exception expected to compare message.');
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException Respect\Validation\Exceptions\ComponentException
|
||||
* @expectedExceptionMessage Symfony/Validator constraint "FluxCapacitor" does not exist.
|
||||
*/
|
||||
public function testValidationWithNonExistingConstraint()
|
||||
{
|
||||
$fantasyConstraintName = 'FluxCapacitor';
|
||||
$fantasyValue = '8GW';
|
||||
v::sf($fantasyConstraintName)->validate($fantasyValue);
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue