I have a site with 1 admin, 11 editors, and 4000+ authors. I need to prevent the authors from adding media to the server and using up all the storage.

Initially I tried

function removemediabuttons()
    if($user->wp_user_level >= 1) {
        remove_action( 'media_buttons', 'media_buttons' );
        global $menu;

This does remove the Add Media button for non-admins but the unset() approach to the admin sidebar menu had no effect and I assume that any author with a knowledge of WordPress could simply enter the media library URL and use it.

So I effectively eliminated this issue with

$wp_roles->remove_cap( 'author', 'upload_files' );

BUT this (correctly) removed the author role's access to use WP User Avatar and it is really important to users to not be forced to use Gravatar and to be able to change their avatars on a strictly local basis.

Is it possible to add_cap() just for the one module?

UPDATE 2015-12-21 Per bueltge's suggestion I changed code to check for profile in get_current_screen(). This definitely enables the UI in the profile but when the uploads.php UI comes up for the upload it checks again and is denied. The check in this case is originating in /wp-admin/includes/ajax-actions.php so it is not the plugin itself doing the upload (and correctly so).

global $wp_roles; 
$wp_roles->remove_cap( 'author', 'upload_files' );
add_action( 'current_screen', 'allowAvatarUploads' );

function allowAvatarUploads() {
    $currentScreen = get_current_screen();
    global $wp_roles; 
    if( $currentScreen->id === "profile" ) {
        $wp_roles->add_cap( 'author', 'upload_files' );
        // keep their menu consistent 
    } else {

  • Upvoting this question as it has implications not just for gravatars but also for limiting what a user can change in their profile.
    – Shawn
    Commented Dec 22, 2015 at 9:02

1 Answer 1


Different hints to your idea to create a solution for your topic.

  1. Since longer time, WP use always role names, no level. Use always the role name ot the capability for a check in the access topic. The function current_user_can() should helps you.

  2. To remove a menu item, use the wp core function remove_menu_page( $menu_slug ); and not the unset. Is more stable and supported.

  3. The hook admin_head is not the best hook to init changes on menu or remove cap. To remove cap use the init hook or similar, early on the load stack. For the menu item use admin_menu.

To your question

Is it possible to add_cap() just for the one module?

No, the capability is globally. But you can check the site, the screen in the back end and remove it only on this screen, if this is helpful and possible. If you you will check the page of the packend, use the function https://codex.wordpress.org/Function_Reference/get_current_screen. You get an array with a lot of information about the page and use this for a statement to set the capability.

In your topic, I think it, that you should remove the capability upload_files with your idea - $wp_roles->remove_cap( 'author', 'upload_files' );. Check the avatar or profile page and add this capability for your users.

  • Thank you for the reply. Unfortunately there end up being a number of pages involved in uploading an avatar. So while I can use $wp_roles->add_cap( 'author', 'upload_files' ); on the profile page the avatar upload invokes uploads.php which denies the user the upload. Commented Dec 20, 2015 at 21:30
  • Maybe an another check of the plugin, enhanced to the default of WP to upload files?
    – bueltge
    Commented Dec 20, 2015 at 22:18
  • Why not have them manage the avatar through gravatar instead of using the plugin and your server space? Commented Dec 21, 2015 at 14:46
  • @GregMcMullen because Gravatar is tied to email and many of them do not wish their email associated with the images they prefer for the site avatars. If Gravatar would let them pair just the one domain with the image they might be ok with that but would still rather these images be limited visibility only on the one site. Commented Dec 21, 2015 at 22:57
  • @bueltge I'm not sure I follow what your comment means? The error in this case is originating in /wp-admin/includes/ajax-actions.php so it is not the plugin itself making this check. Commented Dec 21, 2015 at 23:02

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.