1

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?

  • What exactly do you mean by "add custom field to search result"? Could you add some examples to your question? – Krzysiek Dróżdż 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 – Luk Jul 28 '18 at 16:01
  • How many custom fields do you have? – Krzysiek Dróżdż Jul 28 '18 at 16:02
  • I can explain this in polish if you want - I'm from Poland too – Luk Jul 28 '18 at 16:03
  • Sorry, this is an english site and we speak in english in here, so other people can learn from questions and answers - that's the point... – Krzysiek Dróżdż Jul 28 '18 at 16:04
1

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"

  • One question for sure - Is it secure to use this modified where SQL, without prepared statement or any escaped? – Luk May 29 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 at 9:48

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.