Верх страницы
Обложка к записи Поиск по произвольным полям WordPress без плагина
Время для прочтения: 1 мин. 43 сек.

Поиск по произвольным полям 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

Автор: Кобзарёв Михаил

Русский разработчик с 20-ти летним стажем. Работаю с PHP, ООП, JavaScript, Git, WordPress, Битрикс, Joomla, Drupal, Opencart, DLE, Laravel, Moonshine, SuiteCRM.

Оптимизирую сайты под Google Page Speed, настраиваю импорты для больших магазинов на WooCommerce + WP All Import. Пишу плагины на заказ. Все мои услуги.

Веду блог о разработке, дайджест в телеграмме и в ВК.

Вы всегда можете нанять меня.

Комментарии
Подписаться
Уведомить о
guest

6 комментариев
Межтекстовые Отзывы
Посмотреть все комментарии
Юрий
Юрий
1 год назад

Добрый вечер! А как сделать поиск для двух призвольных полей

Юрий
Юрий
1 год назад
Ответить на  Кобзарёв Михаил

Спасибо за ответ! Не соображу как. Знаний не достаточно

SeoKardinal
SeoKardinal
6 месяцев назад

Правильно я понимаю, что поиск по произвольным полям будет работать только по текстовым полям? Есть ли возможно искать по другим форматам, например, по полю с типом true/false?

Предыдущая запись
Следующая запись

Давайте дружить
в Telegram

Авторский блог вашего покорного слуги в Telegram про web, программирование, алгоритмы, инструменты разработчика, WordPress, Joomla, Opencart, Laravel, Moonshine, фильмы и сериалы