Ignore my comment about meta_query
. Not only does it not work with $query->set()
, you wouldn’t be able to control the critical “A OR B” requirement of the query.
Instead, I believe what you require is possible via a combination of both the pre_get_posts
action hook and posts_where
filter hook as follows.
add_action('pre_get_posts', 'my_show_appropriate_posts');
function my_show_appropriate_posts($query){
if(strpos($_SERVER[ 'REQUEST_URI' ], '/wp-admin/edit.php') !== false) :
if(!current_user_can('manage_options')) :
/** Unset so that we can control exactly where this part of the query is included */
$query->set('author', null);
/** Ensure that the relevant tables required for a meta query are included */
$query->set('meta_query', array(
array(
'key' => 'add_editing_permission_for',
'value' => 'dummy', // This cannot be empty because of a bug in WordPress
'compare' => '='
)
));
/** Call the filter to amend the '$where' portion of the query */
add_filter('posts_where', 'my_custom_posts_where');
endif;
endif;
}
function my_custom_posts_where( $where="" ){
global $wpdb;
/** Add our required conditions to the '$where' portion of the query */
$where.= sprintf(
' AND ( %1$s.post_author = %2$s OR ( %3$s.meta_key = "add_editing_permission_for" AND %3$s.meta_value = %2$s ) )',
$wpdb->posts,
get_current_user_id(),
$wpdb->postmeta
);
/** Remove the filter to call this function, as we don't want it any more */
remove_filter('posts_where', 'my_custom_posts_where');
return $where;
}
Recommended reading
-
The
pre_get_posts
action hook – http://codex.wordpress.org/Plugin_API/Action_Reference/pre_get_posts -
The
posts_where
filter hook – http://codex.wordpress.org/Plugin_API/Filter_Reference/posts_where