Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

WordPress: Capabilities for custom post types

I'm writing a plugin which creates a custom post_type. I'd also like the plugin to create a custom role which can only add/edit/delete the new post_type. I've tried several plugins (Role Scoper, Advanced Access manager) and they allow me to redefine or create new roles, but they don't allow me to assign capabilities specific to the new post_type. For example, I want to allow the ability to add/edit my new post_type but NOT normal posts/pages.

From what I've read, I can add new roles with the add_role() function. One of the parameters of this function is an array of "capabilities" which appear to be defined here. I think what I need is to be able to add my capabilities that are specific to MY post_type. Is this possible?

like image 780
emersonthis Avatar asked Nov 19 '11 23:11

emersonthis


People also ask

What is capability type in custom post type?

#Update Post Type Capabilities The default post type capabilities will be: edit_post. read_post. delete_post. edit_posts.

What is the use of custom post type in WordPress?

So what is a custom post type? Custom post types are specific post types that have been added to WordPress using custom code or plugins. The idea is that you may want to add additional functionality to your site but don't want to add everything as a standard post.

How do I get all the categories of a custom post type in WordPress?

use get_terms() function to fetch custom taxonomy by its slug, in your case slug is dining-category. read function refrence from wordpress codex website and try this.


2 Answers

Capabilities for Custom Post Types

The function register_post_type() takes a $capabilities array as one of its (optional) arguments.

It could look like so:

$capabilities = array(
    'publish_posts' => 'publish_ypts',
    'edit_posts' => 'edit_ypts',
    'edit_others_posts' => 'edit_others_ypts',
    'delete_posts' => 'delete_ypts',
    'delete_others_posts' => 'delete_others_ypts',
    'read_private_posts' => 'read_private_ypts',
    'edit_post' => 'edit_ypt',
    'delete_post' => 'delete_ypt',
    'read_post' => 'read_ypt'
);

where "ypt" stands for "your post type".

Thereafter you could add a new role to your WordPress that has these exact capabilities (and possibly some more of the standard WordPress capabilities):

add_role(
    'ypt_author',
    'Author of your post type',
    array(
        'publish_ypts' => true,
        'edit_ypts' => true,
        'edit_others_ypts' => true,
        'delete_ypts' => true,
        'delete_others_ypts' => true,
        'read_private_ypts' => true,
        'edit_ypt' => true,
        'delete_ypt' => true,
        'read_ypt' => true,
        // more standard capabilities here
    )
);

The latter can be done using plugins though, check out the Members plugin by Justin Tadlock, for instance.

Thorough Example

To give you a more concrete example:

/* REGISTER POST TYPE */

add_action('init', 'ypt_register');

function ypt_register()
{

    $labels = array(
        'name' => _x('YPTs', 'post type general name'),
        'singular_name' => _x('YPT', 'post type singular name'),
        'add_new' => _x('Add New YPT', 'Team item'),
        'add_new_item' => __('Add a new post of type YPT'),
        'edit_item' => __('Edit YPT'),
        'new_item' => __('New YPT'),
        'view_item' => __('View YPT'),
        'search_items' => __('Search YPTs'),
        'not_found' =>  __('No YPTs found'),
        'not_found_in_trash' => __('No YPTs currently trashed'),
        'parent_item_colon' => ''
    );

    $capabilities = array(
        // this is where the first code block from above goes
    );

    $args = array(
        'labels' => $labels,
        'public' => true,
        'publicly_queryable' => true,
        'show_ui' => true,
        'query_var' => true,
        'rewrite' => true,
        'capability_type' => 'ypt',
        'capabilities' => $capabilities,
        'hierarchical' => false,
        'menu_position' => null,
        'supports' => array( 'title', 'author', 'thumbnail' )
    ); 

    register_post_type( 'ypt' , $args );

    flush_rewrite_rules( false );
}


/* MAP META CAPABILITIES */

add_filter( 'map_meta_cap', 'ypt_map_meta_cap', 10, 4 );

function ypt_map_meta_cap( $caps, $cap, $user_id, $args )
{

    if ( 'edit_ypt' == $cap || 'delete_ypt' == $cap || 'read_ypt' == $cap ) {
        $post = get_post( $args[0] );
        $post_type = get_post_type_object( $post->post_type );
        $caps = array();
    }

    if ( 'edit_ypt' == $cap ) {
        if ( $user_id == $post->post_author )
            $caps[] = $post_type->cap->edit_posts;
        else
            $caps[] = $post_type->cap->edit_others_posts;
    }

    elseif ( 'delete_ypt' == $cap ) {
        if ( $user_id == $post->post_author )
            $caps[] = $post_type->cap->delete_posts;
        else
            $caps[] = $post_type->cap->delete_others_posts;
    }

    elseif ( 'read_ypt' == $cap ) {
        if ( 'private' != $post->post_status )
            $caps[] = 'read';
        elseif ( $user_id == $post->post_author )
            $caps[] = 'read';
        else
            $caps[] = $post_type->cap->read_private_posts;
    }

    return $caps;
}
like image 144
Johannes Pille Avatar answered Oct 16 '22 13:10

Johannes Pille


Nowadays (WP 3.5+), it's much easier. Just set the map_meta_cap argument to TRUE and choose a string (typically the post type name) for the capability_type argument when registering the post type.

A simple var_dump( $GLOBALS['wp_post_types']['new_custom_post_type'] ) ); will show you something like the following.

[cap] => stdClass Object
(
    [edit_post]      => "edit_{$capability_type}"
    [read_post]      => "read_{$capability_type}"
    [delete_post]        => "delete_{$capability_type}"
    [edit_posts]         => "edit_{$capability_type}s"
    [edit_others_posts]  => "edit_others_{$capability_type}s"
    [publish_posts]      => "publish_{$capability_type}s"
    [read_private_posts]     => "read_private_{$capability_type}s"
        [delete_posts]           => "delete_{$capability_type}s"
        [delete_private_posts]   => "delete_private_{$capability_type}s"
        [delete_published_posts] => "delete_published_{$capability_type}s"
        [delete_others_posts]    => "delete_others_{$capability_type}s"
        [edit_private_posts]     => "edit_private_{$capability_type}s"
        [edit_published_posts]   => "edit_published_{$capability_type}s"
)

The more intended array part are the seven other primitive capabilities that are not checked by core, but mapped by map_meta_caps() during post type registration.

like image 21
kaiser Avatar answered Oct 16 '22 11:10

kaiser