Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Metadata caching isn't compatible with prefixed cache keys #338

Open
wants to merge 7 commits into
base: 3.3.x
Choose a base branch
from
16 changes: 3 additions & 13 deletions src/Persistence/Mapping/AbstractClassMetadataFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,6 @@
use ReflectionClass;
use ReflectionException;

use function array_combine;
use function array_keys;
use function array_map;
use function array_reverse;
use function array_unshift;
use function assert;
Expand Down Expand Up @@ -205,17 +202,10 @@ public function getMetadataFor(string $className)
$this->wakeupReflection($cached, $this->getReflectionService());
} else {
$loadedMetadata = $this->loadMetadata($realClassName);
$classNames = array_combine(
array_map([$this, 'getCacheKey'], $loadedMetadata),
$loadedMetadata
);

foreach ($this->cache->getItems(array_keys($classNames)) as $item) {
if (! isset($classNames[$item->getKey()])) {
continue;
}

$item->set($this->loadedMetadata[$classNames[$item->getKey()]]);
foreach ($loadedMetadata as $loadedClassName) {
$item = $this->cache->getItem($this->getCacheKey($loadedClassName));
$item->set($this->loadedMetadata[$loadedClassName]);
$this->cache->saveDeferred($item);
}

Expand Down
27 changes: 27 additions & 0 deletions tests/Persistence/Mapping/AbstractClassMetadataFactoryTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
use Doctrine\Persistence\Mapping\Driver\MappingDriver;
use Doctrine\Persistence\Mapping\MappingException;
use Doctrine\Tests\DoctrineTestCase;
use Psr\Cache\CacheItemInterface;
use Psr\Cache\CacheItemPoolInterface;

use function get_class;

Expand Down Expand Up @@ -83,6 +85,31 @@ public function testItGetsTheSameMetadataForBackslashedClassName(): void

self::assertSame($cmf->getMetadataFor(SomeOtherEntity::class), $cmf->getMetadataFor('\\' . SomeOtherEntity::class));
}

public function testCacheStoredWithPrefixedKeys(): void
{
$cmf = $this->getMockForAbstractClass(AbstractClassMetadataFactory::class);
$cmf
->method('newClassMetadataInstance')
->with(SomeOtherEntity::class)
->willReturn(
$this->createStub(ClassMetadata::class)
);

$cache = $this->createMock(CacheItemPoolInterface::class);
$cmf->setCache($cache);

$cacheItem = $this->createMock(CacheItemInterface::class);
$cacheItem->method('getKey')->willReturn('prefix__Doctrine__Tests__Persistence__Mapping__SomeOtherEntity__CLASSMETADATA__'); //Cache item's key is prefixed
$cache->method('getItem')
->with('Doctrine__Tests__Persistence__Mapping__SomeOtherEntity__CLASSMETADATA__') //Key which is generated from class name is not prefixed
->willReturn($cacheItem);

$cacheItem->expects(self::once())->method('set');
$cache->expects(self::once())->method('saveDeferred');

$cmf->getMetadataFor(SomeOtherEntity::class);
}
}

class SomeGrandParentEntity
Expand Down