Custom Queries. Фильтры для изменения SQL запроса на выборку постов в wordpress.

Здравствуйте, У меня довольно сложный вопрос касающийся вордпресс и выборки записей через wp_query с использованием кастомного(произвольного) SQL запроса. Мне нужно в стандартный вывод продуктов(из woocommerce), добавить несколько своих параметров для нужной мне выборке продуктов. Требуется выбрать по произвольным полям и сортировать в определенном порядке(моем порядке, не просто asc или desc). Стандартные средства wp_query не помогают. Из вариантов вижу только полностью переписать запрос перед выборкой(что не хотелось бы делать, так как нужно будет самому получать параметры категорий, сколько выводить на страницу и прочее). И частично внедриться в sql запрос, только как это сделать не представляю.  Может кто нибудь чем нибудь помочь?

Добавить Комментарий
Ответ

Фильтры:

Фильтры на SQL запрос через wp_query

posts_request — Весь sql запрос

Пример:

add_filter('posts_request', 'post_search_request');
function post_search_request($request){
var_dump($request); // выведет запрос полностью
}
 

posts_join — фильтр на соединение таблиц с помощью оператора join

Пример:

add_filter('posts_join', 'post_search_join');
function post_search_join($join){
var_dump($join); // выведет часть запроса по выбору/соединению таблиц базы данных с использованием оператора join
}
 

posts_where — фильтр на параметры выборки в sql запросе wp_query

Пример:

add_filter('posts_where', 'post_search_where');
function post_search_where($where){
var_dump($where); // выведет часть запроса с условиями выборки WHERE ...
}
 

posts_orderby — фильтр на сортировку выборки ORDER BY

Пример:

add_filter('posts_orderby', 'post_search_orderby');
function post_search_orderby($orderby){
var_dump($orderby);  // выведет часть запроса указанного после оператора ORDER BY
}
 

post_limits — фильтр на оператор LIMIT(количество выводимых записей)

Пример:

 function wpcodex_filter_main_search_post_limits( $limit, $query ) {
 if ( ! is_admin() && $query->is_main_query() && $query->is_search() ) {
 return 'LIMIT 0, 25'; // будем выводить 25 записей из базы
 }
 return $limit;
 }
 add_filter( 'post_limits', 'wpcodex_filter_main_search_post_limits', 10, 2 );
 

posts_clauses — вернем в в виде массива параметры текущего запроса

Пример:

/**
Функция выведет параметры sql для всех запросов на странице.
В массиве содержаться
* posts_where_paged
 * posts_groupby
 * posts_join_paged
 * posts_orderby
 * posts_distinct
 * post_limits
 * posts_fields
*/
 function intercept_query_clauses( $pieces )
 {
 echo '<style>#post-clauses-dump { display: block; background-color: #777; color: #fff; white-space: pre-line; }</style>';
 // >>>> Inspect & Debug the Query
 // NEVER EVER show this to anyone other than an admin user - unless you're in your local installation
 if ( current_user_can( 'manage_options' ) )
 {
 $dump = var_export( $pieces, true );
 echo "<pre id='post-clauses-dump'>{$dump}</pre>";
 }
return $pieces;
 }
 add_filter( 'posts_clauses', 'intercept_query_clauses', 20, 1 );
 

posts_distinctфильтр устраняет дубликаты в результатах поиска.

Пример:

 function search_distinct() {
 if ( $this->allow_duplicates )
 return ""; // filter has no effect
 return "DISTINCT";
 }
 add_filter('posts_distinct', 'search_distinct');
 

posts_results — Фильтр дает возможность отфильтровать полученные результаты sql запроса

Пример:

 function my_posts_results_filter( $posts ) {
 $filtered_posts = array();
 print_r( $posts );
 foreach ( $posts as $post ) {
 if ( false === strpos($post->post_title, 'selfie')) {
 // safe to add non-selfie title post to array
 $filtered_posts[] = $post;
 }
 }
 return $filtered_posts ;
 }
 add_filter( 'posts_results', 'my_posts_results_filter' );
 

 

Добавить Комментарий

Как выбрать нужный нам sql запрос

Что бы применить изменения(фильтры которые перечислены выше) в sql запросе, именно для нужного нам запроса, можно использовать событие «pre_get_posts«.

pre_get_posts — срабатывает перед каждым запросом WP_Query

Например:

 function onwp_pre_get_posts($query) {
 if (is_archive()) {
 if (!is_admin() && $query->is_main_query() && ($query->query_vars['post_type'] == 'product')) {
 add_filter('posts_join', 'post_search_join');
 add_filter('posts_where', 'post_search_where');
 add_filter('posts_orderby', 'post_alphabetical');
 }
 }
 return $query;
 }
add_action('pre_get_posts', 'onwp_pre_get_posts');
 

Теперь наши 3 фильтра сработают только на странице категории, не в админки и если тип записи будет ‘product’.

Для применения событий только к нужному запросу нам возможно понадобятся другие функции для проверки. Приведу пример некоторых из них:

// простые проверки true/false
 $query->is_404
 $query->is_admin
 $query->is_archive
 $query->is_attachment
 $query->is_author
 $query->is_category
 $query->is_comments_popup
 $query->is_comment_feed
 $query->is_date
 $query->is_day
 $query->is_feed
 $query->is_home
 $query->is_month
 $query->is_page
 $query->is_paged
 $query->is_posts_page
 $query->is_post_type_archive
 $query->is_preview
 $query->is_robots
 $query->is_search
 $query->is_single
 $query->is_singular
 $query->is_tag
 $query->is_tax
 $query->is_time
 $query->is_trackback
 $query->is_year
// функции
 $query->is_front_page() // это главная страница?
 $query->is_main_query() // проверяет в главном ли цикле WordPress выполняется действие.
is_post_type_archive( 'kino' ) // это post_type == kino?
 
Добавить Комментарий

Так же не забываем что pre_get_posts может намного больше:

Как добавить свои параметры в запрос не используя WP_Query?

http://onwp.ru/question/kak-dobavit-v-svoi-parametry-v-zapros-ne-ispolzuyu-wp_query

Добавить Комментарий

Ваш ответ

Размещая свой ответ, вы соглашаетесь с правилами сайта.