[wp-trac] [WordPress Trac] #30452: _wp_translate_postdata() aggressively checks current_user_can( $ptype->cap->edit_others_posts ) on update
WordPress Trac
noreply at wordpress.org
Fri Nov 21 23:13:48 UTC 2014
#30452: _wp_translate_postdata() aggressively checks current_user_can(
$ptype->cap->edit_others_posts ) on update
-------------------------------+----------------------------
Reporter: danielbachhuber | Owner:
Type: defect (bug) | Status: new
Priority: normal | Milestone: Future Release
Component: Posts, Post Types | Version:
Severity: normal | Keywords: dev-feedback
Focuses: |
-------------------------------+----------------------------
The product use-case is that the creator of a post should always be able
to edit the post, even when they've assigned someone else as a byline. To
do so, I'm storing their user ID to post meta:
{{{
public function action_wp_insert_post_persist_author( $post_id, $post,
$update ) {
$post_obj = Post::get_by_post_id( $post_id );
if ( $update
|| ! in_array( $post->post_type,
Fusion()->get_post_types() )
|| ! $post_obj
|| ! $post->post_author ) {
return;
}
$post_obj->set_first_author_id( $post->post_author );
}
}}}
And then filtering `map_meta_cap`:
{{{
/**
* Filter map meta cap to do whatever custom caps we need
*/
public function filter_map_meta_cap( $caps, $cap, $user_id, $args ) {
switch ( $cap ) {
case 'edit_post':
$post_obj = Post::get_by_post_id( $args[0] );
if ( ! $post_obj ) {
break;
}
$post_type = get_post_type_object(
$post_obj->get_post_type() );
// Allow first authors to always edit the post
if ( $post_obj->get_first_author_id() && $user_id
== $post_obj->get_first_author_id() ) {
// Don't require editing others' posts
if ( false !== ( $key = array_search(
$post_type->cap->edit_others_posts, $caps ) ) ) {
unset( $caps[ $key ] );
}
// If the post is published...
if ( 'publish' == $post_obj->get_status()
) {
$caps[] =
$post_type->cap->edit_published_posts;
} elseif ( 'trash' ==
$post_obj->get_status() ) {
if ( 'publish' == get_post_meta(
$post_obj->get_id(), '_wp_trash_meta_status', true ) ) {
$caps[] =
$post_type->cap->edit_published_posts;
}
} else {
// If the post is draft...
$caps[] =
$post_type->cap->edit_posts;
}
}
break;
}
return $caps;
}
}}}
This approach generally works — except the original author isn't able to
save an update to a post because `_wp_translate_postdata()` aggressively
checks `current_user_can( $ptype->cap->edit_others_posts )`
([https://core.trac.wordpress.org/browser/tags/4.0.1/src/wp-
admin/includes/post.php#L67 ref]).
A check for `current_user_can( $ptype->cap->edit_post, $post_data['ID'] )`
was added to `_wp_translate_postdata()` in r22950, but the changeset also
leaves in the `edit_others_posts` check.
Given `current_user_can( 'edit_post' )` falls back to `edit_others_posts`
behind the scenes ([https://core.trac.wordpress.org/browser/tags/4.0.1/src
/wp-includes/capabilities.php#L1114 ref]), I'd expect we could remove the
second check.
--
Ticket URL: <https://core.trac.wordpress.org/ticket/30452>
WordPress Trac <https://core.trac.wordpress.org/>
WordPress publishing platform
More information about the wp-trac
mailing list