I have a plugin with a custom post type (with 'capability_type' => 'post') and a custom user role (test_user). When I check if a user is allowed to edit a post (of the CPT and which this user created) with current_user_can, I get different results when using edit_post and edit_posts (with the s).
See example code below:
register_post_type('test_cpt', [
'labels' => ['name' => 'TEST CPT'],
'description' => 'A custom post type for testing',
'public' => true,
'publicly_queryable' => true,
'show_ui' => true,
'show_in_menu' => true,
'query_var' => true,
'rewrite' => ['slug' => 'testcpt'],
'capability_type' => 'post',
'has_archive' => true,
'hierarchical' => false,
]);
$new_post = [
'post_content' => 'Lorem ipsum dolor sit amet consectetur adipisicing elit.',
'post_name' => 'test',
'post_title' => 'TEST',
'post_status' => 'publish',
'post_type' => 'test_cpt'
];
wp_insert_post($new_post);
$new_post = [
'post_content' => 'Lorem ipsum dolor sit amet consectetur adipisicing elit.',
'post_name' => 'test_post',
'post_title' => 'TEST post',
'post_status' => 'publish',
'post_type' => 'post'
];
wp_insert_post($new_post);
$user_id = get_current_user_id();
$data = get_userdata( $user_id );
echo '<pre>' . print_r( $data->allcaps, true ) . '</pre>';
$id = 153;
$post = get_post( $id );
echo '<dl>';
echo '<dt>current user: </dt>';
echo '<dd>'. $user_id . '</dd>';
echo '<dt>post id: </dt>';
echo '<dd>'. $post->ID . '</dd>';
echo '<dt>post_author: </dt>';
echo '<dd>'. $post->post_author . '</dd>';
echo '<dt>edit_posts: </dt>';
echo '<dd>'. (current_user_can('edit_posts') ? 'true' : 'false') . '</dd>';
echo '<dt>edit_post '.$post->ID.': </dt>';
echo '<dd>'. (current_user_can('edit_post', $post->ID) ? 'true' : 'false') . '</dd>';
echo '</dl>';
which results to:
Array
(
[read] => 1
[edit_posts] => 1
[upload_files] => 1
[test_user] => 1
)
current user: 3
post id: 153
post_author: 3
edit_posts: true
edit_post 153: false
According to this post, edit_post “evaluates to the capability edit_posts if the post_author field of this post matches the current users ID”. Which makes sense and is what I expected it should do.
If I include the code provided in this WP SE answer, then I also get true for edit_post.
But I do not understand why this is necessary. It seems to me, that there should be a better way to deal with this situation. I would image this is a pretty common use case.
Answers:
Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.
Method 1
The post in question is published, but your user is missing the edit_published_posts capability, so they’re not allowed to edit it.
All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0