MENU_LOCAL_TASK disappears when same path is used in a primary link

andrewlevine - July 7, 2006 - 20:03
Project:Drupal
Version:5.0-beta1
Component:menu system
Category:bug report
Priority:normal
Assigned:kkaefer
Status:closed
Description

I guess this could be some kind of bizarre feature but IMHO it's a bug.

Steps:
1. log into Drupal
2. Set up a primary link with the path user/*yourID*/edit
3. go to "my account" (user/*yourID*)

The edit MENU_LOCAL_TASK has disappeared for that user.

This also happened to someone using my module here: http://drupal.org/node/72642

#1

magico - September 20, 2006 - 20:05
Title:MENU_LOCAL_TASK disappears when same path is used in a primary link» Cannot edit account through "my account" if primary link menu is created pointing to it
Version:4.7.2» x.y.z

Confirmed in HEAD.

#2

andrewlevine - September 22, 2006 - 02:37
Title:Cannot edit account through "my account" if primary link menu is created pointing to it» MENU_LOCAL_TASK disappears when same path is used in a primary link

Thanks for confirming in head, although this is a more general problem with the menu system, not just "my account." So I'm changing the title back for now...

#3

AjK - September 22, 2006 - 13:09

Confirmed, title correct. I've had a quick look and can repeat but not see why at this time. I hope to get some time soon to investigate further. I'll probably have to discuss with chx on IRC but DrupalCON is going to get in the way of alot of things (unless their "bug sessions" look at this issue ;)

#4

edmund.kwok - September 22, 2006 - 18:16

In the menu building process, the $_menu array is populated. Path and item are stored in $_menu['path index'] as [path] => [item_id]. The item with the item_id will contain menu information such as title and type.

In that sense, one path can only be binded to one item. In this case, when the path is a set as a primary link, it cannot be a MENU_LOCAL_TASK at the same time.

I think this conflict might happen for all menu items that share the same path. It might take alot of rewriting to fix this.

#5

AjK - September 22, 2006 - 21:11

Then this is a prime candidate for the "Bug Cafe" at DrupalCON whilst heads are together

#6

chx - October 30, 2006 - 22:48

Rejoice for I got JonBob on the issue. YAY! I see a forthcoming patch soon :D

#7

JonBob - October 31, 2006 - 13:25

I don't have a solution yet, but here's the workflow that causes the problem.

A module defines a menu item which is a local task. The type MENU_LOCAL_TASK is given to this item, which consists only of the flag MENU_IS_LOCAL_TASK.

The menu items are normally stored in the {menu} table by menu_rebuild(). However, this only happens for items that have the MENU_MODIFIABLE_BY_ADMIN flag. This flag is not set for local tasks, so the menu item is not stored in that table.

The user adds a menu item with the same path as the local task. This is stored in the {menu} table in the database.

The _menu_build() function is called to render the menu for the page. Starting at menu.inc line 1091, the saved menu items are read from the database. At this point the local task has already been added to the list of menu items, but has a negative (temporary) mid.

Line 1098 returns TRUE, as the custom menu item and local task have the same path.

Line 1101 returns TRUE, as the local task has a negative mid. This means it is overwritten.

Now this behavior of overwriting the menu item is in place so that module-defined items don't exist twice in the menu when they are customized. Maybe we need to use the "shortcut" behavior from 1113 when the module-defined item wasn't MODIFIABLE_BY_ADMIN?

#8

kkaefer - November 4, 2006 - 22:42
Assigned to:Anonymous» kkaefer
Status:active» needs review

JonBob was wrong. The problem was in _menu_append_local_tasks(). The local task was not added to the $new_items array because the path was already in the menu.

AttachmentSizeStatusTest resultOperations
menu-local-task.patch778 bytesIgnoredNoneNone

#9

webernet - November 4, 2006 - 23:33

Patch works for:
/user/#/edit

Patch does not work for:
/user/login
/admin/build/themes/settings

According to kkaefer these are a related, but separate issue since they are stored in the database rather than being generated.

#10

kkaefer - November 5, 2006 - 11:50

This patch does now fix the other issue as well. In fact, JonBob was not completely wrong. For menu items which are generated in hook_menu(FALSE) ($may_cache == FALSE), the fix is in _menu_append_contextual_items() (my first patch). For cacheable menu items, the problem was in fact in _menu_build(). There, the old menu item was removed although it was still necessary for the local tasks. The menu items are now only removed if the new menu item is of the old menu item’s type. Additionally, we merge the types together so that we can have local tasks and other flags like MENU_VISIBLE_IN_TREE.

AttachmentSizeStatusTest resultOperations
menu-local-task_0.patch1.56 KBIgnoredNoneNone

#11

webernet - November 5, 2006 - 15:32
Status:needs review» reviewed & tested by the community

Patch works for:
/user/#/edit
/user/login
/admin/build/themes/settings

#12

kkaefer - November 8, 2006 - 19:50
Status:reviewed & tested by the community» needs review

I'd like to get the opinion of a menu system wizard on this.

#13

webernet - November 11, 2006 - 20:06
Version:x.y.z» 5.0-beta1

#14

Richard Archer - November 15, 2006 - 00:31
Status:needs review» reviewed & tested by the community

I don't much like special cases, but with code as complex as the menu system I guess they're inevitable.

This patch seems to fix the problem and the conditionals seem to limit side effects to just the problematic items.

+1.

#15

drumm - November 16, 2006 - 07:28
Status:reviewed & tested by the community» fixed

Committed to HEAD.

#16

Anonymous - November 30, 2006 - 07:30
Status:fixed» closed
 
 

Drupal is a registered trademark of Dries Buytaert.