diff --git a/lib/Doctrine/Common/Persistence/Mapping/AbstractClassMetadataFactory.php b/lib/Doctrine/Common/Persistence/Mapping/AbstractClassMetadataFactory.php index ba3e4177..5289c485 100644 --- a/lib/Doctrine/Common/Persistence/Mapping/AbstractClassMetadataFactory.php +++ b/lib/Doctrine/Common/Persistence/Mapping/AbstractClassMetadataFactory.php @@ -35,6 +35,9 @@ abstract class AbstractClassMetadataFactory implements ClassMetadataFactory /** @var ClassMetadata[] */ private $loadedMetadata = []; + /** @var array */ + private $aliasesMap = []; + /** @var bool */ protected $initialized = false; @@ -152,54 +155,35 @@ abstract protected function isEntity(ClassMetadata $class); */ public function getMetadataFor($className) { + $className = $this->getRealClassName($className); + if (isset($this->loadedMetadata[$className])) { return $this->loadedMetadata[$className]; } - // Check for namespace alias - if (strpos($className, ':') !== false) { - [$namespaceAlias, $simpleClassName] = explode(':', $className, 2); - - $realClassName = $this->getFqcnFromAlias($namespaceAlias, $simpleClassName); - } else { - $realClassName = $this->getRealClass($className); - } - - if (isset($this->loadedMetadata[$realClassName])) { - // We do not have the alias name in the map, include it - $this->setMetadataFor($realClassName, $this->loadedMetadata[$realClassName]); - - return $this->loadedMetadata[$realClassName]; - } - $loadingException = null; try { if ($this->cacheDriver) { - $cached = $this->cacheDriver->fetch($realClassName . $this->cacheSalt); + $cached = $this->cacheDriver->fetch($className . $this->cacheSalt); if ($cached instanceof ClassMetadata) { - $this->loadedMetadata[$realClassName] = $cached; + $this->loadedMetadata[$className] = $cached; $this->wakeupReflection($cached, $this->getReflectionService()); } else { - $this->loadMetadata($realClassName); + $this->loadMetadata($className); } } else { - $this->loadMetadata($realClassName); + $this->loadMetadata($className); } } catch (MappingException $loadingException) { - $fallbackMetadataResponse = $this->onNotFoundMetadata($realClassName); + $fallbackMetadataResponse = $this->onNotFoundMetadata($className); if (! $fallbackMetadataResponse) { throw $loadingException; } - $this->setMetadataFor($realClassName, $fallbackMetadataResponse); - } - - if ($className !== $realClassName) { - // We do not have the alias name in the map, include it - $this->setMetadataFor($className, $this->loadedMetadata[$realClassName]); + $this->setMetadataFor($className, $fallbackMetadataResponse); } return $this->loadedMetadata[$className]; @@ -229,6 +213,7 @@ public function hasMetadataFor($className) */ public function setMetadataFor($className, $class) { + $className = $this->getRealClassName($className); $this->loadedMetadata[$className] = $class; if ($this->cacheDriver === null) { @@ -404,16 +389,32 @@ public function getReflectionService() } /** - * Gets the real class name of a class name that could be a proxy. + * Gets the real class name of a class name that could be a proxy or alias. + * + * @param string $className + * + * @return string */ - private function getRealClass(string $class) : string + private function getRealClassName($className) { - $pos = strrpos($class, '\\' . Proxy::MARKER . '\\'); + if (isset($this->aliasesMap[$className])) { + return $this->aliasesMap[$className]; + } - if ($pos === false) { - return $class; + switch (true) { + case strpos($className, ':') !== false: // Check for namespace alias + [$namespaceAlias, $simpleClassName] = explode(':', $className, 2); + $realClassName = $this->getFqcnFromAlias($namespaceAlias, $simpleClassName); + break; + case $pos = strrpos($className, '\\' . Proxy::MARKER . '\\') !== false: // Check for namespace proxy + $realClassName = substr($className, $pos + Proxy::MARKER_LENGTH + 2); + break; + default: + $realClassName = $className; } - return substr($class, $pos + Proxy::MARKER_LENGTH + 2); + $this->aliasesMap[$className] = $realClassName; + + return $realClassName; } }