Make WordPress Core


Ignore:
Timestamp:
02/07/2023 08:53:01 AM (21 months ago)
Author:
audrasjb
Message:

Query: Add a search_columns argument to control which fields are searched in a search query.

Previously, the s argument of the WP_Query::parse_query() method searched the post_title, post_excerpt, and post_content fields, with no way of controlling this apart from using the posts_search filter and adjusting the SQL manually. This changeset adds the ability to specify which fields are searched when performing a query, using the search_columns argument.

Props johnbillion, birgire, petitphp, audrasjb, costdev, mukesh27.
Fixes #43867.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/wp-includes/class-wp-query.php

    r55035 r55248  
    611611            'author__in',
    612612            'author__not_in',
     613            'search_columns',
    613614        );
    614615
     
    638639     * @since 5.3.0 Introduced the `$meta_type_key` parameter.
    639640     * @since 6.1.0 Introduced the `$update_menu_item_cache` parameter.
     641     * @since 6.2.0 Introduced the `$search_columns` parameter.
    640642     *
    641643     * @param string|array $query {
     
    751753     *                                                    character used for exclusion can be modified using the
    752754     *                                                    the 'wp_query_search_exclusion_prefix' filter.
     755     *     @type array           $search_columns          Array of column names to be searched. Accepts 'post_title',
     756     *                                                    'post_excerpt' and 'post_content'. Default empty array.
    753757     *     @type int             $second                  Second of the minute. Default empty. Accepts numbers 0-59.
    754758     *     @type bool            $sentence                Whether to search by phrase. Default false.
     
    14111415        $q['search_orderby_title'] = array();
    14121416
     1417        $default_search_columns = array( 'post_title', 'post_excerpt', 'post_content' );
     1418        $search_columns         = ! empty( $q['search_columns'] ) ? $q['search_columns'] : $default_search_columns;
     1419        if ( ! is_array( $search_columns ) ) {
     1420            $search_columns = array( $search_columns );
     1421        }
     1422
     1423        /**
     1424         * Filters the columns to search in a WP_Query search.
     1425         *
     1426         * The supported columns are `post_title`, `post_excerpt` and `post_content`.
     1427         * They are all included by default.
     1428         *
     1429         * @since 6.2.0
     1430         *
     1431         * @param string[] $search_columns Array of column names to be searched.
     1432         * @param string   $search         Text being searched.
     1433         * @param WP_Query $query          The current WP_Query instance.
     1434         */
     1435        $search_columns = (array) apply_filters( 'post_search_columns', $search_columns, $q['s'], $this );
     1436
     1437        // Use only supported search columns.
     1438        $search_columns = array_intersect( $search_columns, $default_search_columns );
     1439        if ( empty( $search_columns ) ) {
     1440            $search_columns = $default_search_columns;
     1441        }
     1442
    14131443        /**
    14141444         * Filters the prefix that indicates that a search term should be excluded from results.
     
    14401470            $like = $n . $wpdb->esc_like( $term ) . $n;
    14411471
     1472            $search_columns_parts = array();
     1473            foreach ( $search_columns as $search_column ) {
     1474                $search_columns_parts[ $search_column ] = $wpdb->prepare( "({$wpdb->posts}.$search_column $like_op %s)", $like );
     1475            }
     1476
    14421477            if ( ! empty( $this->allow_query_attachment_by_filename ) ) {
    1443                 $search .= $wpdb->prepare( "{$searchand}(({$wpdb->posts}.post_title $like_op %s) $andor_op ({$wpdb->posts}.post_excerpt $like_op %s) $andor_op ({$wpdb->posts}.post_content $like_op %s) $andor_op (sq1.meta_value $like_op %s))", $like, $like, $like, $like );
    1444             } else {
    1445                 $search .= $wpdb->prepare( "{$searchand}(({$wpdb->posts}.post_title $like_op %s) $andor_op ({$wpdb->posts}.post_excerpt $like_op %s) $andor_op ({$wpdb->posts}.post_content $like_op %s))", $like, $like, $like );
    1446             }
     1478                $search_columns_parts['attachment'] = $wpdb->prepare( "(sq1.meta_value $like_op %s)", $like );
     1479            }
     1480
     1481            $search .= "$searchand(" . implode( " $andor_op ", $search_columns_parts ) . ')';
     1482
    14471483            $searchand = ' AND ';
    14481484        }
Note: See TracChangeset for help on using the changeset viewer.