Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 31 additions & 15 deletions src/wp-includes/canonical.php
Original file line number Diff line number Diff line change
Expand Up @@ -919,13 +919,9 @@ function strip_fragment_from_url( $url ) {
*
* @since 2.3.0
*
* @global wpdb $wpdb WordPress database abstraction object.
*
* @return string|false The correct URL if one is found. False on failure.
*/
function redirect_guess_404_permalink() {
global $wpdb;

/**
* Filters whether to attempt to guess a redirect URL for a 404 request.
*
Expand Down Expand Up @@ -972,10 +968,24 @@ function redirect_guess_404_permalink() {
*/
$strict_guess = apply_filters( 'strict_redirect_guess_404_permalink', false );

$query_args = array(
'post_status' => $publicly_viewable_statuses,
'posts_per_page' => 1,
'no_found_rows' => true,
'ignore_sticky_posts' => true,
'update_post_meta_cache' => false,
'update_post_term_cache' => false,
'fields' => 'ids',
'orderby' => 'none',
);

// Handle strict vs. loose post_name matching.
if ( $strict_guess ) {
$where = $wpdb->prepare( 'post_name = %s', get_query_var( 'name' ) );
$query_args['name'] = get_query_var( 'name' );
} else {
$where = $wpdb->prepare( 'post_name LIKE %s', $wpdb->esc_like( get_query_var( 'name' ) ) . '%' );
$query_args['s'] = get_query_var( 'name' );
$query_args['search_columns'] = array( 'post_name' );
$query_args['starts_with'] = true;
}

// If any of post_type, year, monthnum, or day are set, use them to refine the query.
Expand All @@ -985,34 +995,40 @@ function redirect_guess_404_permalink() {
if ( empty( $post_types ) ) {
return false;
}
$where .= " AND post_type IN ('" . join( "', '", esc_sql( get_query_var( 'post_type' ) ) ) . "')";
$query_args['post_type'] = $post_types;
} else {
if ( ! in_array( get_query_var( 'post_type' ), $publicly_viewable_post_types, true ) ) {
return false;
}
$where .= $wpdb->prepare( ' AND post_type = %s', get_query_var( 'post_type' ) );
$query_args['post_type'] = get_query_var( 'post_type' );
}
} else {
$where .= " AND post_type IN ('" . implode( "', '", esc_sql( $publicly_viewable_post_types ) ) . "')";
$query_args['post_type'] = $publicly_viewable_post_types;
}

// Handle date queries.
$date_query = array();
if ( get_query_var( 'year' ) ) {
$where .= $wpdb->prepare( ' AND YEAR(post_date) = %d', get_query_var( 'year' ) );
$date_query['year'] = get_query_var( 'year' );
}
if ( get_query_var( 'monthnum' ) ) {
$where .= $wpdb->prepare( ' AND MONTH(post_date) = %d', get_query_var( 'monthnum' ) );
$date_query['month'] = get_query_var( 'monthnum' );
}
if ( get_query_var( 'day' ) ) {
$where .= $wpdb->prepare( ' AND DAYOFMONTH(post_date) = %d', get_query_var( 'day' ) );
$date_query['day'] = get_query_var( 'day' );
}
if ( ! empty( $date_query ) ) {
$query_args['date_query'] = array( $date_query );
}

// phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared
$post_id = $wpdb->get_var( "SELECT ID FROM $wpdb->posts WHERE $where AND post_status IN ('" . implode( "', '", esc_sql( $publicly_viewable_statuses ) ) . "')" );
$query = new WP_Query( $query_args );

if ( ! $post_id ) {
if ( empty( $query->posts ) ) {
return false;
}

$post_id = $query->posts[0];

if ( get_query_var( 'feed' ) ) {
return get_post_comments_feed_link( $post_id, get_query_var( 'feed' ) );
} elseif ( get_query_var( 'page' ) > 1 ) {
Expand Down
28 changes: 19 additions & 9 deletions src/wp-includes/class-wp-query.php
Original file line number Diff line number Diff line change
Expand Up @@ -660,6 +660,7 @@ public function fill_query_vars( $query_vars ) {
* @since 5.3.0 Introduced the `$meta_type_key` parameter.
* @since 6.1.0 Introduced the `$update_menu_item_cache` parameter.
* @since 6.2.0 Introduced the `$search_columns` parameter.
* @since 7.0.0 Introduced the `$starts_with` parameter.
*
* @param string|array $query {
* Optional. Array or string of Query parameters.
Expand All @@ -686,6 +687,7 @@ public function fill_query_vars( $query_vars ) {
* See WP_Date_Query::__construct().
* @type int $day Day of the month. Default empty. Accepts numbers 1-31.
* @type bool $exact Whether to search by exact keyword. Default false.
* @type bool $starts_with Whether to search start with keyword. Default false.
* @type string $fields Post fields to query for. Accepts:
* - '' Returns an array of complete post objects (`WP_Post[]`).
* - 'ids' Returns an array of post IDs (`int[]`).
Expand Down Expand Up @@ -774,7 +776,7 @@ public function fill_query_vars( $query_vars ) {
* character used for exclusion can be modified using the
* the 'wp_query_search_exclusion_prefix' filter.
* @type string[] $search_columns Array of column names to be searched. Accepts 'post_title',
* 'post_excerpt' and 'post_content'. Default empty array.
* 'post_excerpt', 'post_content' and 'post_name'. Default empty array.
* @type int $second Second of the minute. Default empty. Accepts numbers 0-59.
* @type bool $sentence Whether to search by phrase. Default false.
* @type bool $suppress_filters Whether to suppress filters. Default false.
Expand Down Expand Up @@ -1448,12 +1450,22 @@ protected function parse_search( &$query_vars ) {
}
}

$n = ! empty( $query_vars['exact'] ) ? '' : '%';
$start = '%';
$end = '%';
if ( ! empty( $query_vars['exact'] ) ) {
$start = '';
$end = '';
} elseif ( ! empty( $query_vars['starts_with'] ) ) {
$start = '';
}

$searchand = '';
$query_vars['search_orderby_title'] = array();

$default_search_columns = array( 'post_title', 'post_excerpt', 'post_content' );
$search_columns = ! empty( $query_vars['search_columns'] ) ? $query_vars['search_columns'] : $default_search_columns;
$default_search_columns = array( 'post_title', 'post_excerpt', 'post_content' );
$allowed_search_columns = $default_search_columns;
$allowed_search_columns[] = 'post_name';
$search_columns = ! empty( $query_vars['search_columns'] ) ? $query_vars['search_columns'] : $default_search_columns;
if ( ! is_array( $search_columns ) ) {
$search_columns = array( $search_columns );
}
Expand All @@ -1473,7 +1485,7 @@ protected function parse_search( &$query_vars ) {
$search_columns = (array) apply_filters( 'post_search_columns', $search_columns, $query_vars['s'], $this );

// Use only supported search columns.
$search_columns = array_intersect( $search_columns, $default_search_columns );
$search_columns = array_intersect( $search_columns, $allowed_search_columns );
if ( empty( $search_columns ) ) {
$search_columns = $default_search_columns;
}
Expand All @@ -1500,13 +1512,11 @@ protected function parse_search( &$query_vars ) {
$andor_op = 'OR';
}

if ( $n && ! $exclude ) {
$like = '%' . $wpdb->esc_like( $term ) . '%';
$like = $start . $wpdb->esc_like( $term ) . $end;
if ( $end && ! $exclude ) {
$query_vars['search_orderby_title'][] = $wpdb->prepare( "{$wpdb->posts}.post_title LIKE %s", $like );
}

$like = $n . $wpdb->esc_like( $term ) . $n;

$search_columns_parts = array();
foreach ( $search_columns as $search_column ) {
$search_columns_parts[ $search_column ] = $wpdb->prepare( "({$wpdb->posts}.$search_column $like_op %s)", $like );
Expand Down
Loading