From 7a73d27600c178f75a3dd64d67c3bcc867c7aa34 Mon Sep 17 00:00:00 2001 From: mmoreram Date: Tue, 9 Sep 2014 17:13:34 +0200 Subject: [PATCH] Added resolve entities support in discrim. map --- .../ORM/Mapping/ClassMetadataInfo.php | 2 +- .../Tools/ResolveDiscriminatorMapListener.php | 87 +++++++++++++++++++ 2 files changed, 88 insertions(+), 1 deletion(-) create mode 100644 lib/Doctrine/ORM/Tools/ResolveDiscriminatorMapListener.php diff --git a/lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php b/lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php index 67567456c..b88261a4d 100644 --- a/lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php +++ b/lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php @@ -2748,7 +2748,7 @@ class ClassMetadataInfo implements ClassMetadata if ($this->name == $className) { $this->discriminatorValue = $name; } else { - if ( ! class_exists($className)) { + if ( ! class_exists($className) && ! interface_exists($className)) { throw MappingException::invalidClassInDiscriminatorMap($className, $this->name); } if (is_subclass_of($className, $this->name) && ! in_array($className, $this->subClasses)) { diff --git a/lib/Doctrine/ORM/Tools/ResolveDiscriminatorMapListener.php b/lib/Doctrine/ORM/Tools/ResolveDiscriminatorMapListener.php new file mode 100644 index 000000000..5dc16b768 --- /dev/null +++ b/lib/Doctrine/ORM/Tools/ResolveDiscriminatorMapListener.php @@ -0,0 +1,87 @@ +. + */ + +namespace Doctrine\ORM\Tools; + +use Doctrine\ORM\Event\LoadClassMetadataEventArgs; +use Doctrine\ORM\Mapping\ClassMetadataInfo; + +/** + * ResolveDiscriminatorMapListener + * + * Mechanism to overwrite interfaces or classes specified in discrimination map + * + * @author Benjamin Eberlei + * @since 2.2 + */ +class ResolveDiscriminatorMapListener +{ + /** + * @var array + */ + private $resolveTargetEntities = array(); + + /** + * Adds a target-entity class name to resolve to a new class name. + * + * @param string $originalEntity + * @param string $newEntity + * @param array $mapping + * + * @return void + */ + public function addResolveTargetEntity($originalEntity, $newEntity, array $mapping) + { + $mapping['targetEntity'] = ltrim($newEntity, "\\"); + $this->resolveTargetEntities[ltrim($originalEntity, "\\")] = $mapping; + } + + /** + * Processes event and resolves new target entity names. + * + * @param LoadClassMetadataEventArgs $args + * + * @return void + */ + public function loadClassMetadata(LoadClassMetadataEventArgs $args) + { + $classMetadata = $args->getClassMetadata(); + + if (!empty($classMetadata->discriminatorMap)) { + + $this->remapDiscriminatorMap($classMetadata); + } + } + + /** + * Replaces all Interfaces in discriminator map + * + * @param \Doctrine\ORM\Mapping\ClassMetadataInfo $classMetadata + */ + private function remapDiscriminatorMap(ClassMetadataInfo $classMetadata) + { + foreach ($classMetadata->discriminatorMap as $name => $interface) { + + if (isset($this->resolveTargetEntities[$interface])) { + + $classMetadata->discriminatorMap[$name] = $this->resolveTargetEntities[$interface]['targetEntity']; + } + } + } +}