|
1 <?php |
|
2 |
|
3 /** |
|
4 * Build Administration Menu. |
|
5 * |
|
6 * @package WordPress |
|
7 * @subpackage Administration |
|
8 */ |
|
9 |
|
10 if ( is_network_admin() ) |
|
11 do_action('_network_admin_menu'); |
|
12 elseif ( is_user_admin() ) |
|
13 do_action('_user_admin_menu'); |
|
14 else |
|
15 do_action('_admin_menu'); |
|
16 |
|
17 // Create list of page plugin hook names. |
|
18 foreach ($menu as $menu_page) { |
|
19 if ( false !== $pos = strpos($menu_page[2], '?') ) { |
|
20 // Handle post_type=post|page|foo pages. |
|
21 $hook_name = substr($menu_page[2], 0, $pos); |
|
22 $hook_args = substr($menu_page[2], $pos + 1); |
|
23 wp_parse_str($hook_args, $hook_args); |
|
24 // Set the hook name to be the post type. |
|
25 if ( isset($hook_args['post_type']) ) |
|
26 $hook_name = $hook_args['post_type']; |
|
27 else |
|
28 $hook_name = basename($hook_name, '.php'); |
|
29 unset($hook_args); |
|
30 } else { |
|
31 $hook_name = basename($menu_page[2], '.php'); |
|
32 } |
|
33 $hook_name = sanitize_title($hook_name); |
|
34 |
|
35 if ( isset($compat[$hook_name]) ) |
|
36 $hook_name = $compat[$hook_name]; |
|
37 elseif ( !$hook_name ) |
|
38 continue; |
|
39 |
|
40 $admin_page_hooks[$menu_page[2]] = $hook_name; |
|
41 } |
|
42 unset($menu_page, $compat); |
|
43 |
|
44 $_wp_submenu_nopriv = array(); |
|
45 $_wp_menu_nopriv = array(); |
|
46 // Loop over submenus and remove pages for which the user does not have privs. |
|
47 foreach ( array( 'submenu' ) as $sub_loop ) { |
|
48 foreach ($$sub_loop as $parent => $sub) { |
|
49 foreach ($sub as $index => $data) { |
|
50 if ( ! current_user_can($data[1]) ) { |
|
51 unset(${$sub_loop}[$parent][$index]); |
|
52 $_wp_submenu_nopriv[$parent][$data[2]] = true; |
|
53 } |
|
54 } |
|
55 unset($index, $data); |
|
56 |
|
57 if ( empty(${$sub_loop}[$parent]) ) |
|
58 unset(${$sub_loop}[$parent]); |
|
59 } |
|
60 unset($sub, $parent); |
|
61 } |
|
62 unset($sub_loop); |
|
63 |
|
64 // Loop over the top-level menu. |
|
65 // Menus for which the original parent is not accessible due to lack of privs will have the next |
|
66 // submenu in line be assigned as the new menu parent. |
|
67 foreach ( $menu as $id => $data ) { |
|
68 if ( empty($submenu[$data[2]]) ) |
|
69 continue; |
|
70 $subs = $submenu[$data[2]]; |
|
71 $first_sub = array_shift($subs); |
|
72 $old_parent = $data[2]; |
|
73 $new_parent = $first_sub[2]; |
|
74 // If the first submenu is not the same as the assigned parent, |
|
75 // make the first submenu the new parent. |
|
76 if ( $new_parent != $old_parent ) { |
|
77 $_wp_real_parent_file[$old_parent] = $new_parent; |
|
78 $menu[$id][2] = $new_parent; |
|
79 |
|
80 foreach ($submenu[$old_parent] as $index => $data) { |
|
81 $submenu[$new_parent][$index] = $submenu[$old_parent][$index]; |
|
82 unset($submenu[$old_parent][$index]); |
|
83 } |
|
84 unset($submenu[$old_parent], $index); |
|
85 |
|
86 if ( isset($_wp_submenu_nopriv[$old_parent]) ) |
|
87 $_wp_submenu_nopriv[$new_parent] = $_wp_submenu_nopriv[$old_parent]; |
|
88 } |
|
89 } |
|
90 unset($id, $data, $subs, $first_sub, $old_parent, $new_parent); |
|
91 |
|
92 if ( is_network_admin() ) |
|
93 do_action('network_admin_menu', ''); |
|
94 elseif ( is_user_admin() ) |
|
95 do_action('user_admin_menu', ''); |
|
96 else |
|
97 do_action('admin_menu', ''); |
|
98 |
|
99 // Remove menus that have no accessible submenus and require privs that the user does not have. |
|
100 // Run re-parent loop again. |
|
101 foreach ( $menu as $id => $data ) { |
|
102 if ( ! current_user_can($data[1]) ) |
|
103 $_wp_menu_nopriv[$data[2]] = true; |
|
104 |
|
105 // If there is only one submenu and it is has same destination as the parent, |
|
106 // remove the submenu. |
|
107 if ( ! empty( $submenu[$data[2]] ) && 1 == count ( $submenu[$data[2]] ) ) { |
|
108 $subs = $submenu[$data[2]]; |
|
109 $first_sub = array_shift($subs); |
|
110 if ( $data[2] == $first_sub[2] ) |
|
111 unset( $submenu[$data[2]] ); |
|
112 } |
|
113 |
|
114 // If submenu is empty... |
|
115 if ( empty($submenu[$data[2]]) ) { |
|
116 // And user doesn't have privs, remove menu. |
|
117 if ( isset( $_wp_menu_nopriv[$data[2]] ) ) { |
|
118 unset($menu[$id]); |
|
119 } |
|
120 } |
|
121 } |
|
122 unset($id, $data, $subs, $first_sub); |
|
123 |
|
124 // Remove any duplicated separators |
|
125 $separator_found = false; |
|
126 foreach ( $menu as $id => $data ) { |
|
127 if ( 0 == strcmp('wp-menu-separator', $data[4] ) ) { |
|
128 if (false == $separator_found) { |
|
129 $separator_found = true; |
|
130 } else { |
|
131 unset($menu[$id]); |
|
132 $separator_found = false; |
|
133 } |
|
134 } else { |
|
135 $separator_found = false; |
|
136 } |
|
137 } |
|
138 unset($id, $data); |
|
139 |
|
140 function add_cssclass($add, $class) { |
|
141 $class = empty($class) ? $add : $class .= ' ' . $add; |
|
142 return $class; |
|
143 } |
|
144 |
|
145 function add_menu_classes($menu) { |
|
146 |
|
147 $first = $lastorder = false; |
|
148 $i = 0; |
|
149 $mc = count($menu); |
|
150 foreach ( $menu as $order => $top ) { |
|
151 $i++; |
|
152 |
|
153 if ( 0 == $order ) { // dashboard is always shown/single |
|
154 $menu[0][4] = add_cssclass('menu-top-first', $top[4]); |
|
155 $lastorder = 0; |
|
156 continue; |
|
157 } |
|
158 |
|
159 if ( 0 === strpos($top[2], 'separator') ) { // if separator |
|
160 $first = true; |
|
161 $c = $menu[$lastorder][4]; |
|
162 $menu[$lastorder][4] = add_cssclass('menu-top-last', $c); |
|
163 continue; |
|
164 } |
|
165 |
|
166 if ( $first ) { |
|
167 $c = $menu[$order][4]; |
|
168 $menu[$order][4] = add_cssclass('menu-top-first', $c); |
|
169 $first = false; |
|
170 } |
|
171 |
|
172 if ( $mc == $i ) { // last item |
|
173 $c = $menu[$order][4]; |
|
174 $menu[$order][4] = add_cssclass('menu-top-last', $c); |
|
175 } |
|
176 |
|
177 $lastorder = $order; |
|
178 } |
|
179 |
|
180 return apply_filters( 'add_menu_classes', $menu ); |
|
181 } |
|
182 |
|
183 uksort($menu, "strnatcasecmp"); // make it all pretty |
|
184 |
|
185 if ( apply_filters('custom_menu_order', false) ) { |
|
186 $menu_order = array(); |
|
187 foreach ( $menu as $menu_item ) { |
|
188 $menu_order[] = $menu_item[2]; |
|
189 } |
|
190 unset($menu_item); |
|
191 $default_menu_order = $menu_order; |
|
192 $menu_order = apply_filters('menu_order', $menu_order); |
|
193 $menu_order = array_flip($menu_order); |
|
194 $default_menu_order = array_flip($default_menu_order); |
|
195 |
|
196 function sort_menu($a, $b) { |
|
197 global $menu_order, $default_menu_order; |
|
198 $a = $a[2]; |
|
199 $b = $b[2]; |
|
200 if ( isset($menu_order[$a]) && !isset($menu_order[$b]) ) { |
|
201 return -1; |
|
202 } elseif ( !isset($menu_order[$a]) && isset($menu_order[$b]) ) { |
|
203 return 1; |
|
204 } elseif ( isset($menu_order[$a]) && isset($menu_order[$b]) ) { |
|
205 if ( $menu_order[$a] == $menu_order[$b] ) |
|
206 return 0; |
|
207 return ($menu_order[$a] < $menu_order[$b]) ? -1 : 1; |
|
208 } else { |
|
209 return ($default_menu_order[$a] <= $default_menu_order[$b]) ? -1 : 1; |
|
210 } |
|
211 } |
|
212 |
|
213 usort($menu, 'sort_menu'); |
|
214 unset($menu_order, $default_menu_order); |
|
215 } |
|
216 |
|
217 // Remove the last menu item if it is a separator. |
|
218 $last_menu_key = array_keys( $menu ); |
|
219 $last_menu_key = array_pop( $last_menu_key ); |
|
220 if ( !empty( $menu ) && 'wp-menu-separator' == $menu[ $last_menu_key ][ 4 ] ) |
|
221 unset( $menu[ $last_menu_key ] ); |
|
222 unset( $last_menu_key ); |
|
223 |
|
224 if ( !user_can_access_admin_page() ) { |
|
225 do_action('admin_page_access_denied'); |
|
226 wp_die( __('You do not have sufficient permissions to access this page.') ); |
|
227 } |
|
228 |
|
229 $menu = add_menu_classes($menu); |