0

I am having trouble trying to remove a capability for a role on a custom post type.

I have a CPT defined as

function register_cpt() {
    $labels = array(
        'name'               => _x( 'Companies', 'post type general name', 'textdomain' ),
        'singular_name'      => _x( 'Company', 'post type singular name', 'textdomain' ),
        'menu_name'          => _x( 'My Companies', 'admin menu', 'textdomain' ),
        'name_admin_bar'     => _x( 'Company', 'add new on admin bar', 'textdomain' ),
        'add_new'            => _x( 'Add New', 'company', 'textdomain' ),
        'add_new_item'       => __( 'Add New Company', 'textdomain' ),
        'new_item'           => __( 'New Company', 'textdomain' ),
        'edit_item'          => __( 'Edit Company', 'textdomain' ),
        'view_item'          => __( 'View Company', 'textdomain' ),
        'all_items'          => __( 'All Companies', 'textdomain' ),
        'search_items'       => __( 'Search Companies', 'textdomain' ),
        'parent_item_colon'  => __( 'Parent Companies:', 'textdomain' ),
        'not_found'          => __( 'No companies found.', 'textdomain' ),
        'not_found_in_trash' => __( 'No companies found in Trash.', 'textdomain' ),
    );
    if( current_user_can( 'administrator' ) ) {
        $labels['menu_name'] = _x( 'Companies', 'admin menu', 'textdomain' );
    }
    $args   = array(
        'labels'             => $labels,
        'description'        => __( 'Description.', 'textdomain' ),
        'public'             => true,
        'publicly_queryable' => true,
        'show_ui'            => true,
        'show_in_menu'       => true,
        'query_var'          => true,
        'capability_type'    => array( 'company', 'companies' ),
        'capabilities'       => array(
            'edit_post'          => 'edit_company',
            'read_post'          => 'read_company',
            'delete_post'        => 'delete_company',
            'edit_posts'         => 'edit_companies',
            'edit_others_posts'  => 'edit_others_companies',
            'publish_posts'      => 'publish_companies',
            'read_private_posts' => 'read_private_companies',
            'create_posts'       => 'create_companies',
            'delete_posts'       => 'delete_companies',
        ),
        'map_meta_cap'       => null,
        'has_archive'        => true,
        'hierarchical'       => false,
        'menu_position'      => 1,
        'menu_icon'          => 'dashicons-groups',
        'supports'           => array( 'author', 'revisions' ),
    );
    register_post_type( $this->post_type, $args );
}

The CPT registration works well, I can create such CPT properly.

Now, I created a custom role: Service Provider (service_provider) that can create Company post types, the gist is that users under this role can only edit/delete Own post. They cannot edit/delete other user's posts.

I have the following method on a class to set up its capabilities:

public function allow_owner_permission_for_post_types( array $post_types ) {
    require_once trailingslashit( ABSPATH ) . 'wp-includes/capabilities.php';
    require_once trailingslashit( ABSPATH ) . 'wp-includes/post.php';

    global $wp_roles;

    $capabilities['read'] = true;
    remove_role( $this->role );
    add_role( $this->role , 'Service Provider', $capabilities );

    $role_object = get_role( $this->role );

    $to_not_allow_capabilities_global = array( 'edit_others_posts', 'read_private_posts' );

    foreach ( $to_not_allow_capabilities_global as $c ) {
        // $capabilities[ $post_object->cap->{$c} ] = false;
        $role_object->remove_cap( $c );
    }

    $capabilities = array();

    foreach ( $post_types as $post_type ) {

        $post_object = get_post_type_object( $post_type );

        if ( null === $post_object ) {
            continue;
        }

        $to_allow_capabilities = array( 'edit_post', 'read_post', 'delete_post', 'edit_posts', 'publish_posts',  'create_posts', 'delete_posts');

        $to_not_allow_capabilities = array( 'edit_others_posts', 'read_private_posts' );

        foreach ( $to_allow_capabilities as $c ) {
            // $capabilities[ $post_object->cap->{$c} ] = true;
            $role_object->add_cap( $post_object->cap->{$c} );
        }
        foreach ( $to_not_allow_capabilities as $c ) {
            // $capabilities[ $post_object->cap->{$c} ] = false;
            $role_object->remove_cap( $post_object->cap->{$c} );
        }
    }

}

Which I can call with the following init:

add_action( 'init', function() {
    $service_provider_roles = new \App\ServiceProvider();
    $service_provider_roles->allow_owner_permission_for_post_types( array( 'company' ) );
} );

I can confirm that when I print the capabilities for this role (service_provider):

echo '<pre>';
    print_r( get_role( 'service_provider' )->capabilities );
echo '</pre>';

I am getting the following capabilities array:

Array
(
    [read] => 1
    [edit_company] => 1
    [read_company] => 1
    [delete_company] => 1
    [edit_companies] => 1
    [publish_companies] => 1
    [create_companies] => 1
    [delete_companies] => 1
)

Yet, as you can see, the roles: edit_others_companies and read_private_companies are not in the array yet, a user can still edit other's created companies:

enter image description here

Hope somebody can help as I am out of idea. Regards,

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.