S
S
Sergei Gurdjiyan2017-03-18 14:11:17
WordPress
Sergei Gurdjiyan, 2017-03-18 14:11:17

How to fix pagination in Woocommerce custom product loop?

I implemented my own product filter on the site.
Appearance
7d15d928afe24df79e23cc303df3ee4b.jpg
Unlike standard filters, selects allow you to make multiple selections. The fields in the select and checkboxes are product attributes. The Tempo range selection is the advancedcustomfields field.
After selecting the characteristics to sort, the js script sends POST data, reloading the page.
Sending data example

emotion=bold,exiting&music-genres=fulk,orchestral&min_tempo=75&max_tempo=163&other=lead-vocal

I went this way because I could not implement a filter by the minimum and maximum values ​​of the custom field via GET, as implemented in the standard filter.
After reloading the page, it executes the script:
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');
                    }
}

This code receives POST data, parses it and forms an array of parameters for WP_Query. Here is the var_dump of that array:
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"
    }
  }
}

This script successfully makes a selection according to the required parameters.
BUT it is not possible to solve 2 problems:
1. do_action('woocommerce_after_shop_loop');pagination does not work correctly, it continues to display the number of pages, which corresponds to the number of products in the category without applying filters. Accordingly, switching to other pages does not give the correct result.
2. I also wondered, even if pagination is repaired, then how to save the selection, because POST will no longer be available when you go to page 2.
I ask for advice or ideas, maybe I went the wrong way. What is the best way to do it, how to fix pagination, how to save the selection when switching to another page through pagination?
The result of the filter can be seen here

Answer the question

In order to leave comments, you need to log in

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question