~canonical-sysadmins/wordpress/4.7.4

« back to all changes in this revision

Viewing changes to wp-admin/includes/menu.php

  • Committer: Jacek Nykis
  • Date: 2015-01-05 16:17:05 UTC
  • Revision ID: jacek.nykis@canonical.com-20150105161705-w544l1h5mcg7u4w9
Initial commit

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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
        if ( false !== $pos = strpos($menu_page[2], '?') ) {
 
47
                // Handle post_type=post|page|foo pages.
 
48
                $hook_name = substr($menu_page[2], 0, $pos);
 
49
                $hook_args = substr($menu_page[2], $pos + 1);
 
50
                wp_parse_str($hook_args, $hook_args);
 
51
                // Set the hook name to be the post type.
 
52
                if ( isset($hook_args['post_type']) )
 
53
                        $hook_name = $hook_args['post_type'];
 
54
                else
 
55
                        $hook_name = basename($hook_name, '.php');
 
56
                unset($hook_args);
 
57
        } else {
 
58
                $hook_name = basename($menu_page[2], '.php');
 
59
        }
 
60
        $hook_name = sanitize_title($hook_name);
 
61
 
 
62
        if ( isset($compat[$hook_name]) )
 
63
                $hook_name = $compat[$hook_name];
 
64
        elseif ( !$hook_name )
 
65
                continue;
 
66
 
 
67
        $admin_page_hooks[$menu_page[2]] = $hook_name;
 
68
}
 
69
unset($menu_page, $compat);
 
70
 
 
71
$_wp_submenu_nopriv = array();
 
72
$_wp_menu_nopriv = array();
 
73
// Loop over submenus and remove pages for which the user does not have privs.
 
74
foreach ($submenu as $parent => $sub) {
 
75
        foreach ($sub as $index => $data) {
 
76
                if ( ! current_user_can($data[1]) ) {
 
77
                        unset($submenu[$parent][$index]);
 
78
                        $_wp_submenu_nopriv[$parent][$data[2]] = true;
 
79
                }
 
80
        }
 
81
        unset($index, $data);
 
82
 
 
83
        if ( empty($submenu[$parent]) )
 
84
                unset($submenu[$parent]);
 
85
}
 
86
unset($sub, $parent);
 
87
 
 
88
/*
 
89
 * Loop over the top-level menu.
 
90
 * Menus for which the original parent is not accessible due to lack of privileges
 
91
 * will have the next submenu in line be assigned as the new menu parent.
 
92
 */
 
93
foreach ( $menu as $id => $data ) {
 
94
        if ( empty($submenu[$data[2]]) )
 
95
                continue;
 
96
        $subs = $submenu[$data[2]];
 
97
        $first_sub = array_shift($subs);
 
98
        $old_parent = $data[2];
 
99
        $new_parent = $first_sub[2];
 
100
        /*
 
101
         * If the first submenu is not the same as the assigned parent,
 
102
         * make the first submenu the new parent.
 
103
         */
 
104
        if ( $new_parent != $old_parent ) {
 
105
                $_wp_real_parent_file[$old_parent] = $new_parent;
 
106
                $menu[$id][2] = $new_parent;
 
107
 
 
108
                foreach ($submenu[$old_parent] as $index => $data) {
 
109
                        $submenu[$new_parent][$index] = $submenu[$old_parent][$index];
 
110
                        unset($submenu[$old_parent][$index]);
 
111
                }
 
112
                unset($submenu[$old_parent], $index);
 
113
 
 
114
                if ( isset($_wp_submenu_nopriv[$old_parent]) )
 
115
                        $_wp_submenu_nopriv[$new_parent] = $_wp_submenu_nopriv[$old_parent];
 
116
        }
 
117
}
 
118
unset($id, $data, $subs, $first_sub, $old_parent, $new_parent);
 
