Я пытаюсь использовать свою собственную форму поиска, а не однополюсную форму по умолчанию. Поэтому я сделал свои поля и задал значения для запроса с помощью pre_get_posts
hook.
Все хорошо. Из-за поиска по нескольким custom fields
я использую meta_query
с relation => 'OR'
а также с использованием нескольких массивов ключей / значений внутри него.
Но есть проблема, которую я и буду объяснять. Это запрос, который будет запускаться при нажатии кнопки отправки:
SELECT SQL_CALC_FOUND_ROWS wp_posts.ID FROM wp_posts INNER JOIN wp_postmeta ON (wp_posts.ID = wp_postmeta.post_id) INNER JOIN wp_postmeta AS mt1 ON (wp_posts.ID = mt1.post_id) INNER JOIN wp_postmeta AS mt2 ON (wp_posts.ID = mt2.post_id) INNER JOIN wp_postmeta AS mt3 ON (wp_posts.ID = mt3.post_id) INNER JOIN wp_postmeta AS mt4 ON (wp_posts.ID = mt4.post_id) INNER JOIN wp_postmeta AS mt5 ON (wp_posts.ID = mt5.post_id) INNER JOIN wp_postmeta AS mt6 ON (wp_posts.ID = mt6.post_id) WHERE 1=1 AND (((wp_posts.post_title LIKE '%test%') OR (wp_posts.post_content LIKE '%test%'))) AND wp_posts.post_type IN ('post', 'page', 'attachment') AND (wp_posts.post_status = 'publish' OR wp_posts.post_author = 1 AND wp_posts.post_status = 'private') AND ( (wp_postmeta.meta_key = 'jz_ftype' AND CAST(wp_postmeta.meta_value AS CHAR) = 'pamphlet') OR (mt1.meta_key = 'jz_year' AND CAST(mt1.meta_value AS CHAR) = '') OR (mt2.meta_key = 'jz_has-answer' AND CAST(mt2.meta_value AS CHAR) = 'yes') OR (mt3.meta_key = 'jz_atc-author' AND CAST(mt3.meta_value AS CHAR) LIKE '%%') OR (mt4.meta_key = 'jz_ebook-author' AND CAST(mt4.meta_value AS CHAR) LIKE '%%') OR (mt5.meta_key = 'jz_pro-author' AND CAST(mt5.meta_value AS CHAR) LIKE '%%') OR (mt6.meta_key = 'jz_level' AND CAST(mt6.meta_value AS CHAR) = 'basic') ) GROUP BY wp_posts.ID ORDER BY wp_posts.post_date DESC LIMIT 0, 10
Как вы можете видеть (в конце 7-й строки) дополнительный запрос, который я задал для основного запроса с помощью метода $query->set()
имеет значение AND
:
AND ( (wp_postmeta.meta_key = 'jz_ftype' AND CAST(wp_postmeta.meta_value AS CHAR) = 'pamphlet')
Но мне нужно сделать это OR
:
OR ( (wp_postmeta.meta_key = 'jz_ftype' AND CAST(wp_postmeta.meta_value AS CHAR) = 'pamphlet')
Итак, как я могу это достичь?
Вы можете попытаться добавить фильтр posts_where
в свой крюк pre_get_posts
:
function my_pre_get_posts( $q ){ if( $q->is_main_query() ) add_filter( 'posts_where', 'my_posts_where' ); return $q; } ! is_admin() && add_action( 'pre_get_posts', 'my_pre_get_posts' );
где
function my_posts_where( $where ){ // your custom replacements on the $where string // ... // remove the filter remove_filter( current_filter() , __FUNCTION__ ); return $where; }