/**
  * 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);
     }
 }
 /**
  * Count products after other filters have occured by adjusting the main query.
  * @param  int $rating
  * @return int
  */
 protected function get_filtered_product_count($rating)
 {
     global $wpdb;
     $tax_query = WC_Query::get_main_tax_query();
     $meta_query = WC_Query::get_main_meta_query();
     // Unset current rating filter
     foreach ($meta_query as $key => $query) {
         if (!empty($query['rating_filter'])) {
             unset($meta_query[$key]);
         }
     }
     // Set new rating filter
     $meta_query[] = array('key' => '_wc_average_rating', 'value' => $rating, 'compare' => '>=', 'type' => 'DECIMAL', 'rating_filter' => true);
     $meta_query = new WP_Meta_Query($meta_query);
     $tax_query = new WP_Tax_Query($tax_query);
     $meta_query_sql = $meta_query->get_sql('post', $wpdb->posts, 'ID');
     $tax_query_sql = $tax_query->get_sql($wpdb->posts, 'ID');
     $sql = "SELECT COUNT( {$wpdb->posts}.ID ) FROM {$wpdb->posts} ";
     $sql .= $tax_query_sql['join'] . $meta_query_sql['join'];
     $sql .= " WHERE {$wpdb->posts}.post_type = 'product' AND {$wpdb->posts}.post_status = 'publish' ";
     $sql .= $tax_query_sql['where'] . $meta_query_sql['where'];
     return absint($wpdb->get_var($sql));
 }
Пример #3
0
 /**
  * Layered Nav Init.
  */
 public static function get_layered_nav_chosen_attributes()
 {
     if (!is_array(self::$_chosen_attributes)) {
         self::$_chosen_attributes = array();
         if ($attribute_taxonomies = wc_get_attribute_taxonomies()) {
             foreach ($attribute_taxonomies as $tax) {
                 $attribute = wc_sanitize_taxonomy_name($tax->attribute_name);
                 $taxonomy = wc_attribute_taxonomy_name($attribute);
                 $filter_terms = !empty($_GET['filter_' . $attribute]) ? explode(',', wc_clean($_GET['filter_' . $attribute])) : array();
                 if (empty($filter_terms) || !taxonomy_exists($taxonomy)) {
                     continue;
                 }
                 $query_type = !empty($_GET['query_type_' . $attribute]) && in_array($_GET['query_type_' . $attribute], array('and', 'or')) ? wc_clean($_GET['query_type_' . $attribute]) : '';
                 self::$_chosen_attributes[$taxonomy]['terms'] = array_map('sanitize_title', $filter_terms);
                 // Ensures correct encoding
                 self::$_chosen_attributes[$taxonomy]['query_type'] = $query_type ? $query_type : apply_filters('woocommerce_layered_nav_default_query_type', 'and');
             }
         }
     }
     return self::$_chosen_attributes;
 }
 /**
  * Count products after other filters have occured by adjusting the main query.
  * @param  int $rating
  * @return int
  */
 protected function get_filtered_product_count($rating)
 {
     global $wpdb;
     $tax_query = WC_Query::get_main_tax_query();
     $meta_query = WC_Query::get_main_meta_query();
     // Unset current rating filter.
     foreach ($tax_query as $key => $query) {
         if (!empty($query['rating_filter'])) {
             unset($tax_query[$key]);
             break;
         }
     }
     // Set new rating filter.
     $product_visibility_terms = wc_get_product_visibility_term_ids();
     $tax_query[] = array('taxonomy' => 'product_visibility', 'field' => 'term_taxonomy_id', 'terms' => $product_visibility_terms['rated-' . $rating], 'operator' => 'IN', 'rating_filter' => true);
     $meta_query = new WP_Meta_Query($meta_query);
     $tax_query = new WP_Tax_Query($tax_query);
     $meta_query_sql = $meta_query->get_sql('post', $wpdb->posts, 'ID');
     $tax_query_sql = $tax_query->get_sql($wpdb->posts, 'ID');
     $sql = "SELECT COUNT( DISTINCT {$wpdb->posts}.ID ) FROM {$wpdb->posts} ";
     $sql .= $tax_query_sql['join'] . $meta_query_sql['join'];
     $sql .= " WHERE {$wpdb->posts}.post_type = 'product' AND {$wpdb->posts}.post_status = 'publish' ";
     $sql .= $tax_query_sql['where'] . $meta_query_sql['where'];
     return absint($wpdb->get_var($sql));
 }