119
 
 
120
if ( is_network_admin() ) {
 
121
 
 
122
        /**
 
123
         * Fires before the administration menu loads in the Network Admin.
 
124
         *
 
125
         * @since 3.1.0
 
126
         *
 
127
         * @param string $context Empty context.
 
128
         */
 
129
        do_action( 'network_admin_menu', '' );
 
130
} elseif ( is_user_admin() ) {
 
131
 
 
132
        /**
 
133
         * Fires before the administration menu loads in the User Admin.
 
134
         *
 
135
         * @since 3.1.0
 
136
         *
 
137
         * @param string $context Empty context.
 
138
         */
 
139
        do_action( 'user_admin_menu', '' );
 
140
} else {
 
141
 
 
142
        /**
 
143
         * Fires before the administration menu loads in the admin.
 
144
         *
 
145
         * @since 1.5.0
 
146
         *
 
147
         * @param string $context Empty context.
 
148
         */
 
149
        do_action( 'admin_menu', '' );
 
150
}
 
151
 
 
152
/*
 
153
 * Remove menus that have no accessible submenus and require privileges
 
154
 * that the user does not have. Run re-parent loop again.
 
155
 */
 
156
foreach ( $menu as $id => $data ) {
 
157
        if ( ! current_user_can($data[1]) )
 
158
                $_wp_menu_nopriv[$data[2]] = true;
 
159
 
 
160
        /*
 
161
         * If there is only one submenu and it is has same destination as the parent,
 
162
         * remove the submenu.
 
163
         */
 
164
        if ( ! empty( $submenu[$data[2]] ) && 1 == count ( $submenu[$data[2]] ) ) {
 
165
                $subs = $submenu[$data[2]];
 
166
                $first_sub = array_shift($subs);
 
167
                if ( $data[2] == $first_sub[2] )
 
168
                        unset( $submenu[$data[2]] );
 
169
        }
 
170
 
 
171
        // If submenu is empty...
 
172
        if ( empty($submenu[$data[2]]) ) {
 
173
                // And user doesn't have privs, remove menu.
 
174
                if ( isset( $_wp_menu_nopriv[$data[2]] ) ) {
 
175
                        unset($menu[$id]);
 
176
                }
 
177
        }
 
178
}
 
179
unset($id, $data, $subs, $first_sub);
 
180
 
 
181
// Remove any duplicated separators
 
182
$separator_found = false;
 
183
foreach ( $menu as $id => $data ) {
 
184
        if ( 0 == strcmp('wp-menu-separator', $data[4] ) ) {
 
185
                if (false == $separator_found) {
 
186
                        $separator_found = true;
 
187
                } else {
 
188
                        unset($menu[$id]);
 
189
                        $separator_found = false;
 
190
                }
 
191
        } else {
 
192
                $separator_found = false;
 
193
        }
 
194
}
 
195
unset($id, $data);
 
196
 
 
197
function add_cssclass($add, $class) {
 
198
        $class = empty($class) ? $add : $class .= ' ' . $add;
 
199
        return $class;
 
200
}
 
201
 
 
202
function add_menu_classes($menu) {
 
203
 
 
204
        $first = $lastorder = false;
 
205
        $i = 0;
 
206
        $mc = count($menu);
 
207
        foreach ( $menu as $order => $top ) {
 
208
                $i++;
 
209
 
 
210
                if ( 0 == $order ) { // dashboard is always shown/single
 
211
                        $menu[0][4] = add_cssclass('menu-top-first', $top[4]);
 
212
                        $lastorder = 0;
 
213
                        continue;
 
214
                }
 
215
 
 
216
                if ( 0 === strpos($top[2], 'separator') && false !== $lastorder ) { // if separator
 
217
                        $first = true;
 
218
                        $c = $menu[$lastorder][4];
 
219
                        $menu[$lastorder][4] = add_cssclass('menu-top-last', $c);
 
220
                        continue;
 
221
                }
 
222
 
 
223
                if ( $first ) {
 
224
                        $c = $menu[$order][4];
 
225
                        $menu[$order][4] = add_cssclass('menu-top-first', $c);
 
226
                        $first = false;
 
227
                }
 
228
 
 
229
                if ( $mc == $i ) { // last item
 
230
                        $c = $menu[$order][4];
 
231
                        $menu[$order][4] = add_cssclass('menu-top-last', $c);
 
232
                }
 
233
 
 
234
                $lastorder = $order;
 
235
        }
 
236
 
 
237
        /**
 
238
         * Filter administration menus array with classes added for top-level items.
 
239
         *
 
240
         * @since 2.7.0
 
241
         *
 
242
         * @param array $menu Associative array of administration menu items.
 
243
         */
 
244
        return apply_filters( 'add_menu_classes', $menu );
 
245
}
 
