Intereting Posts
Включая некоторые переменные в function.php и echo, это несколько мест темы не работает Как автоматически регистрировать виджеты в новом блоге? Как просмотреть сайт с точки зрения пользователя без регистрации Разделять одну установку WordPress между несколькими «сайтами»? Очень медленный запрос Лучший способ использовать ajax front-end? Пользовательский почтовый заказ не работает Отображать поле адреса электронной почты рядом с автором в wp_dropdown_users Проверяет ли WordPress на наличие обновлений плагина через имя корневой папки плагинов? bloginfo () и get_template_directory_uri () с SSL? Ограничить просмотр сообщений по категориям, роли пользователя Woocommerce запрашивает все продукты и категории Уменьшить пробел в двадцать четырнадцать Как получить ссылку для самого старого настраиваемого типа сообщений (динамически) Удаление get_template_part в дочерней теме

Манипулирование запросом

Я пытаюсь использовать свою собственную форму поиска, а не однополюсную форму по умолчанию. Поэтому я сделал свои поля и задал значения для запроса с помощью 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; }