So I’ve been exploring the ‘nav_menu_roles_item_visibility’ as helgatheviking suggested and ended up writing a plugin to add Group names as custom roles and enable a filter to turn on menu items when a group-based role has been selected. This approach reduces chance of user error and the redundancy of having to add a capability within Groups.
The plugin has two functions:
1) nmr_groups_to_roles – almost exactly like the function that I started this thread with except the name is more accurate and the $key for $roles[$key] is also the name of the Group. This is important because when we compare arrays of Group names and NMR roles in the next function, $items->roles is an array of the $key values, not the names of the roles. (‘nmr’ is short for Nav Menu Roles, of course.) (BTW – I scoured the Groups API and forum but couldn’t find a way to pull just the names of the Groups w/o a direct database query.)
2) nmr_item_visibility – this is the filter modeled after helgatheviking’s example in the NMR FAQ. It puts the current user’s groups into an array and then checks to see if any of those groups are also in the $item->roles array using array_intersect. Here’s the code:
/*
Add Group names as custom roles to Nav Menu Roles menu list
param: $roles an array of all available roles, by default is global $wp_roles
return: array
*/
function nmr_groups_to_roles ( $roles ) {
global $wpdb;
$order_by = 'name';
$order = 'ASC';
$group_table = _groups_get_tablename( "group" );
if ( $groups = $wpdb->get_results(
"SELECT group_id FROM $group_table ORDER BY $order_by $order" ))
{
foreach( $groups as $group ) {
$group = new Groups_Group( $group->group_id );
// set $key of $roles to $group->name;
// this is important because $item->roles is an array of the $key values
$roles [$group->name] = $group->name;
}
}
return $roles;
}
add_filter( 'nav_menu_roles', 'nmr_groups_to_roles' );
/*
Set visibility of menu item to true, if
- current user is a member of a group
- AND that group has been given permission to see the menu item via Menu interface
param: $visible boolean
param: $item object, the complete menu object. Nav Menu Roles adds its info to $item->roles
return: boolean
*/
function nmr_item_visibility( $visible, $item ){
if( isset( $item->roles ) && is_array( $item->roles ) ){
$current_users_groups = array();
// get current user's groups and put into array
$user_ID = get_current_user_id();
$user = new Groups_User( $user_ID );
$groups = $user->groups;
foreach( $groups as $group ) {
$current_users_groups[] = $group->name;
}
if (! empty($current_users_groups)) {
// if any of the user's groups are among the roles selected via Nav Menu Groups, set visibility to true
if ((bool) array_intersect($current_users_groups, $item->roles) ) {
$visible = true;
}
}
}
return $visible;
}
add_filter( 'nav_menu_roles_item_visibility', 'nmr_item_visibility', 10, 2);