From fbf36957e671721cc20cf76f16aeaab2723cd045 Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Wed, 8 Jun 2011 08:07:12 +0200 Subject: [PATCH] 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. --- UPDATE.md | 4 + .../Doctrine/Form/DoctrineOrmExtension.php | 16 +- .../Doctrine/Form/DoctrineOrmTypeGuesser.php | 202 ++++++------------ .../Bridge/Doctrine/Form/Type/EntityType.php | 14 +- .../Bridge/Doctrine/RegistryInterface.php | 127 +++++++++++ .../Validator/Constraints/UniqueEntity.php | 12 +- .../Constraints/UniqueEntityValidator.php | 32 +-- .../CacheWarmer/ProxyCacheWarmer.php | 6 +- .../DataCollector/DoctrineDataCollector.php | 4 +- .../Mapping/MetadataFactory.php | 6 +- .../Bundle/DoctrineBundle/Registry.php | 4 +- .../DoctrineBundle/Resources/config/orm.xml | 4 +- .../Doctrine/Form/DoctrineOrmTestCase.php | 2 +- .../Doctrine/Form/Type/EntityTypeTest.php | 63 +++--- .../Constraints/UniqueValidatorTest.php | 37 ++-- 15 files changed, 308 insertions(+), 225 deletions(-) create mode 100644 src/Symfony/Bridge/Doctrine/RegistryInterface.php diff --git a/UPDATE.md b/UPDATE.md index 0609708f6c..34854e33ce 100644 --- a/UPDATE.md +++ b/UPDATE.md @@ -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()`). diff --git a/src/Symfony/Bridge/Doctrine/Form/DoctrineOrmExtension.php b/src/Symfony/Bridge/Doctrine/Form/DoctrineOrmExtension.php index 49a8e288fc..eed0ab2c22 100644 --- a/src/Symfony/Bridge/Doctrine/Form/DoctrineOrmExtension.php +++ b/src/Symfony/Bridge/Doctrine/Form/DoctrineOrmExtension.php @@ -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); } } diff --git a/src/Symfony/Bridge/Doctrine/Form/DoctrineOrmTypeGuesser.php b/src/Symfony/Bridge/Doctrine/Form/DoctrineOrmTypeGuesser.php index 538a1231ec..3711f7f52f 100644 --- a/src/Symfony/Bridge/Doctrine/Form/DoctrineOrmTypeGuesser.php +++ b/src/Symfony/Bridge/Doctrine/Form/DoctrineOrmTypeGuesser.php @@ -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); + } + } } } diff --git a/src/Symfony/Bridge/Doctrine/Form/Type/EntityType.php b/src/Symfony/Bridge/Doctrine/Form/Type/EntityType.php index dc6c77be74..b7d60b662d 100644 --- a/src/Symfony/Bridge/Doctrine/Form/Type/EntityType.php +++ b/src/Symfony/Bridge/Doctrine/Form/Type/EntityType.php @@ -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'; } -} \ No newline at end of file +} diff --git a/src/Symfony/Bridge/Doctrine/RegistryInterface.php b/src/Symfony/Bridge/Doctrine/RegistryInterface.php new file mode 100644 index 0000000000..8494528bf0 --- /dev/null +++ b/src/Symfony/Bridge/Doctrine/RegistryInterface.php @@ -0,0 +1,127 @@ + + * + * 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 + */ +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); +} diff --git a/src/Symfony/Bridge/Doctrine/Validator/Constraints/UniqueEntity.php b/src/Symfony/Bridge/Doctrine/Validator/Constraints/UniqueEntity.php index fd011ff4c0..24e115a4a2 100644 --- a/src/Symfony/Bridge/Doctrine/Validator/Constraints/UniqueEntity.php +++ b/src/Symfony/Bridge/Doctrine/Validator/Constraints/UniqueEntity.php @@ -17,7 +17,7 @@ use Symfony\Component\Validator\Exception\UnexpectedTypeException; /** * Constraint for the Unique Entity validator - * + * * @author Benjamin Eberlei */ 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'; } -} \ No newline at end of file +} diff --git a/src/Symfony/Bridge/Doctrine/Validator/Constraints/UniqueEntityValidator.php b/src/Symfony/Bridge/Doctrine/Validator/Constraints/UniqueEntityValidator.php index e166f015c3..826163ecea 100644 --- a/src/Symfony/Bridge/Doctrine/Validator/Constraints/UniqueEntityValidator.php +++ b/src/Symfony/Bridge/Doctrine/Validator/Constraints/UniqueEntityValidator.php @@ -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 */ 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! } -} \ No newline at end of file +} diff --git a/src/Symfony/Bundle/DoctrineBundle/CacheWarmer/ProxyCacheWarmer.php b/src/Symfony/Bundle/DoctrineBundle/CacheWarmer/ProxyCacheWarmer.php index 09fdf01869..955dd6ca29 100644 --- a/src/Symfony/Bundle/DoctrineBundle/CacheWarmer/ProxyCacheWarmer.php +++ b/src/Symfony/Bundle/DoctrineBundle/CacheWarmer/ProxyCacheWarmer.php @@ -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; } diff --git a/src/Symfony/Bundle/DoctrineBundle/DataCollector/DoctrineDataCollector.php b/src/Symfony/Bundle/DoctrineBundle/DataCollector/DoctrineDataCollector.php index 028ea09e09..948dfa4ec9 100644 --- a/src/Symfony/Bundle/DoctrineBundle/DataCollector/DoctrineDataCollector.php +++ b/src/Symfony/Bundle/DoctrineBundle/DataCollector/DoctrineDataCollector.php @@ -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(); diff --git a/src/Symfony/Bundle/DoctrineBundle/Mapping/MetadataFactory.php b/src/Symfony/Bundle/DoctrineBundle/Mapping/MetadataFactory.php index 8be38e8ac8..662a43c091 100644 --- a/src/Symfony/Bundle/DoctrineBundle/Mapping/MetadataFactory.php +++ b/src/Symfony/Bundle/DoctrineBundle/Mapping/MetadataFactory.php @@ -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; } diff --git a/src/Symfony/Bundle/DoctrineBundle/Registry.php b/src/Symfony/Bundle/DoctrineBundle/Registry.php index 5d7bbef382..a435119c87 100644 --- a/src/Symfony/Bundle/DoctrineBundle/Registry.php +++ b/src/Symfony/Bundle/DoctrineBundle/Registry.php @@ -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 */ -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. * diff --git a/src/Symfony/Bundle/DoctrineBundle/Resources/config/orm.xml b/src/Symfony/Bundle/DoctrineBundle/Resources/config/orm.xml index df95d02941..539490ed2a 100644 --- a/src/Symfony/Bundle/DoctrineBundle/Resources/config/orm.xml +++ b/src/Symfony/Bundle/DoctrineBundle/Resources/config/orm.xml @@ -49,12 +49,12 @@ - + - + diff --git a/tests/Symfony/Tests/Bridge/Doctrine/Form/DoctrineOrmTestCase.php b/tests/Symfony/Tests/Bridge/Doctrine/Form/DoctrineOrmTestCase.php index 442341ad0c..e3b8ebac10 100644 --- a/tests/Symfony/Tests/Bridge/Doctrine/Form/DoctrineOrmTestCase.php +++ b/tests/Symfony/Tests/Bridge/Doctrine/Form/DoctrineOrmTestCase.php @@ -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); diff --git a/tests/Symfony/Tests/Bridge/Doctrine/Form/Type/EntityTypeTest.php b/tests/Symfony/Tests/Bridge/Doctrine/Form/Type/EntityTypeTest.php index f772d71be6..7aed8b3fe2 100644 --- a/tests/Symfony/Tests/Bridge/Doctrine/Form/Type/EntityTypeTest.php +++ b/tests/Symfony/Tests/Bridge/Doctrine/Form/Type/EntityTypeTest.php @@ -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; + } } diff --git a/tests/Symfony/Tests/Bridge/Doctrine/Validator/Constraints/UniqueValidatorTest.php b/tests/Symfony/Tests/Bridge/Doctrine/Validator/Constraints/UniqueValidatorTest.php index f904fa33d2..7f1918023c 100644 --- a/tests/Symfony/Tests/Bridge/Doctrine/Validator/Constraints/UniqueValidatorTest.php +++ b/tests/Symfony/Tests/Bridge/Doctrine/Validator/Constraints/UniqueValidatorTest.php @@ -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()); } -} \ No newline at end of file +}