The toolbar module has been implemented with insufficient knowledge and understanding of how the menu system works. The current code is ugly and very inefficient (both in term of processing power and in term of memory usage), introduces some code duplication and a maintenance hell.

We need to fix that. Now.

This issue is the first step: introduce a clean way to build a slice of a menu.

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

Damien Tournoud’s picture

Status: Active » Needs review
FileSize
15.41 KB

This patch:

- factor out the common tree-building logic of menu_tree_all_data() and menu_tree_page_data() into a menu_build_tree() function
- uses this new function in the toolbar module

Status: Needs review » Needs work

The last submitted patch failed testing.

makara’s picture

cache_clear_all('links:' . $menu_name . ':', 'cache_menu', TRUE);
in function
menu_cache_clear()

either remove the ':', or edit your cache cid.

Damien Tournoud’s picture

Status: Needs work » Needs review
FileSize
14.99 KB

@Makara: you are the best.

Same patch, with a simpler, and better tree cache ID.

Status: Needs review » Needs work

The last submitted patch failed testing.

sun’s picture

This is a very interesting alpha-quality patch, which actually maps nicely to what I outlined in #618530: System module's "listing" pages (and blocks) should use menu_build_tree().

sun’s picture

+++ modules/toolbar/toolbar.module
@@ -134,12 +134,13 @@ function toolbar_get_menu_tree() {
   $admin_link = db_query("SELECT * FROM {menu_links} WHERE menu_name = 'management' AND module = 'system' AND link_path = 'admin'")->fetchAssoc();
...
+    $data = menu_build_tree('management', array(
+      'parents' => array($admin_link['mlid']),
+      'min_depth' => 2,
+      'max_depth' => 2,
+    ));

Instead of a hard-coded 2, we want to use $admin_link['depth'] here. :)

+++ modules/toolbar/toolbar.module
@@ -134,12 +134,13 @@ function toolbar_get_menu_tree() {
+    menu_tree_check_access($data['tree'], $data['node_links']);
+    $tree = $data['tree'];

Do we really want to put this into the caller's responsibility?

How about going with this menu_build_tree(), but perhaps make it private, i.e. _menu_build_tree(), and make menu_build_tree() invoke _menu_build_tree() + additionally invoke menu_tree_check_access() and return the resulting tree data? :)

This review is powered by Dreditor.

makara’s picture

now the cid is too long...

sun’s picture

Title: The toolbar module should properly build its menu slice » Toolbar module (and others) should properly build its menu slice
Component: base system » menu system
Status: Needs work » Needs review
FileSize
16.15 KB

This should work.

sun’s picture

Sorry, left a stale parameter in there.

sun’s picture

So what's left here?

This works beautifully. Aside from that:

1) A bit wonky is the "parents" tree parameter (list). When would I want to pass more than one plid? (Though we can as well ignore that, because it equals the current code.)

2) uhm, nothing. I'll check whether we could use this cool thingy also for contextual links now ;) (separate issue)

Damien Tournoud’s picture

+++ includes/menu.inc	5 Nov 2009 18:54:56 -0000
@@ -1212,10 +1131,115 @@ function menu_tree_page_data($menu_name,
+  $tree_cid = 'links:' . $menu_name . ':tree-data:' . $GLOBALS['language_interface']->language . ':' . md5(serialize($parameters));

I'm not comfortable with this. There is no guarantee that the tree ID is unique for a set of parameters. The risk of conflict is small, but real.

I'm on crack. Are you, too?

sun’s picture

That, I don't get. How can the tree be different for the same parameters?

Access checking happens later only, so I really don't see how this would be possible.

I also don't see a ->random() in there. ;)

It would make me really worry about this function. The result of a function should be the same under the same conditions. I'd consider it a critical bug if a function doesn't return the same for the same arguments.

So can you clarify?

sun’s picture

Issue tags: +D7 API clean-up

Tagging (and updating the other issue accordingly)

sun’s picture

Can we proceed here?

In the meantime, I looked into whether this function could be used for contextual links as well. It probably could be, if the menu system would store a proper plid, depth, and pX columns for dynamic paths/local tasks... which it is currently not. That's surely a separate issue (perhaps related to the existing #550254: Menu links are sometimes not properly re-parented), but this patch would be a major step towards a better solution.

Damien Tournoud’s picture

That, I don't get. How can the tree be different for the same parameters?

That's not what I'm saying. I'm saying that md5(serialize($parameters)) can be the same for several $parameters. But it's not probably that common, given that $parameters is typically small.

sun’s picture

Fixed inline comments.

sun’s picture

In $tree_parameters,

- renamed 'parents' to 'expanded'

- renamed 'active_link' to 'active_trail'

because I think that's much more understandable for people who want to use this tree builder.

Status: Needs review » Needs work

The last submitted patch failed testing.

sun’s picture

Status: Needs work » Needs review
FileSize
16.5 KB

Test slave #44 produces non-reliable results.

chx’s picture

Status: Needs review » Reviewed & tested by the community

I RTBC this on the condition that in a followup patch we will review how menu build tree and menu tree data could be merged.

Dries’s picture

I think this is a great clean-up that should be committed.

One comment though: in the original description, DamZ complains about unnecessary duplication but this patch adds more lines than it removes ... Also, in the original description, DamZ complains that the original code is inefficient (both in term of processing power and in term of memory usage), but I don't see performance numbers on the new code? Do we want to test whether it is actually faster? (It should be.)

webchick’s picture

Status: Reviewed & tested by the community » Needs review

That sounds like a 'needs review' to me. :)

