Использование фильтра предварительного получения сообщений для поиска нескольких строк по всем мета-значениям


Использование фильтра pre_get_posts для поиска заданной строки по всем мета_значениям:

$query->set('meta_value', 'first string');

Отладка:

AND ( (CAST(wp_postmeta.meta_value AS CHAR) = 'first string') )

Работает нормально:) но как я могу выполнить поиск по всем мета_значениям массива строк?

Например. Мне нужно что-то вроде:

$query->set('meta_value', array('first string', 'second string'));

AND ( (CAST(wp_postmeta.meta_value AS CHAR) = 'first string') OR (CAST(wp_postmeta.meta_value AS CHAR) = 'second string') )

Это возможно с помощью $query->set('meta_value'... или что-то еще?

Заранее спасибо!

Author: José Pablo Orozco Marín, 2011-12-04

2 answers

Я внес некоторые исправления в этот код, так как он больше не работает.

Следующий код будет искать термины, которые будут ПОХОЖИ на заголовок ИЛИ содержание ИЛИ мета_значение:

function custom_search_where( $where ) {
    if ( is_search() ) {
        global $wpdb;

        // Overwrite the existing WHERE clause.
        $where = '';

        // Store all search terms into array.
        $search_terms = explode( ' ', get_search_query() );

        // Tables names.
        $type       = $wpdb->prefix . "posts.post_type";
        $status     = $wpdb->prefix . "posts.post_status";
        $title      = $wpdb->prefix . "posts.post_title";
        $content    = $wpdb->prefix . "posts.post_content";
        $meta_value = $wpdb->prefix . "postmeta.meta_value";

        foreach ( $search_terms as $term ) {
            $term = trim($term);
            $where .= " AND ( ($title LIKE '%$term%') OR ($content LIKE '%$term%') OR ($meta_value LIKE '%$term%') ) ";
        }

        // As WHERE clause is overwritten, you'll need to specify the post type, the status and/or anything else you need.
        // Post Types.
        $where .= " AND ($type IN ('post', 'page', ... )) ";
        // Post status.
        $where .= " AND ($status = 'publish') ";
    }
    return $where;
}
add_filter('posts_where', 'custom_search_where', 999);

И

function custom_search_join ($join) {
    if( is_search() ) {
        global $wpdb;
        $join .= " INNER JOIN {$wpdb->postmeta} ON ({$wpdb->posts}.ID = {$wpdb->postmeta}.post_id)";
    }
    return $join;
}
add_filter('posts_join', 'custom_search_join' );
 1
Author: Sebastien, 2015-02-06 14:03:45

Да, я понял:

function custom_search_where( $where = '' ) {

    global $wpdb;

    if ( is_search() ) {

        if ( isset($_GET['my-terms']) ) {

            $count = count($_GET['my-terms']);

            if ( $count > 0 ) {

                foreach ( $_GET['my-terms'] as $term ) {

                    // http://codex.wordpress.org/Class_Reference/wpdb

                    $title      = $wpdb->prefix . "posts.post_title";
                    $content    = $wpdb->prefix . "posts.post_content";
                    $meta_value = $wpdb->prefix . "postmeta.meta_value";

                    $term       = trim($term);
                    $my_term    = $wpdb->escape($term);

                    $where .= " AND (($title LIKE '%$my_term%') OR ($content LIKE '%$my_term%') OR (CAST($meta_value AS CHAR) = '$my_term')) ";      

                }

            }

        }

    }

    return $where;

}


add_filter('posts_where', 'custom_search_where', 999);

И:

function custom_search_join ($join) {

    global $wpdb;

    if( is_search() ) {

        $existCustomTerms = false;

        if ( isset($_GET['my-terms']) ) {

            $count = count($_GET['my-terms']);

            if ( $count > 0 ) {

                $join .= "INNER JOIN $table ON ($postID = $postmetaID)";

            }

        }

    }

    return $join;

}


add_filter('posts_join', 'custom_search_join' );
 0
Author: José Pablo Orozco Marín, 2011-12-04 15:12:23