0

I need to allow Subscribers to edit their posts (done) and read (see in backend) posts of specific author or with specific ID (to make copies of it). I found the code, but that's not enough:

function posts_for_current_author ($query) {
        if( $query->is_admin && 'edit.php' == $GLOBALS['pagenow'] && !current_user_can( 'edit_others_posts' ) ) {
            $query->set('author', $GLOBALS['user_ID'] );
        }
        return $query;
    };
    add_filter('pre_get_posts', 'posts_for_current_author');
0

To query posts with more than one author ID, you can use author__in parameter. This makes posts from chosen authors visible (read only) for the current user.

add_filter('pre_get_posts', 'posts_for_current_author');
function posts_for_current_author($query) {
    if (
        $query->is_admin &&
        'edit.php' === $GLOBALS['pagenow'] &&
        ! current_user_can( 'edit_others_posts' )
    ) {
        $query->set('author__in', array(get_current_user_id(), 1, 2, 3) ); // add 1 or more user IDs
    }
    return $query;
};

One option query posts with multiple author IDs and post IDs is to manipulate the where clause with posts_where filter. I picked idea for this from an old WPSE Q&A. This makes posts from chosen authors and chosen posts visible (read only) to the current user.

With this you can do OR comparison instead of AND, which using both author__in and post__in in pre_get_posts would cause. (At least based on the test I ran locally)

add_filter( 'posts_where', 'wpse_posts_where' );
function wpse_posts_where( $where ) {
    if (
        is_admin() &&
        'edit.php' === $GLOBALS['pagenow'] &&
        ! current_user_can( 'edit_others_posts' )
    ) {
        remove_filter( current_filter(), __FUNCTION__ );
        global $wpdb;

        $current_user_id = get_current_user_id();
        $authors = array(
            $current_user_id,
            1,
            2,
            3,
        );

        $posts = array(
            1,
            2,
            3,
        );

        return str_ireplace(
            "{$wpdb->posts}.post_author in ({$current_user_id})",
            sprintf(
                "({$wpdb->posts}.post_author in (%s) OR {$wpdb->posts}.ID in (%s))",
                implode(',', $authors),
                implode(',', $posts)
            ),
            $where
        );
    } else {
        return $where;
    }
}
2
  • It worked perfectly! Thank you! I guess with pages is the same, just change post to pages? – Juliana Jul Jul 24 '20 at 20:17
  • @JulianaJul Yes, I think that just changing the post IDs to page IDs should be enough. – Antti Koskinen Jul 24 '20 at 20:19

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.