you do what you do

Permissions with Wordpress Custom Post Types

To create custom permissions on custom post types, easy way to do so is with the members plugin.

Step 1 - Install Plugin

  1. Install members plugin
  2. Enable roles: Settings > Members Components > Edit Roles
  3. Familiarlize yourself with Users > Roles

Step 2 - Create a Custom Post Type

A simple custom post type (example “Projects”):

add_action( 'init', 'create_post_type' );
function create_post_type() {
  register_post_type( 'project',
    array(
      'labels' => array(
        'name' => __( 'Projects' ),
        'singular_name' => __( 'Project' )
      ),
      'public' => true,
      'capability_type' => 'project',
      array(
        'public' => true,
        'capability_type' => 'project'
      )
    )
  );
}

Step 3 - Set Permissions

My goal was to make it so users could create and edit only their own projects. They key is knowing the difference between meta capabilities and primitive capabilities.

Primitive capabilities are flags, always set to yes or no. Meta capabilities require some context, like “Is the user the author of this post?”.

Primitive caps are set within the role editor. In my case, the primitive capabilities needed for contributors are edit_projects and edit_published_projects. roles in wordpress
Reference of other primitive capabilities.

Meta capabilities need to be defined with the map_meta_cap filter. I found the best place to start is by looking at the wordpress source.

In my functions.php I added:

add_filter( 'map_meta_cap', 'my_map_meta_cap', 10, 4 );
function my_map_meta_cap( $caps, $cap, $user_id, $args ) {

  // almost identical to 'edit page' from
  // http://core.trac.wordpress.org/browser/trunk/wp-includes/capabilities.php?rev=15919#L867
  if ( $cap == 'edit_project'){

    // remove meta cap
    $key = array_search('edit_project', $caps);
    if($key !== false) unset($caps[$key]);

    $author_data = get_userdata( $user_id );
    //echo "post ID: {$args[0]}<br />";
    $page = get_page( $args[0] );
    //print_r($page);
    $page_author_data = get_userdata( $page->post_author );
    //echo "current user id : $user_id, page author id: " . $page_author_data->ID . "<br />";
    // If the user is the author...
    if ( is_object( $page_author_data ) && $user_id == $page_author_data->ID ) {
      // If the page is published...
      if ( 'publish' == $page->post_status ) {
        $caps[] = 'edit_published_projects';
      } elseif ( 'trash' == $page->post_status ) {
        if ('publish' == get_post_meta($page->ID, '_wp_trash_meta_status', true) )
          $caps[] = 'edit_published_projects';
      } else {
        // If the page is draft...
        $caps[] = 'edit_projects';
      }
    } else {
      // The user is trying to edit someone else's page.
      $caps[] = 'edit_others_projects';
      // The page is published, extra cap required.
      if ( 'publish' == $page->post_status )
        $caps[] = 'edit_published_projects';
      elseif ( 'private' == $page->post_status )
        $caps[] = 'edit_private_projects';
    }

  }

  /* Return the capabilities required by the user. */
  return $caps;
}

Result

Users can now create new projects, post them to pending, but are not able to edit anyone else’s projects: CMS result

Final Notes

Some permissions you may want to add to to the administrator include: edit_projects, edit_others_projects, publish_projects, read_private_projects, delete_project, edit_published_projects.

If you add a meta capability through role editor, you will get some unexpected behavior. For example, if you add ‘delete_project’ (a meta capability) to the admin roll, an admin will be able to delete any project, thus ignoring the prim caps delete_published_posts, delete_published_posts, and delete_others_posts.

Thanks:

  1. blurback posted this
blog comments powered by Disqus