17 $self = preg_replace('|^.*/wp-admin/|i', '', $self); |
17 $self = preg_replace('|^.*/wp-admin/|i', '', $self); |
18 $self = preg_replace('|^.*/plugins/|i', '', $self); |
18 $self = preg_replace('|^.*/plugins/|i', '', $self); |
19 $self = preg_replace('|^.*/mu-plugins/|i', '', $self); |
19 $self = preg_replace('|^.*/mu-plugins/|i', '', $self); |
20 |
20 |
21 global $menu, $submenu, $parent_file; //For when admin-header is included from within a function. |
21 global $menu, $submenu, $parent_file; //For when admin-header is included from within a function. |
22 $parent_file = apply_filters("parent_file", $parent_file); // For plugins to move submenu tabs around. |
22 |
|
23 /** |
|
24 * Filter the parent file of an admin menu sub-menu item. |
|
25 * |
|
26 * Allows plugins to move sub-menu items around. |
|
27 * |
|
28 * @since MU |
|
29 * |
|
30 * @param string $parent_file The parent file. |
|
31 */ |
|
32 $parent_file = apply_filters( 'parent_file', $parent_file ); |
23 |
33 |
24 get_admin_page_parent(); |
34 get_admin_page_parent(); |
25 |
35 |
26 /** |
36 /** |
27 * Display menu. |
37 * Display menu. |
35 */ |
45 */ |
36 function _wp_menu_output( $menu, $submenu, $submenu_as_parent = true ) { |
46 function _wp_menu_output( $menu, $submenu, $submenu_as_parent = true ) { |
37 global $self, $parent_file, $submenu_file, $plugin_page, $typenow; |
47 global $self, $parent_file, $submenu_file, $plugin_page, $typenow; |
38 |
48 |
39 $first = true; |
49 $first = true; |
40 // 0 = name, 1 = capability, 2 = file, 3 = class, 4 = id, 5 = icon src |
50 // 0 = menu_title, 1 = capability, 2 = menu_slug, 3 = page_title, 4 = classes, 5 = hookname, 6 = icon_url |
41 foreach ( $menu as $key => $item ) { |
51 foreach ( $menu as $key => $item ) { |
42 $admin_is_parent = false; |
52 $admin_is_parent = false; |
43 $class = array(); |
53 $class = array(); |
44 $aria_attributes = ''; |
54 $aria_attributes = ''; |
|
55 $aria_hidden = ''; |
|
56 $is_separator = false; |
45 |
57 |
46 if ( $first ) { |
58 if ( $first ) { |
47 $class[] = 'wp-first-item'; |
59 $class[] = 'wp-first-item'; |
48 $first = false; |
60 $first = false; |
49 } |
61 } |
50 |
62 |
51 $submenu_items = false; |
63 $submenu_items = array(); |
52 if ( ! empty( $submenu[$item[2]] ) ) { |
64 if ( ! empty( $submenu[$item[2]] ) ) { |
53 $class[] = 'wp-has-submenu'; |
65 $class[] = 'wp-has-submenu'; |
54 $submenu_items = $submenu[$item[2]]; |
66 $submenu_items = $submenu[$item[2]]; |
55 } |
67 } |
56 |
68 |
61 if ( ! empty( $submenu_items ) ) |
73 if ( ! empty( $submenu_items ) ) |
62 $aria_attributes .= 'aria-haspopup="true"'; |
74 $aria_attributes .= 'aria-haspopup="true"'; |
63 } |
75 } |
64 |
76 |
65 if ( ! empty( $item[4] ) ) |
77 if ( ! empty( $item[4] ) ) |
66 $class[] = $item[4]; |
78 $class[] = esc_attr( $item[4] ); |
67 |
79 |
68 $class = $class ? ' class="' . join( ' ', $class ) . '"' : ''; |
80 $class = $class ? ' class="' . join( ' ', $class ) . '"' : ''; |
69 $id = ! empty( $item[5] ) ? ' id="' . preg_replace( '|[^a-zA-Z0-9_:.]|', '-', $item[5] ) . '"' : ''; |
81 $id = ! empty( $item[5] ) ? ' id="' . preg_replace( '|[^a-zA-Z0-9_:.]|', '-', $item[5] ) . '"' : ''; |
70 $img = ''; |
82 $img = $img_style = ''; |
71 // if the string 'none' (previously 'div') is passed instead of an URL, don't output the default menu image |
83 $img_class = ' dashicons-before'; |
72 // so an icon can be added to div.wp-menu-image as background with CSS. |
84 |
73 if ( ! empty( $item[6] ) ) |
85 if ( false !== strpos( $class, 'wp-menu-separator' ) ) { |
74 $img = ( 'none' === $item[6] || 'div' === $item[6] ) ? '<br />' : '<img src="' . $item[6] . '" alt="" />'; |
86 $is_separator = true; |
|
87 } |
|
88 |
|
89 /* |
|
90 * If the string 'none' (previously 'div') is passed instead of an URL, don't output |
|
91 * 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 |
|
93 * as special cases. |
|
94 */ |
|
95 if ( ! empty( $item[6] ) ) { |
|
96 $img = '<img src="' . $item[6] . '" alt="" />'; |
|
97 |
|
98 if ( 'none' === $item[6] || 'div' === $item[6] ) { |
|
99 $img = '<br />'; |
|
100 } elseif ( 0 === strpos( $item[6], 'data:image/svg+xml;base64,' ) ) { |
|
101 $img = '<br />'; |
|
102 $img_style = ' style="background-image:url(\'' . esc_attr( $item[6] ) . '\')"'; |
|
103 $img_class = ' svg'; |
|
104 } elseif ( 0 === strpos( $item[6], 'dashicons-' ) ) { |
|
105 $img = '<br />'; |
|
106 $img_class = ' dashicons-before ' . sanitize_html_class( $item[6] ); |
|
107 } |
|
108 } |
75 $arrow = '<div class="wp-menu-arrow"><div></div></div>'; |
109 $arrow = '<div class="wp-menu-arrow"><div></div></div>'; |
76 |
110 |
77 $title = wptexturize( $item[0] ); |
111 $title = wptexturize( $item[0] ); |
78 |
112 |
79 echo "\n\t<li$class$id>"; |
113 // hide separators from screen readers |
80 |
114 if ( $is_separator ) { |
81 if ( false !== strpos( $class, 'wp-menu-separator' ) ) { |
115 $aria_hidden = ' aria-hidden="true"'; |
|
116 } |
|
117 |
|
118 echo "\n\t<li$class$id$aria_hidden>"; |
|
119 |
|
120 if ( $is_separator ) { |
82 echo '<div class="separator"></div>'; |
121 echo '<div class="separator"></div>'; |
83 } elseif ( $submenu_as_parent && ! empty( $submenu_items ) ) { |
122 } elseif ( $submenu_as_parent && ! empty( $submenu_items ) ) { |
84 $submenu_items = array_values( $submenu_items ); // Re-index. |
123 $submenu_items = array_values( $submenu_items ); // Re-index. |
85 $menu_hook = get_plugin_page_hook( $submenu_items[0][2], $item[2] ); |
124 $menu_hook = get_plugin_page_hook( $submenu_items[0][2], $item[2] ); |
86 $menu_file = $submenu_items[0][2]; |
125 $menu_file = $submenu_items[0][2]; |
87 if ( false !== ( $pos = strpos( $menu_file, '?' ) ) ) |
126 if ( false !== ( $pos = strpos( $menu_file, '?' ) ) ) |
88 $menu_file = substr( $menu_file, 0, $pos ); |
127 $menu_file = substr( $menu_file, 0, $pos ); |
89 if ( ! empty( $menu_hook ) || ( ( 'index.php' != $submenu_items[0][2] ) && file_exists( WP_PLUGIN_DIR . "/$menu_file" ) && ! file_exists( ABSPATH . "/wp-admin/$menu_file" ) ) ) { |
128 if ( ! empty( $menu_hook ) || ( ( 'index.php' != $submenu_items[0][2] ) && file_exists( WP_PLUGIN_DIR . "/$menu_file" ) && ! file_exists( ABSPATH . "/wp-admin/$menu_file" ) ) ) { |
90 $admin_is_parent = true; |
129 $admin_is_parent = true; |
91 echo "<a href='admin.php?page={$submenu_items[0][2]}'$class $aria_attributes>$arrow<div class='wp-menu-image'>$img</div><div class='wp-menu-name'>$title</div></a>"; |
130 echo "<a href='admin.php?page={$submenu_items[0][2]}'$class $aria_attributes>$arrow<div class='wp-menu-image$img_class'$img_style>$img</div><div class='wp-menu-name'>$title</div></a>"; |
92 } else { |
131 } else { |
93 echo "\n\t<a href='{$submenu_items[0][2]}'$class $aria_attributes>$arrow<div class='wp-menu-image'>$img</div><div class='wp-menu-name'>$title</div></a>"; |
132 echo "\n\t<a href='{$submenu_items[0][2]}'$class $aria_attributes>$arrow<div class='wp-menu-image$img_class'$img_style>$img</div><div class='wp-menu-name'>$title</div></a>"; |
94 } |
133 } |
95 } elseif ( ! empty( $item[2] ) && current_user_can( $item[1] ) ) { |
134 } elseif ( ! empty( $item[2] ) && current_user_can( $item[1] ) ) { |
96 $menu_hook = get_plugin_page_hook( $item[2], 'admin.php' ); |
135 $menu_hook = get_plugin_page_hook( $item[2], 'admin.php' ); |
97 $menu_file = $item[2]; |
136 $menu_file = $item[2]; |
98 if ( false !== ( $pos = strpos( $menu_file, '?' ) ) ) |
137 if ( false !== ( $pos = strpos( $menu_file, '?' ) ) ) |
99 $menu_file = substr( $menu_file, 0, $pos ); |
138 $menu_file = substr( $menu_file, 0, $pos ); |
100 if ( ! empty( $menu_hook ) || ( ( 'index.php' != $item[2] ) && file_exists( WP_PLUGIN_DIR . "/$menu_file" ) && ! file_exists( ABSPATH . "/wp-admin/$menu_file" ) ) ) { |
139 if ( ! empty( $menu_hook ) || ( ( 'index.php' != $item[2] ) && file_exists( WP_PLUGIN_DIR . "/$menu_file" ) && ! file_exists( ABSPATH . "/wp-admin/$menu_file" ) ) ) { |
101 $admin_is_parent = true; |
140 $admin_is_parent = true; |
102 echo "\n\t<a href='admin.php?page={$item[2]}'$class $aria_attributes>$arrow<div class='wp-menu-image'>$img</div><div class='wp-menu-name'>{$item[0]}</div></a>"; |
141 echo "\n\t<a href='admin.php?page={$item[2]}'$class $aria_attributes>$arrow<div class='wp-menu-image$img_class'$img_style>$img</div><div class='wp-menu-name'>{$item[0]}</div></a>"; |
103 } else { |
142 } else { |
104 echo "\n\t<a href='{$item[2]}'$class $aria_attributes>$arrow<div class='wp-menu-image'>$img</div><div class='wp-menu-name'>{$item[0]}</div></a>"; |
143 echo "\n\t<a href='{$item[2]}'$class $aria_attributes>$arrow<div class='wp-menu-image$img_class'$img_style>$img</div><div class='wp-menu-name'>{$item[0]}</div></a>"; |
105 } |
144 } |
106 } |
145 } |
107 |
146 |
108 if ( ! empty( $submenu_items ) ) { |
147 if ( ! empty( $submenu_items ) ) { |
109 echo "\n\t<ul class='wp-submenu wp-submenu-wrap'>"; |
148 echo "\n\t<ul class='wp-submenu wp-submenu-wrap'>"; |
110 echo "<li class='wp-submenu-head'>{$item[0]}</li>"; |
149 echo "<li class='wp-submenu-head'>{$item[0]}</li>"; |
111 |
150 |
112 $first = true; |
151 $first = true; |
|
152 |
|
153 // 0 = menu_title, 1 = capability, 2 = menu_slug, 3 = page_title, 4 = classes |
113 foreach ( $submenu_items as $sub_key => $sub_item ) { |
154 foreach ( $submenu_items as $sub_key => $sub_item ) { |
114 if ( ! current_user_can( $sub_item[1] ) ) |
155 if ( ! current_user_can( $sub_item[1] ) ) |
115 continue; |
156 continue; |
116 |
157 |
117 $class = array(); |
158 $class = array(); |
131 if ( isset( $submenu_file ) ) { |
172 if ( isset( $submenu_file ) ) { |
132 if ( $submenu_file == $sub_item[2] ) |
173 if ( $submenu_file == $sub_item[2] ) |
133 $class[] = 'current'; |
174 $class[] = 'current'; |
134 // If plugin_page is set the parent must either match the current page or not physically exist. |
175 // If plugin_page is set the parent must either match the current page or not physically exist. |
135 // This allows plugin pages with the same hook to exist under different parents. |
176 // This allows plugin pages with the same hook to exist under different parents. |
136 } else if ( |
177 } elseif ( |
137 ( ! isset( $plugin_page ) && $self == $sub_item[2] ) || |
178 ( ! isset( $plugin_page ) && $self == $sub_item[2] ) || |
138 ( isset( $plugin_page ) && $plugin_page == $sub_item[2] && ( $item[2] == $self_type || $item[2] == $self || file_exists($menu_file) === false ) ) |
179 ( isset( $plugin_page ) && $plugin_page == $sub_item[2] && ( $item[2] == $self_type || $item[2] == $self || file_exists($menu_file) === false ) ) |
139 ) { |
180 ) { |
140 $class[] = 'current'; |
181 $class[] = 'current'; |
|
182 } |
|
183 |
|
184 if ( ! empty( $sub_item[4] ) ) { |
|
185 $class[] = esc_attr( $sub_item[4] ); |
141 } |
186 } |
142 |
187 |
143 $class = $class ? ' class="' . join( ' ', $class ) . '"' : ''; |
188 $class = $class ? ' class="' . join( ' ', $class ) . '"' : ''; |
144 |
189 |
145 $menu_hook = get_plugin_page_hook($sub_item[2], $item[2]); |
190 $menu_hook = get_plugin_page_hook($sub_item[2], $item[2]); |