diff --git a/src/Symfony/Component/Validator/ExecutionContext.php b/src/Symfony/Component/Validator/ExecutionContext.php index 528baf04b2..41b193e747 100644 --- a/src/Symfony/Component/Validator/ExecutionContext.php +++ b/src/Symfony/Component/Validator/ExecutionContext.php @@ -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 )); } diff --git a/src/Symfony/Component/Validator/GraphWalker.php b/src/Symfony/Component/Validator/GraphWalker.php index ed7490cc9c..887d82cf88 100644 --- a/src/Symfony/Component/Validator/GraphWalker.php +++ b/src/Symfony/Component/Validator/GraphWalker.php @@ -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); } } } diff --git a/src/Symfony/Component/Validator/Mapping/Loader/AbstractLoader.php b/src/Symfony/Component/Validator/Mapping/Loader/AbstractLoader.php new file mode 100644 index 0000000000..959c4766d3 --- /dev/null +++ b/src/Symfony/Component/Validator/Mapping/Loader/AbstractLoader.php @@ -0,0 +1,65 @@ + + * + * 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); + } +} diff --git a/src/Symfony/Component/Validator/Mapping/Loader/FileLoader.php b/src/Symfony/Component/Validator/Mapping/Loader/FileLoader.php index 98a6e1bfc0..2b8c6c04c0 100644 --- a/src/Symfony/Component/Validator/Mapping/Loader/FileLoader.php +++ b/src/Symfony/Component/Validator/Mapping/Loader/FileLoader.php @@ -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); - } } diff --git a/src/Symfony/Component/Validator/Mapping/Loader/XmlFileLoader.php b/src/Symfony/Component/Validator/Mapping/Loader/XmlFileLoader.php index 4c185c604d..4fa94ac76a 100644 --- a/src/Symfony/Component/Validator/Mapping/Loader/XmlFileLoader.php +++ b/src/Symfony/Component/Validator/Mapping/Loader/XmlFileLoader.php @@ -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) { diff --git a/src/Symfony/Component/Validator/Mapping/Loader/YamlFileLoader.php b/src/Symfony/Component/Validator/Mapping/Loader/YamlFileLoader.php index a5ba9624d6..9e85d83ff4 100644 --- a/src/Symfony/Component/Validator/Mapping/Loader/YamlFileLoader.php +++ b/src/Symfony/Component/Validator/Mapping/Loader/YamlFileLoader.php @@ -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']); diff --git a/src/Symfony/Component/Validator/Tests/ExecutionContextTest.php b/src/Symfony/Component/Validator/Tests/ExecutionContextTest.php index 09642afd05..bdde1a1c66 100644 --- a/src/Symfony/Component/Validator/Tests/ExecutionContextTest.php +++ b/src/Symfony/Component/Validator/Tests/ExecutionContextTest.php @@ -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()); }