/** * Output widget. * * @see WP_Widget * * @param array $args * @param array $instance */ public function widget($args, $instance) { if (!is_post_type_archive('product') && !is_tax(get_object_taxonomies('product'))) { return; } $_chosen_attributes = WC_Query::get_layered_nav_chosen_attributes(); $min_price = isset($_GET['min_price']) ? wc_clean($_GET['min_price']) : 0; $max_price = isset($_GET['max_price']) ? wc_clean($_GET['max_price']) : 0; $min_rating = isset($_GET['min_rating']) ? absint($_GET['min_rating']) : 0; if (0 < count($_chosen_attributes) || 0 < $min_price || 0 < $max_price || 0 < $min_rating) { $this->widget_start($args, $instance); echo '<ul>'; // Attributes if (!empty($_chosen_attributes)) { foreach ($_chosen_attributes as $taxonomy => $data) { foreach ($data['terms'] as $term_slug) { if (!($term = get_term_by('slug', $term_slug, $taxonomy))) { continue; } $filter_name = 'filter_' . sanitize_title(str_replace('pa_', '', $taxonomy)); $current_filter = isset($_GET[$filter_name]) ? explode(',', wc_clean($_GET[$filter_name])) : array(); $current_filter = array_map('sanitize_title', $current_filter); $new_filter = array_diff($current_filter, array($term_slug)); $link = remove_query_arg(array('add-to-cart', $filter_name)); if (sizeof($new_filter) > 0) { $link = add_query_arg($filter_name, implode(',', $new_filter), $link); } echo '<li class="chosen"><a title="' . esc_attr__('Remove filter', 'woocommerce') . '" href="' . esc_url($link) . '">' . esc_html($term->name) . '</a></li>'; } } } if ($min_price) { $link = remove_query_arg('min_price'); echo '<li class="chosen"><a title="' . esc_attr__('Remove filter', 'woocommerce') . '" href="' . esc_url($link) . '">' . sprintf(__('Min %s', 'woocommerce'), wc_price($min_price)) . '</a></li>'; } if ($max_price) { $link = remove_query_arg('max_price'); echo '<li class="chosen"><a title="' . esc_attr__('Remove filter', 'woocommerce') . '" href="' . esc_url($link) . '">' . sprintf(__('Max %s', 'woocommerce'), wc_price($max_price)) . '</a></li>'; } if ($min_rating) { $link = remove_query_arg('min_rating'); echo '<li class="chosen"><a title="' . esc_attr__('Remove filter', 'woocommerce') . '" href="' . esc_url($link) . '">' . sprintf(__('Rated %s and above', 'woocommerce'), $min_rating) . '</a></li>'; } echo '</ul>'; $this->widget_end($args); } }
/** * Get current page URL for layered nav items. * @return string */ protected function get_page_base_url() { if (defined('SHOP_IS_ON_FRONT')) { $link = home_url(); } elseif (is_post_type_archive('product') || is_page(wc_get_page_id('shop'))) { $link = get_post_type_archive_link('product'); } else { $link = get_term_link(get_query_var('term'), get_query_var('taxonomy')); } // Min/Max if (isset($_GET['min_price'])) { $link = add_query_arg('min_price', wc_clean($_GET['min_price']), $link); } if (isset($_GET['max_price'])) { $link = add_query_arg('max_price', wc_clean($_GET['max_price']), $link); } // Orderby if (isset($_GET['orderby'])) { $link = add_query_arg('orderby', wc_clean($_GET['orderby']), $link); } /** * Search Arg. * To support quote characters, first they are decoded from " entities, then URL encoded. */ if (get_search_query()) { $link = add_query_arg('s', rawurlencode(htmlspecialchars_decode(get_search_query())), $link); } // Post Type Arg if (isset($_GET['post_type'])) { $link = add_query_arg('post_type', wc_clean($_GET['post_type']), $link); } // All current filters if ($_chosen_attributes = WC_Query::get_layered_nav_chosen_attributes()) { foreach ($_chosen_attributes as $name => $data) { $filter_name = sanitize_title(str_replace('pa_', '', $name)); if (!empty($data['terms'])) { $link = add_query_arg('filter_' . $filter_name, implode(',', $data['terms']), $link); } if ('or' == $data['query_type']) { $link = add_query_arg('query_type_' . $filter_name, 'or', $link); } } } return $link; }
/** * Output widget. * * @see WP_Widget * * @param array $args * @param array $instance */ public function widget($args, $instance) { global $wp, $wp_the_query; if (!is_post_type_archive('product') && !is_tax(get_object_taxonomies('product'))) { return; } if (!$wp_the_query->post_count) { return; } // Remember current filters/search if ('' == get_option('permalink_structure')) { $link_url = remove_query_arg(array('page', 'paged'), add_query_arg($wp->query_string, '', home_url($wp->request))); } else { $link_url = preg_replace('%\\/page/[0-9]+%', '', home_url(trailingslashit($wp->request))); } if (get_search_query()) { $link_url = add_query_arg('s', get_search_query(), $link_url); } if (!empty($_GET['post_type'])) { $link_url = add_query_arg('post_type', urlencode($_GET['post_type']), $link_url); } if (!empty($_GET['product_cat'])) { $link_url = add_query_arg('product_cat', urlencode($_GET['product_cat']), $link_url); } if (!empty($_GET['product_tag'])) { $link_url = add_query_arg('product_tag', urlencode($_GET['product_tag']), $link_url); } if (!empty($_GET['orderby'])) { $link_url = add_query_arg('orderby', urlencode($_GET['orderby']), $link_url); } if ($_chosen_attributes = WC_Query::get_layered_nav_chosen_attributes()) { foreach ($_chosen_attributes as $attribute => $data) { $taxonomy_filter = 'filter_' . str_replace('pa_', '', $attribute); $link_url = add_query_arg($taxonomy_filter, urlencode(implode(',', $data['terms'])), $link_url); if ('or' == $data['query_type']) { $link_url = add_query_arg(str_replace('pa_', 'query_type_', $attribute), 'or', $link_url); } } } // Find min and max price in current result set $prices = $this->get_filtered_price(); $min = floor($prices->min_price); $max = ceil($prices->max_price); if ($min === $max) { return; } $this->widget_start($args, $instance); /** * Adjust max if the store taxes are not displayed how they are stored. * Min is left alone because the product may not be taxable. * Kicks in when prices excluding tax are displayed including tax. */ if (wc_tax_enabled() && 'incl' === get_option('woocommerce_tax_display_shop') && !wc_prices_include_tax()) { $tax_classes = array_merge(array(''), WC_Tax::get_tax_classes()); $class_max = $max; foreach ($tax_classes as $tax_class) { if ($tax_rates = WC_Tax::get_rates($tax_class)) { $class_max = $max + WC_Tax::get_tax_total(WC_Tax::calc_exclusive_tax($max, $tax_rates)); } } $max = $class_max; } $minprice = isset($_GET['min_price']) ? esc_attr($_GET['min_price']) : ''; $maxprice = isset($_GET['max_price']) ? esc_attr($_GET['max_price']) : ''; $output = ''; $min_price = 0; $range_size = intval($instance['range_size']); $max_ranges = intval($instance['max_ranges']) - 1; $count = 0; if (strlen($minprice) > 0) { $output .= '<li><a href="' . esc_url($link_url) . '">' . esc_html__('All', 'cruxstore') . '</a></li>'; } else { $output .= '<li class="selected">' . esc_html__('All', 'cruxstore') . '</li>'; } while ($count <= $max_ranges) { $step = $min_price; $min_price += $range_size; if ($count != $max_ranges) { if ($min_price > $max) { $min_price = $max; } $link = add_query_arg(array('min_price' => $step, 'max_price' => $min_price), $link_url); $price_text = wc_price($step) . ' - ' . wc_price($min_price); } else { $link = add_query_arg(array('min_price' => $step, 'max_price' => $max), $link_url); $price_text = wc_price($step) . '+'; } if ($step == $minprice && $min_price == $maxprice) { $output .= '<li class="selected">' . $price_text . '</li>'; } else { $output .= '<li><a href="' . esc_url($link) . '">' . $price_text . '</a></li>'; } $count++; if ($min_price == $max) { break; } } printf('<ul>%s</ul>', $output); $this->widget_end($args); }
/** * is_filtered - Returns true when filtering products using layered nav or price sliders. * @return bool */ function is_filtered() { return apply_filters('woocommerce_is_filtered', sizeof(WC_Query::get_layered_nav_chosen_attributes()) > 0 || isset($_GET['max_price']) || isset($_GET['min_price']) || isset($_GET['min_rating'])); }
/** * Output widget. * * @see WP_Widget * * @param array $args * @param array $instance */ public function widget($args, $instance) { global $wp, $wp_the_query; if (!is_post_type_archive('product') && !is_tax(get_object_taxonomies('product'))) { return; } if (!$wp_the_query->post_count) { return; } $min_price = isset($_GET['min_price']) ? esc_attr($_GET['min_price']) : ''; $max_price = isset($_GET['max_price']) ? esc_attr($_GET['max_price']) : ''; wp_enqueue_script('wc-price-slider'); // Remember current filters/search $fields = ''; if (get_search_query()) { $fields .= '<input type="hidden" name="s" value="' . get_search_query() . '" />'; } if (!empty($_GET['post_type'])) { $fields .= '<input type="hidden" name="post_type" value="' . esc_attr($_GET['post_type']) . '" />'; } if (!empty($_GET['product_cat'])) { $fields .= '<input type="hidden" name="product_cat" value="' . esc_attr($_GET['product_cat']) . '" />'; } if (!empty($_GET['product_tag'])) { $fields .= '<input type="hidden" name="product_tag" value="' . esc_attr($_GET['product_tag']) . '" />'; } if (!empty($_GET['orderby'])) { $fields .= '<input type="hidden" name="orderby" value="' . esc_attr($_GET['orderby']) . '" />'; } if (!empty($_GET['min_rating'])) { $fields .= '<input type="hidden" name="min_rating" value="' . esc_attr($_GET['min_rating']) . '" />'; } if ($_chosen_attributes = WC_Query::get_layered_nav_chosen_attributes()) { foreach ($_chosen_attributes as $attribute => $data) { $taxonomy_filter = 'filter_' . str_replace('pa_', '', $attribute); $fields .= '<input type="hidden" name="' . esc_attr($taxonomy_filter) . '" value="' . esc_attr(implode(',', $data['terms'])) . '" />'; if ('or' == $data['query_type']) { $fields .= '<input type="hidden" name="' . esc_attr(str_replace('pa_', 'query_type_', $attribute)) . '" value="or" />'; } } } // Find min and max price in current result set $prices = $this->get_filtered_price(); $min = floor($prices->min_price); $max = ceil($prices->max_price); if ($min === $max) { return; } $this->widget_start($args, $instance); if ('' === get_option('permalink_structure')) { $form_action = remove_query_arg(array('page', 'paged'), add_query_arg($wp->query_string, '', home_url($wp->request))); } else { $form_action = preg_replace('%\\/page/[0-9]+%', '', home_url(trailingslashit($wp->request))); } /** * Adjust max if the store taxes are not displayed how they are stored. * Min is left alone because the product may not be taxable. * Kicks in when prices excluding tax are displayed including tax. */ if (wc_tax_enabled() && 'incl' === get_option('woocommerce_tax_display_shop') && !wc_prices_include_tax()) { $tax_classes = array_merge(array(''), WC_Tax::get_tax_classes()); $class_max = $max; foreach ($tax_classes as $tax_class) { if ($tax_rates = WC_Tax::get_rates($tax_class)) { $class_max = $max + WC_Tax::get_tax_total(WC_Tax::calc_exclusive_tax($max, $tax_rates)); } } $max = $class_max; } echo '<form method="get" action="' . esc_url($form_action) . '"> <div class="price_slider_wrapper"> <div class="price_slider" style="display:none;"></div> <div class="price_slider_amount"> <input type="text" id="min_price" name="min_price" value="' . esc_attr($min_price) . '" data-min="' . esc_attr(apply_filters('woocommerce_price_filter_widget_min_amount', $min)) . '" placeholder="' . esc_attr__('Min price', 'woocommerce') . '" /> <input type="text" id="max_price" name="max_price" value="' . esc_attr($max_price) . '" data-max="' . esc_attr(apply_filters('woocommerce_price_filter_widget_max_amount', $max)) . '" placeholder="' . esc_attr__('Max price', 'woocommerce') . '" /> <button type="submit" class="button">' . __('Filter', 'woocommerce') . '</button> <div class="price_label" style="display:none;"> ' . __('Price:', 'woocommerce') . ' <span class="from"></span> — <span class="to"></span> </div> ' . $fields . ' <div class="clear"></div> </div> </div> </form>'; $this->widget_end($args); }
/** * Show list based layered nav. * * @param array $terms * @param string $taxonomy * @param string $query_type * @return bool Will nav display? */ protected function layered_nav_list($terms, $taxonomy, $query_type) { // List display echo '<ul>'; $term_counts = $this->get_filtered_term_product_counts(wp_list_pluck($terms, 'term_id'), $taxonomy, $query_type); $_chosen_attributes = WC_Query::get_layered_nav_chosen_attributes(); $found = false; foreach ($terms as $term) { $current_values = isset($_chosen_attributes[$taxonomy]['terms']) ? $_chosen_attributes[$taxonomy]['terms'] : array(); $option_is_set = in_array($term->slug, $current_values); $count = isset($term_counts[$term->term_id]) ? $term_counts[$term->term_id] : 0; // Skip the term for the current archive if ($this->get_current_term_id() === $term->term_id) { continue; } // Only show options with count > 0 if (0 < $count) { $found = true; } elseif (0 === $count && !$option_is_set) { continue; } $filter_name = 'filter_' . sanitize_title(str_replace('pa_', '', $taxonomy)); $current_filter = isset($_GET[$filter_name]) ? explode(',', wc_clean($_GET[$filter_name])) : array(); $current_filter = array_map('sanitize_title', $current_filter); if (!in_array($term->slug, $current_filter)) { $current_filter[] = $term->slug; } $link = $this->get_page_base_url($taxonomy); // Add current filters to URL. foreach ($current_filter as $key => $value) { // Exclude query arg for current term archive term if ($value === $this->get_current_term_slug()) { unset($current_filter[$key]); } // Exclude self so filter can be unset on click. if ($option_is_set && $value === $term->slug) { unset($current_filter[$key]); } } if (!empty($current_filter)) { $link = add_query_arg($filter_name, implode(',', $current_filter), $link); // Add Query type Arg to URL if ('or' === $query_type && !(1 === sizeof($current_filter) && $option_is_set)) { $link = add_query_arg('query_type_' . sanitize_title(str_replace('pa_', '', $taxonomy)), 'or', $link); } } if ($count > 0 || $option_is_set) { $link = esc_url(apply_filters('woocommerce_layered_nav_link', $link)); $term_html = '<a href="' . $link . '">' . esc_html($term->name) . '</a>'; } else { $link = false; $term_html = '<span>' . esc_html($term->name) . '</span>'; } $term_html .= ' ' . apply_filters('woocommerce_layered_nav_count', '<span class="count">(' . absint($count) . ')</span>', $count, $term); echo '<li class="wc-layered-nav-term ' . ($option_is_set ? 'chosen' : '') . '">'; echo wp_kses_post(apply_filters('woocommerce_layered_nav_term_html', $term_html, $term, $link, $count)); echo '</li>'; } echo '</ul>'; return $found; }