How to let the Contributor role preview unpublished posts?

Unfortunately, WordPress doesn’t use a separate capability for previewing posts. A user needs the ability to edit a post in order to preview it. As seen in the WP_Query::get_posts() method:

// User must have edit permissions on the draft to preview.
if ( ! current_user_can($edit_cap, $this->posts[0]->ID) ) {
    $this->posts = array();
}

What you could do is use a combination of the posts_results filter (which is applied before unpublished posts are handled) and the the_posts filter (which is applied after), to re-populate the posts array if the user is a Contributor.

Please double-check this for any security implications of allowing lower level users access to preview unpublished content.

Untested example:

class wpse_196050 {

    protected $posts = array();

    public function __construct() {
        add_filter( 'posts_results', array( $this, 'filter_posts_results' ), 10, 2 );
        add_filter( 'the_posts',     array( $this, 'filter_the_posts' ), 10, 2 );
    }

    public function filter_posts_results( array $posts, WP_Query $query ) {
        $this->posts = []; // Reset posts array for each WP_Query instance
        if ( $query->is_preview ) {
            $this->posts = $posts;
        }
        return $posts;
    }

    public function filter_the_posts( array $posts, WP_Query $query ) {
        if ( ! empty( $this->posts ) && current_user_can( 'edit_posts' ) ) {
            $posts = $this->posts;
        }
        return $posts;
    }

}

new wpse_196050;

Leave a Comment