Skip to content

Commit

Permalink
Fix Metadata Caching when it changes in EventListeners
Browse files Browse the repository at this point in the history
  • Loading branch information
andrey-bondar-dron committed Nov 21, 2018
1 parent 6f785d5 commit 685b819
Showing 1 changed file with 34 additions and 33 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,9 @@ abstract class AbstractClassMetadataFactory implements ClassMetadataFactory
/** @var ClassMetadata[] */
private $loadedMetadata = [];

/** @var array */
private $aliasesMap = [];

/** @var bool */
protected $initialized = false;

Expand Down Expand Up @@ -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];
Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -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;
}
}

0 comments on commit 685b819

Please sign in to comment.