소스 검색

Add read-through annotation caching and re-generation

This fixes a bug when Gedmo-specific annotation caches are dropped without dropping the related Doctrine annotation. This forces Gedmo metadata re-generation on a cache miss. In order to prevent useless annotation parsing, an empty cache entries are created for Doctrine extensions which are enabled but not present on a given class.

Fixes #89
Justin Hileman 14 년 전
부모
커밋
90f6559b50
2개의 변경된 파일22개의 추가작업 그리고 10개의 파일을 삭제
  1. 8 5
      lib/Gedmo/Mapping/ExtensionMetadataFactory.php
  2. 14 5
      lib/Gedmo/Mapping/MappedEventSubscriber.php

+ 8 - 5
lib/Gedmo/Mapping/ExtensionMetadataFactory.php

@@ -99,12 +99,15 @@ final class ExtensionMetadataFactory
         if ($config) {
             $this->driver->validateFullMetadata($meta, $config);
             $config['useObjectClass'] = $useObjectName;
-            // cache the metadata
-            $cacheId = self::getCacheId($meta->name, $this->extensionNamespace);
-            if ($cacheDriver = $this->objectManager->getMetadataFactory()->getCacheDriver()) {
-                $cacheDriver->save($cacheId, $config, null);
-            }
         }
+
+        // cache the metadata (even if it's empty)
+        // caching empty metadata will prevent re-parsing non-existent annotations
+        $cacheId = self::getCacheId($meta->name, $this->extensionNamespace);
+        if ($cacheDriver = $this->objectManager->getMetadataFactory()->getCacheDriver()) {
+            $cacheDriver->save($cacheId, $config, null);
+        }
+
         return $config;
     }
 

+ 14 - 5
lib/Gedmo/Mapping/MappedEventSubscriber.php

@@ -102,11 +102,20 @@ abstract class MappedEventSubscriber implements EventSubscriber
         if (isset($this->configurations[$class])) {
             $config = $this->configurations[$class];
         } else {
-            $cacheDriver = $objectManager->getMetadataFactory()->getCacheDriver();
-            $cacheId = ExtensionMetadataFactory::getCacheId($class, $this->getNamespace());
-            if ($cacheDriver && ($cached = $cacheDriver->fetch($cacheId)) !== false) {
-                $this->configurations[$class] = $cached;
-                $config = $cached;
+            $factory = $objectManager->getMetadataFactory();
+            $cacheDriver = $factory->getCacheDriver();
+            if ($cacheDriver) {
+                $cacheId = ExtensionMetadataFactory::getCacheId($class, $this->getNamespace());
+                if (($cached = $cacheDriver->fetch($cacheId)) !== false) {
+                    $this->configurations[$class] = $cached;
+                    $config = $cached;
+                } else {
+                    // re-generate metadata on cache miss
+                    $this->loadMetadataForObjectClass($objectManager, $factory->getMetadataFor($class));
+                    if (isset($this->configurations[$class])) {
+                        $config = $this->configurations[$class];
+                    }
+                }
             }
         }
         return $config;