Пример #5
0
 /**
  * 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);
 }
 /**
  * Piggyback WooCommerce's Layered Navigation and inject SearchWP results where applicable
  *
  * @param $filtered_posts
  *
  * @return array
  */
 function post_in($filtered_posts)
 {
     global $wp_query;
     // WooCommerce 2.6 introduced tax/meta query piggybacking that's much better
     if (function_exists('WC') && !empty(WC()->version) && version_compare(WC()->version, '2.6', '<')) {
         return $this->legacy_post_in($filtered_posts);
     }
     if ($this->is_woocommerce_search() && ($query = get_search_query())) {
         if (!empty($this->results)) {
             return $this->results;
         }
         $searchwp_engine = 'default';
         $swppg = get_query_var('paged') ? get_query_var('paged') : 1;
         // force SearchWP to only consider the filtered posts
         if (!empty($filtered_posts)) {
             $this->filtered_posts = $filtered_posts;
             add_filter('searchwp_include', array($this, 'include_filtered_posts'));
         }
         do_action('searchwp_woocommerce_before_search', $this);
         // don't log this search, it's redundant
         add_filter('searchwp_log_search', '__return_false');
         $wc_query = new WC_Query();
         $args = array('s' => $query, 'engine' => $searchwp_engine, 'page' => $swppg, 'fields' => 'ids', 'posts_per_page' => -1, 'tax_query' => $wc_query->get_tax_query(), 'meta_query' => $wc_query->get_meta_query());
         $args = apply_filters('searchwp_woocommerce_query_args', $args);
         $results = new SWP_Query($args);
         $this->results = $results->posts;
         remove_filter('searchwp_log_search', '__return_false');
         return $this->results;
     } elseif (!empty($this->results)) {
         return $this->results;
     }
     return (array) $filtered_posts;
 }
 /**
  * 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> &mdash; <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;
 }
Пример #10
0
 /**
  * Gets sorting options
  *
  * @access public
  * @return array
  */
 public static function getSorting()
 {
     $order = array('orderby' => '', 'order' => '', 'meta_key' => '');
     if (self::isActive()) {
         $query = new WC_Query();
         $order = $query->get_catalog_ordering_args();
     }
     return $order;
 }
Пример #11
0
    /**
     * This method is used to display the output of the element.
     * @return void
     */
    function element()
    {
        // Check if this is a normal page or the Shop archive page
        if (!is_shop()) {
            global $paged;
            $wc_query = new WC_Query();
            // Get the proper page - this resolves the pagination on static frontpage
            if (get_query_var('paged')) {
                $paged = get_query_var('paged');
            } elseif (get_query_var('page')) {
                $paged = get_query_var('page');
            } else {
                $paged = 1;
            }
            $ordering = $wc_query->get_catalog_ordering_args();
            $queryArgs = array('post_type' => 'product', 'paged' => $paged, 'orderby' => $ordering['orderby'], 'order' => $ordering['order']);
            if (isset($ordering['meta_key'])) {
                $queryArgs['meta_key'] = $ordering['meta_key'];
            }
            query_posts($queryArgs);
        }
        // Change the number of columns
        add_filter('loop_shop_columns', array(&$this, 'zn_woo_loop_columns'), 999);
        $sidebar_tweak = $this->opt('num_columns', '4') == 3 ? 'left_sidebar' : '';
        echo '<div class="zn_woo_archive_elemenent woocommerce ' . $this->data['uid'] . ' ' . $sidebar_tweak . ' ' . $this->opt('css_class', '') . '">';
        ?>

		<?php 
        if ($this->opt('show_page_title', 'yes') == 'yes') {
            ?>
			<h1 class="page-title"><?php 
            woocommerce_page_title();
            ?>
</h1>
		<?php 
        }
        ?>

		<?php 
        /**
         * woocommerce_archive_description hook
         *
         * @hooked woocommerce_taxonomy_archive_description - 10
         * @hooked woocommerce_product_archive_description - 10
         */
        do_action('woocommerce_archive_description');
        ?>

		<?php 
        if (have_posts()) {
            ?>

		<?php 
            /**
             * woocommerce_before_shop_loop hook
             *
             * @hooked woocommerce_result_count - 20
             * @hooked woocommerce_catalog_ordering - 30
             */
            do_action('woocommerce_before_shop_loop');
            ?>

		<?php 
            woocommerce_product_loop_start();
            ?>

		<?php 
            woocommerce_product_subcategories();
            ?>

		<?php 
            while (have_posts()) {
                the_post();
                ?>

			<?php 
                wc_get_template_part('content', 'product');
                ?>

		<?php 
            }
            // end of the loop.
            ?>

		<?php 
            woocommerce_product_loop_end();
            ?>

		<?php 
            /**
             * woocommerce_after_shop_loop hook
             *
             * @hooked woocommerce_pagination - 10
             */
            do_action('woocommerce_after_shop_loop');
            ?>

	<?php 
        } elseif (!woocommerce_product_subcategories(array('before' => woocommerce_product_loop_start(false), 'after' => woocommerce_product_loop_end(false)))) {
            ?>

		<?php 
            wc_get_template('loop/no-products-found.php');
            ?>

	<?php 
        }
        ?>

<?php 
        wp_reset_postdata();
        wp_reset_query();
        echo '</div>';
    }