Как сделать поиск по произвольным полям Вордпресс

Как сделать поиск по произвольным полям Вордпресс

21 ноября 2017

Сложно представить сайт на Вордпресс без использования произвольных полей (custom fields). Но есть один нюанс — поисковый механизм Вордпресс игнорирует произвольные поля. То есть, если в произвольных полях хранится какая-то ключевая информация, поиск её просто не найдёт. Сегодня я покажу, как исправить это недоразумение.

Вариантов решения этой задачи много, мне больше понравился способ, предложенный американским коллегой — Adam Balée.

Если заглянуть под капот Вордпресс, можно увидеть, что поиск осуществляется по таблице posts базы данных. Произвольные поля хранятся в таблице postmeta. Получается, нам нужно просто добавить эту таблицу к основному запросу поиска.

/**
 * Join posts and postmeta tables
 *
 * http://codex.wordpress.org/Plugin_API/Filter_Reference/posts_join
 */
function cf_search_join( $join ) {
 global $wpdb;</pre>
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' );

Общий код будет выглядеть следующим образом.

<?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' );

Его традиционно размещаем в файле функций активной темы (functions.php) или в плагине.

Подписываемся на канал Danilin.biz в Telegram, все самое интересное теперь там.
Иван Данилин
Автор: Иван Данилин

Практикующий веб-разработчик, специализируюсь на платформе Вордпресс.

Добавить комментарий

Быстрый, надёжный и недорогой российский хостинг сайтов от 98 руб.