3

I need to add custom field to wordpress search result.

This what i tried to do is used pre_get_posts filter, like this:

function search_filter( $query ) {

    $key_fields = array ( 'buty' );
    $value_field = $query->query_vars['s'];
    $query->query_vars['s'] = '';

    if ( $value_field != '' ) {

        $filter_query = array( 'relation' => 'OR' );

        foreach ( $key_fields as $one_field ) {
            array_push ( $filter_query , array (
                'key' => $one_field,
                'value' => $value_field,
                'compare' => 'LIKE'
            ) );
        }
        $query->set( 'meta_query' , $filter_query );

    }

}
add_filter( 'pre_get_posts' , 'search_filter');

It works, but now search not working for post title and post content

So the question is: how to properly add custom field to Wordpress search result without lose standard functionality?

4
  • What exactly do you mean by "add custom field to search result"? Could you add some examples to your question? Jul 28 '18 at 15:55
  • Of course - for example i have custom field with key 'Shoes' and value is 'Adidas'. Now i would like type in website search form 'Adidas' and in the search results I would like to see posts that contain this field
    – kanlukasz
    Jul 28 '18 at 16:01
  • How many custom fields do you have? Jul 28 '18 at 16:02
  • Let us assume that I only have one field
    – kanlukasz
    May 21 '21 at 8:34
3

Wordpress search in posts table. You must change the search query by adding a postmeta table (with LEFT JOIN) and then add your own conditions to WHERE clause.

<?php
/**
 * Extend WordPress search to include custom fields
 *
 * https://adambalee.com
 */

/**
 * Join posts and postmeta tables
 *
 * http://codex.wordpress.org/Plugin_API/Filter_Reference/posts_join
 */
function cf_search_join( $join ) {
    global $wpdb;

    if ( is_search() ) {    
        $join .=' LEFT JOIN '.$wpdb->postmeta. ' ON '. $wpdb->posts . '.ID = ' . $wpdb->postmeta . '.post_id ';
    }
    return $join;
}
add_filter('posts_join', 'cf_search_join' );

/**
 * Modify the search query with posts_where
 *
 * http://codex.wordpress.org/Plugin_API/Filter_Reference/posts_where
 */
function cf_search_where( $where ) {
    global $pagenow, $wpdb;

    $key_fields = array ( 'buty' );
    if ( is_search() ) 
        $where = preg_replace(
            "/\(\s*".$wpdb->posts.".post_title\s+LIKE\s*(\'[^\']+\')\s*\)/",
            "(".$wpdb->posts.".post_title LIKE $1) OR ("
                 .$wpdb->postmeta. ".meta_value LIKE $1 AND "
                 .$wpdb->postmeta. ".meta_key IN ('" .implode("','", $key_fields). "') )", $where );
    }

    return $where;
}
add_filter( 'posts_where', 'cf_search_where' );

/**
 * Prevent duplicates
 *
 * http://codex.wordpress.org/Plugin_API/Filter_Reference/posts_distinct
 */
function cf_search_distinct( $where ) {
    global $wpdb;

    if ( is_search() ) {
        return "DISTINCT";
    }

    return $where;
}
add_filter( 'posts_distinct', 'cf_search_distinct' );

Details can be found here "Search WordPress by Custom Fields without a Plugin"

4
  • One question for sure - Is it secure to use this modified where SQL, without prepared statement or any escaped?
    – kanlukasz
    May 29 '19 at 9:12
  • 1
    $where SQL was prepared earlier, here you only copy part of it (after LIKE) and use it with another column. The only new thing added to the query are values from $key_fields. In this case, there is no need to escape these values, because they are known to you and do not change. If, for example, the value of the $key_fields would be the result of the function or it would be passed to the filter (apply_filters), then it would be good to use $wpdb->prepare() to secure the SQL statement.
    – nmr
    May 29 '19 at 9:48
  • This doesn't seem to work in current WordPress @nmr, any chance of revising ?
    – AdamJones
    Dec 12 '19 at 13:29
  • @AdamJones I just checked the above code in WordPress v4.8, v5.2, v5.3 and it worked with each of them. Maybe it works differently than you expected with a multi-word search phrase.
    – nmr
    Dec 13 '19 at 23:10

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.