Using Custom Meta Capabilities on Custom Post Type

I am trying to create a product post type. I have already done so and been using it successfully in the development of a product review panel. I am trying to give a certain role the ability to create and manage these products so that vendors could come in and put their own products in. I have looked in other Member Plugin and I understand it 100%. I read this post:

» Meta Capabilities for Custom Post Types — JustinTadlock.com

Read More

And it explains how to add the capabilities. My issue being when I create a custom post type if I make the declaration of 'capability_type' => 'product' in the register_post_type() for product the post type is no longer created. As if I gave it some sort of incorrect input. I have read the Codex and this parameter is a string and defaults to 'post'. Which works if you supply that value.

I have tried just copy and pasting the code from the aforementioned post linked above. I have tried doing this in a different install of WordPress. I have not tried doing a completely fresh install and disabling all plugins however. That is what I am going to do now. I am hoping some one has had this problem before (people in the comments on the above article have and I commented there). Here is my current post registration code

register_post_type( 'bounty_product', array(
  'labels' => array(
     'name' => 'Products',
     'singular_name' => 'Product',
     'add_new' => 'Add New',
     'add_new_item' => 'Add New Product',
     'edit' => 'Edit',
     'edit_item' => 'Edit Product',
     'new_item' => 'New Product',
     'view' => 'View',
     'view_item' => 'View Product',
     'search_items' => 'Search Products',
     'not_found' => 'No Products found',
     'not_found_in_trash' => 'No Products found in Trash',
     'parent' => 'Parent Product'),
  'description' => 'Used for the product review section',
  'public' => true,
  'show_in_menu' => true,
  'menu_position' => 20,
  'has_archive' => true,
  'supports' => array( 'title', 'editor', 'comments', 'thumbnail', 'custom-fields' ),
));

To this I have tried adding bellow the 'public' => true:

'capability_type' => 'product',
        'capabilities' => array(
            'publish_posts' => 'publish_product',
            'edit_posts' => 'edit_product',
            'edit_others_posts' => 'edit_others_product',
            'delete_posts' => 'delete_product',
            'delete_others_posts' => 'delete_others_product',
            'read_private_posts' => 'read_private_product',
            'edit_post' => 'edit_product',
            'delete_post' => 'delete_product',
            'read_post' => 'read_product',
        ),

This simply breaks the custom post and it seems to be the 'capability_type' => 'product' line that is the problem.

Related posts

