uid == 1 || empty($mlid)) {
// Admins do not lose access whatever this module would otherwise say
// Also, if the menu link identifier is not set, ignore the request
return;
}
$rids = _menu_per_role_get_roles($mlid);
// NULL means that you can try some more and FALSE you're definitively out
return !empty($rids) && count(array_intersect($rids, array_keys($user->roles))) == 0 ? FALSE : NULL;
}
/*
* Implementation of hook_form_alter().
*/
function menu_per_role_form_alter(&$form, $form_state, $form_id) {
if ($form_id == 'menu_edit_item') {
$default_value = $form['menu']['mlid']['#value'] ? _menu_per_role_get_roles($form['menu']['mlid']['#value']) : array();
$form['menu_per_role'] = array(
'#type' => 'fieldset',
'#title' => t('Restrict access permission'),
'#collapsible' => TRUE,
'#collapsed' => count($default_value) == 0,
'#weight' => 5,
'#description' => t('Last check: check to know whether the user has proper permission to see the defined item.'),
);
$form['menu_per_role']['roles'] = array(
'#type' => 'checkboxes',
'#title' => t('Restrict access to only these roles'),
'#options' => user_roles(),
'#default_value' => $default_value,
'#description' => t('Check no role to leave the access permission to the default.'),
);
$form['submit']['#weight'] = 10;
$form['#submit'][] = '_menu_per_role_form_submit';
}
}
/*
* Internal function to save the data in our table.
*/
function _menu_per_role_form_submit($form, &$form_state) {
if ($form_state['submitted']) {
$mlid = $form_state['values']['menu']['mlid'];
if ($mlid) {
$rids = array();
foreach ($form_state['values']['roles'] as $rid => $checked) {
if ($checked) {
$rids[] = $rid;
}
}
$rids_str = implode(',', $rids);
db_query("UPDATE {menu_per_role} SET rids = '%s' WHERE mlid = %d", $rids_str, $mlid);
if (db_affected_rows() == 0) {
// if nothing was affected, the row did not exist yet
db_query("INSERT INTO {menu_per_role} (mlid, rids) VALUES (%d, '%s')", $mlid, $rids_str);
}
menu_cache_clear_all();
}
else {
drupal_set_message(t('The menu link identifier was not defined on Submit in Menu per Role. You are most certainly adding a new menu item. For this feature to work when adding a menu item, you must apply the patch defined in node #326210. That patch is included in this module for that purpose.'), 'error');
}
}
}
/*
* When the menu item is being submitted, the core also calls the
* hook_menu_link_alter(&$item, $menu);
*
* By catching that function, we can set the special alter option
* that will let our module receive a call whenever the menu is
* ready for display but was not yet displayed. At that time we
* can mark the access as FALSE.
*/
function menu_per_role_menu_link_alter(&$item, $menu)
{
// TODO: The following marks ALL menu items as alterable.
// Any time a menu item is saved, it is marked as
// such. I have no clue, at this time, of a way to
// avoid such nonsense. Hints welcome!
$item['options']['alter'] = TRUE;
}
/*
* Before a menu item gets displayed, the core calls the hook:
* hook_translated_menu_link_alter(&$item, $map);
* (but only if $item['options']['alter'] is TRUE)
*
* This function is used to alter the access right based on
* the role definition of the item.
*/
function menu_per_role_translated_menu_link_alter(&$item, $map)
{
// avoid checking the role if the item access is already false
if ($item['access'] && _menu_per_role_access($item['mlid']) === FALSE) {
$item['access'] = FALSE;
}
}
/*
* Gets all roles with access to the specified menu item
* No roles mean that access should either be inherited from the parent menu item
* or the user does not have access.
*/
function _menu_per_role_get_roles($mlid) {
$result = db_query("SELECT rids FROM {menu_per_role} WHERE mlid = %d", $mlid);
if ($result && ($row = db_fetch_object($result)) && $row->rids) {
return explode(',', $row->rids);
}
// not defined, everyone has the right to use it
return array();
}