core/includes/common.inc | 13 +++
core/includes/menu.inc | 41 ++++----
.../menu/lib/Drupal/menu/Tests/MenuTest.php | 60 +++++++++++
.../lib/Drupal/menu_link/Entity/MenuLink.php | 13 ++-
.../system/lib/Drupal/system/Entity/Menu.php | 19 ++++
.../Tests/Cache/PageCacheTagsIntegrationTest.php | 105 ++++++++++++++++++++
6 files changed, 228 insertions(+), 23 deletions(-)
diff --git a/core/includes/common.inc b/core/includes/common.inc
index b97cc5e..ff13861 100644
--- a/core/includes/common.inc
+++ b/core/includes/common.inc
@@ -3562,6 +3562,19 @@ function drupal_prepare_page($page) {
// 'sidebar_first', 'footer', etc.
drupal_alter('page', $page);
+ // The "main" and "secondary" menus are never part of the page-level render
+ // array and therefor their cache tags will never bubble up into the page
+ // cache, even though they should be. This happens because they're rendered
+ // directly by the theme system.
+ if (theme_get_setting('features.main_menu') && count(menu_main_menu())) {
+ $main_links_source = _menu_get_links_source('main_links', 'main');
+ $page['page_top']['#cache']['tags']['menu'][$main_links_source] = $main_links_source;
+ }
+ if (theme_get_setting('features.secondary_menu') && count(menu_secondary_menu())) {
+ $secondary_links_source = _menu_get_links_source('secondary_links', 'account');
+ $page['page_top']['#cache']['tags']['menu'][$secondary_links_source] = $secondary_links_source;
+ }
+
// If no module has taken care of the main content, add it to the page now.
// This allows the site to still be usable even if no modules that
// control page regions (for example, the Block module) are enabled.
diff --git a/core/includes/menu.inc b/core/includes/menu.inc
index bbf5c43..814c9d9 100644
--- a/core/includes/menu.inc
+++ b/core/includes/menu.inc
@@ -1100,6 +1100,9 @@ function menu_tree_output($tree) {
// Add the theme wrapper for outer markup.
// Allow menu-specific theme overrides.
$build['#theme_wrappers'][] = 'menu_tree__' . strtr($data['link']['menu_name'], '-', '_');
+ // Set cache tag.
+ $menu_name = $data['link']['menu_name'];
+ $build['#cache']['tags']['menu'][$menu_name] = $menu_name;
}
return $build;
@@ -1758,10 +1761,7 @@ function menu_list_system_menus() {
* Returns an array of links to be rendered as the Main menu.
*/
function menu_main_menu() {
- $config = \Drupal::config('menu.settings');
- $menu_enabled = module_exists('menu');
- // When menu module is not enabled, we need a hardcoded default value.
- $main_links_source = $menu_enabled ? $config->get('main_links') : 'main';
+ $main_links_source = _menu_get_links_source('main_links', 'main');
return menu_navigation_links($main_links_source);
}
@@ -1769,11 +1769,8 @@ function menu_main_menu() {
* Returns an array of links to be rendered as the Secondary links.
*/
function menu_secondary_menu() {
- $config = \Drupal::config('menu.settings');
- $menu_enabled = module_exists('menu');
- // When menu module is not enabled, we need a hardcoded default value.
- $main_links_source = $menu_enabled ? $config->get('main_links') : 'main';
- $secondary_links_source = $menu_enabled ? $config->get('secondary_links') : 'account';
+ $main_links_source = _menu_get_links_source('main_links', 'main');
+ $secondary_links_source = _menu_get_links_source('secondary_links', 'account');
// If the secondary menu source is set as the primary menu, we display the
// second level of the primary menu.
@@ -1786,6 +1783,23 @@ function menu_secondary_menu() {
}
/**
+ * Returns the source of links of a menu.
+ *
+ * @param string $name
+ * A string configuration key of menu link source.
+ * @param string $default
+ * Default menu name.
+ *
+ * @return string
+ * Returns menu name, if exist
+ */
+function _menu_get_links_source($name, $default) {
+ $config = \Drupal::config('menu.settings');
+ // When menu module is not enabled, we need a hardcoded default value.
+ return \Drupal::moduleHandler()->moduleExists('menu') ? $config->get($name) : $default;
+}
+
+/**
* Returns an array of links for a navigation menu.
*
* @param $menu_name
@@ -2404,15 +2418,6 @@ function menu_get_active_trail() {
}
/**
- * Clears the cached cached data for a single named menu.
- */
-function menu_cache_clear($menu_name = 'tools') {
- Cache::deleteTags(array('menu' => $menu_name));
- // Also clear the menu system static caches.
- menu_reset_static_cache();
-}
-
-/**
* Clears all cached menu data.
*
* This should be called any time broad changes
diff --git a/core/modules/menu/lib/Drupal/menu/Tests/MenuTest.php b/core/modules/menu/lib/Drupal/menu/Tests/MenuTest.php
index 48f9361..d03012d 100644
--- a/core/modules/menu/lib/Drupal/menu/Tests/MenuTest.php
+++ b/core/modules/menu/lib/Drupal/menu/Tests/MenuTest.php
@@ -457,6 +457,66 @@ public function testBlockContextualLinks() {
}
/**
+ * Test that cache tags are properly set and bubbled up to the page cache.
+ *
+ * Ensures that invalidation of the "menu: