diff --git src/wp-includes/query.php src/wp-includes/query.php
index 02bfba7..660cae4 100644
|
|
class WP_Query { |
3548 | 3548 | $this->request = apply_filters_ref_array( 'posts_request', array( $this->request, &$this ) ); |
3549 | 3549 | } |
3550 | 3550 | |
| 3551 | /** |
| 3552 | * Filter the posts array before the query takes place. |
| 3553 | * |
| 3554 | * Return a non-null value to bypass WordPress's default post queries. |
| 3555 | * |
| 3556 | * @since 4.6.0 |
| 3557 | * |
| 3558 | * @param array|null $posts Return an array of post data to short-circuit WP's query, |
| 3559 | * or null to allow WP to run its normal queries. |
| 3560 | * @param WP_Query $this The WP_Query instance, passed by reference. |
| 3561 | */ |
| 3562 | $this->posts = apply_filters_ref_array( 'posts_pre_query', array( null, &$this ) ); |
| 3563 | |
3551 | 3564 | if ( 'ids' == $q['fields'] ) { |
3552 | | $this->posts = $wpdb->get_col( $this->request ); |
| 3565 | if ( null === $this->posts ) { |
| 3566 | $this->posts = $wpdb->get_col( $this->request ); |
| 3567 | } |
| 3568 | |
3553 | 3569 | $this->posts = array_map( 'intval', $this->posts ); |
3554 | 3570 | $this->post_count = count( $this->posts ); |
3555 | 3571 | $this->set_found_posts( $q, $limits ); |
… |
… |
class WP_Query { |
3558 | 3574 | } |
3559 | 3575 | |
3560 | 3576 | if ( 'id=>parent' == $q['fields'] ) { |
3561 | | $this->posts = $wpdb->get_results( $this->request ); |
| 3577 | if ( null === $this->posts ) { |
| 3578 | $this->posts = $wpdb->get_results( $this->request ); |
| 3579 | } |
| 3580 | |
3562 | 3581 | $this->post_count = count( $this->posts ); |
3563 | 3582 | $this->set_found_posts( $q, $limits ); |
3564 | 3583 | |
… |
… |
class WP_Query { |
3573 | 3592 | return $r; |
3574 | 3593 | } |
3575 | 3594 | |
3576 | | $split_the_query = ( $old_request == $this->request && "$wpdb->posts.*" == $fields && !empty( $limits ) && $q['posts_per_page'] < 500 ); |
3577 | | |
3578 | | /** |
3579 | | * Filter whether to split the query. |
3580 | | * |
3581 | | * Splitting the query will cause it to fetch just the IDs of the found posts |
3582 | | * (and then individually fetch each post by ID), rather than fetching every |
3583 | | * complete row at once. One massive result vs. many small results. |
3584 | | * |
3585 | | * @since 3.4.0 |
3586 | | * |
3587 | | * @param bool $split_the_query Whether or not to split the query. |
3588 | | * @param WP_Query $this The WP_Query instance. |
3589 | | */ |
3590 | | $split_the_query = apply_filters( 'split_the_query', $split_the_query, $this ); |
3591 | | |
3592 | | if ( $split_the_query ) { |
3593 | | // First get the IDs and then fill in the objects |
3594 | | |
3595 | | $this->request = "SELECT $found_rows $distinct $wpdb->posts.ID FROM $wpdb->posts $join WHERE 1=1 $where $groupby $orderby $limits"; |
| 3595 | if ( null === $this->posts ) { |
| 3596 | $split_the_query = ( $old_request == $this->request && "$wpdb->posts.*" == $fields && !empty( $limits ) && $q['posts_per_page'] < 500 ); |
3596 | 3597 | |
3597 | 3598 | /** |
3598 | | * Filter the Post IDs SQL request before sending. |
| 3599 | * Filter whether to split the query. |
| 3600 | * |
| 3601 | * Splitting the query will cause it to fetch just the IDs of the found posts |
| 3602 | * (and then individually fetch each post by ID), rather than fetching every |
| 3603 | * complete row at once. One massive result vs. many small results. |
3599 | 3604 | * |
3600 | 3605 | * @since 3.4.0 |
3601 | 3606 | * |
3602 | | * @param string $request The post ID request. |
3603 | | * @param WP_Query $this The WP_Query instance. |
| 3607 | * @param bool $split_the_query Whether or not to split the query. |
| 3608 | * @param WP_Query $this The WP_Query instance. |
3604 | 3609 | */ |
3605 | | $this->request = apply_filters( 'posts_request_ids', $this->request, $this ); |
| 3610 | $split_the_query = apply_filters( 'split_the_query', $split_the_query, $this ); |
| 3611 | |
| 3612 | if ( $split_the_query ) { |
| 3613 | // First get the IDs and then fill in the objects |
| 3614 | |
| 3615 | $this->request = "SELECT $found_rows $distinct $wpdb->posts.ID FROM $wpdb->posts $join WHERE 1=1 $where $groupby $orderby $limits"; |
| 3616 | |
| 3617 | /** |
| 3618 | * Filter the Post IDs SQL request before sending. |
| 3619 | * |
| 3620 | * @since 3.4.0 |
| 3621 | * |
| 3622 | * @param string $request The post ID request. |
| 3623 | * @param WP_Query $this The WP_Query instance. |
| 3624 | */ |
| 3625 | $this->request = apply_filters( 'posts_request_ids', $this->request, $this ); |
3606 | 3626 | |
3607 | | $ids = $wpdb->get_col( $this->request ); |
| 3627 | $ids = $wpdb->get_col( $this->request ); |
3608 | 3628 | |
3609 | | if ( $ids ) { |
3610 | | $this->posts = $ids; |
3611 | | $this->set_found_posts( $q, $limits ); |
3612 | | _prime_post_caches( $ids, $q['update_post_term_cache'], $q['update_post_meta_cache'] ); |
| 3629 | if ( $ids ) { |
| 3630 | $this->posts = $ids; |
| 3631 | _prime_post_caches( $ids, $q['update_post_term_cache'], $q['update_post_meta_cache'] ); |
| 3632 | } else { |
| 3633 | $this->posts = array(); |
| 3634 | } |
3613 | 3635 | } else { |
3614 | | $this->posts = array(); |
| 3636 | $this->posts = $wpdb->get_results( $this->request ); |
3615 | 3637 | } |
3616 | | } else { |
3617 | | $this->posts = $wpdb->get_results( $this->request ); |
3618 | | $this->set_found_posts( $q, $limits ); |
3619 | 3638 | } |
3620 | 3639 | |
3621 | | // Convert to WP_Post objects |
3622 | | if ( $this->posts ) |
| 3640 | // Convert to WP_Post objects. |
| 3641 | if ( $this->posts ) { |
| 3642 | $this->set_found_posts( $q, $limits ); |
3623 | 3643 | $this->posts = array_map( 'get_post', $this->posts ); |
| 3644 | } |
3624 | 3645 | |
3625 | 3646 | if ( ! $q['suppress_filters'] ) { |
3626 | 3647 | /** |
diff --git tests/phpunit/tests/post/query.php tests/phpunit/tests/post/query.php
index acc8e4e..551dc1e 100644
|
|
class Tests_Post_Query extends WP_UnitTestCase { |
388 | 388 | $actual_posts = $q->get_posts(); |
389 | 389 | $this->assertEqualSets( $requested, $actual_posts ); |
390 | 390 | } |
| 391 | |
| 392 | /** |
| 393 | * @ticket 36687 |
| 394 | */ |
| 395 | public function test_posts_pre_query_filter_should_bypass_database_query() { |
| 396 | global $wpdb; |
| 397 | |
| 398 | add_filter( 'posts_pre_query', array( __CLASS__, 'filter_posts_pre_query' ) ); |
| 399 | |
| 400 | $num_queries = $wpdb->num_queries; |
| 401 | $q = new WP_Query( array( |
| 402 | 'fields' => 'ids', |
| 403 | 'no_found_rows' => true, |
| 404 | ) ); |
| 405 | |
| 406 | remove_filter( 'posts_pre_query', array( __CLASS__, 'filter_posts_pre_query' ) ); |
| 407 | |
| 408 | $this->assertSame( $num_queries, $wpdb->num_queries ); |
| 409 | $this->assertSame( array( 12345 ), $q->posts ); |
| 410 | } |
| 411 | |
| 412 | public static function filter_posts_pre_query( $posts ) { |
| 413 | return array( 12345 ); |
| 414 | } |
391 | 415 | } |