Restrict custom post type view by user role

Every role has capabilities.

Here is a simple contributor to our endeavor: (he just writes and edits)

add_role('contributor', 'Contributor', array(
    'read' => true,
    'edit_posts' => true,
    'delete_posts' => false,
));

Now he has a new capability (he can edit other peoples posts)

function add_capability()
{
    $role = get_role('contributor');
    $role->add_cap('edit_others_posts');
}
add_action('admin_init', 'add_capability');

Now to add his new capabilities for our new post type. First lets create the post type:

function create_myposttype()
{
    register_post_type(
        'myposttype',
        array(
            'public' => true,
            'capability_type' => 'myposttype',
            'capabilities' => array(
                'publish_posts' => 'publish_myposttypes',
                'edit_posts' => 'edit_myposttypes',
                'edit_others_posts' => 'edit_others_myposttypes',
                'read_private_posts' => 'read_private_myposttypes',
                'edit_post' => 'edit_myposttype',
                'delete_post' => 'delete_myposttype',
                'read_post' => 'read_myposttype',
            ),
        )
    );
}
add_action('init', 'create_myposttype');

Post type is created but the contributor has no power on it. Lets give him some juice:

function add_capability()
{
    $role = get_role('contributor');
    $role->add_cap('read_myposttype');
    $role->add_cap('edit_myposttypes');
    $role->add_cap('delete_myposttype', false); // to be sure
}
add_action('admin_init', 'add_capability');

The read_post and read_* capability assures that the user with that assigned role wont be able to see and access that current area. He will get that generic WordPress error:

You do not have sufficient permissions to access this page

And lets make our authors (that default role) are unable to see the myposttype posts:

function remove_author_capability()
{
    $role = get_role('author');
    $role->add_cap('read_myposttype', false);
}
add_action('admin_init', 'remove_author_capability');

Remember to cleanup:

function add_roles_on_activation() // add roles on activation
{
    add_role('contributor', 'Contributor', array(
        'read' => true,
        'edit_posts' => true,
        'delete_posts' => false,
    ));
}
register_activation_hook(__FILE__, 'add_roles_on_activation');

function add_roles_removal()  // we clean up after ourselves
{
    remove_role('contributor');
}
register_deactivatin_hook(__FILE__, 'add_roles_removal');

Now if you just want to remove stuff from the menu (making them accessible by URL anyway) here is how:

From the adminbar (that top hovering small menu):

function my_edit_adminbar($wp_admin_bar)
{
    if(current_user_can('read_myposttype'))
        $wp_admin_bar->remove_node('new-myposttype');
}
add_action('admin_bar_menu', 'my_edit_adminbar');

From the menu:

function my_edit_menu()
{
    if(current_user_can('read_myposttype'))
    {
        $slug = 'edit.php?post_type=myposttype';
        remove_menu_page($slug);
    }
}
add_action('admin_menu', 'my_edit_menu');

Leave a Comment