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

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

    Ваш ответ

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