8 |
8 |
9 /** |
9 /** |
10 * The current page. |
10 * The current page. |
11 * |
11 * |
12 * @global string $self |
12 * @global string $self |
13 * @name $self |
|
14 * @var string |
|
15 */ |
13 */ |
16 $self = preg_replace('|^.*/wp-admin/network/|i', '', $_SERVER['PHP_SELF']); |
14 $self = preg_replace('|^.*/wp-admin/network/|i', '', $_SERVER['PHP_SELF']); |
17 $self = preg_replace('|^.*/wp-admin/|i', '', $self); |
15 $self = preg_replace('|^.*/wp-admin/|i', '', $self); |
18 $self = preg_replace('|^.*/plugins/|i', '', $self); |
16 $self = preg_replace('|^.*/plugins/|i', '', $self); |
19 $self = preg_replace('|^.*/mu-plugins/|i', '', $self); |
17 $self = preg_replace('|^.*/mu-plugins/|i', '', $self); |
20 |
18 |
21 global $menu, $submenu, $parent_file; //For when admin-header is included from within a function. |
19 /** |
22 |
20 * For when admin-header is included from within a function. |
23 /** |
21 * |
24 * Filter the parent file of an admin menu sub-menu item. |
22 * @global array $menu |
|
23 * @global array $submenu |
|
24 * @global string $parent_file |
|
25 * @global string $submenu_file |
|
26 */ |
|
27 global $menu, $submenu, $parent_file, $submenu_file; |
|
28 |
|
29 /** |
|
30 * Filters the parent file of an admin menu sub-menu item. |
25 * |
31 * |
26 * Allows plugins to move sub-menu items around. |
32 * Allows plugins to move sub-menu items around. |
27 * |
33 * |
28 * @since MU |
34 * @since MU (3.0.0) |
29 * |
35 * |
30 * @param string $parent_file The parent file. |
36 * @param string $parent_file The parent file. |
31 */ |
37 */ |
32 $parent_file = apply_filters( 'parent_file', $parent_file ); |
38 $parent_file = apply_filters( 'parent_file', $parent_file ); |
|
39 |
|
40 /** |
|
41 * Filters the file of an admin menu sub-menu item. |
|
42 * |
|
43 * @since 4.4.0 |
|
44 * |
|
45 * @param string $submenu_file The submenu file. |
|
46 * @param string $parent_file The submenu item's parent file. |
|
47 */ |
|
48 $submenu_file = apply_filters( 'submenu_file', $submenu_file, $parent_file ); |
33 |
49 |
34 get_admin_page_parent(); |
50 get_admin_page_parent(); |
35 |
51 |
36 /** |
52 /** |
37 * Display menu. |
53 * Display menu. |
38 * |
54 * |
39 * @access private |
55 * @access private |
40 * @since 2.7.0 |
56 * @since 2.7.0 |
41 * |
57 * |
|
58 * @global string $self |
|
59 * @global string $parent_file |
|
60 * @global string $submenu_file |
|
61 * @global string $plugin_page |
|
62 * @global string $typenow |
|
63 * |
42 * @param array $menu |
64 * @param array $menu |
43 * @param array $submenu |
65 * @param array $submenu |
44 * @param bool $submenu_as_parent |
66 * @param bool $submenu_as_parent |
45 */ |
67 */ |
46 function _wp_menu_output( $menu, $submenu, $submenu_as_parent = true ) { |
68 function _wp_menu_output( $menu, $submenu, $submenu_as_parent = true ) { |
47 global $self, $parent_file, $submenu_file, $plugin_page, $typenow; |
69 global $self, $parent_file, $submenu_file, $plugin_page, $typenow; |
48 |
70 |
49 $first = true; |
71 $first = true; |
65 $class[] = 'wp-has-submenu'; |
87 $class[] = 'wp-has-submenu'; |
66 $submenu_items = $submenu[$item[2]]; |
88 $submenu_items = $submenu[$item[2]]; |
67 } |
89 } |
68 |
90 |
69 if ( ( $parent_file && $item[2] == $parent_file ) || ( empty($typenow) && $self == $item[2] ) ) { |
91 if ( ( $parent_file && $item[2] == $parent_file ) || ( empty($typenow) && $self == $item[2] ) ) { |
70 $class[] = ! empty( $submenu_items ) ? 'wp-has-current-submenu wp-menu-open' : 'current'; |
92 if ( ! empty( $submenu_items ) ) { |
|
93 $class[] = 'wp-has-current-submenu wp-menu-open'; |
|
94 } else { |
|
95 $class[] = 'current'; |
|
96 $aria_attributes .= 'aria-current="page"'; |
|
97 } |
71 } else { |
98 } else { |
72 $class[] = 'wp-not-current-submenu'; |
99 $class[] = 'wp-not-current-submenu'; |
73 if ( ! empty( $submenu_items ) ) |
100 if ( ! empty( $submenu_items ) ) |
74 $aria_attributes .= 'aria-haspopup="true"'; |
101 $aria_attributes .= 'aria-haspopup="true"'; |
75 } |
102 } |
85 if ( false !== strpos( $class, 'wp-menu-separator' ) ) { |
112 if ( false !== strpos( $class, 'wp-menu-separator' ) ) { |
86 $is_separator = true; |
113 $is_separator = true; |
87 } |
114 } |
88 |
115 |
89 /* |
116 /* |
90 * If the string 'none' (previously 'div') is passed instead of an URL, don't output |
117 * If the string 'none' (previously 'div') is passed instead of a URL, don't output |
91 * the default menu image so an icon can be added to div.wp-menu-image as background |
118 * the default menu image so an icon can be added to div.wp-menu-image as background |
92 * with CSS. Dashicons and base64-encoded data:image/svg_xml URIs are also handled |
119 * with CSS. Dashicons and base64-encoded data:image/svg_xml URIs are also handled |
93 * as special cases. |
120 * as special cases. |
94 */ |
121 */ |
95 if ( ! empty( $item[6] ) ) { |
122 if ( ! empty( $item[6] ) ) { |
144 } |
171 } |
145 } |
172 } |
146 |
173 |
147 if ( ! empty( $submenu_items ) ) { |
174 if ( ! empty( $submenu_items ) ) { |
148 echo "\n\t<ul class='wp-submenu wp-submenu-wrap'>"; |
175 echo "\n\t<ul class='wp-submenu wp-submenu-wrap'>"; |
149 echo "<li class='wp-submenu-head'>{$item[0]}</li>"; |
176 echo "<li class='wp-submenu-head' aria-hidden='true'>{$item[0]}</li>"; |
150 |
177 |
151 $first = true; |
178 $first = true; |
152 |
179 |
153 // 0 = menu_title, 1 = capability, 2 = menu_slug, 3 = page_title, 4 = classes |
180 // 0 = menu_title, 1 = capability, 2 = menu_slug, 3 = page_title, 4 = classes |
154 foreach ( $submenu_items as $sub_key => $sub_item ) { |
181 foreach ( $submenu_items as $sub_key => $sub_item ) { |
155 if ( ! current_user_can( $sub_item[1] ) ) |
182 if ( ! current_user_can( $sub_item[1] ) ) |
156 continue; |
183 continue; |
157 |
184 |
158 $class = array(); |
185 $class = array(); |
|
186 $aria_attributes = ''; |
159 if ( $first ) { |
187 if ( $first ) { |
160 $class[] = 'wp-first-item'; |
188 $class[] = 'wp-first-item'; |
161 $first = false; |
189 $first = false; |
162 } |
190 } |
163 |
191 |
168 |
196 |
169 // Handle current for post_type=post|page|foo pages, which won't match $self. |
197 // Handle current for post_type=post|page|foo pages, which won't match $self. |
170 $self_type = ! empty( $typenow ) ? $self . '?post_type=' . $typenow : 'nothing'; |
198 $self_type = ! empty( $typenow ) ? $self . '?post_type=' . $typenow : 'nothing'; |
171 |
199 |
172 if ( isset( $submenu_file ) ) { |
200 if ( isset( $submenu_file ) ) { |
173 if ( $submenu_file == $sub_item[2] ) |
201 if ( $submenu_file == $sub_item[2] ) { |
174 $class[] = 'current'; |
202 $class[] = 'current'; |
|
203 $aria_attributes .= ' aria-current="page"'; |
|
204 } |
175 // If plugin_page is set the parent must either match the current page or not physically exist. |
205 // If plugin_page is set the parent must either match the current page or not physically exist. |
176 // This allows plugin pages with the same hook to exist under different parents. |
206 // This allows plugin pages with the same hook to exist under different parents. |
177 } elseif ( |
207 } elseif ( |
178 ( ! isset( $plugin_page ) && $self == $sub_item[2] ) || |
208 ( ! isset( $plugin_page ) && $self == $sub_item[2] ) || |
179 ( isset( $plugin_page ) && $plugin_page == $sub_item[2] && ( $item[2] == $self_type || $item[2] == $self || file_exists($menu_file) === false ) ) |
209 ( isset( $plugin_page ) && $plugin_page == $sub_item[2] && ( $item[2] == $self_type || $item[2] == $self || file_exists($menu_file) === false ) ) |
180 ) { |
210 ) { |
181 $class[] = 'current'; |
211 $class[] = 'current'; |
|
212 $aria_attributes .= ' aria-current="page"'; |
182 } |
213 } |
183 |
214 |
184 if ( ! empty( $sub_item[4] ) ) { |
215 if ( ! empty( $sub_item[4] ) ) { |
185 $class[] = esc_attr( $sub_item[4] ); |
216 $class[] = esc_attr( $sub_item[4] ); |
186 } |
217 } |
200 $sub_item_url = add_query_arg( array( 'page' => $sub_item[2] ), $item[2] ); |
231 $sub_item_url = add_query_arg( array( 'page' => $sub_item[2] ), $item[2] ); |
201 else |
232 else |
202 $sub_item_url = add_query_arg( array( 'page' => $sub_item[2] ), 'admin.php' ); |
233 $sub_item_url = add_query_arg( array( 'page' => $sub_item[2] ), 'admin.php' ); |
203 |
234 |
204 $sub_item_url = esc_url( $sub_item_url ); |
235 $sub_item_url = esc_url( $sub_item_url ); |
205 echo "<li$class><a href='$sub_item_url'$class>$title</a></li>"; |
236 echo "<li$class><a href='$sub_item_url'$class$aria_attributes>$title</a></li>"; |
206 } else { |
237 } else { |
207 echo "<li$class><a href='{$sub_item[2]}'$class>$title</a></li>"; |
238 echo "<li$class><a href='{$sub_item[2]}'$class$aria_attributes>$title</a></li>"; |
208 } |
239 } |
209 } |
240 } |
210 echo "</ul>"; |
241 echo "</ul>"; |
211 } |
242 } |
212 echo "</li>"; |
243 echo "</li>"; |
213 } |
244 } |
214 |
245 |
215 echo '<li id="collapse-menu" class="hide-if-no-js"><div id="collapse-button"><div></div></div>'; |
246 echo '<li id="collapse-menu" class="hide-if-no-js">' . |
216 echo '<span>' . esc_html__( 'Collapse menu' ) . '</span>'; |
247 '<button type="button" id="collapse-button" aria-label="' . esc_attr__( 'Collapse Main menu' ) . '" aria-expanded="true">' . |
217 echo '</li>'; |
248 '<span class="collapse-button-icon" aria-hidden="true"></span>' . |
|
249 '<span class="collapse-button-label">' . __( 'Collapse menu' ) . '</span>' . |
|
250 '</button></li>'; |
218 } |
251 } |
219 |
252 |
220 ?> |
253 ?> |
221 |
254 |
222 <div id="adminmenumain" role="navigation" aria-label="<?php esc_attr_e( 'Main menu' ); ?>"> |
255 <div id="adminmenumain" role="navigation" aria-label="<?php esc_attr_e( 'Main menu' ); ?>"> |