WP introduced in 5.3.0 said position argument, it is a very helpful argument and there’s no way right now to add a submenu in ClassicPress at a specific position.
God knows I have tried and almost went insane until I remembered that I am using an outdated CMS: ClassicPress.
Fortunately we have a DOC that at least saved me the time from reading the code
My proposal: to add said argument as below shown.
Replace this:
$submenu[$parent_slug][] = array ( $menu_title, $capability, $menu_slug, $page_title );
with:
$new_sub_menu = array( $menu_title, $capability, $menu_slug, $page_title );
if (!empty ( $function ) && !empty ( $hookname ))
add_action( $hookname, $function ); if ( null !== $position && ! is_numeric( $position ) ) {
_doing_it_wrong(
$_registered_pages[$hookname] = true; __FUNCTION__,
sprintf(
/* /* translators: %s: add_submenu_page() */
* Backward-compatibility for plugins using add_management page. __( 'The seventh parameter passed to %s should be numeric representing menu position.' ),
* See wp-admin/admin.php for redirect from edit.php to tools.php '<code>add_submenu_page()</code>'
*/ ),
if ( 'tools.php' == $parent_slug ) '5.3.0'
$_registered_pages[get_plugin_page_hookname( $menu_slug, 'edit.php')] = true; );
$position = null;
// No parent as top level. }
$_parent_pages[$menu_slug] = $parent_slug;
if (
return $hookname; null === $position ||
( ! isset( $submenu[ $parent_slug ] ) || $position >= count( $submenu[ $parent_slug ] ) )
) {
$submenu[ $parent_slug ][] = $new_sub_menu;
} else {
// Test for a negative position.
$position = max( $position, 0 );
if ( 0 === $position ) {
// For negative or `0` positions, prepend the submenu.
array_unshift( $submenu[ $parent_slug ], $new_sub_menu );
} else {
// Grab all of the items before the insertion point.
$before_items = array_slice( $submenu[ $parent_slug ], 0, $position, true );
// Grab all of the items after the insertion point.
$after_items = array_slice( $submenu[ $parent_slug ], $position, null, true );
// Add the new item.
$before_items[] = $new_sub_menu;
// Merge the items.
$submenu[ $parent_slug ] = array_merge( $before_items, $after_items );
}
}
// Sort the parent array.
ksort( $submenu[ $parent_slug ] );
(and the new argument needs to be added to the function, and PHP Unit tests need to be updated)
Unless there’s a better solution…