Додаємо пошук по метаполі у звичайний пошук WordPress
Базовий пошук WordPress шукає вказаний текст у заголовку, контенті та уривку (у полях post_title , post_content , post_excerpt ). Нижче показано, як до цих базових полів пошуку додати пошук і метаполем. Тобто. нижче будемо вирішувати завдання: як до стандартного пошуку за записами додати пошук за вказаним метаполем.
Дивіться також: Додаємо назву таксономії (терміну) у пошук за записами
Вирішення завдання на хуку posts_clauses
add_filter( 'posts_clauses', 'km_metadata_search'); # Додаємо пошук по метаполям у базовий пошук WordPress function km_metadata_search( $clauses ){ Global $wpdb; if( ! is_search() || ! is_main_query() ) return $clauses; $clauses['join'] .= " LEFT JOIN $wpdb->postmeta kmpm ON (ID = kmpm.post_id)"; $clauses['where'] = preg_replace( "/OR +( *$wpdb->posts.post_content +LIKE +('[^']+')/", "OR (kmpm.meta_value LIKE $1) $0", $clauses['where'] ); // якщо потрібно шукати у вказаному метаполі //$clauses['where'] .= $wpdb->prepare(' AND kmpm.meta_key = %s', 'my_meta_key' ); $clauses['distinct'] = 'DISTINCT'; // дебаг підсумкового запиту 0 && add_filter( 'posts_request', function( $sql ){ die( $sql ); } ); return $clauses; }
Що робиться в коді:
Крок 1: Додавання таблиці метаданих на запит (JOIN)
Розширимо базову таблицю posts, додамо до неї таблицю метаданих. Потрібно це для того, щоб з’явилася можливість вказати поле таблиці метаполів, в якому потрібно шукати. Поле вказуємо на другому кроці.
Крок 2: Зміна вибірки у запиті (WHERE)
Доповнимо WHERE частину запиту, щоб “стандартний пошук” на додаток шукав ще й по всіх метаполях постів.
Крок 3: Зміна вибірки у запиті (DISTINCT)
Через LEFT JOIN в 1 кроці можуть з’явитися дублікати. Позбавимося їх.
Розв’язання задачі на хуках: posts_distinct
add_filter( 'posts_join', 'cf_search_join'); add_filter( 'posts_where', 'cf_search_where'); add_filter( 'posts_distinct', 'cf_search_distinct'); # Об'єднує таблиці записів та таблиць метаданих. function cf_search_join( $join ){ Global $wpdb; if( is_search() ) $join .= " LEFT JOIN $wpdb->postmeta ON ID = $wpdb->postmeta.post_id "; return $join; } # Вказує за якими метаполями та яке значення шукати у секції WHERE. function cf_search_where( $where ){ Global $wpdb; if ( is_search() ) { $where = preg_replace( "/(s*$wpdb->posts.post_titles+LIKEs*('[^']+')s*)/", "($wpdb->posts.post_title LIKE $1) OR ($wpdb->postmeta.meta_value LIKE $1)", $where ); } return $where; } # Запобігає появі дублікатів у вибірці. function cf_search_distinct( $where ){ return is_search() ? 'DISTINCT' : $where; }
Фільтри не працюватимуть, якщо для запиту увімкнено параметр suppress_filters .
Для запиту get_posts() фільтр не працюватиме – там цей параметр включений за замовчуванням!
–
При створенні коду була використана стаття: adambalee.com