Поиск по произвольным полям WordPress без плагина
Пользовательские произвольные поля — это одна из самых мощных функций, доступных в WordPress.
Они особенно полезны при расширении WordPress за счет использования пользовательских типов записей. Я постоянно создаю пользовательские типы записей для таких вещей, как товары, портфолио или галереи при разработке тем WordPress для клиентов.
Эти поля очень удобны, когда нужно добавить детали товара, такие как артикулы или цены. К сожалению, поиск в WordPress по произвольным полям невозможен из коробки. Чтобы исправить это, необходимо изменить поисковый запрос WordPress, чтобы он включал пользовательские поля.
Делаем Left Join
Таблица postmeta
— это место, где в базе данных хранятся вся информация о произвольных полях. По умолчанию функция поиска WordPress настроена на поиск только в таблице posts
.
Чтобы включить данные пользовательских полей в наш поиск, нам сначала нужно выполнить левое объединение таблиц posts
и postmeta
в базе данных.
/**
* 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' );
Модифицируем Query
Далее нам нужно изменить поисковый запрос WordPress, чтобы включить в него произвольные поля.
/**
* 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;
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;
}
add_filter( 'posts_where', 'cf_search_where' );
Исключаем дубликаты
Наконец, нам нужно добавить ключевое слово DISTINCT
в SQL-запрос, чтобы предотвратить появление дубликатов.
/**
* 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' );
Заключение
Добавьте следующий код в файл functions.php, чтобы начать поиск WordPress по произвольным полям. Этот код не только изменит поиск во внешнем интерфейсе, но вы также сможете искать по пользовательским полям на всех экранах редактирования в админке.
<?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;
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;
}
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' );
Источник: Search WordPress by Custom Fields without a Plugin
Добрый вечер! А как сделать поиск для двух призвольных полей
Добавить условие для второго поля через OR во все указанные хуки
Спасибо за ответ! Не соображу как. Знаний не достаточно
Ну вы код напишите и ссылку на него дайде — проверим
Правильно я понимаю, что поиск по произвольным полям будет работать только по текстовым полям? Есть ли возможно искать по другим форматам, например, по полю с типом true/false?
meta_value не имеет типа, но вы всегда можете использовать CAST в SQL-запросе.