diff --git a/core/lib/Drupal/Component/Annotation/Plugin/Discovery/AnnotatedClassDiscovery.php b/core/lib/Drupal/Component/Annotation/Plugin/Discovery/AnnotatedClassDiscovery.php index 50d8856b3cf23f7f729f6d1d081ba08b8d79a6f1..e564fd087a4dde2ee8f56b7e641f0401411e1bfb 100644 --- a/core/lib/Drupal/Component/Annotation/Plugin/Discovery/AnnotatedClassDiscovery.php +++ b/core/lib/Drupal/Component/Annotation/Plugin/Discovery/AnnotatedClassDiscovery.php @@ -3,6 +3,7 @@ namespace Drupal\Component\Annotation\Plugin\Discovery; use Drupal\Component\Annotation\AnnotationInterface; +use Drupal\Component\FileCache\FileCacheFactory; use Drupal\Component\Plugin\Discovery\DiscoveryInterface; use Drupal\Component\Annotation\Reflection\MockFileFinder; use Doctrine\Common\Annotations\SimpleAnnotationReader; @@ -48,6 +49,13 @@ class AnnotatedClassDiscovery implements DiscoveryInterface { */ protected $annotationNamespaces = []; + /** + * The file cache object. + * + * @var \Drupal\Component\FileCache\FileCacheInterface + */ + protected $fileCache; + /** * Constructs a new instance. * @@ -64,6 +72,10 @@ function __construct($plugin_namespaces = array(), $plugin_definition_annotation $this->pluginNamespaces = $plugin_namespaces; $this->pluginDefinitionAnnotationName = $plugin_definition_annotation_name; $this->annotationNamespaces = $annotation_namespaces; + + $file_cache_suffix = str_replace('\\', '_', $plugin_definition_annotation_name); + $file_cache_suffix .= ':' . hash('crc32b', serialize($annotation_namespaces)); + $this->fileCache = FileCacheFactory::get('annotation_discovery:' . $file_cache_suffix); } /** @@ -110,6 +122,14 @@ public function getDefinitions() { ); foreach ($iterator as $fileinfo) { if ($fileinfo->getExtension() == 'php') { + if ($cached = $this->fileCache->get($fileinfo->getPathName())) { + if (isset($cached['id'])) { + // Explicitly unserialize this to create a new object instance. + $definitions[$cached['id']] = unserialize($cached['content']); + } + continue; + } + $sub_path = $iterator->getSubIterator()->getSubPath(); $sub_path = $sub_path ? str_replace(DIRECTORY_SEPARATOR, '\\', $sub_path) . '\\' : ''; $class = $namespace . '\\' . $sub_path . $fileinfo->getBasename('.php'); @@ -123,7 +143,16 @@ public function getDefinitions() { /** @var $annotation \Drupal\Component\Annotation\AnnotationInterface */ if ($annotation = $reader->getClassAnnotation($parser->getReflectionClass(), $this->pluginDefinitionAnnotationName)) { $this->prepareAnnotationDefinition($annotation, $class); - $definitions[$annotation->getId()] = $annotation->get(); + + $id = $annotation->getId(); + $content = $annotation->get(); + $definitions[$id] = $content; + // Explicitly serialize this to create a new object instance. + $this->fileCache->set($fileinfo->getPathName(), ['id' => $id, 'content' => serialize($content)]); + } + else { + // Store a NULL object, so the file is not reparsed again. + $this->fileCache->set($fileinfo->getPathName(), [NULL]); } } } diff --git a/core/lib/Drupal/Component/Annotation/composer.json b/core/lib/Drupal/Component/Annotation/composer.json index ac59021da91ab816e44126a35b0781a3c61fbaa9..76254ea7faa1ec41b716df8b8f44acbf7b59ba75 100644 --- a/core/lib/Drupal/Component/Annotation/composer.json +++ b/core/lib/Drupal/Component/Annotation/composer.json @@ -8,6 +8,7 @@ "php": ">=5.5.9", "doctrine/common": "2.5.*", "doctrine/annotations": "1.2.*", + "drupal/core-fileCache": "~8.2", "drupal/core-plugin": "~8.2", "drupal/core-utility": "~8.2" }, diff --git a/core/modules/views/tests/src/Unit/ViewsHandlerManagerTest.php b/core/modules/views/tests/src/Unit/ViewsHandlerManagerTest.php index d85fb43acecfb2871ec3f226a9f370c5a3a8fdf0..efbbe49e6f6a1bea4346aa3efb3948ec71f19980 100644 --- a/core/modules/views/tests/src/Unit/ViewsHandlerManagerTest.php +++ b/core/modules/views/tests/src/Unit/ViewsHandlerManagerTest.php @@ -42,6 +42,7 @@ class ViewsHandlerManagerTest extends UnitTestCase { * {@inheritdoc} */ protected function setUp() { + parent::setUp(); $this->viewsData = $this->getMockBuilder('Drupal\views\ViewsData') ->disableOriginalConstructor() ->getMock(); diff --git a/core/tests/Drupal/Tests/Core/Field/BaseFieldDefinitionTestBase.php b/core/tests/Drupal/Tests/Core/Field/BaseFieldDefinitionTestBase.php index e6a5de81b68a730835b1130ee30cd503fed09de0..acb7346db0d3b9f1792e417fce7f709a47c49a42 100644 --- a/core/tests/Drupal/Tests/Core/Field/BaseFieldDefinitionTestBase.php +++ b/core/tests/Drupal/Tests/Core/Field/BaseFieldDefinitionTestBase.php @@ -24,6 +24,7 @@ abstract class BaseFieldDefinitionTestBase extends UnitTestCase { * {@inheritdoc} */ protected function setUp() { + parent::setUp(); // getModuleAndPath() returns an array of the module name and directory. list($module_name, $module_dir) = $this->getModuleAndPath(); diff --git a/core/tests/Drupal/Tests/Core/Render/ElementInfoManagerTest.php b/core/tests/Drupal/Tests/Core/Render/ElementInfoManagerTest.php index 647d82dbc6dc8f560706716077cef13aab5b82ab..0d5aec69c53da54d696d9a9970061618b5c32d01 100644 --- a/core/tests/Drupal/Tests/Core/Render/ElementInfoManagerTest.php +++ b/core/tests/Drupal/Tests/Core/Render/ElementInfoManagerTest.php @@ -58,6 +58,8 @@ class ElementInfoManagerTest extends UnitTestCase { * @covers ::__construct */ protected function setUp() { + parent::setUp(); + $this->cache = $this->getMock('Drupal\Core\Cache\CacheBackendInterface'); $this->cacheTagsInvalidator = $this->getMock('Drupal\Core\Cache\CacheTagsInvalidatorInterface'); $this->moduleHandler = $this->getMock('Drupal\Core\Extension\ModuleHandlerInterface'); diff --git a/core/tests/Drupal/Tests/UnitTestCase.php b/core/tests/Drupal/Tests/UnitTestCase.php index 77a3d2253faa4dad6fa79e3859eb0161cff08b6d..d8fbebcb294875081c32fd12e3ee31a1c02928a1 100644 --- a/core/tests/Drupal/Tests/UnitTestCase.php +++ b/core/tests/Drupal/Tests/UnitTestCase.php @@ -43,6 +43,8 @@ protected function setUp() { // Ensure that the NullFileCache implementation is used for the FileCache as // unit tests should not be relying on caches implicitly. FileCacheFactory::setConfiguration(['default' => ['class' => '\Drupal\Component\FileCache\NullFileCache']]); + // Ensure that FileCacheFactory has a prefix. + FileCacheFactory::setPrefix('prefix'); $this->root = dirname(dirname(substr(__DIR__, 0, -strlen(__NAMESPACE__)))); }