| [ Index ] |
PHP Cross Reference of Drupal 6 (gatewave) |
[Summary view] [Print] [Text view]
1 <?php 2 // $Id: menu_per_role.module,v 1.6.2.14 2010/10/19 08:53:15 alexiswilke Exp $ 3 4 /** 5 * @file 6 * Allows restricting access to menu items per role 7 */ 8 9 /* 10 * Permission for who can access the menu per role forms. 11 */ 12 function menu_per_role_perm() { 13 return array('administer menu_per_role'); 14 } 15 16 /* 17 * Determines access for a give menu item id 18 * 19 * \warning 20 * This function is NOT called automatically up to version 6.10. 21 * You need to apply the patch provided in this module so it 22 * actually works in older versions. See file: 23 * 24 * drupal-6.6-menu_per_role.patch 25 * 26 * \param[in] $mlid The menu item identifier 27 * 28 * \return NULL if this module does not forbid the viewing of this menu item, 29 * FALSE otherwise 30 */ 31 function _menu_per_role_access($mlid) { 32 global $user; 33 34 if ($user->uid == 1 || empty($mlid) || user_access('administer menu_per_role')) { 35 // Admins do not lose access whatever this module would otherwise say 36 // Also, if the menu link identifier is not set, ignore the request 37 return NULL; 38 } 39 40 // check whether this role has visibility access (must be present) 41 $rids = _menu_per_role_get_roles($mlid, 0); 42 if (!empty($rids) && count(array_intersect($rids, array_keys($user->roles))) == 0) { 43 // not permitted by the rids... 44 return FALSE; 45 } 46 47 // check whether this role has visibility access (must not be present) 48 $hrids = _menu_per_role_get_roles($mlid, 1); 49 if (!empty($hrids) && count(array_intersect($hrids, array_keys($user->roles))) > 0) { 50 // not permitted by the hrids... 51 return FALSE; 52 } 53 54 // this module is not preventing user from seeing this menu entry 55 return NULL; 56 } 57 58 59 /* 60 * Implementation of hook_form_alter(). 61 */ 62 function menu_per_role_form_alter(&$form, $form_state, $form_id) { 63 if (!user_access('administer menu_per_role')) { 64 return; 65 } 66 67 if ($form_id == 'menu_edit_item') { 68 $f = &$form; 69 $form['submit']['#weight'] = 10; 70 } 71 if (isset($form['#node']) && $form['#node']->type .'_node_form' == $form_id && isset($form['menu'])) { 72 $f = &$form['menu']; 73 } 74 if (isset($f)) { 75 $default_value_roles = $form['menu']['mlid']['#value'] 76 ? _menu_per_role_get_roles($form['menu']['mlid']['#value'], 0) 77 : array(); 78 $default_value_hide_from_roles = $form['menu']['mlid']['#value'] 79 ? _menu_per_role_get_roles($form['menu']['mlid']['#value'], 1) 80 : array(); 81 $f['menu_per_role'] = array( 82 '#type' => 'fieldset', 83 '#title' => t('Restrict item visibility'), 84 '#collapsible' => TRUE, 85 '#collapsed' => (count($default_value_roles) + count($default_value_hide_from_roles)) == 0, 86 '#weight' => 5, 87 '#description' => t('Check to know whether the user has proper visibility permissions to see this menu item. Note that both checks are always performed.'), 88 ); 89 $f['menu_per_role']['menu_per_role_roles'] = array( 90 '#type' => 'checkboxes', 91 '#title' => t('Show menu item only to selected roles'), 92 '#options' => user_roles(), 93 '#default_value' => $default_value_roles, 94 '#description' => t('Check no role to leave the access permission to the default. A user who is not part of at least one of the selected roles will not see this menu item.'), 95 ); 96 $f['menu_per_role']['menu_per_role_hide_from_roles'] = array( 97 '#type' => 'checkboxes', 98 '#title' => t('Hide menu item from selected roles'), 99 '#options' => user_roles(), 100 '#default_value' => $default_value_hide_from_roles, 101 '#description' => t('Check no role to leave the access permission to the default. A user who is part of any one of these roles will not see this menu item.'), 102 ); 103 $form['#submit'][] = '_menu_per_role_form_submit'; 104 } 105 } 106 107 108 /* 109 * Internal function to save the data in our table. 110 */ 111 function _menu_per_role_form_submit($form, &$form_state) { 112 global $db_type; 113 114 if ($form_state['submitted']) { 115 $mlid = $form_state['values']['menu']['mlid']; 116 if ($mlid) { 117 // hide but to those roles 118 $rids = array(); 119 $roles = isset($form_state['values']['menu_per_role_roles']) ? 120 $form_state['values']['menu_per_role_roles'] 121 : $form_state['values']['menu']['menu_per_role']['menu_per_role_roles']; 122 foreach ($roles as $rid => $checked) { 123 if ($checked) { 124 $rids[] = $rid; 125 } 126 } 127 $rids_str = implode(',', $rids); 128 // show but to those roles 129 $hrids = array(); 130 $roles = isset($form_state['values']['menu_per_role_hide_from_roles']) ? 131 $form_state['values']['menu_per_role_hide_from_roles'] 132 : $form_state['values']['menu']['menu_per_role']['menu_per_role_hide_from_roles']; 133 foreach ($roles as $rid => $checked) { 134 if ($checked) { 135 $hrids[] = $rid; 136 } 137 } 138 $hrids_str = implode(',', $hrids); 139 // save in our table 140 //db_lock_table('menu_per_role'); 141 if ($rids_str || $hrids_str) { 142 db_query("UPDATE {menu_per_role} SET rids = '%s', hrids = '%s' WHERE mlid = %d", $rids_str, $hrids_str, $mlid); 143 if (db_affected_rows() == 0) { 144 // if nothing was affected, the row did not exist yet 145 // (although with MySQL this may fail because db_affected_rows() may only return 146 // rows that have been changed instead of the # of rows that match the WHERE clause.) 147 if ($db_type != 'pgsql') { 148 $insert = !db_result(db_query("SELECT 1 FROM {menu_per_role} WHERE mlid = %d", $mlid)); 149 } 150 else { 151 $insert = TRUE; 152 } 153 if ($insert) { 154 db_query("INSERT INTO {menu_per_role} (mlid, rids, hrids) VALUES (%d, '%s', '%s')", $mlid, $rids_str, $hrids_str); 155 } 156 } 157 } 158 else { 159 // we don't need to save it when empty, instead, remove that completely 160 db_query("DELETE FROM {menu_per_role} WHERE mlid = %d", $mlid); 161 } 162 //db_unlock_tables(); 163 // reset the menus 164 menu_cache_clear_all(); 165 } 166 else if (isset($form_state['values']['menu_per_role_roles'])) { 167 drupal_set_message(t('The menu link identifier was not defined on Submit in <b>Menu per Role</b>. 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 <a href="http://drupal.org/node/326210" target="_blank">node #326210</a>. That patch is included in this module for that purpose.'), 'error'); 168 } 169 } 170 } 171 172 173 /* 174 * When the menu item is being submitted, the core also calls the 175 * hook_menu_link_alter(&$item, $menu); 176 * 177 * By catching that function, we can set the special alter option 178 * that will let our module receive a call whenever the menu is 179 * ready for display but was not yet displayed. At that time we 180 * can mark the access as FALSE. 181 */ 182 function menu_per_role_menu_link_alter(&$item, $menu) 183 { 184 // TODO: The following marks ALL menu items as alterable. 185 // Any time a menu item is saved, it is marked as 186 // such. I have no clue, at this time, of a way to 187 // avoid such nonsense. Hints welcome! 188 $item['options']['alter'] = TRUE; 189 } 190 191 192 /* 193 * Before a menu item gets displayed, the core calls the hook: 194 * hook_translated_menu_link_alter(&$item, $map); 195 * (but only if $item['options']['alter'] is TRUE) 196 * 197 * This function is used to alter the access right based on 198 * the role definition of the item. 199 */ 200 function menu_per_role_translated_menu_link_alter(&$item, $map) 201 { 202 // avoid checking the role if the item access is already false 203 if ($item['access'] && _menu_per_role_access($item['mlid']) === FALSE) { 204 $item['access'] = FALSE; 205 } 206 } 207 208 209 /** 210 * Gets all roles with access to the specified menu item 211 * No roles mean that access is granted by this module. 212 * 213 * $show set to 0 for show to roles, 1 for hide from roles 214 */ 215 function _menu_per_role_get_roles($mlid, $show) { 216 static $menu_per_role; 217 218 if (!isset($menu_per_role)) { 219 // read all the data ONCE, it is likely very small 220 $menu_per_role = array(); 221 $result = db_query("SELECT * FROM {menu_per_role}"); 222 while ($row = db_fetch_object($result)) { 223 if ($row->rids || $row->hrids) { 224 $menu_per_role[$row->mlid][0] = explode(',', $row->rids); 225 $menu_per_role[$row->mlid][1] = explode(',', $row->hrids); 226 } 227 } 228 } 229 230 if (isset($menu_per_role[$mlid])) { 231 return $menu_per_role[$mlid][$show]; 232 } 233 234 // not defined, everyone has the right to use it 235 return array(); 236 } 237 238 // vim: ts=2 sw=2 et syntax=php
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
| Generated: Thu Mar 24 11:18:33 2011 | Cross-referenced by PHPXref 0.7 |