merged branch vicb/validator/fix (PR #4200)

Commits
-------

bdc21b4 [Validator] Add a base AbstractLoader
ead4908 [Validator] Some cleanup of the GraphWalker
23e15bb [Validator] Fix a bug in the ExecutionContext

Discussion
----------

[Validator] Fix/cleanup

Bug fix: yes
Feature addition: no
Backwards compatibility break: yes
Symfony2 tests pass: [![Build Status](https://secure.travis-ci.org/vicb/symfony.png?branch=validator/fix)](http://travis-ci.org/vicb/symfony)

* d2100a27 has some fixes for the EC,
* 51769e03 has some cleanup in the graph walker,
* f9b3591c add an AbstractLoader (namespace aliases does not belong to FileLoaders).

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

by vicb at 2012-05-07T08:32:40Z

@fabpot PR ready
This commit is contained in:
Fabien Potencier 2012-05-07 10:44:17 +02:00
commit a3ee885d08
7 changed files with 102 additions and 50 deletions

View File

@ -68,7 +68,7 @@ class ExecutionContext
$this->globalContext->getRoot(),
$this->propertyPath,
// check using func_num_args() to allow passing null values
func_num_args() === 3 ? $invalidValue : $this->value,
func_num_args() >= 3 ? $invalidValue : $this->value,
$pluralization
));
}
@ -91,7 +91,7 @@ class ExecutionContext
$this->globalContext->getRoot(),
$propertyPath,
// check using func_num_args() to allow passing null values
func_num_args() === 4 ? $invalidValue : $this->value,
func_num_args() >= 4 ? $invalidValue : $this->value,
$pluralization
));
}
@ -114,7 +114,7 @@ class ExecutionContext
$this->globalContext->getRoot(),
$this->getPropertyPath($subPath),
// check using func_num_args() to allow passing null values
func_num_args() === 4 ? $invalidValue : $this->value,
func_num_args() >= 4 ? $invalidValue : $this->value,
$pluralization
));
}

View File

@ -91,12 +91,8 @@ class GraphWalker
$hash = spl_object_hash($object);
// Exit, if the object is already validated for the current group
if (isset($this->validatedObjects[$hash])) {
if (isset($this->validatedObjects[$hash][$group])) {
if (isset($this->validatedObjects[$hash][$group])) {
return;
}
} else {
$this->validatedObjects[$hash] = array();
}
// Remember validating this object before starting and possibly
@ -110,10 +106,9 @@ class GraphWalker
}
if (null !== $object) {
$pathPrefix = empty($propertyPath) ? '' : $propertyPath.'.';
foreach ($metadata->getConstrainedProperties() as $property) {
$localPropertyPath = empty($propertyPath) ? $property : $propertyPath.'.'.$property;
$this->walkProperty($metadata, $property, $object, $group, $localPropertyPath, $propagatedGroup);
$this->walkProperty($metadata, $property, $object, $group, $pathPrefix.$property, $propagatedGroup);
}
}
}

View File

@ -0,0 +1,65 @@
<?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\Mapping\Loader;
use Symfony\Component\Validator\Exception\MappingException;
abstract class AbstractLoader implements LoaderInterface
{
/**
* Contains all known namespaces indexed by their prefix
* @var array
*/
protected $namespaces;
/**
* Adds a namespace alias.
*
* @param string $alias The alias
* @param string $namespace The PHP namespace
*/
protected function addNamespaceAlias($alias, $namespace)
{
$this->namespaces[$alias] = $namespace;
}
/**
* Creates a new constraint instance for the given constraint name.
*
* @param string $name The constraint name. Either a constraint relative
* to the default constraint namespace, or a fully
* qualified class name
* @param array $options The constraint options
*
* @return Constraint
*
* @throws MappingException If the namespace prefix is undefined
*/
protected function newConstraint($name, $options)
{
if (strpos($name, '\\') !== false && class_exists($name)) {
$className = (string) $name;
} elseif (strpos($name, ':') !== false) {
list($prefix, $className) = explode(':', $name, 2);
if (!isset($this->namespaces[$prefix])) {
throw new MappingException(sprintf('Undefined namespace prefix "%s"', $prefix));
}
$className = $this->namespaces[$prefix].$className;
} else {
$className = 'Symfony\\Component\\Validator\\Constraints\\'.$name;
}
return new $className($options);
}
}

View File

