Merge branch '3.4'

* 3.4:
  fixed CS
  Only override getProjectDir if it exists in the kernel
  [FrameworkBundle][Validator] Move the PSR-11 factory to the component
This commit is contained in:
Nicolas Grekas 2017-05-27 12:24:10 +02:00
commit 2c4bb0f19c
8 changed files with 82 additions and 154 deletions

View File

@ -203,11 +203,6 @@ FrameworkBundle
deprecated and will be removed in 4.0. Use the `Symfony\Component\PropertyInfo\DependencyInjection\PropertyInfoPass` deprecated and will be removed in 4.0. Use the `Symfony\Component\PropertyInfo\DependencyInjection\PropertyInfoPass`
class instead. class instead.
* The `ConstraintValidatorFactory::$validators` and `$container` properties
have been deprecated and will be removed in 4.0.
* Extending `ConstraintValidatorFactory` is deprecated and won't be supported in 4.0.
* Class parameters related to routing have been deprecated and will be removed in 4.0. * Class parameters related to routing have been deprecated and will be removed in 4.0.
* router.options.generator_class * router.options.generator_class
* router.options.generator_base_class * router.options.generator_base_class
@ -246,9 +241,9 @@ FrameworkBundle
class has been deprecated and will be removed in 4.0. Use the class has been deprecated and will be removed in 4.0. Use the
`Symfony\Component\Workflow\DependencyInjection\ValidateWorkflowsPass` class instead. `Symfony\Component\Workflow\DependencyInjection\ValidateWorkflowsPass` class instead.
* Passing an array of validators or validator aliases as the second argument of * The `Symfony\Bundle\FrameworkBundle\Validator\ConstraintValidatorFactory`
`ConstraintValidatorFactory::__construct()` is deprecated since 3.3 and will class has been deprecated and will be removed in 4.0.
be removed in 4.0. Use the service locator instead. Use `Symfony\Component\Validator\ContainerConstraintValidatorFactory` instead.
HttpFoundation HttpFoundation
-------------- --------------

View File

@ -298,15 +298,6 @@ FrameworkBundle
removed. Use the `Symfony\Component\PropertyInfo\DependencyInjection\PropertyInfoPass` removed. Use the `Symfony\Component\PropertyInfo\DependencyInjection\PropertyInfoPass`
class instead. class instead.
* The `ConstraintValidatorFactory::$validators` and `$container` properties
have been removed.
* Extending `ConstraintValidatorFactory` is not supported anymore.
* Passing an array of validators or validator aliases as the second argument of
`ConstraintValidatorFactory::__construct()` has been removed.
Use the service locator instead.
* Class parameters related to routing have been removed * Class parameters related to routing have been removed
* router.options.generator_class * router.options.generator_class
* router.options.generator_base_class * router.options.generator_base_class
@ -340,6 +331,9 @@ FrameworkBundle
has been removed. Use the `Symfony\Component\Workflow\DependencyInjection\ValidateWorkflowsPass` has been removed. Use the `Symfony\Component\Workflow\DependencyInjection\ValidateWorkflowsPass`
class instead. class instead.
* The `Symfony\Bundle\FrameworkBundle\Validator\ConstraintValidatorFactory` class has been removed.
Use `Symfony\Component\Validator\ContainerConstraintValidatorFactory` instead.
HttpFoundation HttpFoundation
-------------- --------------

View File

@ -48,7 +48,6 @@ CHANGELOG
* Deprecated `Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\ConfigCachePass`. * Deprecated `Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\ConfigCachePass`.
Use `Symfony\Component\Console\DependencyInjection\ConfigCachePass` instead. Use `Symfony\Component\Console\DependencyInjection\ConfigCachePass` instead.
* Deprecated `PropertyInfoPass`, use `Symfony\Component\PropertyInfo\DependencyInjection\PropertyInfoPass` instead * Deprecated `PropertyInfoPass`, use `Symfony\Component\PropertyInfo\DependencyInjection\PropertyInfoPass` instead
* Deprecated extending `ConstraintValidatorFactory`
* Deprecated `ControllerArgumentValueResolverPass`. Use * Deprecated `ControllerArgumentValueResolverPass`. Use
`Symfony\Component\HttpKernel\DependencyInjection\ControllerArgumentValueResolverPass` instead `Symfony\Component\HttpKernel\DependencyInjection\ControllerArgumentValueResolverPass` instead
* Deprecated `RoutingResolverPass`, use `Symfony\Component\Routing\DependencyInjection\RoutingResolverPass` instead * Deprecated `RoutingResolverPass`, use `Symfony\Component\Routing\DependencyInjection\RoutingResolverPass` instead
@ -66,7 +65,8 @@ CHANGELOG
`Symfony\Component\Validator\DependencyInjection\AddConstraintValidatorsPass` instead `Symfony\Component\Validator\DependencyInjection\AddConstraintValidatorsPass` instead
* Deprecated `ValidateWorkflowsPass`, use * Deprecated `ValidateWorkflowsPass`, use
`Symfony\Component\Workflow\DependencyInjection\ValidateWorkflowsPass` instead `Symfony\Component\Workflow\DependencyInjection\ValidateWorkflowsPass` instead
* Deprecated `ConstraintValidatorFactory::__construct()` second argument. * Deprecated `ConstraintValidatorFactory`, use
`Symfony\Component\Validator\ContainerConstraintValidatorFactory` instead.
3.2.0 3.2.0
----- -----

View File

@ -59,7 +59,7 @@
</argument> </argument>
</service> </service>
<service id="validator.validator_factory" class="Symfony\Bundle\FrameworkBundle\Validator\ConstraintValidatorFactory"> <service id="validator.validator_factory" class="Symfony\Component\Validator\ContainerConstraintValidatorFactory">
<argument /> <!-- Constraint validators locator --> <argument /> <!-- Constraint validators locator -->
</service> </service>

View File

@ -1,96 +0,0 @@
<?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\Bundle\FrameworkBundle\Validator;
use Psr\Container\ContainerInterface;
use Symfony\Component\Validator\Constraint;
use Symfony\Component\Validator\ConstraintValidatorFactoryInterface;
use Symfony\Component\Validator\ConstraintValidatorInterface;
use Symfony\Component\Validator\Exception\ValidatorException;
use Symfony\Component\Validator\Exception\UnexpectedTypeException;
/**
* Uses a service container to create constraint validators.
*
* A constraint validator should be tagged as "validator.constraint_validator"
* in the service container and include an "alias" attribute:
*
* <service id="some_doctrine_validator">
* <argument type="service" id="doctrine.orm.some_entity_manager" />
* <tag name="validator.constraint_validator" alias="some_alias" />
* </service>
*
* A constraint may then return this alias in its validatedBy() method:
*
* public function validatedBy()
* {
* return 'some_alias';
* }
*
* @author Kris Wallsmith <kris@symfony.com>
*
* @final since version 3.3
*/
class ConstraintValidatorFactory implements ConstraintValidatorFactoryInterface
{
private $container;
private $validators;
public function __construct(ContainerInterface $container, array $validators = null)
{
$this->container = $container;
if (null !== $validators) {
@trigger_error(sprintf('Passing an array of validators or validator aliases as the second argument of "%s" is deprecated since 3.3 and will be removed in 4.0. Use the service locator instead.', __METHOD__), E_USER_DEPRECATED);
} else {
$validators = array();
}
$this->validators = $validators;
}
/**
* Returns the validator for the supplied constraint.
*
* @param Constraint $constraint A constraint
*
* @return ConstraintValidatorInterface A validator for the supplied constraint
*
* @throws ValidatorException When the validator class does not exist
* @throws UnexpectedTypeException When the validator is not an instance of ConstraintValidatorInterface
*/
public function getInstance(Constraint $constraint)
{
$name = $constraint->validatedBy();
if (!isset($this->validators[$name])) {
if ($this->container->has($name)) {
$this->validators[$name] = $this->container->get($name);
} else {
if (!class_exists($name)) {
throw new ValidatorException(sprintf('Constraint validator "%s" does not exist or it is not enabled. Check the "validatedBy" method in your constraint class "%s".', $name, get_class($constraint)));
}
$this->validators[$name] = new $name();
}
} elseif (is_string($this->validators[$name])) {
// To be removed in 4.0
$this->validators[$name] = $this->container->get($this->validators[$name]);
}
if (!$this->validators[$name] instanceof ConstraintValidatorInterface) {
throw new UnexpectedTypeException($this->validators[$name], 'Symfony\Component\Validator\ConstraintValidatorInterface');
}
return $this->validators[$name];
}
}

