[ 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 * @param string $add 191 * @param string $class 192 * @return string 193 */ 194 function add_cssclass( $add, $class ) { 195 $class = empty( $class ) ? $add : $class .= ' ' . $add; 196 return $class; 197 } 198 199 /** 200 * @param array $menu 201 * @return array 202 */ 203 function add_menu_classes( $menu ) { 204 $first = false; 205 $lastorder = false; 206 $i = 0; 207 $mc = count( $menu ); 208 foreach ( $menu as $order => $top ) { 209 $i++; 210 211 if ( 0 == $order ) { // Dashboard is always shown/single. 212 $menu[0][4] = add_cssclass( 'menu-top-first', $top[4] ); 213 $lastorder = 0; 214 continue; 215 } 216 217 if ( 0 === strpos( $top[2], 'separator' ) && false !== $lastorder ) { // If separator. 218 $first = true; 219 $c = $menu[ $lastorder ][4]; 220 $menu[ $lastorder ][4] = add_cssclass( 'menu-top-last', $c ); 221 continue; 222 } 223 224 if ( $first ) { 225 $c = $menu[ $order ][4]; 226 $menu[ $order ][4] = add_cssclass( 'menu-top-first', $c ); 227 $first = false; 228 } 229 230 if ( $mc == $i ) { // Last item. 231 $c = $menu[ $order ][4]; 232 $menu[ $order ][4] = add_cssclass( 'menu-top-last', $c ); 233 } 234 235 $lastorder = $order; 236 } 237 238 /** 239 * Filters administration menus array with classes added for top-level items. 240 * 241 * @since 2.7.0 242 * 243 * @param array $menu Associative array of administration menu items. 244 */ 245 return apply_filters( 'add_menu_classes', $menu ); 246 } 247 248 uksort( $menu, 'strnatcasecmp' ); // Make it all pretty. 249 250 /** 251 * Filters whether to enable custom ordering of the administration menu. 252 * 253 * See the {@see 'menu_order'} filter for reordering menu items. 254 * 255 * @since 2.8.0 256 * 257 * @param bool $custom Whether custom ordering is enabled. Default false. 258 */ 259 if ( apply_filters( 'custom_menu_order', false ) ) { 260 $menu_order = array(); 261 foreach ( $menu as $menu_item ) { 262 $menu_order[] = $menu_item[2]; 263 } 264 unset( $menu_item ); 265 $default_menu_order = $menu_order; 266 267 /** 268 * Filters the order of administration menu items. 269 * 270 * A truthy value must first be passed to the {@see 'custom_menu_order'} filter 271 * for this filter to work. Use the following to enable custom menu ordering: 272 * 273 * add_filter( 'custom_menu_order', '__return_true' ); 274 * 275 * @since 2.8.0 276 * 277 * @param array $menu_order An ordered array of menu items. 278 */ 279 $menu_order = apply_filters( 'menu_order', $menu_order ); 280 $menu_order = array_flip( $menu_order ); 281 $default_menu_order = array_flip( $default_menu_order ); 282 283 /** 284 * @global array $menu_order 285 * @global array $default_menu_order 286 * 287 * @param array $a 288 * @param array $b 289 * @return int 290 */ 291 function sort_menu( $a, $b ) { 292 global $menu_order, $default_menu_order; 293 $a = $a[2]; 294 $b = $b[2]; 295 if ( isset( $menu_order[ $a ] ) && ! isset( $menu_order[ $b ] ) ) { 296 return -1; 297 } elseif ( ! isset( $menu_order[ $a ] ) && isset( $menu_order[ $b ] ) ) { 298 return 1; 299 } elseif ( isset( $menu_order[ $a ] ) && isset( $menu_order[ $b ] ) ) { 300 if ( $menu_order[ $a ] == $menu_order[ $b ] ) { 301 return 0; 302 } 303 return ( $menu_order[ $a ] < $menu_order[ $b ] ) ? -1 : 1; 304 } else { 305 return ( $default_menu_order[ $a ] <= $default_menu_order[ $b ] ) ? -1 : 1; 306 } 307 } 308 309 usort( $menu, 'sort_menu' ); 310 unset( $menu_order, $default_menu_order ); 311 } 312 313 // Prevent adjacent separators. 314 $prev_menu_was_separator = false; 315 foreach ( $menu as $id => $data ) { 316 if ( false === stristr( $data[4], 'wp-menu-separator' ) ) { 317 318 // This item is not a separator, so falsey the toggler and do nothing. 319 $prev_menu_was_separator = false; 320 } else { 321 322 // The previous item was a separator, so unset this one. 323 if ( true === $prev_menu_was_separator ) { 324 unset( $menu[ $id ] ); 325 } 326 327 // This item is a separator, so truthy the toggler and move on. 328 $prev_menu_was_separator = true; 329 } 330 } 331 unset( $id, $data, $prev_menu_was_separator ); 332 333 // Remove the last menu item if it is a separator. 334 $last_menu_key = array_keys( $menu ); 335 $last_menu_key = array_pop( $last_menu_key ); 336 if ( ! empty( $menu ) && 'wp-menu-separator' === $menu[ $last_menu_key ][4] ) { 337 unset( $menu[ $last_menu_key ] ); 338 } 339 unset( $last_menu_key ); 340 341 if ( ! user_can_access_admin_page() ) { 342 343 /** 344 * Fires when access to an admin page is denied. 345 * 346 * @since 2.5.0 347 */ 348 do_action( 'admin_page_access_denied' ); 349 350 wp_die( __( 'Sorry, you are not allowed to access this page.' ), 403 ); 351 } 352 353 $menu = add_menu_classes( $menu );
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Mon Mar 8 01:00:04 2021 | Cross-referenced by PHPXref 0.7.1 |