From 79afae76ab0e81fc1fcf5f2d4bbc380825602f9b Mon Sep 17 00:00:00 2001 From: Maks3w Date: Tue, 10 May 2016 18:45:22 +0200 Subject: [PATCH 1/2] Don't fail if the cached type is not ClassMetadata This is a random error and I didn't found yet how to reproduce it. It may related with Zend OPCache as usuallly is thrown while hot deploy new versions PHP Fatal error: Uncaught TypeError: Argument 1 passed to Doctrine\\ORM\\Mapping\\ClassMetadataFactory::wakeupReflection() must implement interface Doctrine\\Common\\Persistence\\Mapping\\ClassMetadata, array given, called in /v2/vendor/doctrine/common/lib/Doctrine/Common/Persistence/Mapping/AbstractClassMetadataFactory.php on line 214 and defined in /v2/vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/ClassMetadataFactory.php:718 Stack trace: #0 /v2/vendor/doctrine/common/lib/Doctrine/Common/Persistence/Mapping/AbstractClassMetadataFactory.php(214): Doctrine\\ORM\\Mapping\\ClassMetadataFactory->wakeupReflection(Array, Object(Doctrine\\Common\\Persistence\\Mapping\\RuntimeReflectionService)) #1 /v2/vendor/doctrine/orm/lib/Doctrine/ORM/EntityManager.php(281): Doctrine\\Common\\Persistence\\Mapping\\AbstractClassMetadataFactory->getMetadataFor('Model\\\\...') #2 /v2/vendor/doctrine/orm/lib/Doctrine/ORM/Repository/DefaultRepositoryFactory.php(44): Doctrine\\ORM\\EntityManager->getClassMetadata('Model\\\\...') #3 /v2/vendor/doctrine/orm/ in /v2/vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/ClassMetadataFactory.php on line 718 --- .../Common/Persistence/Mapping/AbstractClassMetadataFactory.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/Doctrine/Common/Persistence/Mapping/AbstractClassMetadataFactory.php b/lib/Doctrine/Common/Persistence/Mapping/AbstractClassMetadataFactory.php index 586b2da2c..cba424b06 100644 --- a/lib/Doctrine/Common/Persistence/Mapping/AbstractClassMetadataFactory.php +++ b/lib/Doctrine/Common/Persistence/Mapping/AbstractClassMetadataFactory.php @@ -208,7 +208,7 @@ public function getMetadataFor($className) try { if ($this->cacheDriver) { - if (($cached = $this->cacheDriver->fetch($realClassName . $this->cacheSalt)) !== false) { + if (($cached = $this->cacheDriver->fetch($realClassName . $this->cacheSalt)) instanceof ClassMetadata) { $this->loadedMetadata[$realClassName] = $cached; $this->wakeupReflection($cached, $this->getReflectionService()); From 0b52f6f8f813f57c785b189406637d4062ae56aa Mon Sep 17 00:00:00 2001 From: Marco Pivetta Date: Wed, 30 Nov 2016 17:40:46 +0100 Subject: [PATCH 2/2] Test coverage for issue #717 --- .../Mapping/ClassMetadataFactoryTest.php | 28 +++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/tests/Doctrine/Tests/Common/Persistence/Mapping/ClassMetadataFactoryTest.php b/tests/Doctrine/Tests/Common/Persistence/Mapping/ClassMetadataFactoryTest.php index 0b0a3e4af..ddcdce480 100644 --- a/tests/Doctrine/Tests/Common/Persistence/Mapping/ClassMetadataFactoryTest.php +++ b/tests/Doctrine/Tests/Common/Persistence/Mapping/ClassMetadataFactoryTest.php @@ -2,6 +2,7 @@ namespace Doctrine\Tests\Common\Persistence\Mapping; +use Doctrine\Common\Cache\Cache; use Doctrine\Common\Persistence\Mapping\Driver\MappingDriver; use Doctrine\Common\Persistence\Mapping\MappingException; use Doctrine\Tests\DoctrineTestCase; @@ -10,6 +11,9 @@ use Doctrine\Common\Persistence\Mapping\AbstractClassMetadataFactory; use Doctrine\Common\Cache\ArrayCache; +/** + * @covers \Doctrine\Common\Persistence\Mapping\AbstractClassMetadataFactory + */ class ClassMetadataFactoryTest extends DoctrineTestCase { /** @@ -130,6 +134,30 @@ public function testWillFailOnFallbackFailureWithNotLoadedMetadata() $this->cmf->getMetadataFor('Foo'); } + + /** + * @group 717 + */ + public function testWillIgnoreCacheEntriesThatAreNotMetadataInstances() + { + /* @var $cacheDriver Cache|\PHPUnit_Framework_MockObject_MockObject */ + $cacheDriver = $this->createMock(Cache::class); + + $this->cmf->setCacheDriver($cacheDriver); + + $cacheDriver->expects(self::once())->method('fetch')->with('Foo$CLASSMETADATA')->willReturn(new \stdClass()); + + /* @var $metadata ClassMetadata */ + $metadata = $this->createMock(ClassMetadata::class); + + $fallbackCallback = $this->getMockBuilder(\stdClass::class)->setMethods(['__invoke'])->getMock(); + + $fallbackCallback->expects(self::any())->method('__invoke')->willReturn($metadata); + + $this->cmf->fallbackCallback = $fallbackCallback; + + self::assertSame($metadata, $this->cmf->getMetadataFor('Foo')); + } } class TestClassMetadataFactory extends AbstractClassMetadataFactory