Consider the following situation:
- Let's say that you have a menu "menu-my-menu" that you have removed on purpose from default active menus by calling menu_set_active_menu_names().
This may happen if you have decided to display different menus based on, for instance, user role or language.

- Do something, like editing a menu link in this menu, that clears its cache.

- On a new page request to a path that is present in different menus, including the unallowed "menu-my-menu", menu_tree_page_data() may be called and cache be rebuilt for the requested path. At this point, menu_link_get_preferred($active_path, $menu_name) will be called with
"menu-my-menu" as $menu_name.

- Next, on breadcrumb build (in the same page request), menu_link_get_preferred() will be called again without parameters. The problem is that at this point, menu_link_get_preferred() will not check menu_set_active_menu_names() and may return a link from "menu-my-menu" for breadcrumb.

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

anrikun’s picture

Version: 7.x-dev » 8.x-dev
Status: Active » Needs review
Issue tags: +Needs tests
FileSize
1.42 KB

Here is patch for D8.
It simply adds an extra condition to prevent a menu link from an non-allowed menu from being stored as the most specific link.

anrikun’s picture

Issue summary: View changes

A word was missing.

anrikun’s picture

Issue summary: View changes

Fixed wrong markup

Damien Tournoud’s picture

Status: Needs review » Needs work

There is indeed a bug here, but it's basically a caching issue: the preferred link is computed in a context and used in another.

It would be easier and make more sense to remove the MENU_PREFERRED_LINK hack and just pick: (1) the link of the specified menu if it exists (ie. $preferred_links[$path][$menu_name]) or else (2) the most specific link (ie. reset($preferred_links[$path])) if it doesn't.

anrikun’s picture

Status: Needs work » Needs review
FileSize
2.98 KB

There you are!
I didn't want to introduce too much change because I thought it wouldn't be appreciated, but if you say so :-)

Extra change: we now initialize $preferred_links[$path] to an empty array so that if no match is found, code is not needlessly run again on the next call.

Damien Tournoud’s picture

I'm happy with #3, but we probably need to extend / write some tests.

Damien Tournoud’s picture

Candidate for backport.

anrikun’s picture

+ I think tag 'translatable' should be added to the query because it is present in _menu_build_tree(), and again a wrong preferred link could be picked up if query is altered in _menu_build_tree() but not in menu_link_get_preferred().
Should we open a separate issue for this?

anrikun’s picture

I still had problems and I noticed that I had skipped another strange part in my previous patch:

<?php
      // Add any menus not already in the menu name search list.
      if (!in_array($candidate['menu_name'], $menu_names)) {
        $menu_names[] = $candidate['menu_name'];
      }
?>

What???

This updated patch removes it.

Status: Needs review » Needs work

The last submitted patch, menu_link_get_preferred-1627276-7.patch, failed testing.

anrikun’s picture

Assigned: Unassigned » anrikun
Status: Needs work » Needs review
FileSize
4.73 KB

There is another bug: menu.module retrieves variable 'menu_default_active_menus' using a different default value from the one used in menu.inc
New patch.
When backporting to D7, we must not forget to add an install update for that.

anrikun’s picture

While writing tests, I found another bug: menu_tree_page_data() should cache separately a menu when it is active and when it is not.

anrikun’s picture

Added tests. Still incomplete though but let's see if they pass.

anrikun’s picture

Tests should be OK now. Let's test the test-only patch and the full one.

anrikun’s picture

Title: menu_link_get_preferred() may not pick up the right item when menu_set_active_menu_names() has been used » Active trail system does not respect whether a menu is set as inactive using menu_set_active_menu_names()

Changing title to better reflect the issue.

anrikun’s picture

Issue summary: View changes

Fixes wrong mark-up again!

anrikun’s picture

Version: 8.x-dev » 7.x-dev
FileSize
6.44 KB

The same patch for D7 (without tests). Let's see if it passes the tests.

anrikun’s picture

Title: Active trail system does not respect whether a menu is set as inactive using menu_set_active_menu_names() » Active trail system does not respect whether a menu is set as inactive or preferred using menu_set_active_menu_names()
FileSize
11.31 KB
4.87 KB

Now with the tests: tests only and full patches

anrikun’s picture

Version: 7.x-dev » 8.x-dev
Status: Needs review » Needs work

Ok patch for D7 works too.
It still lacks the install update part though.
Back to D8 for now.

anrikun’s picture

Status: Needs work » Needs review
FileSize
12.34 KB
5.03 KB

Re-uploading D8 patches with small improvements on #12:
- added a new condition to select only menu links from active menus
- one comment fix
Tests are unchanged.

cweagans’s picture

anrikun’s picture

Completed patch for D7 (see #16).

sun’s picture

#3 made sense to me, but starting from #9, various other changes have been added to the patch, without really explaining what's happening under which circumstances and why the changes are needed.

Some of the changes seem to partially revert the fixes from #942782: Custom menus never receive an active trail -- we need to make sure to not introduce a regression.

sun’s picture

Issue summary: View changes

Updated text to match the new title.

The last submitted patch, 17: menu_link_get_preferred-1627276-17.patch, failed testing.

jhedstrom’s picture

Issue summary: View changes
Status: Needs review » Needs work
Issue tags: +Needs reroll
rteijeiro’s picture

Assigned: anrikun » Unassigned
Status: Needs work » Closed (outdated)

I'm closing this as outdated as the menu module doesn't exists anymore. Feel free to reopen and update the issue summary if the problem still persists.