Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
[FrameworkBundle] added a DIC tag-based constraint validator factory
  • Loading branch information
kriswallsmith authored and fabpot committed Oct 16, 2010
1 parent 5d4c80f commit e1f8423
Show file tree
Hide file tree
Showing 3 changed files with 144 additions and 1 deletion.
Expand Up @@ -6,7 +6,6 @@

<parameters>
<parameter key="validator.class">Symfony\Component\Validator\Validator</parameter>
<parameter key="validator.validator_factory.class">Symfony\Component\Validator\Extension\DependencyInjectionValidatorFactory</parameter>
<parameter key="validator.mapping.class_metadata_factory.class">Symfony\Component\Validator\Mapping\ClassMetadataFactory</parameter>
<parameter key="validator.mapping.loader.loader_chain.class">Symfony\Component\Validator\Mapping\Loader\LoaderChain</parameter>
<parameter key="validator.mapping.loader.static_method_loader.class">Symfony\Component\Validator\Mapping\Loader\StaticMethodLoader</parameter>
Expand All @@ -16,6 +15,7 @@
<parameter key="validator.mapping.loader.xml_files_loader.class">Symfony\Component\Validator\Mapping\Loader\XmlFilesLoader</parameter>
<parameter key="validator.mapping.loader.yaml_files_loader.class">Symfony\Component\Validator\Mapping\Loader\YamlFilesLoader</parameter>
<parameter key="validator.mapping.loader.static_method_loader.method_name">loadValidatorMetadata</parameter>
<parameter key="validator.validator_factory.class">Symfony\Bundle\FrameworkBundle\Validator\ConstraintValidatorFactory</parameter>
</parameters>

<services>
Expand All @@ -30,6 +30,9 @@

<service id="validator.validator_factory" class="%validator.validator_factory.class%">
<argument type="service" id="service_container" />
<call method="loadTaggedServiceIds">
<argument type="service" id="service_container" />
</call>
</service>

<service id="validator.mapping.loader.loader_chain" class="%validator.mapping.loader.loader_chain.class%">
Expand Down
@@ -0,0 +1,64 @@
<?php

namespace Symfony\Bundle\FrameworkBundle\Tests\Validator;

/*
* This file is part of the Symfony framework.
*
* (c) Fabien Potencier <fabien.potencier@symfony-project.com>
*
* This source file is subject to the MIT license that is bundled
* with this source code in the file LICENSE.
*/

use Symfony\Bundle\FrameworkBundle\Validator\ConstraintValidatorFactory;
use Symfony\Component\DependencyInjection\Container;

class ConstraintValidatorFactoryTest extends \PHPUnit_Framework_TestCase
{
public function testLoadTaggedServiceIdsSetsValidators()
{
$service = 'validator_constraint_service';
$alias = 'validator_constraint_alias';
$validator = new \stdClass();

// mock ContainerBuilder b/c it implements TaggedContainerInterface
$container = $this->getMock('Symfony\\Component\\DependencyInjection\\ContainerBuilder');
$container
->expects($this->once())
->method('findTaggedServiceIds')
->with('validator.constraint_validator')
->will($this->returnValue(array(
$service => array(array('alias' => $alias)),
)));
$container
->expects($this->once())
->method('get')
->with($service)
->will($this->returnValue($validator));

$constraint = $this->getMock('Symfony\\Component\\Validator\\Constraint');
$constraint
->expects($this->once())
->method('validatedBy')
->will($this->returnValue($alias));

$factory = new ConstraintValidatorFactory($container);
$factory->loadTaggedServiceIds($container);
$this->assertSame($validator, $factory->getInstance($constraint));
}

public function testGetInstanceException()
{
$this->setExpectedException('InvalidArgumentException');

$constraint = $this->getMock('Symfony\\Component\\Validator\\Constraint');
$constraint
->expects($this->once())
->method('validatedBy')
->will($this->returnValue('foo'));

$factory = new ConstraintValidatorFactory(new Container());
$factory->getInstance($constraint);
}
}
@@ -0,0 +1,76 @@
<?php

namespace Symfony\Bundle\FrameworkBundle\Validator;

/*
* This file is part of the Symfony framework.
*
* (c) Fabien Potencier <fabien.potencier@symfony-project.com>
*
* This source file is subject to the MIT license that is bundled
* with this source code in the file LICENSE.
*/

use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\DependencyInjection\TaggedContainerInterface;
use Symfony\Component\Validator\Constraint;
use Symfony\Component\Validator\ConstraintValidatorFactoryInterface;

/**
* Uses a service container to create constraint validators.
*
* @author Kris Wallsmith <kris.wallsmith@symfony-project.com>
*/
class ConstraintValidatorFactory implements ConstraintValidatorFactoryInterface
{
protected $container;
protected $validators = array();

/**
* Constructor.
*
* @param ContainerInterface $container The service container
*/
public function __construct(ContainerInterface $container)
{
$this->container = $container;
}

/**
* Loads ids for services tagged as constraint validators.
*
* @param TaggedContainerInterface $container The tagged service container
*/
public function loadTaggedServiceIds(TaggedContainerInterface $container)
{
foreach ($container->findTaggedServiceIds('validator.constraint_validator') as $id => $attributes) {
if (isset($attributes[0]['alias'])) {
$this->validators[$attributes[0]['alias']] = $id;
}
}
}

/**
* Returns the validator for the supplied constraint.
*
* @param Constraint $constraint A constraint
*
* @return Symfony\Component\Validator\ConstraintValidator A validator for the supplied constraint
*
* @throws InvalidArgumentException If no validator for the supplied constraint is found
*/
public function getInstance(Constraint $constraint)
{
$name = $constraint->validatedBy();

if (!isset($this->validators[$name])) {
throw new \InvalidArgumentException(sprintf('There is no "%s" constraint validator.', $name));
}

if (is_string($this->validators[$name])) {
$this->validators[$name] = $this->container->get($this->validators[$name]);
}

return $this->validators[$name];
}
}

0 comments on commit e1f8423

Please sign in to comment.