diff options
Diffstat (limited to 'wp-includes/class-wp-query.php')
-rw-r--r-- | wp-includes/class-wp-query.php | 72 |
1 files changed, 64 insertions, 8 deletions
diff --git a/wp-includes/class-wp-query.php b/wp-includes/class-wp-query.php index 66c8280..d25493d 100644 --- a/wp-includes/class-wp-query.php +++ b/wp-includes/class-wp-query.php @@ -2264,6 +2264,9 @@ class WP_Query { $post_type = 'any'; } elseif ( count( $post_type ) === 1 ) { $post_type = $post_type[0]; + } else { + // Sort post types to ensure same cache key generation. + sort( $post_type ); } $post_status_join = true; @@ -2542,6 +2545,8 @@ class WP_Query { $post_type_where = " AND {$wpdb->posts}.post_type IN ('" . implode( "', '", array_map( 'esc_sql', $in_search_post_types ) ) . "')"; } } elseif ( ! empty( $post_type ) && is_array( $post_type ) ) { + // Sort post types to ensure same cache key generation. + sort( $post_type ); $post_type_where = " AND {$wpdb->posts}.post_type IN ('" . implode( "', '", esc_sql( $post_type ) ) . "')"; } elseif ( ! empty( $post_type ) ) { $post_type_where = $wpdb->prepare( " AND {$wpdb->posts}.post_type = %s", $post_type ); @@ -2647,7 +2652,7 @@ class WP_Query { } if ( ! empty( $queried_post_types ) ) { - + sort( $queried_post_types ); $status_type_clauses = array(); foreach ( $queried_post_types as $queried_post_type ) { @@ -3104,14 +3109,24 @@ class WP_Query { $found_rows = 'SQL_CALC_FOUND_ROWS'; } - // Beginning of the string is on a new line to prevent leading whitespace. See https://core.trac.wordpress.org/ticket/56841. + /* + * Beginning of the string is on a new line to prevent leading whitespace. + * + * The additional indentation of subsequent lines is to ensure the SQL + * queries are identical to those generated when splitting queries. This + * improves caching of the query by ensuring the same cache key is + * generated for the same database queries functionally. + * + * See https://core.trac.wordpress.org/ticket/56841. + * See https://github.com/WordPress/wordpress-develop/pull/6393#issuecomment-2088217429 + */ $old_request = "SELECT $found_rows $distinct $fields - FROM {$wpdb->posts} $join - WHERE 1=1 $where - $groupby - $orderby - $limits"; + FROM {$wpdb->posts} $join + WHERE 1=1 $where + $groupby + $orderby + $limits"; $this->request = $old_request; @@ -3298,11 +3313,24 @@ class WP_Query { * complete row at once. One massive result vs. many small results. * * @since 3.4.0 + * @since 6.6.0 Added the `$old_request` and `$clauses` parameters. * * @param bool $split_the_query Whether or not to split the query. * @param WP_Query $query The WP_Query instance. + * @param string $old_request The complete SQL query before filtering. + * @param string[] $clauses { + * Associative array of the clauses for the query. + * + * @type string $where The WHERE clause of the query. + * @type string $groupby The GROUP BY clause of the query. + * @type string $join The JOIN clause of the query. + * @type string $orderby The ORDER BY clause of the query. + * @type string $distinct The DISTINCT clause of the query. + * @type string $fields The SELECT clause of the query. + * @type string $limits The LIMIT clause of the query. + * } */ - $split_the_query = apply_filters( 'split_the_query', $split_the_query, $this ); + $split_the_query = apply_filters( 'split_the_query', $split_the_query, $this, $old_request, compact( $pieces ) ); if ( $split_the_query ) { // First get the IDs and then fill in the objects. @@ -4856,6 +4884,32 @@ class WP_Query { $args['suppress_filters'] ); + if ( empty( $args['post_type'] ) ) { + if ( $this->is_attachment ) { + $args['post_type'] = 'attachment'; + } elseif ( $this->is_page ) { + $args['post_type'] = 'page'; + } else { + $args['post_type'] = 'post'; + } + } elseif ( 'any' === $args['post_type'] ) { + $args['post_type'] = array_values( get_post_types( array( 'exclude_from_search' => false ) ) ); + } + $args['post_type'] = (array) $args['post_type']; + // Sort post types to ensure same cache key generation. + sort( $args['post_type'] ); + + if ( isset( $args['post_status'] ) ) { + $args['post_status'] = (array) $args['post_status']; + // Sort post status to ensure same cache key generation. + sort( $args['post_status'] ); + } + + // Add a default orderby value of date to ensure same cache key generation. + if ( ! isset( $q['orderby'] ) ) { + $args['orderby'] = 'date'; + } + $placeholder = $wpdb->placeholder_escape(); array_walk_recursive( $args, @@ -4874,6 +4928,8 @@ class WP_Query { } ); + ksort( $args ); + // Replace wpdb placeholder in the SQL statement used by the cache key. $sql = $wpdb->remove_placeholder_escape( $sql ); $key = md5( serialize( $args ) . $sql ); |