Add 7th argument for add_submenu_page (position)

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 :rofl:

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…

A petition?
Just start a backport PR.
This one Changeset 53104 – WordPress Trac is at the end result, but there were several in-between states after the initial Changeset 46197 – WordPress Trac

2 Likes

I agree with Joy. Backports don’t need a petition, especially if you’re doing the work. I will move this out of petitions to free up votes.

1 Like

Ok!
Didn’t even think about that back ports don’t need/should not be in petitions, sorry!

3 Likes

Sorry… wrote on wrong topic…

I don’t understand why backports don’t need a petition but I like the initiative. It’s useful.

I should have been more specific. There are exceptions to petitions, which this falls under:

Minor modifications to existing functionality or processes.

1 Like

This is done. Expecting review, etc, that all can happen in Git.

2 Likes

For reference, this is the PR:

I will set this topic to close in a few days, since there’s no need for further discussion.

1 Like

This topic was automatically closed after 2 days. New replies are no longer allowed.