Custom post type role permissions won’t let me read

I cannot get it so that my user role for a supplier can read the shipments post type. It shows up in their menu but when you click on it you get you are not allowed to view this page error message.

It works if I add_cap('read_posts') but I don’t want them to view the regular posts just the shipments post type.

I have a suppliers user role with the following capabilities.

WP_Role Object
(
    [name] => supplier
    [capabilities] => Array
        (
            [read] => 1
            [edit_shipment] => 1
            [read_shipment] => 1
            [edit_others_shipments] => 1
            [publish_shipments] => 1
            [read_private_shipments] => 1
            [edit_shipments] => 1
            [create_shipment] => 1
            [read_shipments] => 1
        )

)

And I have setup the post type for shipments with the following

function shipment_post_type() {
  $labels = array(
    'name'                  => _x( 'Shipments', 'Post Type General Name', 'sage' ),
    'singular_name'         => _x( 'Shipment', 'Post Type Singular Name', 'sage' ),
    'menu_name'             => __( 'Shipments', 'sage' ),
    'name_admin_bar'        => __( 'Shipments', 'sage' ),
    'archives'              => __( 'Shipment Archives', 'sage' ),
    'parent_item_colon'     => __( 'Parent shipment:', 'sage' ),
    'all_items'             => __( 'All shipments', 'sage' ),
    'add_new_item'          => __( 'Add New shipment', 'sage' ),
    'new_item'              => __( 'New shipment', 'sage' ),
    'edit_item'             => __( 'Edit shipment', 'sage' ),
    'update_item'           => __( 'Update shipment', 'sage' ),
    'view_item'             => __( 'View shipment', 'sage' ),
    'search_items'          => __( 'Search shipments', 'sage' ),
    'not_found'             => __( 'Not found', 'sage' ),
    'not_found_in_trash'    => __( 'Not found in Trash', 'sage' ),
    'featured_image'        => __( 'Featured Image', 'sage' ),
    'set_featured_image'    => __( 'Set shipment image', 'sage' ),
    'remove_featured_image' => __( 'Remove shipment image', 'sage' ),
    'use_featured_image'    => __( 'Use as shipment image', 'sage' ),
    'insert_into_item'      => __( 'Insert into shipment', 'sage' ),
    'uploaded_to_this_item' => __( 'Uploaded to this shipment', 'sage' ),
    'items_list'            => __( 'shipments list', 'sage' ),
    'items_list_navigation' => __( 'Constests list navigation', 'sage' ),
    'filter_items_list'     => __( 'Filter shipments list', 'sage' ),
  );
  $args = array(
    'label'                 => __( 'shipments', 'sage' ),
    'description'           => __( 'Manage all shipments, sweepstakes and giveaways.', 'sage' ),
    'labels'                => $labels,
    'supports'              => array( 'revisions' ),
    'taxonomies'            => array( '' ),
    'hierarchical'          => false,
    'public'                => true,
    'show_ui'               => true,
    'show_in_menu'          => true,
    'menu_position'         => 5,
    'menu_icon'             => 'dashicons-archive',
    'show_in_admin_bar'     => true,
    'show_in_nav_menus'     => false,
    'can_export'            => true,
    'has_archive'           => false,
    'exclude_from_search'   => true,
    'publicly_queryable'    => true,
    'map_meta_cap' => true,
    'capabilities' => array(
      'edit_post'          => 'edit_shipment',
      'read_post'          => 'read_shipment',
      'read_posts'         => 'read_shipments',
      'delete_post'        => 'delete_shipment',
      'delete_posts'       => 'delete_shipments',
      'edit_posts'         => 'edit_shipments',
      'edit_others_posts'  => 'edit_others_shipments',
      'publish_posts'      => 'publish_shipments',
      'read_private_posts' => 'read_private_shipments',
      'create_posts'       => 'create_shipments',
    ),
  );
  register_post_type( 'shipment', $args );

}
add_action( 'init', 'shipment_post_type', 0 );

4 s
4

Your custom post type looks like it’s set up properly. It works on my test install. Try this instead of whatever add_role and add_cap code you’re currently using. (For testing purposes only. Don’t use it in production code, for reasons outlined below.) It’s working for me:

function prefix_set_up_supplier_role(){
remove_role( 'supplier' );
add_role( 'supplier', 'Supplier', array(
        'read'                      => true,
        'edit_shipment'             => true,
        'read_shipment'             => true,
        'read_shipments'            => true,
        'delete_shipment'           => true,
        'delete_shipments'          => true,
        'edit_shipments'            => true,
        'edit_others_shipments'     => true,
        'publish_shipments'         => true,
        'read_private_shipments'    => true,
        'create_shipments'          => true,
    )
);
}
add_action( 'init', 'prefix_set_up_supplier_role' );

It’s very important to remember that adding user roles and capabilities actually saves data to the database. So if you had a version of your code before that didn’t quite work, then added something that would make it work, it might not have taken effect if there is still old data in your database. add_role() returns null if the role already exists in the database. For production code, you should actually be using the plugin activation and deactivation hooks for this stuff instead of running it every time, like this:

register_activation_hook( __FILE__, 'prefix_activate' );
function prefix_activate(){
    add_role( 'supplier', 'Supplier', array(
        'read'                      => true,
        'edit_shipment'             => true,
        'read_shipment'             => true,
        'read_shipments'            => true,
        'delete_shipment'           => true,
        'delete_shipments'          => true,
        'edit_shipments'            => true,
        'edit_others_shipments'     => true,
        'publish_shipments'         => true,
        'read_private_shipments'    => true,
        'create_shipments'          => true,
    )
);
}

register_deactivation_hook( __FILE__, 'prefix_deactivate' );
function prefix_deactivate(){
    remove_role( 'supplier' );
}

Leave a Comment