refactored Doctrine Bridge
* added a RegistryInterface * changed all classes to depend on the Registry instead of a specific EntityManager This is more consistent as the validator already took the registry and this allows to use any entity manager in Forms.
This commit is contained in:
parent
84b25b1626
commit
fbf36957e6
@ -9,6 +9,10 @@ timeline closely anyway.
|
||||
beta4 to beta5
|
||||
--------------
|
||||
|
||||
* The `em` option of the Doctrine `EntityType` class now takes the entity
|
||||
manager name instead of the EntityManager instance. If you don't pass this
|
||||
option, the default Entity Manager will be used as before.
|
||||
|
||||
* In the Console component: `Command::getFullname()` and
|
||||
`Command::getNamespace()` have been removed (`Command::getName()` behavior
|
||||
is now the same as the old `Command::getFullname()`).
|
||||
|
@ -12,30 +12,26 @@
|
||||
namespace Symfony\Bridge\Doctrine\Form;
|
||||
|
||||
use Symfony\Component\Form\AbstractExtension;
|
||||
use Doctrine\ORM\EntityManager;
|
||||
use Symfony\Bridge\Doctrine\RegistryInterface;
|
||||
|
||||
class DoctrineOrmExtension extends AbstractExtension
|
||||
{
|
||||
/**
|
||||
* The Doctrine 2 entity manager
|
||||
* @var Doctrine\ORM\EntityManager
|
||||
*/
|
||||
protected $em = null;
|
||||
protected $registry;
|
||||
|
||||
public function __construct(EntityManager $em)
|
||||
public function __construct(RegistryInterface $registry)
|
||||
{
|
||||
$this->em = $em;
|
||||
$this->registry = $registry;
|
||||
}
|
||||
|
||||
protected function loadTypes()
|
||||
{
|
||||
return array(
|
||||
new Type\EntityType($this->em),
|
||||
new Type\EntityType($this->registry),
|
||||
);
|
||||
}
|
||||
|
||||
protected function loadTypeGuesser()
|
||||
{
|
||||
return new DoctrineOrmTypeGuesser($this->em);
|
||||
return new DoctrineOrmTypeGuesser($this->registry);
|
||||
}
|
||||
}
|
||||
|
@ -15,29 +15,18 @@ use Symfony\Component\Form\FormTypeGuesserInterface;
|
||||
use Symfony\Component\Form\Guess\Guess;
|
||||
use Symfony\Component\Form\Guess\TypeGuess;
|
||||
use Symfony\Component\Form\Guess\ValueGuess;
|
||||
use Doctrine\ORM\EntityManager;
|
||||
use Symfony\Bridge\Doctrine\RegistryInterface;
|
||||
|
||||
class DoctrineOrmTypeGuesser implements FormTypeGuesserInterface
|
||||
{
|
||||
/**
|
||||
* The Doctrine 2 entity manager
|
||||
* @var Doctrine\ORM\EntityManager
|
||||
*/
|
||||
protected $em = null;
|
||||
protected $registry;
|
||||
|
||||
public function __construct(EntityManager $em)
|
||||
{
|
||||
$this->em = $em;
|
||||
}
|
||||
private $cache;
|
||||
|
||||
/**
|
||||
* Returns whether Doctrine 2 metadata exists for that class
|
||||
*
|
||||
* @return Boolean
|
||||
*/
|
||||
protected function isMappedClass($class)
|
||||
public function __construct(RegistryInterface $registry)
|
||||
{
|
||||
return !$this->em->getConfiguration()->getMetadataDriverImpl()->isTransient($class);
|
||||
$this->registry = $registry;
|
||||
$this->cache = array();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -45,94 +34,45 @@ class DoctrineOrmTypeGuesser implements FormTypeGuesserInterface
|
||||
*/
|
||||
public function guessType($class, $property)
|
||||
{
|
||||
if ($this->isMappedClass($class)) {
|
||||
$metadata = $this->em->getClassMetadata($class);
|
||||
|
||||
if ($metadata->hasAssociation($property)) {
|
||||
$multiple = $metadata->isCollectionValuedAssociation($property);
|
||||
$mapping = $metadata->getAssociationMapping($property);
|
||||
|
||||
return new TypeGuess(
|
||||
'entity',
|
||||
array(
|
||||
'em' => $this->em,
|
||||
'class' => $mapping['targetEntity'],
|
||||
'multiple' => $multiple,
|
||||
),
|
||||
Guess::HIGH_CONFIDENCE
|
||||
);
|
||||
} else {
|
||||
switch ($metadata->getTypeOfField($property))
|
||||
{
|
||||
// case 'array':
|
||||
// return new TypeGuess(
|
||||
// 'Collection',
|
||||
// array(),
|
||||
// Guess::HIGH_CONFIDENCE
|
||||
// );
|
||||
case 'boolean':
|
||||
return new TypeGuess(
|
||||
'checkbox',
|
||||
array(),
|
||||
Guess::HIGH_CONFIDENCE
|
||||
);
|
||||
case 'datetime':
|
||||
case 'vardatetime':
|
||||
case 'datetimetz':
|
||||
return new TypeGuess(
|
||||
'datetime',
|
||||
array(),
|
||||
Guess::HIGH_CONFIDENCE
|
||||
);
|
||||
case 'date':
|
||||
return new TypeGuess(
|
||||
'date',
|
||||
array(),
|
||||
Guess::HIGH_CONFIDENCE
|
||||
);
|
||||
case 'decimal':
|
||||
case 'float':
|
||||
return new TypeGuess(
|
||||
'number',
|
||||
array(),
|
||||
Guess::MEDIUM_CONFIDENCE
|
||||
);
|
||||
case 'integer':
|
||||
case 'bigint':
|
||||
case 'smallint':
|
||||
return new TypeGuess(
|
||||
'integer',
|
||||
array(),
|
||||
Guess::MEDIUM_CONFIDENCE
|
||||
);
|
||||
case 'string':
|
||||
return new TypeGuess(
|
||||
'text',
|
||||
array(),
|
||||
Guess::MEDIUM_CONFIDENCE
|
||||
);
|
||||
case 'text':
|
||||
return new TypeGuess(
|
||||
'textarea',
|
||||
array(),
|
||||
Guess::MEDIUM_CONFIDENCE
|
||||
);
|
||||
case 'time':
|
||||
return new TypeGuess(
|
||||
'time',
|
||||
array(),
|
||||
Guess::HIGH_CONFIDENCE
|
||||
);
|
||||
// case 'object': ???
|
||||
}
|
||||
}
|
||||
if (!$metadata = $this->getMetadata($class)) {
|
||||
return new TypeGuess('text', array(), Guess::LOW_CONFIDENCE);
|
||||
}
|
||||
|
||||
return new TypeGuess(
|
||||
'text',
|
||||
array(),
|
||||
Guess::LOW_CONFIDENCE
|
||||
);
|
||||
if ($metadata->hasAssociation($property)) {
|
||||
$multiple = $metadata->isCollectionValuedAssociation($property);
|
||||
$mapping = $metadata->getAssociationMapping($property);
|
||||
|
||||
return new TypeGuess('entity', array('em' => $this->em, 'class' => $mapping['targetEntity'], 'multiple' => $multiple), Guess::HIGH_CONFIDENCE);
|
||||
}
|
||||
|
||||
switch ($metadata->getTypeOfField($property))
|
||||
{
|
||||
//case 'array':
|
||||
// return new TypeGuess('Collection', array(), Guess::HIGH_CONFIDENCE);
|
||||
case 'boolean':
|
||||
return new TypeGuess('checkbox', array(), Guess::HIGH_CONFIDENCE);
|
||||
case 'datetime':
|
||||
case 'vardatetime':
|
||||
case 'datetimetz':
|
||||
return new TypeGuess('datetime', array(), Guess::HIGH_CONFIDENCE);
|
||||
case 'date':
|
||||
return new TypeGuess('date', array(), Guess::HIGH_CONFIDENCE);
|
||||
case 'decimal':
|
||||
case 'float':
|
||||
return new TypeGuess('number', array(), Guess::MEDIUM_CONFIDENCE);
|
||||
case 'integer':
|
||||
case 'bigint':
|
||||
case 'smallint':
|
||||
return new TypeGuess('integer', array(), Guess::MEDIUM_CONFIDENCE);
|
||||
case 'string':
|
||||
return new TypeGuess('text', array(), Guess::MEDIUM_CONFIDENCE);
|
||||
case 'text':
|
||||
return new TypeGuess('textarea', array(), Guess::MEDIUM_CONFIDENCE);
|
||||
case 'time':
|
||||
return new TypeGuess('time', array(), Guess::HIGH_CONFIDENCE);
|
||||
default:
|
||||
return new TypeGuess('text', array(), Guess::LOW_CONFIDENCE);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -140,22 +80,12 @@ class DoctrineOrmTypeGuesser implements FormTypeGuesserInterface
|
||||
*/
|
||||
public function guessRequired($class, $property)
|
||||
{
|
||||
if ($this->isMappedClass($class)) {
|
||||
$metadata = $this->em->getClassMetadata($class);
|
||||
|
||||
if ($metadata->hasField($property)) {
|
||||
if (!$metadata->isNullable($property)) {
|
||||
return new ValueGuess(
|
||||
true,
|
||||
Guess::HIGH_CONFIDENCE
|
||||
);
|
||||
}
|
||||
|
||||
return new ValueGuess(
|
||||
false,
|
||||
Guess::MEDIUM_CONFIDENCE
|
||||
);
|
||||
if ($metadata = $this->getMetadata($class) && $metadata->hasField($property)) {
|
||||
if (!$metadata->isNullable($property)) {
|
||||
return new ValueGuess(true, Guess::HIGH_CONFIDENCE);
|
||||
}
|
||||
|
||||
return new ValueGuess(false, Guess::MEDIUM_CONFIDENCE);
|
||||
}
|
||||
}
|
||||
|
||||
@ -164,19 +94,11 @@ class DoctrineOrmTypeGuesser implements FormTypeGuesserInterface
|
||||
*/
|
||||
public function guessMaxLength($class, $property)
|
||||
{
|
||||
if ($this->isMappedClass($class)) {
|
||||
$metadata = $this->em->getClassMetadata($class);
|
||||
if ($metadata = $this->getMetadata($class) && !$metadata->hasAssociation($property)) {
|
||||
$mapping = $metadata->getFieldMapping($property);
|
||||
|
||||
if (!$metadata->hasAssociation($property)) {
|
||||
$mapping = $metadata->getFieldMapping($property);
|
||||
|
||||
|
||||
if (isset($mapping['length'])) {
|
||||
return new ValueGuess(
|
||||
$mapping['length'],
|
||||
Guess::HIGH_CONFIDENCE
|
||||
);
|
||||
}
|
||||
if (isset($mapping['length'])) {
|
||||
return new ValueGuess($mapping['length'], Guess::HIGH_CONFIDENCE);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -186,6 +108,24 @@ class DoctrineOrmTypeGuesser implements FormTypeGuesserInterface
|
||||
*/
|
||||
public function guessMinLength($class, $property)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether Doctrine 2 metadata exists for that class
|
||||
*
|
||||
* @return Boolean
|
||||
*/
|
||||
protected function getMetadata($class)
|
||||
{
|
||||
if (array_key_exists($class, $this->cache)) {
|
||||
return $this->cache[$class];
|
||||
}
|
||||
|
||||
$this->cache[$class] = null;
|
||||
foreach ($this->registry->getEntityManagers() as $em) {
|
||||
if ($em->getConfiguration()->getMetadataDriverImpl()->isTransient($class)) {
|
||||
return $this->cache[$class] = $em->getClassMetadata($class);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -13,20 +13,20 @@ namespace Symfony\Bridge\Doctrine\Form\Type;
|
||||
|
||||
use Symfony\Component\Form\FormBuilder;
|
||||
use Symfony\Component\Form\FormFactoryInterface;
|
||||
use Symfony\Bridge\Doctrine\RegistryInterface;
|
||||
use Symfony\Bridge\Doctrine\Form\ChoiceList\EntityChoiceList;
|
||||
use Symfony\Bridge\Doctrine\Form\EventListener\MergeCollectionListener;
|
||||
use Symfony\Bridge\Doctrine\Form\DataTransformer\EntitiesToArrayTransformer;
|
||||
use Symfony\Bridge\Doctrine\Form\DataTransformer\EntityToIdTransformer;
|
||||
use Symfony\Component\Form\AbstractType;
|
||||
use Doctrine\ORM\EntityManager;
|
||||
|
||||
class EntityType extends AbstractType
|
||||
{
|
||||
private $em;
|
||||
protected $registry;
|
||||
|
||||
public function __construct(EntityManager $em)
|
||||
public function __construct(RegistryInterface $registry)
|
||||
{
|
||||
$this->em = $em;
|
||||
$this->registry = $registry;
|
||||
}
|
||||
|
||||
public function buildForm(FormBuilder $builder, array $options)
|
||||
@ -46,7 +46,7 @@ class EntityType extends AbstractType
|
||||
$defaultOptions = array(
|
||||
'multiple' => false,
|
||||
'expanded' => false,
|
||||
'em' => $this->em,
|
||||
'em' => null,
|
||||
'class' => null,
|
||||
'property' => null,
|
||||
'query_builder' => null,
|
||||
@ -60,7 +60,7 @@ class EntityType extends AbstractType
|
||||
|
||||
if (!isset($options['choice_list'])) {
|
||||
$defaultOptions['choice_list'] = new EntityChoiceList(
|
||||
$options['em'],
|
||||
$this->registry->getEntityManager($options['em']),
|
||||
$options['class'],
|
||||
$options['property'],
|
||||
$options['query_builder'],
|
||||
@ -80,4 +80,4 @@ class EntityType extends AbstractType
|
||||
{
|
||||
return 'entity';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
127
src/Symfony/Bridge/Doctrine/RegistryInterface.php
Normal file
127
src/Symfony/Bridge/Doctrine/RegistryInterface.php
Normal file
@ -0,0 +1,127 @@
|
||||
<?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\Bridge\Doctrine;
|
||||
|
||||
use Symfony\Bridge\Doctrine\RegistryInterface;
|
||||
use Doctrine\DBAL\Connection;
|
||||
use Doctrine\ORM\Configuration;
|
||||
use Doctrine\ORM\ORMException;
|
||||
|
||||
/**
|
||||
* References Doctrine connections and entity managers.
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*/
|
||||
interface RegistryInterface
|
||||
{
|
||||
/**
|
||||
* Gets the default connection name.
|
||||
*
|
||||
* @return string The default connection name
|
||||
*/
|
||||
function getDefaultConnectionName();
|
||||
|
||||
/**
|
||||
* Gets the named connection.
|
||||
*
|
||||
* @param string $name The connection name (null for the default one)
|
||||
*
|
||||
* @return Connection
|
||||
*/
|
||||
function getConnection($name = null);
|
||||
|
||||
/**
|
||||
* Gets an array of all registered connections
|
||||
*
|
||||
* @return array An array of Connection instances
|
||||
*/
|
||||
function getConnections();
|
||||
|
||||
/**
|
||||
* Gets all connection names.
|
||||
*
|
||||
* @return array An array of connection names
|
||||
*/
|
||||
function getConnectionNames();
|
||||
|
||||
/**
|
||||
* Gets the default entity manager name.
|
||||
*
|
||||
* @return string The default entity manager name
|
||||
*/
|
||||
function getDefaultEntityManagerName();
|
||||
|
||||
/**
|
||||
* Gets a named entity manager.
|
||||
*
|
||||
* @param string $name The entity manager name (null for the default one)
|
||||
*
|
||||
* @return EntityManager
|
||||
*/
|
||||
function getEntityManager($name = null);
|
||||
|
||||
/**
|
||||
* Gets an array of all registered entity managers
|
||||
*
|
||||
* @return array An array of EntityManager instances
|
||||
*/
|
||||
function getEntityManagers();
|
||||
|
||||
/**
|
||||
* Resets a named entity manager.
|
||||
*
|
||||
* This method is useful when an entity manager has been closed
|
||||
* because of a rollbacked transaction AND when you think that
|
||||
* it makes sense to get a new one to replace the closed one.
|
||||
*
|
||||
* Be warned that you will get a brand new entity manager as
|
||||
* the existing one is not useable anymore. This means that any
|
||||
* other object with a dependency on this entity manager will
|
||||
* hold an obsolete reference. You can inject the registry instead
|
||||
* to avoid this problem.
|
||||
*
|
||||
* @param string $name The entity manager name (null for the default one)
|
||||
*
|
||||
* @return EntityManager
|
||||
*/
|
||||
function resetEntityManager($name = null);
|
||||
|
||||
/**
|
||||
* Resolves a registered namespace alias to the full namespace.
|
||||
*
|
||||
* This method looks for the alias in all registered entity managers.
|
||||
*
|
||||
* @param string $alias The alias
|
||||
*
|
||||
* @return string The full namespace
|
||||
*
|
||||
* @see Configuration::getEntityNamespace
|
||||
*/
|
||||
function getEntityNamespace($alias);
|
||||
|
||||
/**
|
||||
* Gets all connection names.
|
||||
*
|
||||
* @return array An array of connection names
|
||||
*/
|
||||
function getEntityManagerNames();
|
||||
|
||||
/**
|
||||
* Gets the EntityRepository for an entity.
|
||||
*
|
||||
* @param string $entityName The name of the entity.
|
||||
* @param string $entityManagerNAme The entity manager name (null for the default one)
|
||||
*
|
||||
* @return Doctrine\ORM\EntityRepository
|
||||
*/
|
||||
function getRepository($entityName, $entityManagerName = null);
|
||||
}
|
@ -17,7 +17,7 @@ use Symfony\Component\Validator\Exception\UnexpectedTypeException;
|
||||
|
||||
/**
|
||||
* Constraint for the Unique Entity validator
|
||||
*
|
||||
*
|
||||
* @author Benjamin Eberlei <kontakt@beberlei.de>
|
||||
*/
|
||||
class UniqueEntity extends Constraint
|
||||
@ -25,12 +25,12 @@ class UniqueEntity extends Constraint
|
||||
public $message = 'This value is already used.';
|
||||
public $em = null;
|
||||
public $fields = array();
|
||||
|
||||
|
||||
public function getRequiredOptions()
|
||||
{
|
||||
return array('fields');
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* The validator must be defined as a service with this name.
|
||||
*
|
||||
@ -40,7 +40,7 @@ class UniqueEntity extends Constraint
|
||||
{
|
||||
return 'doctrine.orm.validator.unique';
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@ -48,9 +48,9 @@ class UniqueEntity extends Constraint
|
||||
{
|
||||
return self::CLASS_CONSTRAINT;
|
||||
}
|
||||
|
||||
|
||||
public function getDefaultOption()
|
||||
{
|
||||
return 'fields';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -11,7 +11,7 @@
|
||||
|
||||
namespace Symfony\Bridge\Doctrine\Validator\Constraints;
|
||||
|
||||
use Symfony\Bundle\DoctrineBundle\Registry;
|
||||
use Symfony\Bridge\Doctrine\RegistryInterface;
|
||||
use Symfony\Component\Validator\Constraint;
|
||||
use Symfony\Component\Validator\Exception\UnexpectedTypeException;
|
||||
use Symfony\Component\Validator\Exception\ConstraintDefinitionException;
|
||||
@ -19,24 +19,24 @@ use Symfony\Component\Validator\ConstraintValidator;
|
||||
|
||||
/**
|
||||
* Unique Entity Validator checks if one or a set of fields contain unique values.
|
||||
*
|
||||
*
|
||||
* @author Benjamin Eberlei <kontakt@beberlei.de>
|
||||
*/
|
||||
class UniqueEntityValidator extends ConstraintValidator
|
||||
{
|
||||
/**
|
||||
* @var Registry
|
||||
* @var RegistryInterface
|
||||
*/
|
||||
private $registry;
|
||||
|
||||
|
||||
/**
|
||||
* @param Registry $registry
|
||||
* @param RegistryInterface $registry
|
||||
*/
|
||||
public function __construct(Registry $registry)
|
||||
public function __construct(RegistryInterface $registry)
|
||||
{
|
||||
$this->registry = $registry;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param object $entity
|
||||
* @param Constraint $constraint
|
||||
@ -47,35 +47,37 @@ class UniqueEntityValidator extends ConstraintValidator
|
||||
if (!is_array($constraint->fields) && !is_string($constraint->fields)) {
|
||||
throw new UnexpectedTypeException($constraint->fields, 'array');
|
||||
}
|
||||
|
||||
$fields = (array)$constraint->fields;
|
||||
|
||||
if (count($constraint->fields) == 0) {
|
||||
throw new ConstraintDefinitionException("At least one field has to specified.");
|
||||
}
|
||||
|
||||
|
||||
$em = $this->registry->getEntityManager($constraint->em);
|
||||
|
||||
|
||||
$className = $this->context->getCurrentClass();
|
||||
$class = $em->getClassMetadata($className);
|
||||
|
||||
|
||||
$criteria = array();
|
||||
foreach ($fields as $fieldName) {
|
||||
if (!isset($class->reflFields[$fieldName])) {
|
||||
throw new ConstraintDefinitionException("Only field names mapped by Doctrine can be validated for uniqueness.");
|
||||
}
|
||||
|
||||
|
||||
$criteria[$fieldName] = $class->reflFields[$fieldName]->getValue($entity);
|
||||
}
|
||||
|
||||
|
||||
$repository = $em->getRepository($className);
|
||||
$result = $repository->findBy($criteria);
|
||||
|
||||
|
||||
if (count($result) > 0 && $result[0] !== $entity) {
|
||||
$oldPath = $this->context->getPropertyPath();
|
||||
$this->context->setPropertyPath( empty($oldPath) ? $fields[0] : $oldPath . "." . $fields[0]);
|
||||
$this->context->addViolation($constraint->message, array(), $criteria[$constraint->fields[0]]);
|
||||
$this->context->setPropertyPath($oldPath);
|
||||
}
|
||||
|
||||
|
||||
return true; // all true, we added the violation already!
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -11,7 +11,7 @@
|
||||
|
||||
namespace Symfony\Bundle\DoctrineBundle\CacheWarmer;
|
||||
|
||||
use Symfony\Bundle\DoctrineBundle\Registry;
|
||||
use Symfony\Bridge\Doctrine\RegistryInterface;
|
||||
use Symfony\Component\HttpKernel\CacheWarmer\CacheWarmerInterface;
|
||||
|
||||
/**
|
||||
@ -29,9 +29,9 @@ class ProxyCacheWarmer implements CacheWarmerInterface
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param Registry $registry The Doctrine registry
|
||||
* @param RegistryInterface $registry A RegistryInterface instance
|
||||
*/
|
||||
public function __construct(Registry $registry)
|
||||
public function __construct(RegistryInterface $registry)
|
||||
{
|
||||
$this->registry = $registry;
|
||||
}
|
||||
|
@ -15,7 +15,7 @@ use Symfony\Component\HttpKernel\DataCollector\DataCollector;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
use Symfony\Bundle\DoctrineBundle\Logger\DbalLogger;
|
||||
use Symfony\Bundle\DoctrineBundle\Registry;
|
||||
use Symfony\Bridge\Doctrine\RegistryInterface;
|
||||
|
||||
/**
|
||||
* DoctrineDataCollector.
|
||||
@ -28,7 +28,7 @@ class DoctrineDataCollector extends DataCollector
|
||||
private $managers;
|
||||
private $logger;
|
||||
|
||||
public function __construct(Registry $registry, DbalLogger $logger = null)
|
||||
public function __construct(RegistryInterface $registry, DbalLogger $logger = null)
|
||||
{
|
||||
$this->connections = $registry->getConnectionNames();
|
||||
$this->managers = $registry->getEntityManagerNames();
|
||||
|
@ -11,7 +11,7 @@
|
||||
|
||||
namespace Symfony\Bundle\DoctrineBundle\Mapping;
|
||||
|
||||
use Symfony\Bundle\DoctrineBundle\Registry;
|
||||
use Symfony\Bridge\Doctrine\RegistryInterface;
|
||||
use Symfony\Component\HttpKernel\Bundle\BundleInterface;
|
||||
use Doctrine\ORM\Tools\EntityRepositoryGenerator;
|
||||
use Doctrine\ORM\Mapping\ClassMetadata;
|
||||
@ -31,9 +31,9 @@ class MetadataFactory
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param Registry $registry A Registry instance
|
||||
* @param RegistryInterface $registry A RegistryInterface instance
|
||||
*/
|
||||
public function __construct(Registry $registry)
|
||||
public function __construct(RegistryInterface $registry)
|
||||
{
|
||||
$this->registry = $registry;
|
||||
}
|
||||
|
@ -12,6 +12,7 @@
|
||||
namespace Symfony\Bundle\DoctrineBundle;
|
||||
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
use Symfony\Bridge\Doctrine\RegistryInterface;
|
||||
use Doctrine\DBAL\Connection;
|
||||
use Doctrine\ORM\Configuration;
|
||||
use Doctrine\ORM\ORMException;
|
||||
@ -21,7 +22,7 @@ use Doctrine\ORM\ORMException;
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*/
|
||||
class Registry
|
||||
class Registry implements RegistryInterface
|
||||
{
|
||||
private $container;
|
||||
private $connections;
|
||||
@ -203,7 +204,6 @@ class Registry
|
||||
return $this->entityManagers;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Gets the EntityRepository for an entity.
|
||||
*
|
||||
|
@ -49,12 +49,12 @@
|
||||
|
||||
<service id="form.type_guesser.doctrine" class="%form.type_guesser.doctrine.class%">
|
||||
<tag name="form.type_guesser" />
|
||||
<argument type="service" id="doctrine.orm.entity_manager" />
|
||||
<argument type="service" id="doctrine" />
|
||||
</service>
|
||||
|
||||
<service id="form.type.entity" class="Symfony\Bridge\Doctrine\Form\Type\EntityType">
|
||||
<tag name="form.type" alias="entity" />
|
||||
<argument type="service" id="doctrine.orm.entity_manager" />
|
||||
<argument type="service" id="doctrine" />
|
||||
</service>
|
||||
|
||||
<service id="doctrine.orm.configuration" class="%doctrine.orm.configuration.class%" abstract="true" public="false" />
|
||||
|
@ -32,7 +32,7 @@ abstract class DoctrineOrmTestCase extends \PHPUnit_Framework_TestCase
|
||||
/**
|
||||
* @return EntityManager
|
||||
*/
|
||||
public static function createTestEntityManager($paths = array())
|
||||
static public function createTestEntityManager($paths = array())
|
||||
{
|
||||
$config = new \Doctrine\ORM\Configuration();
|
||||
$config->setAutoGenerateProxyClasses(true);
|
||||
|
@ -70,7 +70,7 @@ class EntityTypeTest extends TypeTestCase
|
||||
protected function getExtensions()
|
||||
{
|
||||
return array_merge(parent::getExtensions(), array(
|
||||
new DoctrineOrmExtension($this->em),
|
||||
new DoctrineOrmExtension($this->createRegistryMock('default', $this->em)),
|
||||
));
|
||||
}
|
||||
|
||||
@ -93,7 +93,7 @@ class EntityTypeTest extends TypeTestCase
|
||||
// $this->persist(array($entity1, $entity2));
|
||||
//
|
||||
// $field = $this->factory->createNamed('entity', 'name', null, array(
|
||||
// 'em' => $this->em,
|
||||
// 'em' => 'default',
|
||||
// 'class' => self::SINGLE_IDENT_CLASS,
|
||||
// 'required' => false,
|
||||
// 'property' => 'name'
|
||||
@ -109,7 +109,7 @@ class EntityTypeTest extends TypeTestCase
|
||||
public function testConfigureQueryBuilderWithNonQueryBuilderAndNonClosure()
|
||||
{
|
||||
$field = $this->factory->createNamed('entity', 'name', null, array(
|
||||
'em' => $this->em,
|
||||
'em' => 'default',
|
||||
'class' => self::SINGLE_IDENT_CLASS,
|
||||
'query_builder' => new \stdClass(),
|
||||
));
|
||||
@ -121,7 +121,7 @@ class EntityTypeTest extends TypeTestCase
|
||||
public function testConfigureQueryBuilderWithClosureReturningNonQueryBuilder()
|
||||
{
|
||||
$field = $this->factory->createNamed('entity', 'name', null, array(
|
||||
'em' => $this->em,
|
||||
'em' => 'default',
|
||||
'class' => self::SINGLE_IDENT_CLASS,
|
||||
'query_builder' => function () {
|
||||
return new \stdClass();
|
||||
@ -135,7 +135,7 @@ class EntityTypeTest extends TypeTestCase
|
||||
{
|
||||
$field = $this->factory->createNamed('entity', 'name', null, array(
|
||||
'multiple' => false,
|
||||
'em' => $this->em,
|
||||
'em' => 'default',
|
||||
'class' => self::SINGLE_IDENT_CLASS,
|
||||
));
|
||||
$field->setData(null);
|
||||
@ -149,7 +149,7 @@ class EntityTypeTest extends TypeTestCase
|
||||
$field = $this->factory->createNamed('entity', 'name', null, array(
|
||||
'multiple' => true,
|
||||
'expanded' => true,
|
||||
'em' => $this->em,
|
||||
'em' => 'default',
|
||||
'class' => self::SINGLE_IDENT_CLASS,
|
||||
));
|
||||
$field->setData(null);
|
||||
@ -163,7 +163,7 @@ class EntityTypeTest extends TypeTestCase
|
||||
$field = $this->factory->createNamed('entity', 'name', null, array(
|
||||
'multiple' => true,
|
||||
'expanded' => false,
|
||||
'em' => $this->em,
|
||||
'em' => 'default',
|
||||
'class' => self::SINGLE_IDENT_CLASS,
|
||||
));
|
||||
$field->setData(null);
|
||||
@ -177,7 +177,7 @@ class EntityTypeTest extends TypeTestCase
|
||||
$field = $this->factory->createNamed('entity', 'name', null, array(
|
||||
'multiple' => false,
|
||||
'expanded' => true,
|
||||
'em' => $this->em,
|
||||
'em' => 'default',
|
||||
'class' => self::SINGLE_IDENT_CLASS,
|
||||
));
|
||||
$field->bind(null);
|
||||
@ -191,7 +191,7 @@ class EntityTypeTest extends TypeTestCase
|
||||
$field = $this->factory->createNamed('entity', 'name', null, array(
|
||||
'multiple' => false,
|
||||
'expanded' => false,
|
||||
'em' => $this->em,
|
||||
'em' => 'default',
|
||||
'class' => self::SINGLE_IDENT_CLASS,
|
||||
));
|
||||
$field->bind(null);
|
||||
@ -204,7 +204,7 @@ class EntityTypeTest extends TypeTestCase
|
||||
{
|
||||
$field = $this->factory->createNamed('entity', 'name', null, array(
|
||||
'multiple' => true,
|
||||
'em' => $this->em,
|
||||
'em' => 'default',
|
||||
'class' => self::SINGLE_IDENT_CLASS,
|
||||
));
|
||||
$field->bind(null);
|
||||
@ -223,7 +223,7 @@ class EntityTypeTest extends TypeTestCase
|
||||
$field = $this->factory->createNamed('entity', 'name', null, array(
|
||||
'multiple' => false,
|
||||
'expanded' => false,
|
||||
'em' => $this->em,
|
||||
'em' => 'default',
|
||||
'class' => self::SINGLE_IDENT_CLASS,
|
||||
'property' => 'name',
|
||||
));
|
||||
@ -245,7 +245,7 @@ class EntityTypeTest extends TypeTestCase
|
||||
$field = $this->factory->createNamed('entity', 'name', null, array(
|
||||
'multiple' => false,
|
||||
'expanded' => false,
|
||||
'em' => $this->em,
|
||||
'em' => 'default',
|
||||
'class' => self::COMPOSITE_IDENT_CLASS,
|
||||
'property' => 'name',
|
||||
));
|
||||
@ -269,7 +269,7 @@ class EntityTypeTest extends TypeTestCase
|
||||
$field = $this->factory->createNamed('entity', 'name', null, array(
|
||||
'multiple' => true,
|
||||
'expanded' => false,
|
||||
'em' => $this->em,
|
||||
'em' => 'default',
|
||||
'class' => self::SINGLE_IDENT_CLASS,
|
||||
'property' => 'name',
|
||||
));
|
||||
@ -294,7 +294,7 @@ class EntityTypeTest extends TypeTestCase
|
||||
$field = $this->factory->createNamed('entity', 'name', null, array(
|
||||
'multiple' => true,
|
||||
'expanded' => false,
|
||||
'em' => $this->em,
|
||||
'em' => 'default',
|
||||
'class' => self::SINGLE_IDENT_CLASS,
|
||||
'property' => 'name',
|
||||
));
|
||||
@ -325,7 +325,7 @@ class EntityTypeTest extends TypeTestCase
|
||||
$field = $this->factory->createNamed('entity', 'name', null, array(
|
||||
'multiple' => true,
|
||||
'expanded' => false,
|
||||
'em' => $this->em,
|
||||
'em' => 'default',
|
||||
'class' => self::COMPOSITE_IDENT_CLASS,
|
||||
'property' => 'name',
|
||||
));
|
||||
@ -351,7 +351,7 @@ class EntityTypeTest extends TypeTestCase
|
||||
$field = $this->factory->createNamed('entity', 'name', null, array(
|
||||
'multiple' => true,
|
||||
'expanded' => false,
|
||||
'em' => $this->em,
|
||||
'em' => 'default',
|
||||
'class' => self::COMPOSITE_IDENT_CLASS,
|
||||
'property' => 'name',
|
||||
));
|
||||
@ -381,7 +381,7 @@ class EntityTypeTest extends TypeTestCase
|
||||
$field = $this->factory->createNamed('entity', 'name', null, array(
|
||||
'multiple' => false,
|
||||
'expanded' => true,
|
||||
'em' => $this->em,
|
||||
'em' => 'default',
|
||||
'class' => self::SINGLE_IDENT_CLASS,
|
||||
'property' => 'name',
|
||||
));
|
||||
@ -407,7 +407,7 @@ class EntityTypeTest extends TypeTestCase
|
||||
$field = $this->factory->createNamed('entity', 'name', null, array(
|
||||
'multiple' => true,
|
||||
'expanded' => true,
|
||||
'em' => $this->em,
|
||||
'em' => 'default',
|
||||
'class' => self::SINGLE_IDENT_CLASS,
|
||||
'property' => 'name',
|
||||
));
|
||||
@ -437,7 +437,7 @@ class EntityTypeTest extends TypeTestCase
|
||||
$this->persist(array($entity1, $entity2, $entity3));
|
||||
|
||||
$field = $this->factory->createNamed('entity', 'name', null, array(
|
||||
'em' => $this->em,
|
||||
'em' => 'default',
|
||||
'class' => self::SINGLE_IDENT_CLASS,
|
||||
// not all persisted entities should be displayed
|
||||
'choices' => array($entity1, $entity2),
|
||||
@ -461,7 +461,7 @@ class EntityTypeTest extends TypeTestCase
|
||||
$this->persist(array($entity1, $entity2, $entity3));
|
||||
|
||||
$field = $this->factory->createNamed('entity', 'name', null, array(
|
||||
'em' => $this->em,
|
||||
'em' => 'default',
|
||||
'class' => self::SINGLE_IDENT_CLASS,
|
||||
'choices' => array($entity1, $entity2),
|
||||
'property' => 'name',
|
||||
@ -482,7 +482,7 @@ class EntityTypeTest extends TypeTestCase
|
||||
$this->persist(array($entity1, $entity2, $entity3));
|
||||
|
||||
$field = $this->factory->createNamed('entity', 'name', null, array(
|
||||
'em' => $this->em,
|
||||
'em' => 'default',
|
||||
'class' => self::COMPOSITE_IDENT_CLASS,
|
||||
'choices' => array($entity1, $entity2),
|
||||
'property' => 'name',
|
||||
@ -505,7 +505,7 @@ class EntityTypeTest extends TypeTestCase
|
||||
$repository = $this->em->getRepository(self::SINGLE_IDENT_CLASS);
|
||||
|
||||
$field = $this->factory->createNamed('entity', 'name', null, array(
|
||||
'em' => $this->em,
|
||||
'em' => 'default',
|
||||
'class' => self::SINGLE_IDENT_CLASS,
|
||||
'query_builder' => $repository->createQueryBuilder('e')
|
||||
->where('e.id IN (1, 2)'),
|
||||
@ -527,7 +527,7 @@ class EntityTypeTest extends TypeTestCase
|
||||
$this->persist(array($entity1, $entity2, $entity3));
|
||||
|
||||
$field = $this->factory->createNamed('entity', 'name', null, array(
|
||||
'em' => $this->em,
|
||||
'em' => 'default',
|
||||
'class' => self::SINGLE_IDENT_CLASS,
|
||||
'query_builder' => function ($repository) {
|
||||
return $repository->createQueryBuilder('e')
|
||||
@ -551,7 +551,7 @@ class EntityTypeTest extends TypeTestCase
|
||||
$this->persist(array($entity1, $entity2, $entity3));
|
||||
|
||||
$field = $this->factory->createNamed('entity', 'name', null, array(
|
||||
'em' => $this->em,
|
||||
'em' => 'default',
|
||||
'class' => self::COMPOSITE_IDENT_CLASS,
|
||||
'query_builder' => function ($repository) {
|
||||
return $repository->createQueryBuilder('e')
|
||||
@ -575,7 +575,7 @@ class EntityTypeTest extends TypeTestCase
|
||||
$field = $this->factory->createNamed('entity', 'name', null, array(
|
||||
'multiple' => false,
|
||||
'expanded' => false,
|
||||
'em' => $this->em,
|
||||
'em' => 'default',
|
||||
'class' => self::SINGLE_STRING_IDENT_CLASS,
|
||||
'property' => 'name',
|
||||
));
|
||||
@ -596,7 +596,7 @@ class EntityTypeTest extends TypeTestCase
|
||||
$field = $this->factory->createNamed('entity', 'name', null, array(
|
||||
'multiple' => false,
|
||||
'expanded' => false,
|
||||
'em' => $this->em,
|
||||
'em' => 'default',
|
||||
'class' => self::COMPOSITE_STRING_IDENT_CLASS,
|
||||
'property' => 'name',
|
||||
));
|
||||
@ -608,4 +608,15 @@ class EntityTypeTest extends TypeTestCase
|
||||
$this->assertEquals($entity1, $field->getData());
|
||||
$this->assertEquals(0, $field->getClientData());
|
||||
}
|
||||
|
||||
protected function createRegistryMock($name, $em)
|
||||
{
|
||||
$registry = $this->getMock('Symfony\Bridge\Doctrine\RegistryInterface');
|
||||
$registry->expects($this->any())
|
||||
->method('getEntityManager')
|
||||
->with($this->equalTo($name))
|
||||
->will($this->returnValue($em));
|
||||
|
||||
return $registry;
|
||||
}
|
||||
}
|
||||
|
@ -27,14 +27,15 @@ class UniqueValidatorTest extends DoctrineOrmTestCase
|
||||
{
|
||||
protected function createRegistryMock($entityManagerName, $em)
|
||||
{
|
||||
$registry = $this->getMock('Symfony\Bundle\DoctrineBundle\Registry', array(), array(), '', false);
|
||||
$registry = $this->getMock('Symfony\Bridge\Doctrine\RegistryInterface');
|
||||
$registry->expects($this->any())
|
||||
->method('getEntityManager')
|
||||
->with($this->equalTo($entityManagerName))
|
||||
->will($this->returnValue($em));
|
||||
|
||||
return $registry;
|
||||
}
|
||||
|
||||
|
||||
protected function createMetadataFactoryMock($metadata)
|
||||
{
|
||||
$metadataFactory = $this->getMock('Symfony\Component\Validator\Mapping\ClassMetadataFactoryInterface');
|
||||
@ -42,9 +43,10 @@ class UniqueValidatorTest extends DoctrineOrmTestCase
|
||||
->method('getClassMetadata')
|
||||
->with($this->equalTo($metadata->name))
|
||||
->will($this->returnValue($metadata));
|
||||
|
||||
return $metadataFactory;
|
||||
}
|
||||
|
||||
|
||||
protected function createValidatorFactory($uniqueValidator)
|
||||
{
|
||||
$validatorFactory = $this->getMock('Symfony\Component\Validator\ConstraintValidatorFactoryInterface');
|
||||
@ -52,9 +54,10 @@ class UniqueValidatorTest extends DoctrineOrmTestCase
|
||||
->method('getInstance')
|
||||
->with($this->isInstanceOf('Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity'))
|
||||
->will($this->returnValue($uniqueValidator));
|
||||
|
||||
return $validatorFactory;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This is a functinoal test as there is a large integration necessary to get the validator working.
|
||||
*/
|
||||
@ -66,38 +69,38 @@ class UniqueValidatorTest extends DoctrineOrmTestCase
|
||||
$schemaTool->createSchema(array(
|
||||
$em->getClassMetadata('Symfony\Tests\Bridge\Doctrine\Form\Fixtures\SingleIdentEntity')
|
||||
));
|
||||
|
||||
|
||||
$entity1 = new SingleIdentEntity(1, 'Foo');
|
||||
|
||||
|
||||
$registry = $this->createRegistryMock($entityManagerName, $em);
|
||||
|
||||
|
||||
$uniqueValidator = new UniqueEntityValidator($registry);
|
||||
|
||||
|
||||
$metadata = new ClassMetadata('Symfony\Tests\Bridge\Doctrine\Form\Fixtures\SingleIdentEntity');
|
||||
$metadata->addConstraint(new UniqueEntity(array('fields' => array('name'), 'em' => $entityManagerName)));
|
||||
|
||||
|
||||
$metadataFactory = $this->createMetadataFactoryMock($metadata);
|
||||
$validatorFactory = $this->createValidatorFactory($uniqueValidator);
|
||||
|
||||
|
||||
$validator = new Validator($metadataFactory, $validatorFactory);
|
||||
|
||||
|
||||
$violationsList = $validator->validate($entity1);
|
||||
$this->assertEquals(0, $violationsList->count(), "No violations found on entity before it is saved to the database.");
|
||||
|
||||
|
||||
$em->persist($entity1);
|
||||
$em->flush();
|
||||
|
||||
|
||||
$violationsList = $validator->validate($entity1);
|
||||
$this->assertEquals(0, $violationsList->count(), "No violations found on entity after it was saved to the database.");
|
||||
|
||||
|
||||
$entity2 = new SingleIdentEntity(2, 'Foo');
|
||||
|
||||
|
||||
$violationsList = $validator->validate($entity2);
|
||||
$this->assertEquals(1, $violationsList->count(), "No violations found on entity after it was saved to the database.");
|
||||
|
||||
|
||||
$violation = $violationsList[0];
|
||||
$this->assertEquals('This value is already used.', $violation->getMessage());
|
||||
$this->assertEquals('name', $violation->getPropertyPath());
|
||||
$this->assertEquals('Foo', $violation->getInvalidValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user