Как починить пагинацию в кастомном цикле товаров Woocommerce?

Осуществил на сайте собственный фильтр товаров.
Внешний вид
7d15d928afe24df79e23cc303df3ee4b.jpg
В отличии от стандартных фильтров, селекты позволяют сделать множественный выбор. Поля в селектах ичекбоксах - это атрибуты товаров. Выбор диапазона Tempo - это поле advancedcustomfields.
После выбора сортируемых характеристик скрипт js отправляет POST данные, перегружая страницу.
Пример отправляемых данных
emotion=bold,exiting&music-genres=fulk,orchestral&min_tempo=75&max_tempo=163&other=lead-vocal

Таким путём пошёл, потому что не смог реализовать фильтр по минимальному и максимальному значению кастомного поля через GET, как реализовано в стандартном фильтре.
После перезагрузки страницы, отрабатывает скрипт:
if (isset($_POST['filter-data']) && !empty($_POST['filter-data']))  {
                    global $paged;
                    $paged = (get_query_var('page')) ? get_query_var('page') : 1;

                    global $wp_query;
                    $catObj = $wp_query->get_queried_object();
                    $catId = $catObj->term_id;
                    $filterData = $_POST['filter-data'];
                    $filterData = explode('&', $filterData);
                    $params = [
                        'post_status' => 'publish',
                        'posts_per_page' => 12,
                        'paged' => $paged,
                        'post_type' => 'product'
                    ];
                    $meta_query = [
                        'relation' => 'AND'
                    ];
                    $tax_query = [
                        'relation' => 'AND',
                        array(
                            'taxonomy' => 'product_cat',
                            'field' => 'term_id',
                            'terms' => $catId,
                            'operator' => 'IN'
                        )
                    ];
                    foreach ($filterData as $metaItem) {
                        if ($metaItem != '') {
                            $metaItem = explode('=', $metaItem);
                            $key = $metaItem[0];
                            $values = explode(',', $metaItem[1]);
                            $compare = '=';
                            switch ($key) {
                                case ('min_tempo') :
                                    $key = 'tempo';
                                    $compare = '>=';
                                    break;
                                case ('max_tempo') :
                                    $key = 'tempo';
                                    $compare = '<=';
                                    break;
                            }
                            foreach ($values as $value) {
                                if ($key == 'tempo') {
                                    $meta_query[] = [
                                        'key' => $key,
                                        'value' => $value,
                                        'compare' => $compare,
                                        'type' => 'NUMERIC'
                                    ];
                                } else {
                                    $tax_query[] = [
                                        'taxonomy' => 'pa_' . $key,
                                        'field' => 'slug',
                                        'terms' => $value
                                    ];
                                }
                            }
                        }
                    }
                    if (count($meta_query) > 1) {
                        $params['meta_query'] = $meta_query;
                    }
                    $params['tax_query'] = $tax_query;
                    $wc_query = new WP_Query($params);
                    if ($wc_query->have_posts()) {

                        woocommerce_product_loop_start();
                        woocommerce_product_subcategories();
                        while ($wc_query->have_posts()) {
                            $wc_query->the_post();
                            wc_get_template_part('content', 'product');
                        }
                        woocommerce_product_loop_end();

                        do_action('woocommerce_after_shop_loop');
                    } elseif (!woocommerce_product_subcategories(array('before' => woocommerce_product_loop_start(false), 'after' => woocommerce_product_loop_end(false)))) {
                        wc_get_template('loop/no-products-found.php');
                    }
}


Данный код получает POST данные, разбирает их и формирует массив параметров для WP_Query. Вот var_dump этого массива:
array(6) {
  ["post_status"]=>string(7) "publish"
  ["posts_per_page"]=>int(12)
  ["paged"]=>int(1)
  ["post_type"]=>string(7) "product"
  ["meta_query"]=>
  array(3) {
    ["relation"]=>string(3) "AND"
    [0]=>
    array(4) {
      ["key"]=>string(5) "tempo"
      ["value"]=>string(2) "79"
      ["compare"]=>string(2) ">="
      ["type"]=>string(7) "NUMERIC"
    }
    [1]=>
    array(4) {
      ["key"]=>string(5) "tempo"
      ["value"]=>string(3) "179"
      ["compare"]=>string(2) "<="
      ["type"]=>string(7) "NUMERIC"
    }
  }
  ["tax_query"]=>
  array(9) {
    ["relation"]=>string(3) "AND"
    [0]=>
    array(4) {
      ["taxonomy"]=>string(11) "product_cat"
      ["field"]=>string(7) "term_id"
      ["terms"]=>int(7)
      ["operator"]=>string(2) "IN"
    }
    [1]=>
    array(3) {
      ["taxonomy"]=>string(10) "pa_emotion"
      ["field"]=>string(4) "slug"
      ["terms"]=>string(4) "bold"
    }
    [2]=>
    array(3) {
      ["taxonomy"]=>string(10) "pa_emotion"
      ["field"]=>string(4) "slug"
      ["terms"]=>string(7) "exiting"
    }
    [3]=>
    array(3) {
      ["taxonomy"]=>string(15) "pa_video-genres"
      ["field"]=>string(4) "slug"
      ["terms"]=>string(5) "indie"
    }
    [4]=>
    array(3) {
      ["taxonomy"]=>string(15) "pa_music-genres"
      ["field"]=>string(4) "slug"
      ["terms"]=>string(3) "pop"
    }
    [5]=>
    array(3) {
      ["taxonomy"]=>string(7) "pa_mood"
      ["field"]=>string(4) "slug"
      ["terms"]=>string(4) "dark"
    }
    [6]=>
    array(3) {
      ["taxonomy"]=>string(8) "pa_other"
      ["field"]=>string(4) "slug"
      ["terms"]=>string(10) "lead-vocal"
    }
    [7]=>
    array(3) {
      ["taxonomy"]=>string(8) "pa_other"
      ["field"]=>string(4) "slug"
      ["terms"]=>string(13) "loop-included"
    }
  }
}


Данный скрипт удачно делает выборку по требуемым параметрам.
НО не удаётся решить 2 проблемы:
1. do_action('woocommerce_after_shop_loop'); пагинация работает некорректно, она продолжает выводить количество страниц, которое соответствует количеству товаров в категории без применения фильтров. Соответственно и переключение на другие страницы выдают не верный результат.
2. Так же задался вопросом, если даже починить пагинацию, то как сохранить выборку, ведь POST уже будет недоступен при переходе на страницу 2.

Прошу совета или идей, возможно я пошёл не правильным путём. Как лучше сделать, как починить пагинацию, как сохранить выборку при переходе на другую страницу через пагинацию?

Результат работы фильтра можно посмотреть тут
  • Вопрос задан
  • 299 просмотров
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы