How do I remove the entire Media section from the main WordPress navigation without just hiding it?

I would like to remove the entire “Media” section from the main WordPress admin navigation ont he left hand side. What I don’t want to do is just “hide” it with CSS or a plugin/function like I have done so below, because it’s still accessible via the URL. This is crucial users shouldn’t see each others uploads by any means.

Here’s what I currently have, which just hides it. If you went to upload.php in the url, you could still access it.

Read More
add_action( 'admin_menu', 'remove_menu_links' );
function remove_menu_links() {
    remove_menu_page('upload.php'); //remove media
}

Any ideas? A suitable method I believe would be to just direct the user to the dashboard with an error message if they tried to access the upload.php url? Not sure how to do this though.

Related posts

Leave a Reply

2 comments

  1. You are indeed correct, before the admin update(i imagine the UI redesign, etc), unsetting items from the menus would in effect prevent access to those pages, that’s clearly changed now and requires additional cap checking.

    This isn’t something i’ve looked into myself(as i’ve just found out this moment), so i can’t speak about methods for doing so.. but it does bother me they’ve now turned a simple unsetting task into a bigger one that requires conditionalised capability checking(it’s just more leg work that was not previously required).

    Moving on from the revelation:

    Ok, seeing as the remove_menu_page and submenu equivalents are pretty much pointless now(i mean seriously, what good is making a page simply hidden from view) what i’d suggest is looping over the media submenu items and updating the required caps on the fly(if that’s what you need to do).

    This appears to have the desired outcome… 🙂

    add_action( 'admin_menu', 'remove_menu_links' );
    function remove_menu_links() {
        global $submenu;
        remove_menu_page('upload.php');
        foreach( $submenu['upload.php'] as $position => $data ) {
            $submenu['upload.php'][$position][1] = 'desired cap here';
        }
    }
    

    NOTE: If you want the items completely gone / inaccessible, simply use a non-existant cap(or just leave the code as it is above)..

    Updated version of the above code:

    Following on your last comment, perhaps it might be smart to do it like this… or something along these lines..

    add_action( 'admin_menu', 'remove_menu_links' );
    function remove_menu_links() {
        global $submenu;
    
        // Remove media for non-admins
        if( !current_user_can('manage_options') )
            remove_menu_page('upload.php');
    
        // Still need to update cap requirements even when hidden
        foreach( $submenu['upload.php'] as $position => $data ) {
            $submenu['upload.php'][$position][1] = 'manage_options';
        }
    }
    

    I realise now you do actually still need the current_user_can call, just to deal with conditionalising the removal of the parent item..