Intercept Topbar Menu Items

My client wants to eliminate the "Settings" topbar menu item for certain users. I have tried registering a plugin hook to intercept both "prepare" and "register" for the topbar menu. I get logo, profile, friends and messages items but neither "Settings" or "Log out" items seem to come through. Most of these items are registered in users.php in the users page setup function. Settings is registered with a higher priority (500) and in section 'alt'. I cannot figure out how to intercept and delete the settings menu item. Any one out there have any ideas?

  • I've managed to intercept the menu item... but only through a pagesetup event handler. Any other approach seems to be too early since the menu is registered in a pagesetup event. Is this a bug or intended behaviour?

  • You're on the right track with the prepare hook. Register later and examine the array that's passed to your handler. 

  • I tried registering as late as I could - using 10000 still with no success. I have a system message that reports menu items by name on the prepare - and yet find that there is a very (as in very very late) register menu item. The only way I get a shot at it is to use a late registered page setup and unregister the settings topbar menu item... seems wrong but it works. I'd love to figure out how to do it the right way... Users.php registers a page setup with priority 0 - and that's where the menus are registered. The odd part is that logo, profile, friends and messages are all registered at the same time - and those I have no problem getting. For some reason the settings (usersettings) and logout are just not reported in the prepare hook. After I get the messages from those items, I see that the users page setup is called twice! Very odd...

  • How can I register my hook even later? Nothing I do seems to work.

  • The other settings links are registered to the "page" menu here. Can you try var_dump in your handler? I wonder if you're not seeing them because they haven't been converted to ElggMenuItems yet...

  • I think I have confused you. Sorry. The code I'm referring to is in engine/lib/users.php. That file registers an event handler:  elgg_register_event_handler('pagesetup', 'system', 'users_pagesetup', 0); at the bottom of the file. The function users_pagesetup registers topbar menu items. Here is the code:

    // topbar
    if ($viewer) {
    elgg_register_menu_item('topbar', array(
    'name' => 'profile',
    'href' => $viewer->getURL(),
    'text' => elgg_view('output/img', array(
    'src' => $viewer->getIconURL('topbar'),
    'alt' => $viewer->name,
    'title' => elgg_echo('profile'),
    'class' => 'elgg-border-plain elgg-transition',
    )),
    'priority' => 100,
    'link_class' => 'elgg-topbar-avatar',
    ));

    elgg_register_menu_item('topbar', array(
    'name' => 'friends',
    'href' => "friends/{$viewer->username}",
    'text' => elgg_view_icon('users'),
    'title' => elgg_echo('friends'),
    'priority' => 300,
    ));

    elgg_register_menu_item('topbar', array(
    'name' => 'usersettings',
    'href' => "settings/user/{$viewer->username}",
    'text' => elgg_view_icon('settings') . elgg_echo('settings'),
    'priority' => 500,
    'section' => 'alt',
    ));

    elgg_register_menu_item('topbar', array(
    'name' => 'logout',
    'href' => "action/logout",
    'text' => elgg_echo('logout'),
    'is_action' => TRUE,
    'priority' => 1000,
    'section' => 'alt',
    ));
    }

    If I delete this code for the item named 'usersettings' the topbar "Settings" menu item is gone (the one with the wrench). So, since I cannot edit system files I figured I'd register for a 'prepare' hool for menu:topbar. When I do and I system_message the item names for the menu items I get "logo", "profile", "friends", and "messages". "Settings" and "logout" are not returned. If I put a system_message in the users.php file immediately before the menu item is registered in users.php I see that it is registered after my "prepare" hook fires. That is why I do not see them - they are registered after my hook is called (and btw the register call is called twice). So somehow I need to get my hook to be called later - after the users.php registers them.

    Am I making this clear?

    Thanks for your help on this - it is appreciated.

  • If you're sure you can't get the menu item in that hook you can try hooking 'prepare', 'all'

    Hooks with the keyword 'all' are run after specific hooks regardless of priority - see http://trac.elgg.org/ticket/1378

  • Are you sure you've inspected the returnvalue of the hook?  It's actually going to be a multidimensional array and your item will be in $return['alt']

  • Tried that... good suggestion - but same result. Get every menu item in the view and page (of course) but still no settings and logout menu items. Very odd.

    I have it hacked by unregistering the menu item in a page setup hook when it meets the proper conditions, but I feel like that is a bit of a hack. Seems these items should be available to the "prepare" hook. Do you think this is a bug?

  • Darn, I just read your last reply thoroughly. No, I did not check $return['alt']. Thats what I was missing. Haven't tried that yet but I bet thats what I am missing. I've been checking $return['default']. Its always so obvious when you finally see it... lol... Thanks for your help. I'm a bit new to the menu system and was not clued into the data structures.