WordPress.org

Make WordPress Core

Ticket #48556: 48556.diff

File 48556.diff, 9.2 KB (added by leogermani, 8 months ago)
  • src/wp-includes/class-wp-query.php

    diff --git a/src/wp-includes/class-wp-query.php b/src/wp-includes/class-wp-query.php
    index 9d7d1a5be7..442b19625a 100644
    a b class WP_Query { 
    23962396                if ( 'any' == $post_type ) {
    23972397                        $in_search_post_types = get_post_types( array( 'exclude_from_search' => false ) );
    23982398                        if ( empty( $in_search_post_types ) ) {
    2399                                 $where .= ' AND 1=0 ';
     2399                                $post_type_where = ' AND 1=0 ';
    24002400                        } else {
    2401                                 $where .= " AND {$wpdb->posts}.post_type IN ('" . join( "', '", array_map( 'esc_sql', $in_search_post_types ) ) . "')";
     2401                                $post_type_where = " AND {$wpdb->posts}.post_type IN ('" . join( "', '", array_map( 'esc_sql', $in_search_post_types ) ) . "')";
    24022402                        }
    24032403                } elseif ( ! empty( $post_type ) && is_array( $post_type ) ) {
    2404                         $where .= " AND {$wpdb->posts}.post_type IN ('" . join( "', '", esc_sql( $post_type ) ) . "')";
     2404                        $post_type_where = " AND {$wpdb->posts}.post_type IN ('" . join( "', '", esc_sql( $post_type ) ) . "')";
    24052405                } elseif ( ! empty( $post_type ) ) {
    2406                         $where           .= $wpdb->prepare( " AND {$wpdb->posts}.post_type = %s", $post_type );
     2406                        $post_type_where           = $wpdb->prepare( " AND {$wpdb->posts}.post_type = %s", $post_type );
    24072407                        $post_type_object = get_post_type_object( $post_type );
    24082408                } elseif ( $this->is_attachment ) {
    2409                         $where           .= " AND {$wpdb->posts}.post_type = 'attachment'";
     2409                        $post_type_where           = " AND {$wpdb->posts}.post_type = 'attachment'";
    24102410                        $post_type_object = get_post_type_object( 'attachment' );
    24112411                } elseif ( $this->is_page ) {
    2412                         $where           .= " AND {$wpdb->posts}.post_type = 'page'";
     2412                        $post_type_where           = " AND {$wpdb->posts}.post_type = 'page'";
    24132413                        $post_type_object = get_post_type_object( 'page' );
    24142414                } else {
    2415                         $where           .= " AND {$wpdb->posts}.post_type = 'post'";
     2415                        $post_type_where           = " AND {$wpdb->posts}.post_type = 'post'";
    24162416                        $post_type_object = get_post_type_object( 'post' );
    24172417                }
    24182418
    class WP_Query { 
    24312431
    24322432                $q_status = array();
    24332433                if ( ! empty( $q['post_status'] ) ) {
     2434
     2435                        $where .= $post_type_where;
     2436
    24342437                        $statuswheres = array();
    24352438                        $q_status     = $q['post_status'];
    24362439                        if ( ! is_array( $q_status ) ) {
    class WP_Query { 
    24892492                        if ( ! empty( $where_status ) ) {
    24902493                                $where .= " AND ($where_status)";
    24912494                        }
     2495                } elseif ( ! $this->is_singular && is_user_logged_in() && ( is_array( $post_type ) && sizeof( $post_type ) > 1 || $post_type == 'any' ) ) {
     2496
     2497                        if ( 'any' == $post_type ) {
     2498                                $cpts = get_post_types( array( 'exclude_from_search' => false ) );
     2499                        } else {
     2500                                $cpts = $post_type;
     2501                        }
     2502
     2503                        $statustypeswheres = [];
     2504
     2505                        foreach ($cpts as $ptype) {
     2506
     2507                                $cpt_object = get_post_type_object($ptype);
     2508                                if ( ! $cpt_object instanceof \WP_Post_Type ) {
     2509                                        continue;
     2510                                }
     2511                                //var_dump($cpt_object);
     2512                                $read_private_cap = $cpt_object->cap->read_private_posts;
     2513
     2514                                $typewheres = '(';
     2515
     2516                                        $typewheres .= $wpdb->prepare( "{$wpdb->posts}.post_type = %s AND (", $ptype );
     2517
     2518                                                // public statuses
     2519                                                $public_states = get_post_stati( array( 'public' => true ) );
     2520                                                $statuswheres = [];
     2521                                                foreach ( (array) $public_states as $state ) {
     2522                                                        $statuswheres[] = "{$wpdb->posts}.post_status = '$state'";
     2523                                                }
     2524                                                $typewheres .= implode(' OR ', $statuswheres);
     2525
     2526                                                // private statuses
     2527                                                $private_states = get_post_stati( array( 'private' => true ) );
     2528                                                foreach ( (array) $private_states as $state ) {
     2529                                                        $typewheres .= current_user_can( $read_private_cap ) ? " OR {$wpdb->posts}.post_status = '$state'" : " OR {$wpdb->posts}.post_author = $user_id AND {$wpdb->posts}.post_status = '$state'";
     2530                                                }
     2531
     2532                                        $typewheres .= ')';
     2533
     2534
     2535                                $typewheres .= ')';
     2536
     2537                                $statustypeswheres[] = $typewheres;
     2538
     2539                        }
     2540
     2541                        $where .= ' AND (' . implode(' OR ', $statustypeswheres) . ')';
     2542
    24922543                } elseif ( ! $this->is_singular ) {
     2544
     2545                        $where .= $post_type_where;
     2546
    24932547                        $where .= " AND ({$wpdb->posts}.post_status = 'publish'";
    24942548
    24952549                        // Add public states.
    class WP_Query { 
    25232577                        }
    25242578
    25252579                        $where .= ')';
     2580                } else {
     2581                        $where .= $post_type_where;
    25262582                }
    25272583
    25282584                /*
  • tests/phpunit/tests/post/query.php

    diff --git a/tests/phpunit/tests/post/query.php b/tests/phpunit/tests/post/query.php
    index 4bac94c1bc..da8d193dda 100644
    a b class Tests_Post_Query extends WP_UnitTestCase { 
    721721                $this->assertEquals( $expected, $q->found_posts );
    722722        }
    723723
     724        /**
     725         * @ticket 48556
     726         */
     727        public function test_query_posts_perm_readable_mutliple_post_types_with_private_posts() {
     728                $current_user = get_current_user_id();
     729                wp_set_current_user( self::factory()->user->create( array( 'role' => 'administrator' ) ) );
     730
     731                $public_post = $this->factory->post->create( array( 'post_title' => 'Test Post' ) );
     732                $private_post = $this->factory->post->create( array( 'post_title' => 'Test Post', 'post_status' => 'private' ) );
     733
     734                $public_page = $this->factory->post->create( array(  'post_type' => 'page', 'post_title' => 'Test Page' ) );
     735                $private_page = $this->factory->post->create( array( 'post_type' => 'page', 'post_title' => 'Test Page', 'post_status' => 'private' ) );
     736
     737                $q = new WP_Query(
     738                        array(
     739                                'post_type'      => ['post', 'page']
     740                        )
     741                );
     742
     743                $this->assertEquals(4, $q->found_posts);
     744
     745                wp_set_current_user( $current_user );
     746
     747        }
     748
     749        /**
     750         * @ticket 48556
     751         */
     752        public function test_query_posts_perm_readable_mutliple_post_types_with_private_posts_cpt_any() {
     753                $current_user = get_current_user_id();
     754                wp_set_current_user( self::factory()->user->create( array( 'role' => 'administrator' ) ) );
     755
     756                $public_post = $this->factory->post->create( array( 'post_title' => 'Test Post' ) );
     757                $private_post = $this->factory->post->create( array( 'post_title' => 'Test Post', 'post_status' => 'private' ) );
     758
     759                $public_page = $this->factory->post->create( array(  'post_type' => 'page', 'post_title' => 'Test Page' ) );
     760                $private_page = $this->factory->post->create( array( 'post_type' => 'page', 'post_title' => 'Test Page', 'post_status' => 'private' ) );
     761
     762                $q = new WP_Query(
     763                        array(
     764                                'post_type'      => 'any'
     765                        )
     766                );
     767
     768                $this->assertEquals(4, $q->found_posts);
     769
     770                wp_set_current_user( $current_user );
     771
     772        }
     773
     774        /**
     775         * @ticket 48556
     776         */
     777        public function test_query_posts_perm_readable_mutliple_post_types_with_private_posts_user_permissions() {
     778                global $current_user;
     779                $current_user_id = get_current_user_id();
     780
     781                $public_post = $this->factory->post->create( array( 'post_title' => 'Test Post' ) );
     782                $private_post = $this->factory->post->create( array( 'post_title' => 'Test Post', 'post_status' => 'private' ) );
     783
     784                $public_page = $this->factory->post->create( array(  'post_type' => 'page', 'post_title' => 'Test Page' ) );
     785                $private_page = $this->factory->post->create( array( 'post_type' => 'page', 'post_title' => 'Test Page', 'post_status' => 'private' ) );
     786
     787                $subscriber = self::factory()->user->create( array( 'role' => 'subscriber' ) );
     788                $subscriber_user = get_userdata($subscriber);
     789
     790                wp_set_current_user( $subscriber );
     791
     792                $q = new WP_Query(
     793                        array(
     794                                'post_type'      => ['post', 'page']
     795                        )
     796                );
     797
     798                $this->assertEquals(2, $q->found_posts);
     799
     800                $subscriber_user->add_cap('read_private_posts');
     801                $current_user = $subscriber_user; // ensure new cap is considered
     802
     803                $q = new WP_Query(
     804                        array(
     805                                'post_type'      => ['post', 'page']
     806                        )
     807                );
     808
     809                $this->assertEquals(3, $q->found_posts);
     810
     811                $subscriber_user->add_cap('read_private_pages');
     812                $current_user = $subscriber_user; // ensure new cap is considered
     813
     814                $q = new WP_Query(
     815                        array(
     816                                'post_type'      => ['post', 'page']
     817                        )
     818                );
     819
     820                $this->assertEquals(4, $q->found_posts);
     821
     822                wp_set_current_user( $current_user_id );
     823
     824
     825        }
     826
     827        /**
     828         * @ticket 48556
     829         */
     830        public function test_query_posts_perm_readable_mutliple_post_types_with_private_posts_user_permissions_cpt_any() {
     831                global $current_user;
     832                $current_user_id = get_current_user_id();
     833
     834                $public_post = $this->factory->post->create( array( 'post_title' => 'Test Post' ) );
     835                $private_post = $this->factory->post->create( array( 'post_title' => 'Test Post', 'post_status' => 'private' ) );
     836
     837                $public_page = $this->factory->post->create( array(  'post_type' => 'page', 'post_title' => 'Test Page' ) );
     838                $private_page = $this->factory->post->create( array( 'post_type' => 'page', 'post_title' => 'Test Page', 'post_status' => 'private' ) );
     839
     840                $subscriber = self::factory()->user->create( array( 'role' => 'subscriber' ) );
     841                $subscriber_user = get_userdata($subscriber);
     842
     843                wp_set_current_user( $subscriber );
     844
     845                $q = new WP_Query(
     846                        array(
     847                                'post_type'      => 'any'
     848                        )
     849                );
     850
     851                $this->assertEquals(2, $q->found_posts);
     852
     853                $subscriber_user->add_cap('read_private_posts');
     854                $current_user = $subscriber_user; // ensure new cap is considered
     855
     856                $q = new WP_Query(
     857                        array(
     858                                'post_type'      => 'any'
     859                        )
     860                );
     861
     862                $this->assertEquals(3, $q->found_posts);
     863
     864                $subscriber_user->add_cap('read_private_pages');
     865                $current_user = $subscriber_user; // ensure new cap is considered
     866
     867                $q = new WP_Query(
     868                        array(
     869                                'post_type'      => 'any'
     870                        )
     871                );
     872
     873                $this->assertEquals(4, $q->found_posts);
     874
     875                wp_set_current_user( $current_user_id );
     876
     877
     878        }
     879
    724880}