Restrict Block By Role
StevenSokulski - February 1, 2006 - 06:04
Spent a while searching for this and found some PHP code that'd do it but was wondering if there's an easier way to restrict the apearance of a block by a user's role.
Spent a while searching for this and found some PHP code that'd do it but was wondering if there's an easier way to restrict the apearance of a block by a user's role.
Unfortunately.
If it's a custom block you need then http://drupal.org/node/27690 (I assume you found that) is about as easy as it goes.
--
Tips for posting to the forums.
When your problem is solved, please post a follow-up to the thread you started.
thats a neat trick
Hey... thats a neat trick. I didn't know blocks could be played around with like that. Thanks.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
My Drupal-powered Blog: ThoughtfulChaos
It is most certainly not
It is most certainly not custom. My mistake there in not mentioning that.
I would gladly use the PHP code (no fear of code here) if it were custom. I actually am using it with another block.
But what about, say, a block generated by the menu module?
Thanks again!
Custom menu's for specific roles
Suppose you made several custom menus (Sales_menu, Engineering_menu etc) , one for each role with names Sales, Engineering.
Then make a block titled eg 'Menu' set it to PHP.
This block will hold the logic for retrieving an displaying menu's for each role. Of course you can make multiple blocks with similar code, and different roles to check.
The following code is the 'simplest' one role, one menu.
<?phpglobal $user;
$output ='';
// Generate an associative array mapping menu_id and menu_title
$mid_by_title = array();
$menu = module_invoke('menu', 'block', 'list');
foreach($menu as $mid => $value) {
$mid_by_title[$value['info']] = $mid;
}
if(is_array($user->roles)){
if( in_array('Sales', $user->roles) && isset($mid_by_title['Sales_menu'])){
$block = module_invoke('menu', 'block', 'view', $mid_by_title['Sales_menu']);
$output .= $block['content'];
} else if (in_array('Engineering', $user->roles) && isset($mid_by_title['Engineering_menu'])) {
$block = module_invoke('menu', 'block', 'view', $mid_by_title['Engineering_menu']);
$output .= $block['content'];
} else if(in_array('Ad nauseam', $user->roles) && isset($mid_by_title['Adnauseam_menu'])) {
$block = module_invoke('menu', 'block', 'view', $mid_by_title['Adnauseam_menu']);
$output .= $block['content'];
} else {
// Menu block for others; you can leave the entire else out
}
}
return $output;
?>
If you want it to be possible for people with multiple roles eg the one person in Sales and Engineering, change the else if statements to if (that's why the .=) or change the strategy to multiple blocks.
caveat: this is all posted in a haste and I feel I haven't explained things very well. But right now I can't find the words... Don't hesitate to ask.
--
Tips for posting to the forums.
When your problem is solved, please post a follow-up to the thread you started.
Wow!
I must say I'm very pleased to have seen such a detailed post and hunk of code that seems to do exactly what I need. Even a bit more.
Just to clarify: The Ad nauseam menu applies to any user that is not specified in the if/else if statements?
Thank you so very much!
Sorry no
The ad nauseam indicate that you can display other menu for other roles (until your sick of it)...
You are welcome.
(edit: menu not menu items)
--
Tips for posting to the forums.
When your problem is solved, please post a follow-up to the thread you started.
Ugh...
In my attempt to scale your code down to my current need (A single menu that appears and disappears based on whether the user is considered a 'Broadway Cares Support Staff' member or not) I believe I have successfully messed up your code. I know very little PHP and probably screwed up something here:
<?phpglobal $user;
$output ='';
// Generate an associative array mapping menu_id and menu_title
$mid_by_title = array();
$menu = module_invoke('menu', 'block', 'list');
foreach($menu as $mid => $value) {
$mid_by_title[$value['info']] = $mid;
}
if(is_array($user->roles)){
if( in_array('Broadway Cares Support Staff', $user->roles) && isset($mid_by_title['bway_cares'])){
$block = module_invoke('menu', 'block', 'view', $mid_by_title['bway_cares']);
$output .= $block['content'];
} else {
// Menu block for others; you can leave the entire else out
}
}
return $output;
?>
While I'm here, when creating the block that contains this code it should be enabled, correct? And it should be set so all users see the block no matter what, correct?
Thank you!
Looks good
What you posted above looks good. But to make sure I tested it on my local install; I'll repeat the steps here, also in light of your questions.
Setting up user & role
Setting up menu's administer » menus (admin/menu)
Setting up the block administer » blocks (admin/block)
Works as expected: only when logged in as test_user (with role Broadway Cares Support Staff) I see the menu in the custom block.
Thanks again!
Thanks again! It worked perfectly!
patch to 4.6 block.module to do this automatically
i wrote a patch to the 4.6 version of block.module that allows site admins to just select via checkboxes what roles should be able to view any given block. see http://drupal.org/node/49154 for details. also, this functionality will be added to 4.7 sometime soon (see http://drupal.org/node/18018 for info on that discussion).
Thanks!
Can't test it out right now. Test site is offline. But definitely looks good!
Thanks!
glad to share
i'm happy to share... open source is the way to go.
Thank you DDW!
Thank you DDW!
Just finished installing your 4.6 block.module patch and it worked like a charm. It was exactly what I was looking for.
I am another one who greatly appreciates and benefits from your contribution.
Thanks for me too!!
Nice work indeed!
maybe it's simpler...
make your custom block the way you want it, and select "show this block if the following PHP code returns TRUE"
<?phpglobal $user;
$allowed_role = 'writer'; //change to your liking!!
if(is_array($user->roles))
if( in_array($allowed_role, $user->roles)){
return true;
}
?>
it worked for me
That seems logical enough.
That seems logical enough. Also, the PHP above that I am currently using could probably be rewritten to use a switch instead of a chain of if/else statements. Although I like your idea for the simplicity of it especially if using only one menu.
Thanks.
Not in 4.6
"show this block if the following PHP code returns TRUE" is not available in 4.6.
--
The Manual | Troubleshooting FAQ | Tips for posting | Make Backups! | Consider creating a Test site.
show block only to administrator
just made a menu with a couple shortcuts to certain pages i was working on frequently, little blog for my development notes, whathaveyou..
and put it in a custom block for me, as user 1.
//show a a block if a user is only a specific user, in my case, admin.<?php
global $user;
if ($user->uid == 1) {
return true;
}
?>
and thats as simple as it gets