The menu tree returned by menu_tree_data() puts elements on the wrong level because it looks at the wrong item when determining the termination condition. After filling the current item's
below array using a recursive call to _menu_tree_data(), the $next element still points at the item before entering the recursion. However, we need to look at the next item after the recursion returned to determine whether the current loop needs to be terminated, thus a refresh of $next is needed.
Example using an excerpt of the menu structure:
+ admin/structure/blocks (depth=2)
+ + admin/structure/blocks/list (depth=3)
+ + - admin/structure/blocks/list/garland etc. (depth=4)
+ + - admin/structure/blocks/list/stark (still depth=4)
+ admin/structure/types (depth=2, need to terminate two recursions but fails!)
Consider we're at admin/structure/blocks/list and about to enter recursion for the sub-tree garland, etc. until stark. When the recursion returns, $next still points at admin/structure/blocks/list/garland, ie. the item before we entered the recursion. However, we need to look at the item after the sub-tree (admin/structure/types), to determine whether the loop needs to be terminated.
You can most easily validate the results by installing Admin Menu HEAD, which is finally working for D7 after applying this patch.
|Passed: 12836 passes, 0 fails, 0 exceptions|
|Passed: 12882 passes, 0 fails, 0 exceptions|
|Passed: 12898 passes, 0 fails, 0 exceptions|
|Unable to apply patch menu_tree_data.patch|