diff --git a/src/Symfony/Component/Validator/CHANGELOG.md b/src/Symfony/Component/Validator/CHANGELOG.md index 57d6b17bf5..c988d1e471 100644 --- a/src/Symfony/Component/Validator/CHANGELOG.md +++ b/src/Symfony/Component/Validator/CHANGELOG.md @@ -57,6 +57,8 @@ CHANGELOG * added `Exception\UnsupportedMetadataException` * made `Exception\ValidatorException` extend `Exception\RuntimeException` * added `Util\PropertyPath` + * made the PropertyAccess component an optional dependency + * deprecated `ValidatorBuilder::setPropertyAccessor()` 2.4.0 diff --git a/src/Symfony/Component/Validator/ConstraintValidatorFactory.php b/src/Symfony/Component/Validator/ConstraintValidatorFactory.php index 5cf36eccff..d26680ea09 100644 --- a/src/Symfony/Component/Validator/ConstraintValidatorFactory.php +++ b/src/Symfony/Component/Validator/ConstraintValidatorFactory.php @@ -11,8 +11,6 @@ namespace Symfony\Component\Validator; -use Symfony\Component\PropertyAccess\PropertyAccess; -use Symfony\Component\PropertyAccess\PropertyAccessorInterface; use Symfony\Component\Validator\Constraints\ExpressionValidator; /** @@ -28,14 +26,11 @@ class ConstraintValidatorFactory implements ConstraintValidatorFactoryInterface { protected $validators = array(); - /** - * @var PropertyAccessorInterface - */ private $propertyAccessor; - public function __construct(PropertyAccessorInterface $propertyAccessor = null) + public function __construct($propertyAccessor = null) { - $this->propertyAccessor = $propertyAccessor ?: PropertyAccess::createPropertyAccessor(); + $this->propertyAccessor = $propertyAccessor; } /** diff --git a/src/Symfony/Component/Validator/Constraints/ExpressionValidator.php b/src/Symfony/Component/Validator/Constraints/ExpressionValidator.php index 0151dfe6bc..0e8bd405a4 100644 --- a/src/Symfony/Component/Validator/Constraints/ExpressionValidator.php +++ b/src/Symfony/Component/Validator/Constraints/ExpressionValidator.php @@ -12,10 +12,12 @@ namespace Symfony\Component\Validator\Constraints; use Symfony\Component\ExpressionLanguage\ExpressionLanguage; +use Symfony\Component\PropertyAccess\PropertyAccess; use Symfony\Component\PropertyAccess\PropertyAccessorInterface; use Symfony\Component\PropertyAccess\PropertyPath; use Symfony\Component\Validator\Constraint; use Symfony\Component\Validator\ConstraintValidator; +use Symfony\Component\Validator\Context\ExecutionContextInterface; use Symfony\Component\Validator\Exception\RuntimeException; use Symfony\Component\Validator\Exception\UnexpectedTypeException; @@ -35,8 +37,17 @@ class ExpressionValidator extends ConstraintValidator */ private $expressionLanguage; - public function __construct(PropertyAccessorInterface $propertyAccessor) + /** + * @param PropertyAccessorInterface|null $propertyAccessor Optional as of Symfony 2.5 + * + * @throws UnexpectedTypeException If the property accessor is invalid + */ + public function __construct($propertyAccessor = null) { + if (null !== $propertyAccessor && !$propertyAccessor instanceof PropertyAccessorInterface) { + throw new UnexpectedTypeException($propertyAccessor, 'null or \Symfony\Component\PropertyAccess\PropertyAccessorInterface'); + } + $this->propertyAccessor = $propertyAccessor; } @@ -55,7 +66,12 @@ class ExpressionValidator extends ConstraintValidator $variables = array(); - if (null === $this->context->getPropertyName()) { + // Symfony 2.5+ + if ($this->context instanceof ExecutionContextInterface) { + $variables['value'] = $value; + $variables['this'] = $this->context->getObject(); + } elseif (null === $this->context->getPropertyName()) { + $variables['value'] = $value; $variables['this'] = $value; } else { // Extract the object that the property belongs to from the object @@ -65,7 +81,7 @@ class ExpressionValidator extends ConstraintValidator $root = $this->context->getRoot(); $variables['value'] = $value; - $variables['this'] = $parentPath ? $this->propertyAccessor->getValue($root, $parentPath) : $root; + $variables['this'] = $parentPath ? $this->getPropertyAccessor()->getValue($root, $parentPath) : $root; } if (!$this->getExpressionLanguage()->evaluate($constraint->expression, $variables)) { @@ -84,4 +100,16 @@ class ExpressionValidator extends ConstraintValidator return $this->expressionLanguage; } + + private function getPropertyAccessor() + { + if (null === $this->propertyAccessor) { + if (!class_exists('Symfony\Component\PropertyAccess\PropertyAccess')) { + throw new RuntimeException('Unable to use expressions as the Symfony PropertyAccess component is not installed.'); + } + $this->propertyAccessor = PropertyAccess::createPropertyAccessor(); + } + + return $this->propertyAccessor; + } } diff --git a/src/Symfony/Component/Validator/ValidatorBuilder.php b/src/Symfony/Component/Validator/ValidatorBuilder.php index c84466d094..6f33a8d222 100644 --- a/src/Symfony/Component/Validator/ValidatorBuilder.php +++ b/src/Symfony/Component/Validator/ValidatorBuilder.php @@ -16,7 +16,6 @@ use Doctrine\Common\Annotations\AnnotationRegistry; use Doctrine\Common\Annotations\CachedReader; use Doctrine\Common\Annotations\Reader; use Doctrine\Common\Cache\ArrayCache; -use Symfony\Component\PropertyAccess\PropertyAccess; use Symfony\Component\PropertyAccess\PropertyAccessorInterface; use Symfony\Component\Translation\TranslatorInterface; use Symfony\Component\Validator\Context\LegacyExecutionContextFactory; @@ -395,8 +394,7 @@ class ValidatorBuilder implements ValidatorBuilderInterface $metadataFactory = new ClassMetadataFactory($loader, $this->metadataCache); } - $propertyAccessor = $this->propertyAccessor ?: PropertyAccess::createPropertyAccessor(); - $validatorFactory = $this->validatorFactory ?: new ConstraintValidatorFactory($propertyAccessor); + $validatorFactory = $this->validatorFactory ?: new ConstraintValidatorFactory($this->propertyAccessor); $translator = $this->translator ?: new DefaultTranslator(); $apiVersion = $this->apiVersion; diff --git a/src/Symfony/Component/Validator/ValidatorBuilderInterface.php b/src/Symfony/Component/Validator/ValidatorBuilderInterface.php index e35822e262..f13fbdda3b 100644 --- a/src/Symfony/Component/Validator/ValidatorBuilderInterface.php +++ b/src/Symfony/Component/Validator/ValidatorBuilderInterface.php @@ -166,6 +166,8 @@ interface ValidatorBuilderInterface * @param PropertyAccessorInterface $propertyAccessor The property accessor * * @return ValidatorBuilderInterface The builder object + * + * @deprecated Deprecated since version 2.5, to be removed in Symfony 3.0. */ public function setPropertyAccessor(PropertyAccessorInterface $propertyAccessor); diff --git a/src/Symfony/Component/Validator/composer.json b/src/Symfony/Component/Validator/composer.json index 2e97389ca5..de88ca40d8 100644 --- a/src/Symfony/Component/Validator/composer.json +++ b/src/Symfony/Component/Validator/composer.json @@ -17,14 +17,14 @@ ], "require": { "php": ">=5.3.3", - "symfony/translation": "~2.0", - "symfony/property-access": "~2.2" + "symfony/translation": "~2.0" }, "require-dev": { "symfony/http-foundation": "~2.1", "symfony/intl": "~2.3", "symfony/yaml": "~2.0", "symfony/config": "~2.2", + "symfony/property-access": "~2.2", "doctrine/annotations": "~1.0", "doctrine/cache": "~1.0", "egulias/email-validator": "~1.0" @@ -37,6 +37,7 @@ "symfony/yaml": "", "symfony/config": "", "egulias/email-validator": "Strict (RFC compliant) email validation" + "symfony/property-access": "For using the 2.4 Validator API" }, "autoload": { "psr-0": { "Symfony\\Component\\Validator\\": "" }