/**
  * Output widget.
  *
  * @see WP_Widget
  *
  * @param array $args
  * @param array $instance
  */
 public function widget($args, $instance)
 {
     global $_chosen_attributes;
     if (!is_post_type_archive('product') && !is_tax(get_object_taxonomies('product'))) {
         return;
     }
     $current_term = is_tax() ? get_queried_object()->term_id : '';
     $current_tax = is_tax() ? get_queried_object()->taxonomy : '';
     $taxonomy = isset($instance['attribute']) ? wc_attribute_taxonomy_name($instance['attribute']) : $this->settings['attribute']['std'];
     $query_type = isset($instance['query_type']) ? $instance['query_type'] : $this->settings['query_type']['std'];
     $display_type = isset($instance['display_type']) ? $instance['display_type'] : $this->settings['display_type']['std'];
     if (!taxonomy_exists($taxonomy)) {
         return;
     }
     $get_terms_args = array('hide_empty' => '1');
     $orderby = wc_attribute_orderby($taxonomy);
     switch ($orderby) {
         case 'name':
             $get_terms_args['orderby'] = 'name';
             $get_terms_args['menu_order'] = false;
             break;
         case 'id':
             $get_terms_args['orderby'] = 'id';
             $get_terms_args['order'] = 'ASC';
             $get_terms_args['menu_order'] = false;
             break;
         case 'menu_order':
             $get_terms_args['menu_order'] = 'ASC';
             break;
     }
     $terms = get_terms($taxonomy, $get_terms_args);
     if (0 < count($terms)) {
         ob_start();
         $found = false;
         $this->widget_start($args, $instance);
         // Force found when option is selected - do not force found on taxonomy attributes
         if (!is_tax() && is_array($_chosen_attributes) && array_key_exists($taxonomy, $_chosen_attributes)) {
             $found = true;
         }
         if ('dropdown' == $display_type) {
             // skip when viewing the taxonomy
             if ($current_tax && $taxonomy == $current_tax) {
                 $found = false;
             } else {
                 $taxonomy_filter = str_replace('pa_', '', $taxonomy);
                 $found = false;
                 echo '<select class="dropdown_layered_nav_' . $taxonomy_filter . '">';
                 echo '<option value="">' . sprintf(__('Any %s', 'woocommerce'), wc_attribute_label($taxonomy)) . '</option>';
                 foreach ($terms as $term) {
                     // If on a term page, skip that term in widget list
                     if ($term->term_id == $current_term) {
                         continue;
                     }
                     // Get count based on current view
                     $_products_in_term = wc_get_term_product_ids($term->term_id, $taxonomy);
                     $option_is_set = isset($_chosen_attributes[$taxonomy]) && in_array($term->term_id, $_chosen_attributes[$taxonomy]['terms']);
                     // If this is an AND query, only show options with count > 0
                     if ('and' == $query_type) {
                         $count = sizeof(array_intersect($_products_in_term, WC()->query->filtered_product_ids));
                         if (0 < $count) {
                             $found = true;
                         }
                         if (0 == $count && !$option_is_set) {
                             continue;
                         }
                         // If this is an OR query, show all options so search can be expanded
                     } else {
                         $count = sizeof(array_intersect($_products_in_term, WC()->query->unfiltered_product_ids));
                         if (0 < $count) {
                             $found = true;
                         }
                     }
                     echo '<option value="' . esc_attr($term->term_id) . '" ' . selected(isset($_GET['filter_' . $taxonomy_filter]) ? $_GET['filter_' . $taxonomy_filter] : '', $term->term_id, false) . '>' . esc_html($term->name) . '</option>';
                 }
                 echo '</select>';
                 wc_enqueue_js("\n\t\t\t\t\t\tjQuery( '.dropdown_layered_nav_{$taxonomy_filter}' ).change( function() {\n\t\t\t\t\t\t\tvar term_id = parseInt( jQuery( this ).val(), 10 );\n\t\t\t\t\t\t\tlocation.href = '" . preg_replace('%\\/page\\/[0-9]+%', '', str_replace(array('&amp;', '%2C'), array('&', ','), esc_js(add_query_arg('filtering', '1', remove_query_arg(array('page', 'filter_' . $taxonomy_filter)))))) . "&filter_{$taxonomy_filter}=' + ( isNaN( term_id ) ? '' : term_id );\n\t\t\t\t\t\t});\n\t\t\t\t\t");
             }
         } else {
             // List display
             echo '<ul>';
             // flip the filtered_products_ids array so that we can use the more efficient array_intersect_key
             $filtered_product_ids = array_flip(WC()->query->filtered_product_ids);
             foreach ($terms as $term) {
                 // Get count based on current view - uses transients
                 $_products_in_term = wc_get_term_product_ids($term->term_id, $taxonomy);
                 $option_is_set = isset($_chosen_attributes[$taxonomy]) && in_array($term->term_id, $_chosen_attributes[$taxonomy]['terms']);
                 // skip the term for the current archive
                 if ($current_term == $term->term_id) {
                     continue;
                 }
                 // If this is an AND query, only show options with count > 0
                 if ('and' == $query_type) {
                     // flip the product_in_term array so that we can use array_intersect_key
                     $_products_in_term = array_flip($_products_in_term);
                     // Intersect both arrays now they have been flipped so that we can use their keys
                     $count = sizeof(array_intersect_key($_products_in_term, $filtered_product_ids));
                     if (0 < $count && $current_term !== $term->term_id) {
                         $found = true;
                     }
                     if (0 == $count && !$option_is_set) {
                         continue;
                     }
                     // If this is an OR query, show all options so search can be expanded
                 } else {
                     $count = sizeof(array_intersect($_products_in_term, WC()->query->unfiltered_product_ids));
                     if (0 < $count) {
                         $found = true;
                     }
                 }
                 $arg = 'filter_' . sanitize_title($instance['attribute']);
                 $current_filter = isset($_GET[$arg]) ? explode(',', $_GET[$arg]) : array();
                 if (!is_array($current_filter)) {
                     $current_filter = array();
                 }
                 $current_filter = array_map('esc_attr', $current_filter);
                 if (!in_array($term->term_id, $current_filter)) {
                     $current_filter[] = $term->term_id;
                 }
                 // Base Link decided by current page
                 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'));
                 }
                 // All current filters
                 if ($_chosen_attributes) {
                     foreach ($_chosen_attributes as $name => $data) {
                         if ($name !== $taxonomy) {
                             // Exclude query arg for current term archive term
                             while (in_array($current_term, $data['terms'])) {
                                 $key = array_search($current_term, $data);
                                 unset($data['terms'][$key]);
                             }
                             // Remove pa_ and sanitize
                             $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);
                             }
                         }
                     }
                 }
                 // Min/Max
                 if (isset($_GET['min_price'])) {
                     $link = add_query_arg('min_price', $_GET['min_price'], $link);
                 }
                 if (isset($_GET['max_price'])) {
                     $link = add_query_arg('max_price', $_GET['max_price'], $link);
                 }
                 // Orderby
                 if (isset($_GET['orderby'])) {
                     $link = add_query_arg('orderby', $_GET['orderby'], $link);
                 }
                 // Current Filter = this widget
                 if (isset($_chosen_attributes[$taxonomy]) && is_array($_chosen_attributes[$taxonomy]['terms']) && in_array($term->term_id, $_chosen_attributes[$taxonomy]['terms'])) {
                     $class = 'class="chosen"';
                     // Remove this term is $current_filter has more than 1 term filtered
                     if (sizeof($current_filter) > 1) {
                         $current_filter_without_this = array_diff($current_filter, array($term->term_id));
                         $link = add_query_arg($arg, implode(',', $current_filter_without_this), $link);
                     }
                 } else {
                     $class = '';
                     $link = add_query_arg($arg, implode(',', $current_filter), $link);
                 }
                 // Search Arg
                 if (get_search_query()) {
                     $link = add_query_arg('s', get_search_query(), $link);
                 }
                 // Post Type Arg
                 if (isset($_GET['post_type'])) {
                     $link = add_query_arg('post_type', $_GET['post_type'], $link);
                 }
                 // Query type Arg
                 if ($query_type == 'or' && !(sizeof($current_filter) == 1 && isset($_chosen_attributes[$taxonomy]['terms']) && is_array($_chosen_attributes[$taxonomy]['terms']) && in_array($term->term_id, $_chosen_attributes[$taxonomy]['terms']))) {
                     $link = add_query_arg('query_type_' . sanitize_title($instance['attribute']), 'or', $link);
                 }
                 echo '<li ' . $class . '>';
                 echo $count > 0 || $option_is_set ? '<a href="' . esc_url(apply_filters('woocommerce_layered_nav_link', $link)) . '">' : '<span>';
                 echo $term->name;
                 echo $count > 0 || $option_is_set ? '</a>' : '</span>';
                 echo ' <span class="count">(' . $count . ')</span></li>';
             }
             echo '</ul>';
         }
         // End display type conditional
         $this->widget_end($args);
         if (!$found) {
             ob_end_clean();
         } else {
             echo ob_get_clean();
         }
     }
 }
 /**
  * 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)
 {
     global $_chosen_attributes;
     // List display
     echo '<ul>';
     // flip the filtered_products_ids array so that we can use the more efficient array_intersect_key
     $filtered_product_ids = array_flip(WC()->query->filtered_product_ids);
     $unfiltered_product_ids = array_flip(WC()->query->unfiltered_product_ids);
     $found = false;
     foreach ($terms as $term) {
         // Get count based on current view - uses transients
         // flip the product_in_term array so that we can use array_intersect_key
         $_products_in_term = array_flip(wc_get_term_product_ids($term->term_id, $taxonomy));
         $current_values = isset($_chosen_attributes[$taxonomy]['terms']) ? $_chosen_attributes[$taxonomy]['terms'] : array();
         $option_is_set = in_array($term->slug, $current_values);
         // skip the term for the current archive
         if ($this->get_current_term_id() === $term->term_id) {
             continue;
         }
         // If this is an AND query, only show options with count > 0
         if ('and' === $query_type) {
             // Intersect both arrays now they have been flipped so that we can use their keys
             $count = sizeof(array_intersect_key($_products_in_term, $filtered_product_ids));
             if (0 < $count) {
                 $found = true;
             }
             if (0 === $count && !$option_is_set) {
                 continue;
             }
             // If this is an OR query, show all options so search can be expanded
         } else {
             // Intersect both arrays now they have been flipped so that we can use their keys
             $count = sizeof(array_intersect_key($_products_in_term, $unfiltered_product_ids));
             if (0 < $count) {
                 $found = true;
             }
         }
         $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();
         // 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 ($query_type === 'or' && !(1 === sizeof($current_filter) && $option_is_set)) {
                 $link = add_query_arg('query_type_' . sanitize_title(str_replace('pa_', '', $taxonomy)), 'or', $link);
             }
         }
         echo '<li class="wc-layered-nav-term ' . ($option_is_set ? 'chosen' : '') . '">';
         echo $count > 0 || $option_is_set ? '<a href="' . esc_url(apply_filters('woocommerce_layered_nav_link', $link)) . '">' : '<span>';
         echo esc_html($term->name);
         echo $count > 0 || $option_is_set ? '</a>' : '</span>';
         echo ' <span class="count">(' . absint($count) . ')</span></li>';
     }
     echo '</ul>';
     return $found;
 }