Make WordPress Core

Changeset 31302


Ignore:
Timestamp:
01/30/2015 02:19:46 AM (10 years ago)
Author:
boonebgorges
Message:

In get_adjacent_post(), return private post if the current user has the capacity to read it.

This mirrors the check that happens post-query in WP_Query. See #30911.

Props bswatson.
Fixes #30287.

Location:
trunk
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/wp-includes/link-template.php

    r31219 r31302  
    15221522    }
    15231523
     1524    // 'post_status' clause depends on the current user.
     1525    if ( is_user_logged_in() ) {
     1526        $user_id = get_current_user_id();
     1527
     1528        $post_type_object = get_post_type_object( $post->post_type );
     1529        if ( empty( $post_type_object ) ) {
     1530            $post_type_cap    = $post->post_type;
     1531            $read_private_cap = 'read_private_' . $post_type_cap . 's';
     1532        } else {
     1533            $read_private_cap = $post_type_object->cap->read_private_posts;
     1534        }
     1535
     1536        /*
     1537         * Results should include private posts belonging to the current user, or private posts where the
     1538         * current user has the 'read_private_posts' cap.
     1539         */
     1540        $private_states = get_post_stati( array( 'private' => true ) );
     1541        $where .= " AND ( p.post_status = 'publish'";
     1542        foreach ( (array) $private_states as $state ) {
     1543            if ( current_user_can( $read_private_cap ) ) {
     1544                $where .= $wpdb->prepare( " OR p.post_status = %s", $state );
     1545            } else {
     1546                $where .= $wpdb->prepare( " OR (p.post_author = %d AND p.post_status = %s)", $user_id, $state );
     1547            }
     1548        }
     1549        $where .= " )";
     1550    } else {
     1551        $where .= " AND p.post_status = 'publish'";
     1552    }
     1553
    15241554    $adjacent = $previous ? 'previous' : 'next';
    15251555    $op = $previous ? '<' : '>';
     
    15521582     * @param array  $excluded_terms Array of excluded term IDs.
    15531583     */
    1554     $where = apply_filters( "get_{$adjacent}_post_where", $wpdb->prepare( "WHERE p.post_date $op %s AND p.post_type = %s AND p.post_status = 'publish' $where", $current_post_date, $post->post_type ), $in_same_term, $excluded_terms );
     1584    $where = apply_filters( "get_{$adjacent}_post_where", $wpdb->prepare( "WHERE p.post_date $op %s AND p.post_type = %s $where", $current_post_date, $post->post_type ), $in_same_term, $excluded_terms );
    15551585
    15561586    /**
  • trunk/tests/phpunit/tests/url.php

    r28609 r31302  
    280280    }
    281281
    282     function test_get_adjacent_post() {
    283         $post_id = $this->factory->post->create();
    284         sleep( 1 ); // get_adjacent_post() doesn't handle posts created in the same second.
    285         $post_id2 = $this->factory->post->create();
     282    public function test_get_adjacent_post() {
     283        $now = time();
     284        $post_id = $this->factory->post->create( array( 'post_date' => date( 'Y-m-d H:i:s', $now - 1 ) ) );
     285        $post_id2 = $this->factory->post->create( array( 'post_date' => date( 'Y-m-d H:i:s', $now ) ) );
    286286
    287287        if ( ! isset( $GLOBALS['post'] ) )
     
    307307
    308308        $GLOBALS['post'] = $orig_post;
    309 
    310         // Tests requiring creating more posts can't be run since the query
    311         // cache in get_adjacent_post() requires a fresh page load to invalidate.
     309    }
     310
     311    /**
     312     * Test get_adjacent_post returns the next private post when the author is the currently logged in user.
     313     *
     314     * @ticket 30287
     315     */
     316    public function test_get_adjacent_post_should_return_private_posts_belonging_to_the_current_user() {
     317        $u = $this->factory->user->create( array( 'role' => 'author' ) );
     318        $old_uid = get_current_user_id();
     319        wp_set_current_user( $u );
     320
     321        $now = time();
     322        $p1 = $this->factory->post->create( array( 'post_author' => $u, 'post_status' => 'private', 'post_date' => date( 'Y-m-d H:i:s', $now - 1 ) ) );
     323        $p2 = $this->factory->post->create( array( 'post_author' => $u, 'post_date' => date( 'Y-m-d H:i:s', $now ) ) );
     324
     325        if ( ! isset( $GLOBALS['post'] ) ) {
     326            $GLOBALS['post'] = null;
     327        }
     328        $orig_post = $GLOBALS['post'];
     329
     330        $GLOBALS['post'] = get_post( $p2 );
     331
     332        $p = get_adjacent_post();
     333        $this->assertEquals( $p1, $p->ID );
     334
     335        $GLOBALS['post'] = $orig_post;
     336        wp_set_current_user( $old_uid );
     337    }
     338
     339    /**
     340     * @ticket 30287
     341     */
     342    public function test_get_adjacent_post_should_return_private_posts_belonging_to_other_users_if_the_current_user_can_read_private_posts() {
     343        $u1 = $this->factory->user->create( array( 'role' => 'author' ) );
     344        $u2 = $this->factory->user->create( array( 'role' => 'administrator' ) );
     345        $old_uid = get_current_user_id();
     346        wp_set_current_user( $u2 );
     347
     348        $now = time();
     349        $p1 = $this->factory->post->create( array( 'post_author' => $u1, 'post_status' => 'private', 'post_date' => date( 'Y-m-d H:i:s', $now - 1 ) ) );
     350        $p2 = $this->factory->post->create( array( 'post_author' => $u1, 'post_date' => date( 'Y-m-d H:i:s', $now ) ) );
     351
     352        if ( ! isset( $GLOBALS['post'] ) ) {
     353            $GLOBALS['post'] = null;
     354        }
     355        $orig_post = $GLOBALS['post'];
     356
     357        $GLOBALS['post'] = get_post( $p2 );
     358
     359        $p = get_adjacent_post();
     360        $this->assertEquals( $p1, $p->ID );
     361
     362        $GLOBALS['post'] = $orig_post;
     363        wp_set_current_user( $old_uid );
     364    }
     365
     366    /**
     367     * @ticket 30287
     368     */
     369    public function test_get_adjacent_post_should_not_return_private_posts_belonging_to_other_users_if_the_current_user_cannot_read_private_posts() {
     370        $u1 = $this->factory->user->create( array( 'role' => 'author' ) );
     371        $u2 = $this->factory->user->create( array( 'role' => 'author' ) );
     372        $old_uid = get_current_user_id();
     373        wp_set_current_user( $u2 );
     374
     375        $now = time();
     376        $p1 = $this->factory->post->create( array( 'post_author' => $u1, 'post_date' => date( 'Y-m-d H:i:s', $now - 2 ) ) );
     377        $p2 = $this->factory->post->create( array( 'post_author' => $u1, 'post_status' => 'private', 'post_date' => date( 'Y-m-d H:i:s', $now - 1 ) ) );
     378        $p3 = $this->factory->post->create( array( 'post_author' => $u1, 'post_date' => date( 'Y-m-d H:i:s', $now ) ) );
     379
     380        if ( ! isset( $GLOBALS['post'] ) ) {
     381            $GLOBALS['post'] = null;
     382        }
     383        $orig_post = $GLOBALS['post'];
     384
     385        $GLOBALS['post'] = get_post( $p3 );
     386
     387        $p = get_adjacent_post();
     388        $this->assertEquals( $p1, $p->ID );
     389
     390        $GLOBALS['post'] = $orig_post;
     391        wp_set_current_user( $old_uid );
    312392    }
    313393
Note: See TracChangeset for help on using the changeset viewer.