Добавляем название таксономии (термина) в поиск по записям
Задача: к стандартному поиску по товарам нужно добавить поиск и по названию атрибута товара. Другими словами нужно к дефолтному поиску товаров добавить товары, которые относятся к атрибуту "Производитель" из поисковой фразы.
Смотрите также: Добавляем поиск по метаполю в поиск по записям
Логика работы такая:
- Ищем в таксономии (атрибуте) "Производитель" термины по поисковой фразе
- Запрашиваем все записи, относящиеся к найденным производителям
- Добавляем найденные записи в общий пул записей, что были найдены стандартно
Данный механизм можно использовать и для поиска по любым типам записей и таксономиям - измените в коде их на желаемые.
// init new Post_Search_With_Terms( [ 'post_type' => 'product', 'taxonomy' => 'pa_izgotovitel' ] ); /** * Extends default posts search in order to search by terms titles too. * * @version: 1.0 */ final class Post_Search_With_Terms { private $post_type; private $taxonomy; /** * @param array $args { * Arguments to retreive posts. * * @type string $post_type Default: post * @type string $taxonomy Default: post_tag * } */ public function __construct( $args = [] ) { $args = (object) array_merge( [ 'post_type' => 'post', 'taxonomy' => 'post_tag' ], $args ); foreach( $args as $key => $val ){ $this->$key = $val; } add_filter( 'pre_get_posts', [ $this, 'extends_search_query' ] ); } /** * @param WP_Query $wp_query */ public function extends_search_query( $wp_query ) { // Только для основного запроса if ( ! $wp_query->is_main_query() ) { return; } // Только для указанного типа поста if ( ! $wp_query->is_post_type_archive( $this->post_type ) ) { return; } // Для поиска во фронте if ( ! is_admin() && $wp_query->is_search() ) { add_filter( 'posts_where', [ $this, 'add_tax_query' ] ); } // Для поиска в админке if ( is_admin() ) { add_filter( 'posts_where', [ $this, 'add_tax_query' ] ); } } /** * Возвращает термины указанной таксономии на основе поискового запроса. * * @return WP_Term[]|array Empty array if no terms found. */ private function search_terms() { $search_query = filter_input( INPUT_GET, 's' ); if ( empty( $search_query ) ) { return []; } $terms = get_terms( [ 'taxonomy' => $this->taxonomy, 'name__like' => $search_query, ] ); return is_wp_error( $terms ) ? [] : $terms; } /** * Добавляет в базовый запрос условия расширенной выборки по указанной таксономии. * * @param string $where * * @return string */ public function add_tax_query( $where ) { global $wpdb; $terms = $this->search_terms(); if ( $terms ) { $ids = implode( ',', wp_list_pluck( $terms, 'term_id' ) ); $where .= " OR ID IN (SELECT object_id FROM {$wpdb->term_relationships} WHERE term_taxonomy_id IN ($ids) )"; } // Отменяем фильтр, чтобы он не применялся к другим запросам remove_filter( 'posts_where', [ $this, __FUNCTION__ ] ); return $where; } }