| 1187 | * Add a top-level menu link. |
| 1188 | * |
| 1189 | * This function takes a capability which will be used to determine whether |
| 1190 | * or not a page is included in the menu. |
| 1191 | * |
| 1192 | * The function which is hooked in to handle the output of the page must check |
| 1193 | * that the user has the required capability as well. |
| 1194 | * |
| 1195 | * @global array $menu |
| 1196 | * @global array $admin_page_hooks |
| 1197 | * @global array $_parent_pages |
| 1198 | * |
| 1199 | * @param string $menu_title The text to be used for the menu. |
| 1200 | * @param string $capability The capability required for this menu to be displayed to the user. |
| 1201 | * @param string $url The url that the menu item should go to. |
| 1202 | * @param string $icon_url The URL to the icon to be used for this menu. |
| 1203 | * * Pass a base64-encoded SVG using a data URI, which will be colored to match |
| 1204 | * the color scheme. This should begin with 'data:image/svg+xml;base64,'. |
| 1205 | * * Pass the name of a Dashicons helper class to use a font icon, |
| 1206 | * e.g. 'dashicons-chart-pie'. |
| 1207 | * * Pass 'none' to leave div.wp-menu-image empty so an icon can be added via CSS. |
| 1208 | * @param int $position The position in the menu order this one should appear. |
| 1209 | * @return string The resulting page's menu_slug. |
| 1210 | */ |
| 1211 | function add_menu_link( $menu_title, $capability, $url, $icon_url = '', $position = null ) { |
| 1212 | global $menu, $admin_page_hooks, $_parent_pages; |
| 1213 | |
| 1214 | $menu_slug = plugin_basename( $url ); |
| 1215 | |
| 1216 | $admin_page_hooks[ $menu_slug ] = sanitize_title( $menu_title ); |
| 1217 | |
| 1218 | if ( empty( $icon_url ) ) { |
| 1219 | $icon_url = 'dashicons-admin-generic'; |
| 1220 | $icon_class = 'menu-icon-generic '; |
| 1221 | } else { |
| 1222 | $icon_url = set_url_scheme( $icon_url ); |
| 1223 | $icon_class = ''; |
| 1224 | } |
| 1225 | |
| 1226 | $new_menu = array( $menu_title, $capability, $url, null, "menu-top {$icon_class}", null, $icon_url ); |
| 1227 | |
| 1228 | if ( null === $position ) { |
| 1229 | $menu[] = $new_menu; |
| 1230 | } elseif ( isset( $menu[ "$position" ] ) ) { |
| 1231 | $position = $position + substr( base_convert( md5( $url . $menu_title ), 16, 10 ) , -5 ) * 0.00001; |
| 1232 | $menu[ "$position" ] = $new_menu; |
| 1233 | } else { |
| 1234 | $menu[ $position ] = $new_menu; |
| 1235 | } |
| 1236 | |
| 1237 | // No parent as top level |
| 1238 | $_parent_pages[ $menu_slug ] = false; |
| 1239 | |
| 1240 | return $url; |
| 1241 | } |
| 1242 | |
| 1243 | /** |
| 1244 | * Add a submenu link. |
| 1245 | * |
| 1246 | * This function takes a capability which will be used to determine whether |
| 1247 | * or not a page is included in the menu. |
| 1248 | * |
| 1249 | * The function which is hooked in to handle the output of the page must check |
| 1250 | * that the user has the required capability as well. |
| 1251 | * |
| 1252 | * @global array $submenu |
| 1253 | * @global array $menu |
| 1254 | * @global array $_wp_real_parent_file |
| 1255 | * @global bool $_wp_submenu_nopriv |
| 1256 | * @global array $_parent_pages |
| 1257 | * |
| 1258 | * @param string $parent_slug The slug name for the parent menu (or the file name of a standard WordPress admin page). |
| 1259 | * @param string $menu_title The text to be used for the menu. |
| 1260 | * @param string $capability The capability required for this menu to be displayed to the user. |
| 1261 | * @param string $url The url that the menu item should go to. |
| 1262 | * @return false|string The resulting page's menu_slug, or false if the user does not have the capability required. |
| 1263 | */ |
| 1264 | function add_submenu_link( $parent_slug, $menu_title, $capability, $url ) { |
| 1265 | global $submenu, $menu, $_wp_real_parent_file, $_wp_submenu_nopriv, $_parent_pages; |
| 1266 | |
| 1267 | $menu_slug = plugin_basename( $url ); |
| 1268 | $parent_slug = plugin_basename( $parent_slug ); |
| 1269 | |
| 1270 | if ( isset( $_wp_real_parent_file[ $parent_slug ] ) ) { |
| 1271 | $parent_slug = $_wp_real_parent_file[ $parent_slug ]; |
| 1272 | } |
| 1273 | |
| 1274 | if ( ! current_user_can( $capability ) ) { |
| 1275 | $_wp_submenu_nopriv[ $parent_slug ][ $menu_slug ] = true; |
| 1276 | return false; |
| 1277 | } |
| 1278 | |
| 1279 | /* |
| 1280 | * If the parent doesn't already have a submenu, add a link to the parent |
| 1281 | * as the first item in the submenu. If the submenu file is the same as the |
| 1282 | * parent file someone is trying to link back to the parent manually. In |
| 1283 | * this case, don't automatically add a link back to avoid duplication. |
| 1284 | */ |
| 1285 | if ( ! isset( $submenu[ $parent_slug ] ) && $menu_slug !== $parent_slug ) { |
| 1286 | foreach ( (array) $menu as $parent_menu ) { |
| 1287 | if ( $parent_menu[2] == $parent_slug && current_user_can( $parent_menu[1] ) ) { |
| 1288 | $submenu[ $parent_slug ][] = array_slice( $parent_menu, 0, 4 ); |
| 1289 | } |
| 1290 | } |
| 1291 | } |
| 1292 | |
| 1293 | $submenu[ $parent_slug ][] = array ( $menu_title, $capability, $url, null ); |
| 1294 | |
| 1295 | // No parent as top level. |
| 1296 | $_parent_pages[ $menu_slug ] = $parent_slug; |
| 1297 | |
| 1298 | return $menu_slug; |
| 1299 | } |
| 1300 | |
| 1301 | /** |