/** * {@inheritdoc} */ protected function alterRoutes(RouteCollection $collection) { foreach ($this->entityStorage->loadMultiple() as $entity_id => $entity) { /** @var \Drupal\page_manager\PageInterface $entity */ // If the page is disabled skip making a route for it. if (!$entity->status() || !$entity->getVariants()) { continue; } // Prepare the values that need to be altered for an existing page. $parameters = ['page_manager_page_variant' => ['type' => 'entity:page_variant'], 'page_manager_page' => ['type' => 'entity:page']]; $requirements = []; if ($route_name = $this->findPageRouteName($entity, $collection)) { $this->cacheTagsInvalidator->invalidateTags(["page_manager_route_name:{$route_name}"]); $collection_route = $collection->get($route_name); $path = $collection_route->getPath(); $parameters += $collection_route->getOption('parameters') ?: []; $requirements += $collection_route->getRequirements(); $collection->remove($route_name); } else { $route_name = "page_manager.page_view_{$entity_id}"; $path = $entity->getPath(); $requirements['_entity_access'] = 'page_manager_page.view'; } $page_id = $entity->id(); $first = TRUE; foreach ($entity->getVariants() as $variant_id => $variant) { // Construct and add a new route. $route = new Route($path, ['_entity_view' => 'page_manager_page_variant', '_title' => $entity->label(), 'page_manager_page_variant' => $variant_id, 'page_manager_page' => $page_id, 'base_route_name' => $route_name], $requirements, ['parameters' => $parameters, '_admin_route' => $entity->usesAdminTheme()]); $collection->add($first ? $route_name : $route_name . '_' . $variant_id, $route); $first = FALSE; } } }
/** * Invalidate cache tags when a color theme config object changes. * * @param \Drupal\Core\Config\ConfigCrudEvent $event * The Event to process. */ public function onChange(ConfigCrudEvent $event) { // Changing a theme's color settings causes the theme's asset library // containing the color CSS file to be altered to use a different file. if (strpos($event->getConfig()->getName(), 'color.theme.') === 0) { $this->cacheTagsInvalidator->invalidateTags(['library_info']); } }
/** * Invalidate the 'rendered' cache tag whenever the settings are modified. * * @param \Drupal\Core\Config\ConfigCrudEvent $event * The Event to process. */ public function onSave(ConfigCrudEvent $event) { // Changing the Global Redirect settings means that any cached page might // result in a different response, so we need to invalidate them all. if ($event->getConfig()->getName() === 'globalredirect.settings') { $this->cacheTagsInvalidator->invalidateTags(['rendered']); } }
/** * @covers ::rename */ public function testRename() { $old = new Config($this->randomMachineName(), $this->storage, $this->eventDispatcher, $this->typedConfig); $new = new Config($this->randomMachineName(), $this->storage, $this->eventDispatcher, $this->typedConfig); $this->storage->expects($this->exactly(2))->method('readMultiple')->willReturnMap([[[$old->getName()], $old->getRawData()], [[$new->getName()], $new->getRawData()]]); $this->cacheTagsInvalidator->expects($this->once())->method('invalidateTags')->with($old->getCacheTags()); $this->storage->expects($this->once())->method('rename')->with($old->getName(), $new->getName()); $this->configFactory->rename($old->getName(), $new->getName()); }
/** * Invalidate the 'rendered' cache tag whenever a theme setting is modified. * * @param \Drupal\Core\Config\ConfigCrudEvent $event * The Event to process. */ public function onSave(ConfigCrudEvent $event) { // Global theme settings. if ($event->getConfig()->getName() === 'system.theme.global') { $this->cacheTagsInvalidator->invalidateTags(['rendered']); } // Theme-specific settings, check if this matches a theme settings // configuration object, in that case, clear the rendered cache tag. foreach (array_keys($this->themeHandler->listInfo()) as $theme_name) { if ($theme_name == $event->getConfig()->getName()) { $this->cacheTagsInvalidator->invalidateTags(['rendered']); break; } } }
/** * Tests the getAllBundleInfo() method. * * @covers ::getAllBundleInfo */ public function testGetAllBundleInfo() { $this->moduleHandler->invokeAll('entity_bundle_info')->willReturn([]); $this->moduleHandler->alter('entity_bundle_info', Argument::type('array'))->willReturn(NULL); $apple = $this->prophesize(EntityTypeInterface::class); $apple->getLabel()->willReturn('Apple'); $apple->getBundleOf()->willReturn(NULL); $banana = $this->prophesize(EntityTypeInterface::class); $banana->getLabel()->willReturn('Banana'); $banana->getBundleOf()->willReturn(NULL); $this->setUpEntityTypeDefinitions(['apple' => $apple, 'banana' => $banana]); $this->cacheBackend->get('entity_bundle_info:en')->willReturn(FALSE); $this->cacheBackend->set('entity_bundle_info:en', Argument::any(), Cache::PERMANENT, ['entity_types', 'entity_bundles'])->will(function () { $this->get('entity_bundle_info:en')->willReturn((object) ['data' => 'cached data'])->shouldBeCalled(); })->shouldBeCalled(); $this->cacheTagsInvalidator->invalidateTags(['entity_bundles'])->shouldBeCalled(); $this->typedDataManager->clearCachedDefinitions()->shouldBeCalled(); $expected = ['apple' => ['apple' => ['label' => 'Apple']], 'banana' => ['banana' => ['label' => 'Banana']]]; $bundle_info = $this->entityTypeBundleInfo->getAllBundleInfo(); $this->assertSame($expected, $bundle_info); $bundle_info = $this->entityTypeBundleInfo->getAllBundleInfo(); $this->assertSame($expected, $bundle_info); $this->entityTypeBundleInfo->clearCachedBundles(); $bundle_info = $this->entityTypeBundleInfo->getAllBundleInfo(); $this->assertSame('cached data', $bundle_info); }
/** * @covers ::delete * @dataProvider overrideDataProvider */ public function testDelete($data, $module_data) { $this->cacheTagsInvalidator->expects($this->once())->method('invalidateTags')->with(['config:config.test']); // Set initial data. foreach ($data as $key => $value) { $this->config->set($key, $value); } // Set overrides. $this->config->setModuleOverride($module_data); // Save. $this->config->save(); // Check that original data is still correct. $this->assertOriginalConfigDataEquals($data, FALSE); // Check overrides have been set. $this->assertConfigDataEquals($module_data); $this->assertOriginalConfigDataEquals($module_data, TRUE); // Check that config is new. $this->assertFalse($this->config->isNew()); // Delete. $this->config->delete(); // Check object properties have been reset. $this->assertTrue($this->config->isNew()); foreach ($data as $key => $value) { $this->assertEmpty($this->config->getOriginal($key, FALSE)); } // Check that overrides have persisted. foreach ($module_data as $key => $value) { $this->assertConfigDataEquals($module_data); $this->assertOriginalConfigDataEquals($module_data, TRUE); } }
/** * Tests overriding an existing route. * * @covers ::alterRoutes * @covers ::findPageRouteName * * @dataProvider providerTestAlterRoutesOverrideExisting */ public function testAlterRoutesOverrideExisting($page_path, $existing_route_path, $requirements = []) { $route_name = 'test_route'; // Set up a page with the same path as an existing route. $page = $this->prophesize(PageInterface::class); $page->status()->willReturn(TRUE)->shouldBeCalled(); $page->getPath()->willReturn($page_path)->shouldBeCalled(); $variant1 = $this->prophesize(PageVariantInterface::class); $variant1->getWeight()->willReturn(0); $page->getVariants()->willReturn(['variant1' => $variant1->reveal()]); $page->id()->willReturn('page1'); $page->label()->willReturn(NULL); $page->usesAdminTheme()->willReturn(FALSE); $this->pageStorage->loadMultiple()->willReturn(['page1' => $page->reveal()])->shouldBeCalledTimes(1); $this->cacheTagsInvalidator->invalidateTags(["page_manager_route_name:{$route_name}"])->shouldBeCalledTimes(1); $collection = new RouteCollection(); $collection->add($route_name, new Route($existing_route_path, ['default_exists' => 'default_value'], $requirements, ['parameters' => ['foo' => 'bar']])); $route_event = new RouteBuildEvent($collection); $this->routeSubscriber->onAlterRoutes($route_event); // The normal route name is not used, the existing route name is instead. $this->assertSame(1, $collection->count()); $this->assertNull($collection->get('page_manager.page_view_page1')); $this->assertNull($collection->get('page_manager.page_view_page1_variant1')); $route = $collection->get($route_name); $expected_defaults = ['_entity_view' => 'page_manager_page_variant', '_title' => NULL, 'page_manager_page_variant' => 'variant1', 'page_manager_page' => 'page1', 'page_manager_page_variant_weight' => 0, 'base_route_name' => $route_name]; $expected_requirements = $requirements; $expected_options = ['compiler_class' => 'Symfony\\Component\\Routing\\RouteCompiler', 'parameters' => ['page_manager_page_variant' => ['type' => 'entity:page_variant'], 'page_manager_page' => ['type' => 'entity:page'], 'foo' => 'bar'], '_admin_route' => FALSE]; $this->assertMatchingRoute($route, $existing_route_path, $expected_defaults, $expected_requirements, $expected_options); }
/** * @covers ::delete * @covers ::doDelete */ public function testDeleteNothing() { $this->moduleHandler->expects($this->never())->method($this->anything()); $this->configFactory->expects($this->never())->method('get'); $this->cacheTagsInvalidator->expects($this->never())->method('invalidateTags'); $this->entityStorage->delete(array()); }
/** * @covers ::disable * @depends testSetStatus */ public function testDisable() { $this->cacheTagsInvalidator->expects($this->once())->method('invalidateTags')->with(array('config:test_provider.' . $this->entityTypeId . '.' . $this->id)); $this->entity->setStatus(TRUE); $this->assertSame($this->entity, $this->entity->disable()); $this->assertFalse($this->entity->status()); }
/** * Tests the clearCachedFieldDefinitions() method. * * @covers ::clearCachedFieldDefinitions */ public function testClearCachedFieldDefinitions() { $this->setUpEntityTypeDefinitions(); $this->cacheTagsInvalidator->invalidateTags(['entity_field_info'])->shouldBeCalled(); $this->container->get('cache_tags.invalidator')->willReturn($this->cacheTagsInvalidator->reveal())->shouldBeCalled(); $this->typedDataManager->clearCachedDefinitions()->shouldBeCalled(); $this->entityFieldManager->clearCachedFieldDefinitions(); }
/** * @covers ::postDelete */ public function testPostDelete() { $this->cacheTagsInvalidator->expects($this->once())->method('invalidateTags')->with(array($this->entityTypeId . ':' . $this->values['id'], $this->entityTypeId . '_list')); $storage = $this->getMock('\\Drupal\\Core\\Entity\\EntityStorageInterface'); $storage->expects($this->once())->method('getEntityType')->willReturn($this->entityType); $entities = array($this->values['id'] => $this->entity); $this->entity->postDelete($storage, $entities); }
/** * Invalidate cache tags when particular system config objects are saved. * * @param \Drupal\Core\Config\ConfigCrudEvent $event * The Event to process. */ public function onSave(ConfigCrudEvent $event) { // Changing the site settings may mean a different route is selected for the // front page. Additionally a change to the site name or similar must // invalidate the render cache since this could be used anywhere. if ($event->getConfig()->getName() === 'system.site') { $this->cacheTagsInvalidator->invalidateTags(['route_match', 'rendered']); } // Theme configuration and global theme settings. if (in_array($event->getConfig()->getName(), ['system.theme', 'system.theme.global'], TRUE)) { $this->cacheTagsInvalidator->invalidateTags(['rendered']); } // Theme-specific settings, check if this matches a theme settings // configuration object, in that case, clear the rendered cache tag. foreach (array_keys($this->themeHandler->listInfo()) as $theme_name) { if ($theme_name == $event->getConfig()->getName()) { $this->cacheTagsInvalidator->invalidateTags(['rendered']); break; } } }
/** * Finishes the submit */ public function finishSubmitForm(array &$form, FormStateInterface $form_state) { $field = $this->field; // Save field and clear ds_fields_info cache. $this->cacheInvalidator->invalidateTags(array('ds_fields_info')); // Also clear the ds plugin cache \Drupal::service('plugin.manager.ds')->clearCachedDefinitions(); // Redirect. $url = new Url('ds.fields_list'); $form_state->setRedirectUrl($url); drupal_set_message(t('The field %field has been saved.', array('%field' => $field['label']))); }
/** * Tests a clear of the cache collector using tags. */ public function testUpdateCacheClearTags() { $key = $this->randomMachineName(); $value = $this->randomMachineName(); $tags = array($this->randomMachineName()); $this->collector = new CacheCollectorHelper($this->cid, $this->cacheBackend, $this->lock, $tags); // Set the data and request it. $this->collector->setCacheMissData($key, $value); $this->assertEquals($value, $this->collector->get($key)); $this->assertEquals($value, $this->collector->get($key)); // Should have been added to the storage and only be requested once. $this->assertEquals(1, $this->collector->getCacheMisses()); // Clear the collected cache using the tags, should call it again. $this->cacheBackend->expects($this->never())->method('delete'); $this->cacheTagsInvalidator->expects($this->once())->method('invalidateTags')->with($tags); $this->collector->clear(); $this->assertEquals($value, $this->collector->get($key)); $this->assertEquals(2, $this->collector->getCacheMisses()); }
/** * {@inheritdoc} */ public function delete($id) { // Children get re-attached to the menu link's parent. $item = $this->loadFull($id); // It's possible the link is already deleted. if ($item) { $parent = $item['parent']; $children = $this->loadByProperties(array('parent' => $id)); foreach ($children as $child) { $child['parent'] = $parent; $this->save($child); } $this->doDeleteMultiple([$id]); $this->updateParentalStatus($item); // Many children may have moved. $this->resetDefinitions(); $this->cacheTagsInvalidator->invalidateTags(['config:system.menu.' . $item['menu_name']]); } }
/** * Tests the cache of the full and single table data. */ public function testFullAndTableGetCache() { $expected_views_data = $this->viewsDataWithProvider(); $table_name = 'views_test_data'; $table_name_2 = 'views_test_data_2'; $random_table_name = $this->randomMachineName(); // Views data should be invoked twice due to the clear call. $this->moduleHandler->expects($this->at(0))->method('getImplementations')->with('views_data')->willReturn(array('views_test_data')); $this->moduleHandler->expects($this->at(1))->method('invoke')->with('views_test_data', 'views_data')->willReturn($this->viewsData()); $this->moduleHandler->expects($this->at(2))->method('alter')->with('views_data', $expected_views_data); $this->moduleHandler->expects($this->at(3))->method('getImplementations')->with('views_data')->willReturn(array('views_test_data')); $this->moduleHandler->expects($this->at(4))->method('invoke')->with('views_test_data', 'views_data')->willReturn($this->viewsData()); $this->moduleHandler->expects($this->at(5))->method('alter')->with('views_data', $expected_views_data); // The cache should only be called once (before the clear() call) as get // will get all table data in the first get(). $this->cacheBackend->expects($this->at(0))->method('get')->with("views_data:en")->will($this->returnValue(FALSE)); $this->cacheBackend->expects($this->at(1))->method('set')->with("views_data:en", $expected_views_data); $this->cacheBackend->expects($this->at(2))->method('get')->with("views_data:{$random_table_name}:en")->will($this->returnValue(FALSE)); $this->cacheBackend->expects($this->at(3))->method('set')->with("views_data:{$random_table_name}:en", array()); $this->cacheTagsInvalidator->expects($this->once())->method('invalidateTags')->with(['views_data']); $this->cacheBackend->expects($this->at(4))->method('get')->with("views_data:en")->will($this->returnValue(FALSE)); $this->cacheBackend->expects($this->at(5))->method('set')->with("views_data:en", $expected_views_data); $this->cacheBackend->expects($this->at(6))->method('get')->with("views_data:{$random_table_name}:en")->will($this->returnValue(FALSE)); $this->cacheBackend->expects($this->at(7))->method('set')->with("views_data:{$random_table_name}:en", array()); $views_data = $this->viewsData->get(); $this->assertSame($expected_views_data, $views_data); // Request a specific table should be static cached. $views_data = $this->viewsData->get($table_name); $this->assertSame($expected_views_data[$table_name], $views_data); // Another table being requested should also come from the static cache. $views_data = $this->viewsData->get($table_name_2); $this->assertSame($expected_views_data[$table_name_2], $views_data); $views_data = $this->viewsData->get($random_table_name); $this->assertSame(array(), $views_data); $this->viewsData->clear(); // Get the views data again. $this->viewsData->get(); $this->viewsData->get($table_name); $this->viewsData->get($table_name_2); $this->viewsData->get($random_table_name); }
/** * Tests the getAllBundleInfo() method. * * @covers ::getAllBundleInfo */ public function testGetAllBundleInfo() { $apple = $this->getMock('Drupal\\Core\\Entity\\EntityTypeInterface'); $apple->expects($this->once())->method('getLabel')->will($this->returnValue('Apple')); $banana = $this->getMock('Drupal\\Core\\Entity\\EntityTypeInterface'); $banana->expects($this->once())->method('getLabel')->will($this->returnValue('Banana')); $this->setUpEntityManager(array('apple' => $apple, 'banana' => $banana)); $this->cacheBackend->expects($this->at(0))->method('get')->with("entity_bundle_info:en", FALSE)->will($this->returnValue(FALSE)); $this->cacheBackend->expects($this->at(1))->method('get')->with("entity_type", FALSE)->will($this->returnValue(FALSE)); $this->cacheBackend->expects($this->at(2))->method('set')->with("entity_type"); $this->cacheBackend->expects($this->at(3))->method('set')->with("entity_bundle_info:en"); $this->cacheTagsInvalidator->expects($this->at(0))->method('invalidateTags')->with(array('entity_types')); $this->cacheTagsInvalidator->expects($this->at(1))->method('invalidateTags')->with(array('entity_bundles')); $this->cacheTagsInvalidator->expects($this->at(2))->method('invalidateTags')->with(array('entity_field_info')); $this->cacheBackend->expects($this->at(4))->method('get')->with("entity_bundle_info:en", FALSE)->will($this->returnValue((object) array('data' => 'cached data'))); $expected = array('apple' => array('apple' => array('label' => 'Apple')), 'banana' => array('banana' => array('label' => 'Banana'))); $bundle_info = $this->entityManager->getAllBundleInfo(); $this->assertSame($expected, $bundle_info); $bundle_info = $this->entityManager->getAllBundleInfo(); $this->assertSame($expected, $bundle_info); $this->entityManager->clearCachedDefinitions(); $bundle_info = $this->entityManager->getAllBundleInfo(); $this->assertSame('cached data', $bundle_info); }
/** * {@inheritdoc} */ public function clearCachedDefinitions() { $this->cacheTagInvalidator->invalidateTags(['library_info']); $this->libraryDefinitions = []; $this->collector->clear(); }
/** * {@inheritdoc} */ public function reset() { $this->routes = array(); $this->serializedRoutes = array(); $this->cacheTagInvalidator->invalidateTags(['routes']); }
/** * {@inheritdoc} */ public function clearCachedDefinitions() { $this->cacheTagInvalidator->invalidateTags(['library_info']); }
/** * @covers ::delete */ public function testDelete() { $this->cacheTagsInvalidator->expects($this->once())->method('invalidateTags')->with(['config:config.test']); $this->configTranslation->initWithData([]); $this->configTranslation->delete(); }
/** * @covers ::resetInfo */ public function testResetInfo() { $this->cacheTagsInvalidator->expects($this->once())->method('invalidateTags')->with(['token_info']); $this->token->resetInfo(); }
/** * {@inheritdoc} */ public function clearCachedDefinitions() { $this->elementInfo = NULL; $this->cacheTagInvalidator->invalidateTags(['element_info_build']); parent::clearCachedDefinitions(); }
/** * Invalidate cache tags whenever a string is translated. */ public function saveTranslation() { $this->cacheTagsInvalidator->invalidateTags(['rendered', 'locale']); }
/** * Resets metadata describing supported tokens. */ public function resetInfo() { $this->tokenInfo = NULL; $this->cacheTagsInvalidator->invalidateTags([static::TOKEN_INFO_CACHE_TAG]); }