Добавление поиска по метаполям в WordPress: руководство.

Добавление поиска по метаполям в стандартный поиск WordPress

Стандартный поиск WordPress ищет указанный текст в заголовке, содержании и отрывке записи (в полях post_title, post_content, post_excerpt). В этой статье мы рассмотрим, как добавить поиск по указанным метаполям в стандартный поиск записей.

Как это работает: использование хука posts_clauses

Давайте начнём с добавления функциональности поиска по метаполям с помощью хука posts_clauses.

Код для добавления поиска по метаполям

add_filter( 'posts_clauses', 'km_metadata_search' );

function km_metadata_search( $clauses ) {
    global $wpdb;

    // Проверяем, что это поиск и основной запрос
    if ( ! is_search() || ! is_main_query() ) {
        return $clauses;
    }

    // Объединяем таблицы записей и метаданных
    $clauses['join'] .= " LEFT JOIN $wpdb->postmeta kmpm ON (ID = kmpm.post_id)";

    // Добавляем условие для поиска в метаполе
    $clauses['where'] = preg_replace(
        "/OR +( *$wpdb->posts.post_content +LIKE +('[^']+')/",
        "OR (kmpm.meta_value LIKE $1) $0",
        $clauses['where']
    );

    // Убираем дубликаты
    $clauses['distinct'] = 'DISTINCT';

    return $clauses;
}

Что делает этот код

  1. Добавление таблицы метаданных к запросу (JOIN):

    • Мы расширяем базовую таблицу записей, добавляя к ней таблицу метаданных. Это нужно, чтобы указать, по какому полю в таблице метаданных мы будем искать.
  2. Модификация условий запроса (WHERE):

    • Мы добавляем условие в секцию WHERE, чтобы стандартный поиск также искал в всех полях метаданных постов.
  3. Избежание дубликатов (DISTINCT):

    • При LEFT JOIN могут появляться дубликаты. Мы используем DISTINCT, чтобы избавиться от них.

Альтернативный способ: использование хуков posts_join, posts_where и posts_distinct

Еще один способ добавить поиск по метаполям — использовать разные хуки.

Код для альтернативного метода

add_filter( 'posts_join', 'cf_search_join' );
add_filter( 'posts_where', 'cf_search_where' );
add_filter( 'posts_distinct', 'cf_search_distinct' );

function cf_search_join( $join ) {
    global $wpdb;

    // Присоединяем таблицу метаданных
    if ( is_search() ) {
        $join .= " LEFT JOIN $wpdb->postmeta ON ID = $wpdb->postmeta.post_id ";
    }

    return $join;
}

function cf_search_where( $where ) {
    global $wpdb;

    // Уточняем условия поиска по метаполям и значениям
    if ( is_search() ) {
        $where = preg_replace(
            "/(s*$wpdb->posts.post_titles+LIKEs*('[^']+')s*)/",
            "($wpdb->posts.post_title LIKE $1) OR ($wpdb->postmeta.meta_value LIKE $1)", 
            $where 
        );
    }

    return $where;
}

function cf_search_distinct( $where ) {
    return is_search() ? 'DISTINCT' : $where;
}

Важные моменты

  • Функции не будут работать, если в запросе включен параметр suppress_filters.
  • Также данный код не сработает для функции get_posts(), так как этот параметр включен по умолчанию.

Заключение

Теперь вы знаете, как добавить функциональность поиска по метаполям в стандартный поиск WordPress. Это полезно, если вам нужно, чтобы пользователи могли находить записи не только по заголовкам и содержимому, но и по дополнительной информации, которую вы храните в метаполях.

Leave a Reply

Ваш адрес email не будет опубликован. Обязательные поля помечены *