Permalink
Switch branches/tags
Nothing to show
Find file
Fetching contributors…
Cannot retrieve contributors at this time
164 lines (122 sloc) 6.13 KB
<?php
// to override default WP core meta_cap translation
add_filter( 'map_meta_cap', '_map_core_meta_cap_rs', 1, 4 ); // register early because we are wiping out default meta_cap expansion
// used by UsersInterceptor for users_who_can filtering
add_filter( 'map_meta_cap_rs', '_map_meta_cap_rs', 1, 4 ); // register early because we are wiping out default meta_cap expansion
// no need to reconstruct WP-generated cap mapping except for revisions and attachments (not supporting custom statuses)
function _map_core_meta_cap_rs( $caps, $meta_cap, $user_id, $args ) {
if ( ( -1 === $user_id ) || in_array( $meta_cap, array( 'read_attachment', 'edit_attachment', 'delete_attachment', 'read_revision', 'edit_revision', 'delete_revision' ) ) || defined( 'SCOPER_FORCE_MAP_METACAP' ) )
$caps = _map_meta_cap_rs( $caps, $meta_cap, $user_id, $args );
return $caps;
}
function _map_meta_cap_rs( $caps, $meta_cap, $user_id, $args ) {
static $defined_meta_caps;
// support usage by RS users_who_can function, which needs to remap meta caps to simple equivalent but builds owner cap adjustment into DB query
$adjust_for_user = ( -1 !== $user_id );
// separate filtering function _map_user_meta_cap_rs handles this for users_who_can filtering
if ( in_array( $meta_cap, array( 'edit_users', 'delete_users', 'remove_users', 'promote_users' ) ) )
return $caps;
if ( ! isset( $defined_meta_caps ) ) {
$defined_meta_caps = array();
$defined_meta_caps ['read'] = array( 'read_attachment', 'read_revision' );
$defined_meta_caps ['edit'] = array( 'edit_attachment', 'edit_revision' );
$defined_meta_caps ['delete'] = array( 'delete_attachment', 'delete_revision' );
$post_types = array_diff_key( get_post_types( array( 'public' => true ), 'object' ), array( 'attachment' => true ) );
foreach( $post_types as $type => $post_type_obj ) {
$defined_meta_caps ['read'] []= $post_type_obj->cap->read_post;
$defined_meta_caps ['edit'] []= $post_type_obj->cap->edit_post;
$defined_meta_caps ['delete'] []= $post_type_obj->cap->delete_post;
}
}
$matched_op = false;
foreach( array_keys($defined_meta_caps) as $op ) {
if ( in_array( $meta_cap, $defined_meta_caps[$op] ) ) {
$matched_op = $op;
break;
}
}
if ( ! $matched_op )
return $caps;
$object_id = ( is_array($args) ) ? $args[0] : $args;
if ( ! $object_id )
return $caps;
if ( ! $post = get_post( $object_id ) )
return $caps;
if ( in_array( $post->post_type, array( 'revision', 'attachment' ) ) )
if ( ! $post = get_post( $post->post_parent ) )
return $caps;
$use_post_types = scoper_get_option( 'use_post_types' );
if ( empty( $use_post_types[$post->post_type] ) )
return $caps;
if ( ! $post_type_obj = get_post_type_object( $post->post_type ) )
return $caps;
if ( ! $post_status_obj = get_post_status_object( $post->post_status ) )
return $caps;
// no need to modify meta caps for post/page checks with built-in status
if ( in_array( $post->post_type, array( 'post', 'page' ) ) && $post_status_obj->_builtin && $adjust_for_user && $caps )
return $caps;
if ( ! $adjust_for_user ) {
$is_post_author = false;
} elseif ( ! $post->post_author ) {
$is_post_author = true; //No author set yet so treat current user as author for cap checks
$require_all_status_caps = true;
} else {
$post_author_data = get_userdata( $post->post_author );
$is_post_author = ( $user_id == $post_author_data->ID );
$require_all_status_caps = ! defined( 'SCOPER_LEGACY_META_CAPS' );
}
// Need to override default output from core map_meta_caps. This filter hooks early to avoid wiping out other supplemental filters.
$caps = array();
switch ( $op ) {
case 'read':
if ( ! empty($post_status_obj->private) ) {
if ( $is_post_author )
$caps[] = 'read';
else
$caps[] = $post_type_obj->cap->read_private_posts;
} else
$caps[] = 'read';
break;
case 'edit' :
$caps[] = $post_type_obj->cap->edit_posts;
// The post is public, extra cap required.
if ( ! empty($post_status_obj->public) ) {
$caps[] = $post_type_obj->cap->edit_published_posts;
} elseif ( 'trash' == $post->post_status ) {
if ('publish' == get_post_meta($post->ID, '_wp_trash_meta_status', true) )
$caps[] = $post_type_obj->cap->edit_published_posts;
}
// note: as of 3.0, WP core requires edit_published_posts, but not edit_private_posts, when logged user is the post author. That's inconsistent when used in conjunction with custom statuses
if ( ! empty($post_status_obj->private) && ! $is_post_author ) //&& $require_all_status_caps )
$caps[] = $post_type_obj->cap->edit_private_posts;
if ( ! $is_post_author )
$caps[] = $post_type_obj->cap->edit_others_posts; // The user is trying to edit someone else's post.
break;
case 'delete' :
$caps[] = $post_type_obj->cap->delete_posts;
// The post is public, extra cap required.
if ( ! empty($post_status_obj->public) ) {
$caps[] = $post_type_obj->cap->delete_published_posts;
} elseif ( 'trash' == $post->post_status ) {
if ('publish' == get_post_meta($post->ID, '_wp_trash_meta_status', true) )
$caps[] = $post_type_obj->cap->delete_published_posts;
}
// note: as of 3.0, WP core requires delete_published_posts, but not delete_private_posts, when logged user is the post author. That's inconsistent when used in conjunction with custom statuses
if ( ! empty($post_status_obj->private) && ! $is_post_author ) //&& $require_all_status_caps )
$caps[] = $post_type_obj->cap->delete_private_posts;
if ( ! $is_post_author )
$caps[] = $post_type_obj->cap->delete_others_posts; // The user is trying to delete someone else's post.
break;
} // end switch
// if a capability is defined for this custom status, require it also
if ( empty($require_all_status_caps) ) {
if ( empty($post_status_obj->_builtin) ) {
$status_cap_name = "{$op}_{$post->post_status}_posts";
if ( ! empty( $post_type_obj->cap->$status_cap_name ) )
$caps []= $post_type_obj->cap->$status_cap_name;
}
}
$caps = array_unique( $caps );
return $caps;
}
?>