Wordpress 3.6
[autoinstalls/wordpress.git] / wp-admin / includes / menu.php
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') && false !== $lastorder ) { // 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);