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

All we need is an easy explanation of the problem, so here it is.

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.

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.

How to solve :

I know you bored from this bug, So we are here to help you! Take a deep breath and look at the explanation of your problem. We have many solutions to this problem, But we recommend you to use the first method because it is tested & true method that will 100% work for you.

Method 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..

Method 2

Why not you try Role scoper plugin?

Note: Use and implement method 1 because this method fully tested our system.
Thank you 🙂

All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

Leave a Reply