in my admin/menu table, a lot of the mids in links show up as negative, which makes actions like disabling them silently fail to work.

Comments

Wesley Tanaka’s picture

Problem looks to be in _menu_build()

Wesley Tanaka’s picture

And the "problem" looks intentional. Perhaps my install is in a weird state.


// Menu items not in the DB get temporary negative IDs.
$temp_mid = -1;

Wesley Tanaka’s picture

_menu_build is getting called 3 times on my install. once from menu_get_menu() and then twice from menu_rebuild

Wesley Tanaka’s picture

The problem may be that drupal_normal_path is getting called when the mids get rewritten to positive integers, but never gets called on the initial list from the modules.

Wesley Tanaka’s picture

If I make the paths match (by either getting rid of

      // $item->path = drupal_get_normal_path($item->path);

or adding a call to $item['path'] = '';, the admin/menu page totally blows up.

Wesley Tanaka’s picture

I just looked, and my {menu} table has 6 copies of "log out" (multiple copies of other things too)

That doesn't seem right... but it looks like it's just a side-effect.

delete from drupal_sequences where name like '%menu_mid%'; delete from  drupal_menu;

and then a reload of admin/menu gets rid of the duplicates, but that first display of admin/menu also has a bunch of negative numbers.

Richard Archer’s picture

They are supposed to be negative. These are menu items that are created by modules and haven't been modified by the admin.

There should be no duplicate items... there are a couple of issues dealing with duplicates but I suspect they are all due to contrib modules which aren't playing nicely or broken databases. If you can reproduce this bug with a clean install and core modules only I'd be very interested in details of how you do it.

Wesley Tanaka’s picture

But I noticed that the mid gets passed verbatim into the function that disables menu items and is used as the key for the database update. None of the mids in the database are negative, so that disable call always fails...

How could a contrib module be not playing nicely? all it does is return an array... all the logic is in _menu_build?

I'd like to figure out which modules are triggering this, so if you have any insights, i'd appreciate them.

Richard Archer’s picture

Can you create a page on the site containing the following (input format = php code, of course):

<?php $menu = menu_get_menu(); echo "<code>".var_export($menu, TRUE)."
\r"; ?>

And email me the results: drupal@juggernaut.com.au

Wesley Tanaka’s picture

I added

echo '<!-- ';
$menu = menu_get_menu(); echo "<code>".var_export($menu,
TRUE)."


\r";
echo '-->';

to the bottom of an existing menu callback and am emailing you the result.

Richard Archer’s picture

There's something seriously wrong there. ALL those menu items are negative... only local tasks should be negative. The other items should all have a positive ID.

Is it possible for you to reset all menus? Or are there custom menu items that would be painful to recreate?

If you can do that, menu_rebuild should re-insert all the items that show up on the admin/menu page into the database and then you should be able to edit them.

If that doesn't work... hmm... are you sure you can write to the menu table in the database?
No corrupt source files?

Wesley Tanaka’s picture

There's something seriously wrong there. ALL those menu items are negative... only local tasks should be negative. The other items should all have a positive ID.

I should clarify comment #4. My drupal_get_normal_path is not a no-op, because I have i18n turned on. Thus the initial paths that get assigned negative numbers (which I believe weren't passed through the function) don't match up with the database checks (which get passed through drupal_get_normal_path). I tried to either add the function to the one place or remove it from the other, but both actions seemed to cause admin/menu to go into an infinite loop.

Do the steps taken in comment #6 count as resetting the menus? After I did that, the duplicates were gone (I haven't loaded admin/menu again because I fear that will cause the duplicates to come back), and the mids in the database were positive, but the menu_get_menu structure still had mostly negative mids.

Richard Archer’s picture

I have confirmed that the i18n module causes all menu items to have a negative mid. Which is because of the way i18n mangles the paths.

I also had a couple of duplicate menu items appear, due to the fact that the menu system uses the path to determine whether an item is already present and if the path is mangled this test fails.

This is a bug (or misfeature) in i18n and I'm inclined to close this issue as such.

puregin’s picture

Could someone have a look at this issue, I believe it's related to this menu/path discussion...

http://drupal.org/node/40384

(Access denied after registering the first user). This bug prevents users from being able to install Drupal 4.7

In the first call to _menu_item_is_accessible() from menu_execute_active_handler() in index.php, the 'access' attribute is empty...

I started looking into this but am fighting other fires.

Thanks, Djun

Wesley Tanaka’s picture

The analysis in #13 isn't complete in my opinion.

i18n is "mangling" the return value of the drupal_get_normal_path function.

_menu_build() is making two passes of the site menus. The first pass does not pass the paths through drupal_get_normal_path, but instead takes the paths directly out of hook_menu(). The second pass calls drupal_get_normal_path on all of the paths.

If drupal_get_normal_path is expected to be a no-op, then why is it even called in the second case? If it is not expected to be a no-op, then this bug will appear as soon as drupal_get_normal_path is doing any "mangling".

Richard Archer’s picture

drupal_get_normal_path is designed to convert url aliases back to the internal drupal path. Since hook_menu cannot return an alias, there is no need to run these paths through drupal_get_normal_path.

I believe that what i18n is doing by prepending the language code to the path is very bad behaviour and doing it by patching drupal_get_normal_path is not a valid application of this hook.

Maybe if i18n patched url() to add the language to the paths displayed on the site and then patched drupal_get_normal_path to remove the language from the path it would work better.

I'll see if chx can take a look at this issue as the full implications are over my head.

Richard Archer’s picture

Project: Drupal core » Internationalization
Version: x.y.z »
Component: menu system » Code

This is an i18n problem. The path rewriting in i18n prevents the menu from being built correctly.

See my previous comment for a possible solution.

kiev1.org’s picture

Has updated all to last version cvs too most - in the table menu already 5068 here such records what to do further?


	 	 	15759	15758	node/add	create content	 	1	28	
 	 	 	15803	15802	node/add	create content	 	1	28	
 	 	 	15847	15846	node/add	create content	 	1	28	
 	 	 	15891	15890	node/add	create content	 	1	28	
 	 	 	15935	15934	node/add	create content	 	1	28	
 	 	 	15979	15978	node/add	create content	 	1	28	
 	 	 	16022	16021	node/add	create content	 	1	28	
 	 	 	16065	16064	node/add	create content	 	1	28	
 	 	 	16108	16107	node/add	create content	 	1	28	
 	 	 	11531	11538	admin/settings/content-types	content types	 	0	22	
 	 	 	11575	11582	admin/settings/content-types	content types	 	0	22	
 	 	 	11620	11627	admin/settings/content-types	content types	 	0	22	
 	 	 	11664	11671	admin/settings/content-types	content types	 	0	22	
 	 	 	11709	11716	admin/settings/content-types	content types	 	0	22	
 	 	 	11753	11760	admin/settings/content-types	content types	 	0	22	
 	 	 	11797	11804	admin/settings/content-types	content types	 	0	22	
 	 	 	11841	11848	admin/settings/content-types	content types	 	0	22	
 	 	 	11885	11892	admin/settings/content-types	content types	

But it not the most terrible - is terribly that that some correct references give out
======
Primary menu links
2
======

*** And the most unpleasant that in drupal so functions are mixed and disguised what to find the ends it is simply impossible

Richard Archer’s picture

Hi Wesley,

Could you please confirm whether the latest patch at: http://drupal.org/node/9477 fixes this problem also?

kiev1.org’s picture

Thank you!!!
After addition of path - all hung, and then when deleted superfluous records from the table of menu, began to work fine.

however all very much incomprehensible )

