• Resolved Fact Maven

    (@factmaven)


    I made a function to remove certain submenu items in the admin dashboard using remove_submenu_page:

    $submenu = array(
        'tools.php' => 'tools.php', // Tools > Available Tools
        'options-general.php' => 'options-writing.php', // Settings > Writing
        'options-general.php' => 'options-discussion.php' // Settings > Discussion
        );
    foreach ( $submenu as $main => $sub ) {
        remove_submenu_page( $main, $sub );
    }

    All of items are hidden except for the Settings > Writing menu. It looks like it has to due with the fact that I am also hidding another submenu under Settings (Settings > Discussion), but I am not sure why it’s being “skipped”.

    I could just do the following which would fix this:

    remove_submenu_page( 'tools.php', 'tools.php' ); // Tools > Available Tools
    remove_submenu_page( 'options-general.php', 'options-writing.php' ); // Settings > Writing
    remove_submenu_page( 'options-general.php', 'options-discussion.php' ); // Settings > Discussion

    But I want to use the foreach method instead and to understand why this logic isn’t working 100%. Any help is appreciated.

Viewing 9 replies - 1 through 9 (of 9 total)
  • Strange, your foreach block should be executed exactly like your manual block functions. Are you sure there’s no typo?

    Thread Starter Fact Maven

    (@factmaven)

    Yes, because like you said, the manual block works with the same spelling. Even when I added the Settings > Media menu to the array, both Writing and Discussion now show up:

    $submenu = array(
        'tools.php' => 'tools.php',
        'options-general.php' => 'options-writing.php',
        'options-general.php' => 'options-discussion.php',
        'options-general.php' => 'options-media.php'
        );
        foreach ( $submenu as $main => $sub ) {
            remove_submenu_page( $main, $sub );
        }

    It appears that only the last item I hide under the Settings menu is hidden. I encourage you to try this out on your end.

    In which hook do you fire this function?

    Try this:

    add_action( 'admin_menu', 'prfx_remove_menu', 999 );
    
    function prfx_remove_menu() {
        $submenu = array(
            'tools.php' => 'tools.php',
            'options-general.php' => 'options-writing.php',
            'options-general.php' => 'options-discussion.php',
            'options-general.php' => 'options-media.php'
        );
    
        foreach ( $submenu as $main => $sub ) {
            remove_submenu_page( $main, $sub );
        }
    }
    Thread Starter Fact Maven

    (@factmaven)

    I am using the admin_menu hook. THis is what I’ve been using which worked with the manual block before

    add_action( 'admin_menu', 'remove_menu' ), 10, 1 );

    I know the logic error has to be related to having the same parent menu options-general.php in the array. It looks like it only hides ones of the submenus under Settings.

    Just trying to understand how to work around that.

    Moderator bcworkz

    (@bcworkz)

    It’s because your array declaration has multiple matching keys. When PHP parses your code and builds the array, every occurrence of ‘options-general.php’ key overwrites the previous construct having the same key. Associative arrays must have unique keys.

    See for yourself by var dumping $submenu right after your array declaration.

    You need an array of arrays to be able to loop through the array and maintain replicated data as values, not keys.

    array(
      array(
        'parent' => 'options-general.php',
        'remove' => 'options-writing.php',
      ),
      array(
        'parent' => 'options-general.php',
        'remove' => 'options-discussion.php',
      ),
      //etc.
    )

    And of course modify the foreach loop to work with the new array structure. Other array structures are possible if you prefer, just avoid repeated key names.

    Silly me, I didn’t realize the repeated key names. Thanks bcworkz!

    Thread Starter Fact Maven

    (@factmaven)

    Makes sense, this is what I’ve done

    $submenu = array(
                    'tools.php' => 'tools.php', // Tools > Available Tools
                    array( // Settings > Writing
                        'parent' => 'options-general.php',
                        'remove' => 'options-writing.php'
                        ),
                    array( // Settings > Discussion
                        'parent' => 'options-general.php',
                        'remove' => 'options-discussion.php'
                        )
                    );
                foreach ( $submenu as $main => $sub ) {
                    if ( is_array( $sub ) ) {
                        foreach ($sub as $main1 => $sub1 ) {
                            remove_submenu_page( $main1, $sub1 );
                        }
                    }
                    else {
                        remove_submenu_page( $main, $sub );
                    }
                }

    However, based on testing found here, the output would be:

    tools.php, tools.php
    parent, options-general.php
    remove, options-writing.php
    parent, options-general.php
    remove, options-discussion.php

    I know I’m close, but the logic is still off. Any suggestions?

    Try this:

    $remove = array(
        array( // Tools > Available Tools
            'parent' => 'tools.php',
            'remove' => 'tools.php',
        ),
        array( // Settings > Writing
            'parent' => 'options-general.php',
            'remove' => 'options-writing.php'
        ),
        array( // Settings > Discussion
            'parent' => 'options-general.php',
            'remove' => 'options-discussion.php'
        )
    );
    
    foreach ( $remove as $menu ) {
       foreach ( $menu as $key => $value ) {
           remove_submenu_page( $key['parent'], $key['remove'] );
       }
    }
    Thread Starter Fact Maven

    (@factmaven)

    Unfortunately this is becoming more complex than I imagined for a simple function. Will revert back to using a manual block instead for simplicity’s sake. Thank you everyone for the help.

Viewing 9 replies - 1 through 9 (of 9 total)
  • The topic ‘Unable to hide all submenus items using foreach construct’ is closed to new replies.