File "class-wc-widget-layered-nav.php"

Full path: /home/kosmetik/public_html/wp-content/plugins/woocommerce/includes/widgets/class-wc-widget-layered-nav.php
File size: 12.54 B
MIME-type: text/x-php
Charset: utf-8

Download   Open   Edit   Advanced Editor   Back

<?php

use Automattic\WooCommerce\Internal\ProductAttributesLookup\Filterer;
defined('ABSPATH') || exit;
class WC_Widget_Layered_Nav extends WC_Widget
{
    public function __construct()
    {
        $this->widget_cssclass = 'woocommerce widget_layered_nav woocommerce-widget-layered-nav';
        $this->widget_description = __('Display a list of attributes to filter products in your store.', 'woocommerce');
        $this->widget_id = 'woocommerce_layered_nav';
        $this->widget_name = __('Filter Products by Attribute', 'woocommerce');
        parent::__construct();
    }
    public function update($new_instance, $old_instance)
    {
        $this->init_settings();
        return parent::update($new_instance, $old_instance);
    }
    public function form($instance)
    {
        $this->init_settings();
        parent::form($instance);
    }
    public function init_settings()
    {
        $attribute_array = array();
        $std_attribute = '';
        $attribute_taxonomies = wc_get_attribute_taxonomies();
        if (!empty($attribute_taxonomies)) {
            foreach ($attribute_taxonomies as $tax) {
                if (taxonomy_exists(wc_attribute_taxonomy_name($tax->attribute_name))) {
                    $attribute_array[$tax->attribute_name] = $tax->attribute_name;
                }
            }
            $std_attribute = current($attribute_array);
        }
        $this->settings = array('title' => array('type' => 'text', 'std' => __('Filter by', 'woocommerce'), 'label' => __('Title', 'woocommerce')), 'attribute' => array('type' => 'select', 'std' => $std_attribute, 'label' => __('Attribute', 'woocommerce'), 'options' => $attribute_array), 'display_type' => array('type' => 'select', 'std' => 'list', 'label' => __('Display type', 'woocommerce'), 'options' => array('list' => __('List', 'woocommerce'), 'dropdown' => __('Dropdown', 'woocommerce'))), 'query_type' => array('type' => 'select', 'std' => 'and', 'label' => __('Query type', 'woocommerce'), 'options' => array('and' => __('AND', 'woocommerce'), 'or' => __('OR', 'woocommerce'))));
    }
    protected function get_instance_taxonomy($instance)
    {
        if (isset($instance['attribute'])) {
            return wc_attribute_taxonomy_name($instance['attribute']);
        }
        $attribute_taxonomies = wc_get_attribute_taxonomies();
        if (!empty($attribute_taxonomies)) {
            foreach ($attribute_taxonomies as $tax) {
                if (taxonomy_exists(wc_attribute_taxonomy_name($tax->attribute_name))) {
                    return wc_attribute_taxonomy_name($tax->attribute_name);
                }
            }
        }
        return '';
    }
    protected function get_instance_query_type($instance)
    {
        return isset($instance['query_type']) ? $instance['query_type'] : 'and';
    }
    protected function get_instance_display_type($instance)
    {
        return isset($instance['display_type']) ? $instance['display_type'] : 'list';
    }
    public function widget($args, $instance)
    {
        if (!is_shop() && !is_product_taxonomy()) {
            return;
        }
        $_chosen_attributes = WC_Query::get_layered_nav_chosen_attributes();
        $taxonomy = $this->get_instance_taxonomy($instance);
        $query_type = $this->get_instance_query_type($instance);
        $display_type = $this->get_instance_display_type($instance);
        if (!taxonomy_exists($taxonomy)) {
            return;
        }
        $terms = get_terms($taxonomy, array('hide_empty' => '1'));
        if (0 === count($terms)) {
            return;
        }
        ob_start();
        $this->widget_start($args, $instance);
        if ('dropdown' === $display_type) {
            wp_enqueue_script('selectWoo');
            wp_enqueue_style('select2');
            $found = $this->layered_nav_dropdown($terms, $taxonomy, $query_type);
        } else {
            $found = $this->layered_nav_list($terms, $taxonomy, $query_type);
        }
        $this->widget_end($args);
        if (!is_tax() && is_array($_chosen_attributes) && array_key_exists($taxonomy, $_chosen_attributes)) {
            $found = true;
        }
        if (!$found) {
            ob_end_clean();
        } else {
            echo ob_get_clean();
        }
    }
    protected function get_current_taxonomy()
    {
        return is_tax() ? get_queried_object()->taxonomy : '';
    }
    protected function get_current_term_id()
    {
        return absint(is_tax() ? get_queried_object()->term_id : 0);
    }
    protected function get_current_term_slug()
    {
        return absint(is_tax() ? get_queried_object()->slug : 0);
    }
    protected function layered_nav_dropdown($terms, $taxonomy, $query_type)
    {
        global $wp;
        $found = false;
        if ($taxonomy !== $this->get_current_taxonomy()) {
            $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();
            $taxonomy_filter_name = wc_attribute_taxonomy_slug($taxonomy);
            $taxonomy_label = wc_attribute_label($taxonomy);
            $any_label = apply_filters('woocommerce_layered_nav_any_label', sprintf(__('Any %s', 'woocommerce'), $taxonomy_label), $taxonomy_label, $taxonomy);
            $multiple = 'or' === $query_type;
            $current_values = isset($_chosen_attributes[$taxonomy]['terms']) ? $_chosen_attributes[$taxonomy]['terms'] : array();
            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(user_trailingslashit($wp->request)));
            }
            echo '<form method="get" action="' . esc_url($form_action) . '" class="woocommerce-widget-layered-nav-dropdown">';
            echo '<select class="woocommerce-widget-layered-nav-dropdown dropdown_layered_nav_' . esc_attr($taxonomy_filter_name) . '"' . ($multiple ? 'multiple="multiple"' : '') . '>';
            echo '<option value="">' . esc_html($any_label) . '</option>';
            foreach ($terms as $term) {
                if ($term->term_id === $this->get_current_term_id()) {
                    continue;
                }
                $option_is_set = in_array($term->slug, $current_values, true);
                $count = isset($term_counts[$term->term_id]) ? $term_counts[$term->term_id] : 0;
                if (0 < $count) {
                    $found = true;
                } elseif (0 === $count && !$option_is_set) {
                    continue;
                }
                echo '<option value="' . esc_attr(urldecode($term->slug)) . '" ' . selected($option_is_set, true, false) . '>' . esc_html($term->name) . '</option>';
            }
            echo '</select>';
            if ($multiple) {
                echo '<button class="woocommerce-widget-layered-nav-dropdown__submit" type="submit" value="' . esc_attr__('Apply', 'woocommerce') . '">' . esc_html__('Apply', 'woocommerce') . '</button>';
            }
            if ('or' === $query_type) {
                echo '<input type="hidden" name="query_type_' . esc_attr($taxonomy_filter_name) . '" value="or" />';
            }
            echo '<input type="hidden" name="filter_' . esc_attr($taxonomy_filter_name) . '" value="' . esc_attr(implode(',', $current_values)) . '" />';
            echo wc_query_string_form_fields(null, array('filter_' . $taxonomy_filter_name, 'query_type_' . $taxonomy_filter_name), '', true);
            echo '</form>';
            wc_enqueue_js("\n\t\t\t\t// Update value on change.\n\t\t\t\tjQuery( '.dropdown_layered_nav_" . esc_js($taxonomy_filter_name) . "' ).on( 'change', function() {\n\t\t\t\t\tvar slug = jQuery( this ).val();\n\t\t\t\t\tjQuery( ':input[name=\"filter_" . esc_js($taxonomy_filter_name) . "\"]' ).val( slug );\n\n\t\t\t\t\t// Submit form on change if standard dropdown.\n\t\t\t\t\tif ( ! jQuery( this ).attr( 'multiple' ) ) {\n\t\t\t\t\t\tjQuery( this ).closest( 'form' ).trigger( 'submit' );\n\t\t\t\t\t}\n\t\t\t\t});\n\n\t\t\t\t// Use Select2 enhancement if possible\n\t\t\t\tif ( jQuery().selectWoo ) {\n\t\t\t\t\tvar wc_layered_nav_select = function() {\n\t\t\t\t\t\tjQuery( '.dropdown_layered_nav_" . esc_js($taxonomy_filter_name) . "' ).selectWoo( {\n\t\t\t\t\t\t\tplaceholder: decodeURIComponent('" . rawurlencode((string) wp_specialchars_decode($any_label)) . "'),\n\t\t\t\t\t\t\tminimumResultsForSearch: 5,\n\t\t\t\t\t\t\twidth: '100%',\n\t\t\t\t\t\t\tallowClear: " . ($multiple ? 'false' : 'true') . ",\n\t\t\t\t\t\t\tlanguage: {\n\t\t\t\t\t\t\t\tnoResults: function() {\n\t\t\t\t\t\t\t\t\treturn '" . esc_js(_x('No matches found', 'enhanced select', 'woocommerce')) . "';\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} );\n\t\t\t\t\t};\n\t\t\t\t\twc_layered_nav_select();\n\t\t\t\t}\n\t\t\t");
        }
        return $found;
    }
    protected function get_filtered_term_product_counts($term_ids, $taxonomy, $query_type)
    {
        return wc_get_container()->get(Filterer::class)->get_filtered_term_product_counts($term_ids, $taxonomy, $query_type);
    }
    protected function get_main_tax_query()
    {
        return WC_Query::get_main_tax_query();
    }
    protected function get_main_search_query_sql()
    {
        return WC_Query::get_main_search_query_sql();
    }
    protected function get_main_meta_query()
    {
        return WC_Query::get_main_meta_query();
    }
    protected function layered_nav_list($terms, $taxonomy, $query_type)
    {
        echo '<ul class="woocommerce-widget-layered-nav-list">';
        $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;
        $base_link = $this->get_current_page_url();
        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, true);
            $count = isset($term_counts[$term->term_id]) ? $term_counts[$term->term_id] : 0;
            if ($this->get_current_term_id() === $term->term_id) {
                continue;
            }
            if (0 < $count) {
                $found = true;
            } elseif (0 === $count && !$option_is_set) {
                continue;
            }
            $filter_name = 'filter_' . wc_attribute_taxonomy_slug($taxonomy);
            $current_filter = isset($_GET[$filter_name]) ? explode(',', wc_clean(wp_unslash($_GET[$filter_name]))) : array();
            $current_filter = array_map('sanitize_title', $current_filter);
            if (!in_array($term->slug, $current_filter, true)) {
                $current_filter[] = $term->slug;
            }
            $link = remove_query_arg($filter_name, $base_link);
            foreach ($current_filter as $key => $value) {
                if ($value === $this->get_current_term_slug()) {
                    unset($current_filter[$key]);
                }
                if ($option_is_set && $value === $term->slug) {
                    unset($current_filter[$key]);
                }
            }
            if (!empty($current_filter)) {
                asort($current_filter);
                $link = add_query_arg($filter_name, implode(',', $current_filter), $link);
                if ('or' === $query_type && !(1 === count($current_filter) && $option_is_set)) {
                    $link = add_query_arg('query_type_' . wc_attribute_taxonomy_slug($taxonomy), 'or', $link);
                }
                $link = str_replace('%2C', ',', $link);
            }
            if ($count > 0 || $option_is_set) {
                $link = apply_filters('woocommerce_layered_nav_link', $link, $term, $taxonomy);
                $term_html = '<a rel="nofollow" href="' . esc_url($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="woocommerce-widget-layered-nav-list__item wc-layered-nav-term ' . ($option_is_set ? 'woocommerce-widget-layered-nav-list__item--chosen chosen' : '') . '">';
            echo apply_filters('woocommerce_layered_nav_term_html', $term_html, $term, $link, $count);
            echo '</li>';
        }
        echo '</ul>';
        return $found;
    }
}