246
 
 
247
uksort($menu, "strnatcasecmp"); // make it all pretty
 
248
 
 
249
/**
 
250
 * Filter whether to enable custom ordering of the administration menu.
 
251
 *
 
252
 * See the 'menu_order' filter for reordering menu items.
 
253
 *
 
254
 * @since 2.8.0
 
255
 *
 
256
 * @param bool $custom Whether custom ordering is enabled. Default false.
 
257
 */
 
258
if ( apply_filters( 'custom_menu_order', false ) ) {
 
259
        $menu_order = array();
 
260
        foreach ( $menu as $menu_item ) {
 
261
                $menu_order[] = $menu_item[2];
 
262
        }
 
263
        unset($menu_item);
 
264
        $default_menu_order = $menu_order;
 
265
 
 
266
        /**
 
267
         * Filter the order of administration menu items.
 
268
         *
 
269
         * A truthy value must first be passed to the 'custom_menu_order' filter
 
270
         * for this filter to work. Use the following to enable custom menu ordering:
 
271
         *
 
272
         *     add_filter( 'custom_menu_order', '__return_true' );
 
273
         *
 
274
         * @since 2.8.0
 
275
         *
 
276
         * @param array $menu_order An ordered array of menu items.
 
277
         */
 
278
        $menu_order = apply_filters( 'menu_order', $menu_order );
 
279
        $menu_order = array_flip($menu_order);
 
280
        $default_menu_order = array_flip($default_menu_order);
 
281
 
 
282
        function sort_menu($a, $b) {
 
283
                global $menu_order, $default_menu_order;
 
284
                $a = $a[2];
 
285
                $b = $b[2];
 
286
                if ( isset($menu_order[$a]) && !isset($menu_order[$b]) ) {
 
287
                        return -1;
 
288
                } elseif ( !isset($menu_order[$a]) && isset($menu_order[$b]) ) {
 
289
                        return 1;
 
290
                } elseif ( isset($menu_order[$a]) && isset($menu_order[$b]) ) {
 
291
                        if ( $menu_order[$a] == $menu_order[$b] )
 
292
                                return 0;
 
293
                        return ($menu_order[$a] < $menu_order[$b]) ? -1 : 1;
 
294
                } else {
 
295
                        return ($default_menu_order[$a] <= $default_menu_order[$b]) ? -1 : 1;
 
296
                }
 
297
        }
 
298
 
 
299
        usort($menu, 'sort_menu');
 
300
        unset($menu_order, $default_menu_order);
 
301
}
 
302
 
 
303
// Remove the last menu item if it is a separator.
 
304
$last_menu_key = array_keys( $menu );
 
305
$last_menu_key = array_pop( $last_menu_key );
 
306
if ( !empty( $menu ) && 'wp-menu-separator' == $menu[ $last_menu_key ][ 4 ] )
 
307
        unset( $menu[ $last_menu_key ] );
 
308
unset( $last_menu_key );
 
309
 
 
310
if ( !user_can_access_admin_page() ) {
 
311
 
 
312
        /**
 
313
         * Fires when access to an admin page is denied.
 
314
         *
 
315
         * @since 2.5.0
 
316
         */
 
317
        do_action( 'admin_page_access_denied' );
 
318
 
 
319
        wp_die( __('You do not have sufficient permissions to access this page.') );
 
320
}
 
321
 
 
322
$menu = add_menu_classes($menu);