.../lib/Drupal/menu_link/Entity/MenuLink.php | 38 +++++++++++++++++----- .../lib/Drupal/system/Tests/Menu/LinksTest.php | 13 ++++++++ .../config/install/system.menu.changed.yml | 5 +++ .../config/install/system.menu.original.yml | 5 +++ .../views/lib/Drupal/views/Tests/ViewTestBase.php | 6 ++++ 5 files changed, 58 insertions(+), 9 deletions(-) diff --git a/core/modules/menu_link/lib/Drupal/menu_link/Entity/MenuLink.php b/core/modules/menu_link/lib/Drupal/menu_link/Entity/MenuLink.php index e979dbb..ac32839 100644 --- a/core/modules/menu_link/lib/Drupal/menu_link/Entity/MenuLink.php +++ b/core/modules/menu_link/lib/Drupal/menu_link/Entity/MenuLink.php @@ -7,6 +7,7 @@ namespace Drupal\menu_link\Entity; +use Drupal\Component\Utility\NestedArray; use Drupal\Component\Utility\UrlHelper; use Drupal\Core\Cache\Cache; use Drupal\Core\Entity\Entity; @@ -453,20 +454,13 @@ public static function preDelete(EntityStorageInterface $storage, array $entitie public static function postDelete(EntityStorageInterface $storage, array $entities) { parent::postDelete($storage, $entities); - $affected_menus = array(); // Update the has_children status of the parent. foreach ($entities as $entity) { if (!$storage->getPreventReparenting()) { $storage->updateParentalStatus($entity); } - - // Store all menu names for which we need to clear the cache. - if (!isset($affected_menus[$entity->menu_name])) { - $affected_menus[$entity->menu_name] = $entity->menu_name; - } } - Cache::invalidateTags(array('menu' => array_keys($affected_menus))); // Also clear the menu system static caches. menu_reset_static_cache(); _menu_clear_page_cache(); @@ -543,10 +537,22 @@ public function postSave(EntityStorageInterface $storage, $update = TRUE) { // Check the has_children status of the parent. $storage->updateParentalStatus($this); - Cache::invalidateTags(array('menu' => $this->menu_name)); + + // Entity::postSave() calls Entity::invalidateTagsOnSave(), which only + // handles the regular cases. The MenuLink entity has two special cases. + $cache_tags = array(); + // Case 1: a newly created menu link is *also* added to a menu, so we must + // invalidate the associated menu's cache tag. + if (!$update) { + $cache_tags = $this->getCacheTag(); + } + // Case 2: a menu link may be moved from one menu to another; the original + // menu's cache tag must also be invalidated. if (isset($this->original) && $this->menu_name != $this->original->menu_name) { - Cache::invalidateTags(array('menu' => $this->original->menu_name)); + $cache_tags = NestedArray::mergeDeep($cache_tags, $this->original->getCacheTag()); } + Cache::invalidateTags($cache_tags); + // Also clear the menu system static caches. menu_reset_static_cache(); @@ -657,4 +663,18 @@ public function build() { return $build; } + /** + * {@inheritdoc} + */ + public function getCacheTag() { + return entity_load('menu', $this->menu_name)->getCacheTag(); + } + + /** + * {@inheritdoc} + */ + public function getListCacheTags() { + return entity_load('menu', $this->menu_name)->getListCacheTags(); + } + } diff --git a/core/modules/system/lib/Drupal/system/Tests/Menu/LinksTest.php b/core/modules/system/lib/Drupal/system/Tests/Menu/LinksTest.php index 8148c7a..d0db0de 100644 --- a/core/modules/system/lib/Drupal/system/Tests/Menu/LinksTest.php +++ b/core/modules/system/lib/Drupal/system/Tests/Menu/LinksTest.php @@ -31,6 +31,19 @@ public static function getInfo() { } /** + * {@inheritdoc} + */ + public function setUp() { + parent::setUp(); + + entity_create('menu', array( + 'id' => 'menu_test', + 'label' => 'Test menu', + 'description' => 'Description text', + ))->save(); + } + + /** * Create a simple hierarchy of links. */ function createLinkHierarchy($module = 'menu_test') { diff --git a/core/modules/system/tests/modules/menu_test/config/install/system.menu.changed.yml b/core/modules/system/tests/modules/menu_test/config/install/system.menu.changed.yml new file mode 100644 index 0000000..4530fee --- /dev/null +++ b/core/modules/system/tests/modules/menu_test/config/install/system.menu.changed.yml @@ -0,0 +1,5 @@ +id: changed +label: Changed test menu +description: 'The changed menu for menu_test tests.' +langcode: en +locked: true diff --git a/core/modules/system/tests/modules/menu_test/config/install/system.menu.original.yml b/core/modules/system/tests/modules/menu_test/config/install/system.menu.original.yml new file mode 100644 index 0000000..c3443fd --- /dev/null +++ b/core/modules/system/tests/modules/menu_test/config/install/system.menu.original.yml @@ -0,0 +1,5 @@ +id: original +label: Original test menu +description: 'The original menu for menu_test tests.' +langcode: en +locked: true diff --git a/core/modules/views/lib/Drupal/views/Tests/ViewTestBase.php b/core/modules/views/lib/Drupal/views/Tests/ViewTestBase.php index 4ed9064..1752961 100644 --- a/core/modules/views/lib/Drupal/views/Tests/ViewTestBase.php +++ b/core/modules/views/lib/Drupal/views/Tests/ViewTestBase.php @@ -33,6 +33,12 @@ protected function setUp() { parent::setUp(); + // Views' Page displays put menu links in the 'navigation' menu by default. + entity_create('menu', array( + 'id' => 'navigation', + 'label' => 'Navigation', + ))->save(); + // Ensure that the plugin definitions are cleared. foreach (ViewExecutable::getPluginTypes() as $plugin_type) { $this->container->get("plugin.manager.views.$plugin_type")->clearCachedDefinitions();