View File

@ -20,6 +20,7 @@ CHANGELOG
* added `AddValidatorInitializersPass` * added `AddValidatorInitializersPass`
* added `AddConstraintValidatorsPass` * added `AddConstraintValidatorsPass`
* added `ContainerConstraintValidatorFactory`
3.2.0 3.2.0
----- -----

View File

@ -0,0 +1,62 @@
<?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;
use Psr\Container\ContainerInterface;
use Symfony\Component\Validator\Exception\UnexpectedTypeException;
use Symfony\Component\Validator\Exception\ValidatorException;
/**
* Uses a service container to create constraint validators.
*
* @author Kris Wallsmith <kris@symfony.com>
*/
class ContainerConstraintValidatorFactory implements ConstraintValidatorFactoryInterface
{
private $container;
private $validators;
public function __construct(ContainerInterface $container)
{
$this->container = $container;
$this->validators = array();
}
/**
* {@inheritdoc}
*
* @throws ValidatorException When the validator class does not exist
* @throws UnexpectedTypeException When the validator is not an instance of ConstraintValidatorInterface
*/
public function getInstance(Constraint $constraint)
{
$name = $constraint->validatedBy();
if (!isset($this->validators[$name])) {
if ($this->container->has($name)) {
$this->validators[$name] = $this->container->get($name);
} else {
if (!class_exists($name)) {
throw new ValidatorException(sprintf('Constraint validator "%s" does not exist or it is not enabled. Check the "validatedBy" method in your constraint class "%s".', $name, get_class($constraint)));
}
$this->validators[$name] = new $name();
}
}
if (!$this->validators[$name] instanceof ConstraintValidatorInterface) {
throw new UnexpectedTypeException($this->validators[$name], ConstraintValidatorInterface::class);
}
return $this->validators[$name];
}
}

View File

