[ Index ] |
PHP Cross Reference of WordPress |
[Summary view] [Print] [Text view]
1 <?php 2 /** 3 * Build Administration Menu. 4 * 5 * @package WordPress 6 * @subpackage Administration 7 */ 8 9 if ( is_network_admin() ) { 10 11 /** 12 * Fires before the administration menu loads in the Network Admin. 13 * 14 * The hook fires before menus and sub-menus are removed based on user privileges. 15 * 16 * @private 17 * @since 3.1.0 18 */ 19 do_action( '_network_admin_menu' ); 20 } elseif ( is_user_admin() ) { 21 22 /** 23 * Fires before the administration menu loads in the User Admin. 24 * 25 * The hook fires before menus and sub-menus are removed based on user privileges. 26 * 27 * @private 28 * @since 3.1.0 29 */ 30 do_action( '_user_admin_menu' ); 31 } else { 32 33 /** 34 * Fires before the administration menu loads in the admin. 35 * 36 * The hook fires before menus and sub-menus are removed based on user privileges. 37 * 38 * @private 39 * @since 2.2.0 40 */ 41 do_action( '_admin_menu' ); 42 } 43 44 // Create list of page plugin hook names. 45 foreach ( $menu as $menu_page ) { 46 $pos = strpos( $menu_page[2], '?' ); 47 if ( false !== $pos ) { 48 // Handle post_type=post|page|foo pages. 49 $hook_name = substr( $menu_page[2], 0, $pos ); 50 $hook_args = substr( $menu_page[2], $pos + 1 ); 51 wp_parse_str( $hook_args, $hook_args ); 52 // Set the hook name to be the post type. 53 if ( isset( $hook_args['post_type'] ) ) { 54 $hook_name = $hook_args['post_type']; 55 } else { 56 $hook_name = basename( $hook_name, '.php' ); 57 } 58 unset( $hook_args ); 59 } else { 60 $hook_name = basename( $menu_page[2], '.php' ); 61 } 62 $hook_name = sanitize_title( $hook_name ); 63 64 if ( isset( $compat[ $hook_name ] ) ) { 65 $hook_name = $compat[ $hook_name ]; 66 } elseif ( ! $hook_name ) { 67 continue; 68 } 69 70 $admin_page_hooks[ $menu_page[2] ] = $hook_name; 71 } 72 unset( $menu_page, $compat ); 73 74 $_wp_submenu_nopriv = array(); 75 $_wp_menu_nopriv = array(); 76 // Loop over submenus and remove pages for which the user does not have privs. 77 foreach ( $submenu as $parent => $sub ) { 78 foreach ( $sub as $index => $data ) { 79 if ( ! current_user_can( $data[1] ) ) { 80 unset( $submenu[ $parent ][ $index ] ); 81 $_wp_submenu_nopriv[ $parent ][ $data[2] ] = true; 82 } 83 } 84 unset( $index, $data ); 85 86 if ( empty( $submenu[ $parent ] ) ) { 87 unset( $submenu[ $parent ] ); 88 } 89 } 90 unset( $sub, $parent ); 91 92 /* 93 * Loop over the top-level menu. 94 * Menus for which the original parent is not accessible due to lack of privileges 95 * will have the next submenu in line be assigned as the new menu parent. 96 */ 97 foreach ( $menu as $id => $data ) { 98 if ( empty( $submenu[ $data[2] ] ) ) { 99 continue; 100 } 101 $subs = $submenu[ $data[2] ]; 102 $first_sub = reset( $subs ); 103 $old_parent = $data[2]; 104 $new_parent = $first_sub[2]; 105 /* 106 * If the first submenu is not the same as the assigned parent, 107 * make the first submenu the new parent. 108 */ 109 if ( $new_parent != $old_parent ) { 110 $_wp_real_parent_file[ $old_parent ] = $new_parent; 111 $menu[ $id ][2] = $new_parent; 112 113 foreach ( $submenu[ $old_parent ] as $index => $data ) { 114 $submenu[ $new_parent ][ $index ] = $submenu[ $old_parent ][ $index ]; 115 unset( $submenu[ $old_parent ][ $index ] ); 116 } 117 unset( $submenu[ $old_parent ], $index ); 118 119 if ( isset( $_wp_submenu_nopriv[ $old_parent ] ) ) { 120 $_wp_submenu_nopriv[ $new_parent ] = $_wp_submenu_nopriv[ $old_parent ]; 121 } 122 } 123 } 124 unset( $id, $data, $subs, $first_sub, $old_parent, $new_parent ); 125 126 if ( is_network_admin() ) { 127 128 /** 129 * Fires before the administration menu loads in the Network Admin. 130 * 131 * @since 3.1.0 132 * 133 * @param string $context Empty context. 134 */ 135 do_action( 'network_admin_menu', '' ); 136 } elseif ( is_user_admin() ) { 137 138 /** 139 * Fires before the administration menu loads in the User Admin. 140 * 141 * @since 3.1.0 142 * 143 * @param string $context Empty context. 144 */ 145 do_action( 'user_admin_menu', '' ); 146 } else { 147 148 /** 149 * Fires before the administration menu loads in the admin. 150 * 151 * @since 1.5.0 152 * 153 * @param string $context Empty context. 154 */ 155 do_action( 'admin_menu', '' ); 156 } 157 158 /* 159 * Remove menus that have no accessible submenus and require privileges 160 * that the user does not have. Run re-parent loop again. 161 */ 162 foreach ( $menu as $id => $data ) { 163 if ( ! current_user_can( $data[1] ) ) { 164 $_wp_menu_nopriv[ $data[2] ] = true; 165 } 166 167 /* 168 * If there is only one submenu and it is has same destination as the parent, 169 * remove the submenu. 170 */ 171 if ( ! empty( $submenu[ $data[2] ] ) && 1 === count( $submenu[ $data[2] ] ) ) { 172 $subs = $submenu[ $data[2] ]; 173 $first_sub = reset( $subs ); 174 if ( $data[2] == $first_sub[2] ) { 175 unset( $submenu[ $data[2] ] ); 176 } 177 } 178 179 // If submenu is empty... 180 if ( empty( $submenu[ $data[2] ] ) ) { 181 // And user doesn't have privs, remove menu. 182 if ( isset( $_wp_menu_nopriv[ $data[2] ] ) ) { 183 unset( $menu[ $id ] ); 184 } 185 } 186 } 187 unset( $id, $data, $subs, $first_sub ); 188 189 /** 190 * Adds a CSS class to a string. 191 * 192 * @since 2.7.0 193 * 194 * @param string $class_to_add The CSS class to add. 195 * @param string $classes The string to add the CSS class to. 196 * @return string The string with the CSS class added. 197 */ 198 function add_cssclass( $class_to_add, $classes ) { 199 if ( empty( $classes ) ) { 200 return $class_to_add; 201 } 202 203 return $classes . ' ' . $class_to_add; 204 } 205 206 /** 207 * Adds CSS classes for top-level administration menu items. 208 * 209 * The list of added classes includes `.menu-top-first` and `.menu-top-last`. 210 * 211 * @since 2.7.0 212 * 213 * @param array $menu The array of administration menu items. 214 * @return array The array of administration menu items with the CSS classes added. 215 */ 216 function add_menu_classes( $menu ) { 217 $first_item = false; 218 $last_order = false; 219 $items_count = count( $menu ); 220 $i = 0; 221 222 foreach ( $menu as $order => $top ) { 223 $i++; 224 225 if ( 0 == $order ) { // Dashboard is always shown/single. 226 $menu[0][4] = add_cssclass( 'menu-top-first', $top[4] ); 227 $last_order = 0; 228 continue; 229 } 230 231 if ( 0 === strpos( $top[2], 'separator' ) && false !== $last_order ) { // If separator. 232 $first_item = true; 233 $classes = $menu[ $last_order ][4]; 234 $menu[ $last_order ][4] = add_cssclass( 'menu-top-last', $classes ); 235 continue; 236 } 237 238 if ( $first_item ) { 239 $classes = $menu[ $order ][4]; 240 $menu[ $order ][4] = add_cssclass( 'menu-top-first', $classes ); 241 $first_item = false; 242 } 243 244 if ( $i == $items_count ) { // Last item. 245 $classes = $menu[ $order ][4]; 246 $menu[ $order ][4] = add_cssclass( 'menu-top-last', $classes ); 247 } 248 249 $last_order = $order; 250 } 251 252 /** 253 * Filters administration menu array with classes added for top-level items. 254 * 255 * @since 2.7.0 256 * 257 * @param array $menu Associative array of administration menu items. 258 */ 259 return apply_filters( 'add_menu_classes', $menu ); 260 } 261 262 uksort( $menu, 'strnatcasecmp' ); // Make it all pretty. 263 264 /** 265 * Filters whether to enable custom ordering of the administration menu. 266 * 267 * See the {@see 'menu_order'} filter for reordering menu items. 268 * 269 * @since 2.8.0 270 * 271 * @param bool $custom Whether custom ordering is enabled. Default false. 272 */ 273 if ( apply_filters( 'custom_menu_order', false ) ) { 274 $menu_order = array(); 275 foreach ( $menu as $menu_item ) { 276 $menu_order[] = $menu_item[2]; 277 } 278 unset( $menu_item ); 279 $default_menu_order = $menu_order; 280 281 /** 282 * Filters the order of administration menu items. 283 * 284 * A truthy value must first be passed to the {@see 'custom_menu_order'} filter 285 * for this filter to work. Use the following to enable custom menu ordering: 286 * 287 * add_filter( 'custom_menu_order', '__return_true' ); 288 * 289 * @since 2.8.0 290 * 291 * @param array $menu_order An ordered array of menu items. 292 */ 293 $menu_order = apply_filters( 'menu_order', $menu_order ); 294 $menu_order = array_flip( $menu_order ); 295 $default_menu_order = array_flip( $default_menu_order ); 296 297 /** 298 * @global array $menu_order 299 * @global array $default_menu_order 300 * 301 * @param array $a 302 * @param array $b 303 * @return int 304 */ 305 function sort_menu( $a, $b ) { 306 global $menu_order, $default_menu_order; 307 $a = $a[2]; 308 $b = $b[2]; 309 if ( isset( $menu_order[ $a ] ) && ! isset( $menu_order[ $b ] ) ) { 310 return -1; 311 } elseif ( ! isset( $menu_order[ $a ] ) && isset( $menu_order[ $b ] ) ) { 312 return 1; 313 } elseif ( isset( $menu_order[ $a ] ) && isset( $menu_order[ $b ] ) ) { 314 if ( $menu_order[ $a ] == $menu_order[ $b ] ) { 315 return 0; 316 } 317 return ( $menu_order[ $a ] < $menu_order[ $b ] ) ? -1 : 1; 318 } else { 319 return ( $default_menu_order[ $a ] <= $default_menu_order[ $b ] ) ? -1 : 1; 320 } 321 } 322 323 usort( $menu, 'sort_menu' ); 324 unset( $menu_order, $default_menu_order ); 325 } 326 327 // Prevent adjacent separators. 328 $prev_menu_was_separator = false; 329 foreach ( $menu as $id => $data ) { 330 if ( false === stristr( $data[4], 'wp-menu-separator' ) ) { 331 332 // This item is not a separator, so falsey the toggler and do nothing. 333 $prev_menu_was_separator = false; 334 } else { 335 336 // The previous item was a separator, so unset this one. 337 if ( true === $prev_menu_was_separator ) { 338 unset( $menu[ $id ] ); 339 } 340 341 // This item is a separator, so truthy the toggler and move on. 342 $prev_menu_was_separator = true; 343 } 344 } 345 unset( $id, $data, $prev_menu_was_separator ); 346 347 // Remove the last menu item if it is a separator. 348 $last_menu_key = array_keys( $menu ); 349 $last_menu_key = array_pop( $last_menu_key ); 350 if ( ! empty( $menu ) && 'wp-menu-separator' === $menu[ $last_menu_key ][4] ) { 351 unset( $menu[ $last_menu_key ] ); 352 } 353 unset( $last_menu_key ); 354 355 if ( ! user_can_access_admin_page() ) { 356 357 /** 358 * Fires when access to an admin page is denied. 359 * 360 * @since 2.5.0 361 */ 362 do_action( 'admin_page_access_denied' ); 363 364 wp_die( __( 'Sorry, you are not allowed to access this page.' ), 403 ); 365 } 366 367 $menu = add_menu_classes( $menu );
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Sat Nov 23 01:00:02 2024 | Cross-referenced by PHPXref 0.7.1 |