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.