@ -9,35 +9,35 @@
* file that was distributed with this source code. * file that was distributed with this source code.
*/ */
namespace Symfony\Bundle\FrameworkBundle\Tests\Validator; namespace Symfony\Component\Validator\Tests;
use PHPUnit\Framework\TestCase; use PHPUnit\Framework\TestCase;
use Symfony\Bundle\FrameworkBundle\Validator\ConstraintValidatorFactory;
use Symfony\Component\DependencyInjection\Container; use Symfony\Component\DependencyInjection\Container;
use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\Validator\Constraint; use Symfony\Component\Validator\Constraint;
use Symfony\Component\Validator\Constraints\Blank as BlankConstraint; use Symfony\Component\Validator\Constraints\Blank as BlankConstraint;
use Symfony\Component\Validator\ConstraintValidator; use Symfony\Component\Validator\ConstraintValidator;
use Symfony\Component\Validator\ContainerConstraintValidatorFactory;
class ConstraintValidatorFactoryTest extends TestCase class ContainerConstraintValidatorFactoryTest extends TestCase
{ {
public function testGetInstanceCreatesValidator() public function testGetInstanceCreatesValidator()
{ {
$class = get_class($this->getMockForAbstractClass('Symfony\\Component\\Validator\\ConstraintValidator')); $class = get_class($this->getMockForAbstractClass(ConstraintValidator::class));
$constraint = $this->getMockBuilder('Symfony\\Component\\Validator\\Constraint')->getMock(); $constraint = $this->getMockBuilder(Constraint::class)->getMock();
$constraint $constraint
->expects($this->once()) ->expects($this->once())
->method('validatedBy') ->method('validatedBy')
->will($this->returnValue($class)); ->will($this->returnValue($class));
$factory = new ConstraintValidatorFactory(new Container()); $factory = new ContainerConstraintValidatorFactory(new Container());
$this->assertInstanceOf($class, $factory->getInstance($constraint)); $this->assertInstanceOf($class, $factory->getInstance($constraint));
} }
public function testGetInstanceReturnsExistingValidator() public function testGetInstanceReturnsExistingValidator()
{ {
$factory = new ConstraintValidatorFactory(new Container()); $factory = new ContainerConstraintValidatorFactory(new Container());
$v1 = $factory->getInstance(new BlankConstraint()); $v1 = $factory->getInstance(new BlankConstraint());
$v2 = $factory->getInstance(new BlankConstraint()); $v2 = $factory->getInstance(new BlankConstraint());
$this->assertSame($v1, $v2); $this->assertSame($v1, $v2);
@ -67,35 +67,7 @@ class ConstraintValidatorFactoryTest extends TestCase
->method('validatedBy') ->method('validatedBy')
->will($this->returnValue($service)); ->will($this->returnValue($service));
$factory = new ConstraintValidatorFactory($container); $factory = new ContainerConstraintValidatorFactory($container);
$this->assertSame($validator, $factory->getInstance($constraint));
}
/**
* @group legacy
* @expectedDeprecation Passing an array of validators or validator aliases as the second argument of "Symfony\Bundle\FrameworkBundle\Validator\ConstraintValidatorFactory::__construct" is deprecated since 3.3 and will be removed in 4.0. Use the service locator instead.
*/
public function testGetInstanceReturnsServiceWithAlias()
{
$service = 'validator_constraint_service';
$alias = 'validator_constraint_alias';
$validator = $this->getMockForAbstractClass('Symfony\\Component\\Validator\\ConstraintValidator');
// mock ContainerBuilder b/c it implements TaggedContainerInterface
$container = $this->getMockBuilder('Symfony\\Component\\DependencyInjection\\ContainerBuilder')->setMethods(array('get'))->getMock();
$container
->expects($this->once())
->method('get')
->with($service)
->will($this->returnValue($validator));
$constraint = $this->getMockBuilder('Symfony\\Component\\Validator\\Constraint')->getMock();
$constraint
->expects($this->once())
->method('validatedBy')
->will($this->returnValue($alias));
$factory = new ConstraintValidatorFactory($container, array('validator_constraint_alias' => 'validator_constraint_service'));
$this->assertSame($validator, $factory->getInstance($constraint)); $this->assertSame($validator, $factory->getInstance($constraint));
} }
@ -104,13 +76,13 @@ class ConstraintValidatorFactoryTest extends TestCase
*/ */
public function testGetInstanceInvalidValidatorClass() public function testGetInstanceInvalidValidatorClass()
{ {
$constraint = $this->getMockBuilder('Symfony\\Component\\Validator\\Constraint')->getMock(); $constraint = $this->getMockBuilder(Constraint::class)->getMock();
$constraint $constraint
->expects($this->once()) ->expects($this->once())
->method('validatedBy') ->method('validatedBy')
->will($this->returnValue('Fully\\Qualified\\ConstraintValidator\\Class\\Name')); ->will($this->returnValue('Fully\\Qualified\\ConstraintValidator\\Class\\Name'));
$factory = new ConstraintValidatorFactory(new Container()); $factory = new ContainerConstraintValidatorFactory(new Container());
$factory->getInstance($constraint); $factory->getInstance($constraint);
} }
} }