Добавить поиск по собственным полям в WordPress
Пользовательские поля в WordPress очень удобный инструмент для работы с данными, их можно добавить с помощью плагина или в ручную.
Есть одна проблема при использовании кастомных полей, по ним не возможен поиск с помощью стандартного функционала WordPress.
Для исправления этого мы изменим поисковый запрос, добавив в него пользовательские поля.
В этой статье мы добавляем пользовательские поля к товарам на Woocommerce.
В примере ниже мы не будем использовать плагины, а просто добавим определенный код к functions.php. Это решение я подсмотрел у Adam Balée.
Связываем таблицы
Данные пользовательских полей в базе данных храниться в таблице postmeta
. Но функция поиска WordPress по умолчанию настроена только на поиск в таблице posts
. Нам необходимо включить данные пользовательских полей в поиск, для этого свяжем таблицы posts и postmeta для этого используем фильтр posts_join:
add_filter('posts_join', 'custom_fields_search_join' );
function custom_fields_search_join( $join ) {
global $wpdb;
if ( is_search() ) {
$join .=' LEFT JOIN '.$wpdb->postmeta. ' ON '. $wpdb->posts . '.ID = ' . $wpdb->postmeta . '.post_id ';
}
return $join;
}
Изменяем поисковый запрос WordPress
Далее, чтобы включить наши собственные поля в поисковый запрос, нам нужно его изменить. Для этого воспользуемся фильтром posts_where который позволяет изменять запросы и создавать свои произвольные условия:
add_filter( 'posts_where', 'custom_fields_search_where' );
function cf_search_where( $where ) {
global $wpdb;
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)", $where );
}
return $where;
}
Отсеиваем дубли
И на последок, нам нужно добавить ключевое слово DISTINCT (оно позволяет выбирать только уникальные значения из базы данных) в SQL-запрос, чтобы предотвратить возврат дубликатов. Воспользуемся WordPress фильтром posts_distinct:
add_filter( 'posts_distinct', 'custom_fields_search_distinct' );
function custom_fields_search_distinct( $where ) {
global $wpdb;
if ( is_search() ) {
return "DISTINCT";
}
return $where;
}
На этом все, просто добавьте весь код выше в файл functions.php
вашей темы и поиск по пользовательским полям заработает не только в фронтэнд части сайта, но и в админке.