1 comment

  1. It seems like you have to assign the capabilities manually to user roles, otherwise your post type simply doesn’t show, this is true for the administrator role too.

    Taking another look at the arguments section of the register_post_type() reference I changed your code a bit:

    • map_meta_cap
      • necessary

    It seems that map_meta_cap needs to be set to true, to make this work.

    • capability_type
      • single and plurals array
      • not necessary

    May be passed as an array to allow for alternative plurals when using this argument as a base to construct the capabilities (…), the first array element will be used for the singular capabilities and the second array element for the plural capabilities (…).

    • capabilities
      • not needed, because

    (array) (optional) An array of the capabilities for this post type
    Default: capability_type is used to construct

    The above is for clarification about the code changes. Besides that I added a debugging part, printing $GLOBALS['wp_post_types']['bounty_product'], because like it’s mentioned in the codex reference:

    If you assign a ‘capability_type’ and then take a look into the $GLOBALS[‘wp_post_types’][‘your_cpt_name’] array, then you’ll see the (…)

    capabilities in the [cap] => stdClass Object ( ... ) part.

    Code:

    add_action( 'init', 'pt_bounty_product');
    function pt_bounty_product() { 
    register_post_type( 'bounty_product', array(
      'labels' => array(
         'name' => 'Products',
         'singular_name' => 'Product',
         'add_new' => 'Add New',
         'add_new_item' => 'Add New Product',
         'edit' => 'Edit',
         'edit_item' => 'Edit Product',
         'new_item' => 'New Product',
         'view' => 'View',
         'view_item' => 'View Product',
         'search_items' => 'Search Products',
         'not_found' => 'No Products found',
         'not_found_in_trash' => 'No Products found in Trash',
         'parent' => 'Parent Product'),
      'description' => 'Used for the product review section',
      'public' => true,
      'capability_type' => array('bounty_product','bounty_products'),
      'map_meta_cap' => true,
      'show_in_menu' => true,
      'menu_position' => 20,
      'has_archive' => true,
      'supports' => array( 'title', 'editor', 'comments', 'thumbnail', 'custom-fields' ),
    
    ));
    
    // uncomment /** like this /**/
    /**
    echo '<pre>';
    print_r($GLOBALS['wp_post_types']['www_product']);
    echo '</pre>';
    /**/
    }
    

    Codex: register_post_type()

    You have to uncomment to see that the capabilities are associated to the post type. If you can see them that means the post type initialization and the custom capabilities work. But like I said in the beginning, it’s seems you have to assign the capabilities manually to the according user roles.

    One – first – approach to do so – at least for the administrator role – is shown below.

    Code:

        add_action( 'init', 'add_bounty_product_caps_admin');
        function add_bounty_product_caps_admin() {
              $role = get_role( 'administrator' );
    
              $role->add_cap( 'edit_bounty_product' ); 
              $role->add_cap( 'edit_bounty_products' ); 
              $role->add_cap( 'edit_others_bounty_products' ); 
              $role->add_cap( 'publish_bounty_products' ); 
              $role->add_cap( 'read_bounty_product' ); 
              $role->add_cap( 'read_private_bounty_products' ); 
              $role->add_cap( 'delete_bounty_product' ); 
              $role->add_cap( 'edit_published_bounty_products' );
              $role->add_cap( 'delete_published_bounty_products' );
        }
    

    Source: https://stackoverflow.com/a/18342740/2505105
    Codex: get_role() | add_cap

    Now you should be able to see, add, edit and so forth your new post type as user with administrator role. You could duplicate and change or add to that to assign capabilities to other roles.

    I decided to showcase a second – a bit different – approach how capabilities can be assigned to user roles.

    Code:

        add_action( 'init', 'add_bounty_product_caps');
        function add_bounty_product_caps() {
            global $wp_roles;
    
            if ( isset($wp_roles) ) {
                $wp_roles->add_cap( 'administrator', 'edit_bounty_product' );
                $wp_roles->add_cap( 'administrator', 'read_bounty_product' );
                $wp_roles->add_cap( 'administrator', 'delete_bounty_product' );
                $wp_roles->add_cap( 'administrator', 'publish_bounty_products' );
                $wp_roles->add_cap( 'administrator', 'edit_bounty_products' );
                $wp_roles->add_cap( 'administrator', 'edit_others_bounty_products' );
                $wp_roles->add_cap( 'administrator', 'delete_bounty_products' );
                $wp_roles->add_cap( 'administrator', 'delete_others_bounty_products' );
                $wp_roles->add_cap( 'administrator', 'read_private_bounty_products' );
    
                $wp_roles->add_cap( 'editor', 'read_bounty_product' );
                $wp_roles->add_cap( 'editor', 'read_private_bounty_products' );
    
                $wp_roles->add_cap( 'author', 'read_bounty_product' );
                $wp_roles->add_cap( 'author', 'read_private_bounty_products' );
    
                $wp_roles->add_cap( 'contributor', 'read_bounty_product' );
                $wp_roles->add_cap( 'contributor', 'read_private_bounty_products' );
            }
      }
    

    Source: http://isabelcastillo.com/assign-custom-post-type-capabilities-roles-wordpress
    Codex: add_cap

    Do not to double assign capabilities. Above approaches are exemplary, you have to decide how to use them in what way.

    A last addition would be how to create a specific user role

    Code:

    add_action('init', 'bounty_product_author_user_role');
    function bounty_product_author_user_role() {
        add_role('bounty_product_author', 'Bounty Product Author',
            array (
                    'edit_bounty_product' => true,
                    'delete_bounty_product' => true,
                    'read_bounty_product' => true,
                    'publish_bounty_products' => true,
                    'edit_bounty_products' => true,
                    'edit_others_bounty_products' => true,
                    'delete_bounty_products' => true,
                    'delete_others_bounty_products' => true,
                    'read_private_bounty_products' => true,
                    // more standard capabilities here
                    'read' => true,
            )
        );
    }
    

    Source: http://wp-snppts.com/create-a-custom-post-type-and-define-custom-role-capabilities
    Codex: add_role()


    Keep in mind the above is exemplary, so you should fit it to you needs. To fully understand the different parts you might have to read the source and codex links – not saying that they cover all you can know about that, but it should get you started.


    Edit:
    A general overview of available capabilities can be found at the codex page: Roles and Capabilities.

Comments are closed.