@ -13,16 +13,10 @@ namespace Symfony\Component\Validator\Mapping\Loader;
use Symfony\Component\Validator\Exception\MappingException;
abstract class FileLoader implements LoaderInterface
abstract class FileLoader extends AbstractLoader
{
protected $file;
/**
* Contains all known namespaces indexed by their prefix
* @var array
*/
protected $namespaces;
/**
* Constructor.
*
@ -43,33 +37,4 @@ abstract class FileLoader implements LoaderInterface
$this->file = $file;
}
/**
* Creates a new constraint instance for the given constraint name.
*
* @param string $name The constraint name. Either a constraint relative
* to the default constraint namespace, or a fully
* qualified class name
* @param array $options The constraint options
*
* @return Constraint
*/
protected function newConstraint($name, $options)
{
if (strpos($name, '\\') !== false && class_exists($name)) {
$className = (string) $name;
} elseif (strpos($name, ':') !== false) {
list($prefix, $className) = explode(':', $name, 2);
if (!isset($this->namespaces[$prefix])) {
throw new MappingException(sprintf('Undefined namespace prefix "%s"', $prefix));
}
$className = $this->namespaces[$prefix].$className;
} else {
$className = 'Symfony\\Component\\Validator\\Constraints\\'.$name;
}
return new $className($options);
}
}

View File

@ -32,7 +32,7 @@ class XmlFileLoader extends FileLoader
$xml = $this->parseFile($this->file);
foreach ($xml->namespace as $namespace) {
$this->namespaces[(string) $namespace['prefix']] = trim((string) $namespace);
$this->addNamespaceAlias((string) $namespace['prefix'], trim((string) $namespace));
}
foreach ($xml->class as $class) {

View File

@ -41,8 +41,8 @@ class YamlFileLoader extends FileLoader
}
if (isset($this->classes['namespaces'])) {
foreach ($this->classes['namespaces'] as $prefix => $namespace) {
$this->namespaces[$prefix] = $namespace;
foreach ($this->classes['namespaces'] as $alias => $namespace) {
$this->addNamespaceAlias($alias, $namespace);
}
unset($this->classes['namespaces']);

View File

@ -93,6 +93,7 @@ class ExecutionContextTest extends \PHPUnit_Framework_TestCase
{
// passed null value should override preconfigured value "invalid"
$this->context->addViolation('Error', array('foo' => 'bar'), null);
$this->context->addViolation('Error', array('foo' => 'bar'), null, 1);
$this->assertEquals(new ConstraintViolationList(array(
new ConstraintViolation(
@ -102,6 +103,14 @@ class ExecutionContextTest extends \PHPUnit_Framework_TestCase
'foo.bar',
null
),
new ConstraintViolation(
'Error',
array('foo' => 'bar'),
'Root',
'foo.bar',
null,
1
),
)), $this->context->getViolations());
}
@ -140,6 +149,7 @@ class ExecutionContextTest extends \PHPUnit_Framework_TestCase
{
// passed null value should override preconfigured value "invalid"
$this->context->addViolationAtPath('bar.baz', 'Error', array('foo' => 'bar'), null);
$this->context->addViolationAtPath('bar.baz', 'Error', array('foo' => 'bar'), null, 1);
$this->assertEquals(new ConstraintViolationList(array(
new ConstraintViolation(
@ -149,6 +159,14 @@ class ExecutionContextTest extends \PHPUnit_Framework_TestCase
'bar.baz',
null
),
new ConstraintViolation(
'Error',
array('foo' => 'bar'),
'Root',
'bar.baz',
null,
1
),
)), $this->context->getViolations());
}
@ -187,6 +205,7 @@ class ExecutionContextTest extends \PHPUnit_Framework_TestCase
{
// passed null value should override preconfigured value "invalid"
$this->context->addViolationAtSubPath('bam.baz', 'Error', array('foo' => 'bar'), null);
$this->context->addViolationAtSubPath('bam.baz', 'Error', array('foo' => 'bar'), null, 1);
$this->assertEquals(new ConstraintViolationList(array(
new ConstraintViolation(
@ -196,6 +215,14 @@ class ExecutionContextTest extends \PHPUnit_Framework_TestCase
'foo.bar.bam.baz',
null
),
new ConstraintViolation(
'Error',
array('foo' => 'bar'),
'Root',
'foo.bar.bam.baz',
null,
1
),
)), $this->context->getViolations());
}