I've been playing with the custom post types capabilities and some behaviors remains really mysticals for me.
Say you have a Custom Post Type (CPT) called show for defining a radio broadcast with this capabilities :
'capabilities' => array( // meta caps 'read_post' => 'read_show', 'edit_post' => 'edit_show', 'delete_post' => 'delete_show', // primitive/meta caps 'create_posts' => 'create_shows', // primitive caps used outside of map_meta_cap() 'publish_posts' => 'publish_shows', 'read_private_posts' => 'read_private_shows', 'edit_posts' => 'edit_shows', 'edit_others_posts' => 'edit_others_shows', // primitive caps used inside of map_meta_cap() 'read' => 'read_shows', 'edit_private_posts' => 'edit_private_shows', 'edit_published_posts' => 'edit_published_shows', 'delete_posts' => 'delete_shows', 'delete_private_posts' => 'delete_private_shows', 'delete_published_posts' => 'delete_published_shows', 'delete_others_posts' => 'delete_others_shows' )
Add another CPT called podcast which are linked to a radio broadcast via a meta value (anyway, it's not important here). It ha these capabilities :
'capabilities' => array( // meta caps 'read_post' => 'read_podcast', 'edit_post' => 'edit_podcast', 'delete_post' => 'delete_podcast', // primitive/meta caps 'create_posts' => 'create_podcasts', // primitive caps used outside of map_meta_cap() 'publish_posts' => 'publish_podcasts', 'read_private_posts' => 'read_private_podcasts', 'edit_posts' => 'edit_podcasts', 'edit_others_posts' => 'edit_others_podcasts', // primitive caps used inside of map_meta_cap() 'read' => 'read_podcasts', 'edit_private_posts' => 'edit_private_podcasts', 'edit_published_posts' => 'edit_published_podcasts', 'delete_posts' => 'delete_podcasts', 'delete_private_posts' => 'delete_private_podcasts', 'delete_published_posts' => 'delete_published_podcasts', 'delete_others_posts' => 'delete_others_podcasts' )
Say you add a new role called Show Runner which should have this rights :
- Edit its own radio broadcast (no creation or deletion, the radio broadcast is created by an editor which change the author to the show runner).
- Create / Edit its podcasts (but not publish or delete)
Here is the role capabilities mapping :
add_role( 'show_runner', __( 'Show Runner', 'lang_plugin' ), array( 'read' => true, /* Media upload */ 'upload_files' => true, /* CPT show */ 'read_shows' => true, 'create_shows' => false, 'publish_shows' => false, 'edit_shows' => true, 'edit_published_shows' => true, 'delete_shows' => false, /* CPT podcast */ 'read_podcasts' => true, 'create_podcasts' => true, 'publish_podcasts' => false, 'edit_podcasts' => true, 'edit_published_podcasts' => true, 'delete_podcasts' => false, ) );
The first weird thing
A show runner can not access the list of shows although he has 'read_shows' and 'edit_shows' to true and that I can see the "Shows" Menu in the sidebar.
But if I put 'create_shows' to true, he access the list...and can create a show (but I don't want that !).
The second weird thing (coming from the first one)
I have set 'create_shows' to false (to reflect what I really want) again before continuing.
If I change the show_in_menu parameters of the podcast CPT to put it into the show menu (as a submenu) like this :
'show_in_menu' => 'edit.php?post_type=show'
... then the show runner has access to the Shows list, without the "New Show" button. Cool ! That's what I want.
BUT : If the show runner tries to create a new podcast (he can do this regarding capabilities), wordpress says he has no rights for this...
Conclusion / Question
Why a CPT creation depends like this of the menu position ?? It's like the podcast CPT heritates of the false value of create_shows although it's true for him.
Subquestion : how can a role have access to the list of a CPT without setting 'create_xxxxx' to true ?