views:

236

answers:

2

Is there any way to show local tasks to user if they doesn't have necessary permissions? Right now it seems like Drupal just excludes them from page code. I want to show them, but with different CSS class.

Version of Drupal is 5.20

+3  A: 

I know the D6 version of hook_menu much better than D5's. AFAIK - however - you can't override that behaviour as it is hardcoded in menu.inc.

If I am right with what above, a workaround (rather inelegant, I must admit) could be:

  1. Remove the access control from the menu item, so that all menu items are visible to all user.
  2. Put access control in the callback directly (you will make the tab non-clickable in a moment, but if the user insert the URL directly, this will prevent access to pages they must not see).
  3. In the page displaying the tabs, load a different js file according to what roles the user has. The js file for users with limited access will select tabs by mean of their text content (at least in D6 tabs do not get any "individual" class: they only get a common "tab" one), it will remove the link to the tabs the user has no permission to visit and it will add a custom class to those tabs that should be displayed differently.
  4. Add CSS theming for your custom class.

As stated before, I do not know D5 much, so it might also turn out that you can actually achieve what you want in a much cleaner way!

mac
+1 - I'd use another approach (as proposed in a separate answer), just to prevent the need for adding access checking to all affected menu callbacks, which would be cumbersome to maintain. But this version is a valid option and could well be easier/more suited for cases with a less generic adjustment need.
Henrik Opel
+3  A: 

Even though there are some differences concerning the local task building between Drupal 5 and 6, Mac is right that the logic to ignore entries not accessible by the current user is pretty deeply embedded in the menu.inc functions. If you want to look for yourself, start with theme_menu_local_tasks() and follow the function calls from there.

If I had to implement the feature you're looking for, I'd rather avoid Macs suggestion of messing around with the menu access settings directly. Instead, I'd override theme_menu_local_tasks() with a custom version and duplicate the entry retrieval logic in there. The first run would fetch the primary and secondary links as before, and the second would do the same while impersonating another user (probably user 1 in this case). That way, I'd get two versions of the local task markup which I'd then needed to diff somehow in order to find the ones not allowed for the current user, thus needing the extra CSS class.

Note that this would still be somewhat ugly to do, as menu_primary_local_tasks() and menu_secondary_local_tasks() return already themed lists, so the comparison would need to work on the markup, probably parsing out the li tags somehow. So it might be worth spending some time trying to do the same thing (fetching the local tasks as two different users), but using lower level functions to get the entries before theming.

Note: Should you end up using the user impersonation logic, make sure to use the safe, second version that disables session saving during impersonation.

Henrik Opel
Thanks, done just that. It worked. User impersonation wasn't necessary, but thanks for the link anyway.
Kuroki Kaze
I like this approach too. The biggest advantage I see over the one I previously proposed is that this one scales better: as the markup is generated by some kind of "diff" function rather than by selecting the menu entry by its text content, it is faster to apply this solution if the number of menu you need to tweak is elevated. It also does not rely on js/jQuery which (although supported by nearly every browser) is a "dependency" more for your pages to be displayed correctly.
mac