Richard Archer’s picture

Priority: Critical » Normal
Status: Active » Fixed

Fixed by http://drupal.org/node/9477 (Comment #12)

Wesley Tanaka’s picture

Project: Internationalization » Drupal core
Version: » x.y.z
Component: Code » menu system

I'll check it out, but it sounds like it's been fixed.

Anonymous’s picture

Status: Fixed » Closed (fixed)
killes@www.drop.org’s picture

Version: x.y.z » 4.7.3
Status: Closed (fixed) » Active

I am re-opening this, as it happened to me today when installing the tagadelic module. There doesn't seem to be a fault in the module's hook, but all the menu items that it declares as suggested items get a negative ID iff they are in the seconf tier of the menu. Ie /chunk has a positive ID, but /chunk/n where n is the vocabulary ID has a negaive one.

nevets’s picture

I was having the problem with negative mid's and spent some time determining the source of the problem.

First a little background, if you have a module called 'example' which defines the menu paths 'example', 'example/a' and 'example/b', 'example/a' and 'example/b' will be considered children of 'example' and have the pid set to reflect that. Note this is always true even if 'example' is simply used for a callback.

In the case where 'example' is callback the pid for 'example/a' and 'example/b' ends up negative. This results in the function menu_rebuild() never storing 'example/a' and 'example/b' in the menu table since the pid is negative and menu_rebuild() checks to see the pid is zero or greater. If 'example/a' and 'example/b' are also callbacks there is no problem, but if either is meant to show up in the menu it causes the problem with the negative mid being exposed at admin/menu.

The simple fix is to change the path 'example' to something else (say 'example/x') so the other paths are no longer children and they become children of the root menu. The question in my mind is should callback entries be included as part of the menu structure as far as determing child/parent relationships.

This may explain the problem with tagadelic since it builds a menu entry with a path of 'tagadelic' and a type of MENU_SUGGESTED_ITEM (which means the entry is not visible by default). It also defines a number of possible children that I am guessing end up with negative mids for the same or similiar reason as outlines for the case above.

mr700’s picture

Version: 4.7.3 » 4.7.4

Many thanks nevets, I got the same problem (thanks to google too):

I defined 'home' as MENU_CALLBACK with callback and access functions, then 'home/1', 'home/2', 'home/3' and so on without. They should (and they do) inherit the callback function and access, but show in the root menu because there's no 'home' to collapse them. This worked, but I got menu items with negative 'mid's, which can't be edited/reordered...

The solution (other than defininf every 'home/*' alone) is to define 'home' as MENU_SUGGESTED_ITEM. This way I get no negative 'mid's and as added bonus I can now easy move all 'home/*' items under 'home' and back to the root menu.

I can't find anything on the subject in the docs, a brief note maybe (Don't put MENU_NORMAL_ITEM under MENU_CALLBACK path, use MENU_SUGGESTED_ITEM)?

PP: I also had to 'delete from menu' to get rid of manu duplicates, but I have no idea what caused them, the negative 'mid's and my test module or the 4.6 -> 4.7 upgrade.

ricabrantes’s picture

Version: 4.7.4 » 7.x-dev

Any news about this?

pwolanin’s picture

Version: 7.x-dev » 5.x-dev
Status: Active » Closed (fixed)

obviously this is a pre-D6 code issue, and apparently was not urgent.