jurgenhaas’s picture

Wanted to review this patch but it is outdated. However, its purpose is promissing.

yoroy’s picture

#20: drupal.menu-build-tree.20.patch queued for re-testing.

cosmicdreams’s picture

subscribing

JohnAlbin’s picture

patch in #20 no longer applied. Re-rolled.

JohnAlbin’s picture

in the original description, DamZ complains about unnecessary duplication but this patch adds more lines than it removes

Actually, the number of pluses and minuses in the patch is misleading. There are technically more pluses, but there's a lot of added white space, doc blocks, and comments. If you compare just lines of meaningful code. There are 105 minuses of meaningful code versus 89 pluses of meaningful code. So the patch does reduce duplication.

Also, for testers, make sure you clear the cache after applying, otherwise you'll get Fatal errors since the old cache data doesn't match the new cache data structure.

Performance testing it beyond me, or I'd do that and RTBC this again. :-(

David_Rothstein’s picture

Haven't looked too closely at the patch, but it does seem like a nice cleanup for the menu system.

In terms of the toolbar, the changes are probably good for the purposes of this patch - but ideally we want to have the toolbar stop doing weird things altogether, rather than improving the way it does weird things :) In particular, I assume/hope that the fix for #596010: Move "Administration" link into Account menu and make Toolbar output first level of 'admin' menu will involve getting rid of the custom database query in the toolbar module (the one that ties it to paths under 'admin') and allowing it to call something like menu_tree_page_data('management', 1) directly instead...

sun’s picture

@David: That's this patch then. The changes for Toolbar in this patch make it use the ideal way.

Damien Tournoud’s picture

Priority: Normal » Critical

Qualify as critical because 1) it fixes several bugs in one stone, 2) the current implementation is just a performance nightmare.

makara’s picture

FileSize
16.52 KB

Re-rolled patch. Also changed tree cid hash from md5 to sha256 to reflect recent changes.

YesCT’s picture

In preparation for the new "major" issue priority, I'm tagging this (not actually critical, but still important) issue as priority-major.
See: http://drupal.org/node/669048#comment-3019824 (#669048: We should have four priorities not three (introduce a new 'major' priority)) for more information about the coming major issue priority.

Damien Tournoud’s picture

Disagreed on the Major. This critically affect performance (and as a consequence functionality) of any moderately busy site.

catch’s picture

Title: Toolbar module (and others) should properly build its menu slice » Optimize menu tree building and use it for toolbar

Re-titling this so it's more obvious why it's critical, I will try to profile it soonish.

catch’s picture

There's a separate patch for menu_tree_page_data() here #327918: Optimize menu_tree_page_data() performance, one or the other of these patches are duplicate for that hunk, don't have time to look further this morning though.

YesCT’s picture

#32: drupal.menu-build-tree.patch queued for re-testing.

catch’s picture

FileSize
118.3 KB
93.99 KB

This takes ~5% off request time on a newly installed HEAD (with access to toolbar) according to xhprof.

There's no tests with the patch, do we have some already?

Attached screenshots, 004 is head, 005 with patch.

sun’s picture

Status: Needs review » Reviewed & tested by the community

This patch changed only marginally since Damien and me touched it last. What else is left to get this in? Nothing?

marcingy’s picture

Issue tags: -D7 API clean-up

#32: drupal.menu-build-tree.patch queued for re-testing.

marcingy’s picture

Issue tags: +D7 API clean-up

#32: drupal.menu-build-tree.patch queued for re-testing.

Dries’s picture

Status: Reviewed & tested by the community » Fixed

Reviewed and committed to CVS HEAD. :)

David_Rothstein’s picture

The new static cache introduced here needs to be cleared by menu_reset_static_cache() - otherwise it leads to some very odd bugs. The patch is trivial, but could ideally use some tests, so I created a separate issue for it here:

#843278: Tests for Menu system static cache clearing

Status: Fixed » Closed (fixed)
Issue tags: -D7 API clean-up

Automatically closed -- issue fixed for 2 weeks with no activity.