Restrict Admin Capabilities in MultiSite

    update_core
    update_plugins
    update_themes
    install_plugins
    install_themes
    delete_themes
    edit_plugins
    edit_themes

Hi, I want to restrict those capabilities to user_id = 1 so other super admins cant edit network files. (Btw if i am missing something, let me know). What is proper way of this? Tried http://wordpress.org/extend/plugins/extended-super-admins/ but it adds ‘manage_esa_options’ cap to every blog so super_admins see tons of blogs in their admin bar..

Related posts

Leave a Reply

1 comment

  1. Editing super admin capabilities is a little different from editing the capabilities of every other role, because there is a slight detour in the way WP checks the current user’s capabilities. This is what you find on capabilities.php on line 864:

    function has_cap( $cap ) {
    
        // (...)
    
        // Multisite super admin has all caps by definition, Unless specifically denied.
        if ( is_multisite() && is_super_admin( $this->ID ) ) {
            if ( in_array('do_not_allow', $caps) )
                return false;
            return true;
        }
    

    This means that we have to explicitly add ‘do_not_allow’ to the an array which contains the capability we want to block. In effect:

    add_filter('map_meta_cap', 'not_so_super_admins', 10, 4);
    function not_so_super_admins($caps, $cap, $user_id, $args){
    
        $super = array(
            'update_core',
            'update_plugins',
            'update_themes',
            'install_plugins',
            'install_themes',
            'delete_themes',
            'edit_plugins',
            'edit_themes'
        );
    
        if($user_id != 1 && in_array($cap, $super)) {
            $caps[] = 'do_not_allow';
        }
    
        return $caps;
    }
    

    I’ve tested this and it seems to block additional super-admins from doing those things you want to prevent, and it does so fairly silently (i.e. redirects them to the network dashboard).

    For the record, my previous answer, would work for most cases except the one you were asking for. My apologies 🙂

    add_action('init', 'not_so_super_admins');
    function not_so_super_admins() {
        if(is_multisite() && $GLOBALS['blog_id'] == 1) {
            $role = get_role('administrator');
            $super = array(
               'update_core',
               'update_plugins',
               'update_themes',
               'install_plugins',
               'install_themes',
               'delete_themes',
               'edit_plugins',
               'edit_themes'
            );          
            if(get_current_user_id() != 1) {   
                foreach($super as $cap) {
                    $role->remove_cap($cap);
                }
            }
            else {
                foreach($super as $cap) {
                    $role->add_cap($cap);
                }           
            }
        }
    }