class-wc-widget-brand-description.php
1 year ago
class-wc-widget-brand-nav.php
7 months ago
class-wc-widget-brand-thumbnails.php
1 year ago
class-wc-widget-cart.php
3 years ago
class-wc-widget-layered-nav-filters.php
2 years ago
class-wc-widget-layered-nav.php
3 months ago
class-wc-widget-price-filter.php
8 months ago
class-wc-widget-product-categories.php
7 months ago
class-wc-widget-product-search.php
5 years ago
class-wc-widget-product-tag-cloud.php
5 years ago
class-wc-widget-products.php
1 year ago
class-wc-widget-rating-filter.php
5 years ago
class-wc-widget-recent-reviews.php
2 months ago
class-wc-widget-recently-viewed.php
1 year ago
class-wc-widget-top-rated-products.php
5 years ago
class-wc-widget-rating-filter.php
148 lines
| 1 | <?php |
| 2 | /** |
| 3 | * Rating Filter Widget and related functions. |
| 4 | * |
| 5 | * @package WooCommerce\Widgets |
| 6 | * @version 2.6.0 |
| 7 | */ |
| 8 | |
| 9 | defined( 'ABSPATH' ) || exit; |
| 10 | |
| 11 | /** |
| 12 | * Widget rating filter class. |
| 13 | */ |
| 14 | class WC_Widget_Rating_Filter extends WC_Widget { |
| 15 | |
| 16 | /** |
| 17 | * Constructor. |
| 18 | */ |
| 19 | public function __construct() { |
| 20 | $this->widget_cssclass = 'woocommerce widget_rating_filter'; |
| 21 | $this->widget_description = __( 'Display a list of star ratings to filter products in your store.', 'woocommerce' ); |
| 22 | $this->widget_id = 'woocommerce_rating_filter'; |
| 23 | $this->widget_name = __( 'Filter Products by Rating', 'woocommerce' ); |
| 24 | $this->settings = array( |
| 25 | 'title' => array( |
| 26 | 'type' => 'text', |
| 27 | 'std' => __( 'Average rating', 'woocommerce' ), |
| 28 | 'label' => __( 'Title', 'woocommerce' ), |
| 29 | ), |
| 30 | ); |
| 31 | parent::__construct(); |
| 32 | } |
| 33 | |
| 34 | /** |
| 35 | * Count products after other filters have occurred by adjusting the main query. |
| 36 | * |
| 37 | * @param int $rating Rating. |
| 38 | * @return int |
| 39 | */ |
| 40 | protected function get_filtered_product_count( $rating ) { |
| 41 | global $wpdb; |
| 42 | |
| 43 | $tax_query = WC_Query::get_main_tax_query(); |
| 44 | $meta_query = WC_Query::get_main_meta_query(); |
| 45 | |
| 46 | // Unset current rating filter. |
| 47 | foreach ( $tax_query as $key => $query ) { |
| 48 | if ( ! empty( $query['rating_filter'] ) ) { |
| 49 | unset( $tax_query[ $key ] ); |
| 50 | break; |
| 51 | } |
| 52 | } |
| 53 | |
| 54 | // Set new rating filter. |
| 55 | $product_visibility_terms = wc_get_product_visibility_term_ids(); |
| 56 | $tax_query[] = array( |
| 57 | 'taxonomy' => 'product_visibility', |
| 58 | 'field' => 'term_taxonomy_id', |
| 59 | 'terms' => $product_visibility_terms[ 'rated-' . $rating ], |
| 60 | 'operator' => 'IN', |
| 61 | 'rating_filter' => true, |
| 62 | ); |
| 63 | |
| 64 | $meta_query = new WP_Meta_Query( $meta_query ); |
| 65 | $tax_query = new WP_Tax_Query( $tax_query ); |
| 66 | $meta_query_sql = $meta_query->get_sql( 'post', $wpdb->posts, 'ID' ); |
| 67 | $tax_query_sql = $tax_query->get_sql( $wpdb->posts, 'ID' ); |
| 68 | |
| 69 | $sql = "SELECT COUNT( DISTINCT {$wpdb->posts}.ID ) FROM {$wpdb->posts} "; |
| 70 | $sql .= $tax_query_sql['join'] . $meta_query_sql['join']; |
| 71 | $sql .= " WHERE {$wpdb->posts}.post_type = 'product' AND {$wpdb->posts}.post_status = 'publish' "; |
| 72 | $sql .= $tax_query_sql['where'] . $meta_query_sql['where']; |
| 73 | |
| 74 | $search = WC_Query::get_main_search_query_sql(); |
| 75 | if ( $search ) { |
| 76 | $sql .= ' AND ' . $search; |
| 77 | } |
| 78 | |
| 79 | return absint( $wpdb->get_var( $sql ) ); // WPCS: unprepared SQL ok. |
| 80 | } |
| 81 | |
| 82 | /** |
| 83 | * Widget function. |
| 84 | * |
| 85 | * @see WP_Widget |
| 86 | * @param array $args Arguments. |
| 87 | * @param array $instance Widget instance. |
| 88 | */ |
| 89 | public function widget( $args, $instance ) { |
| 90 | if ( ! is_shop() && ! is_product_taxonomy() ) { |
| 91 | return; |
| 92 | } |
| 93 | |
| 94 | if ( ! WC()->query->get_main_query()->post_count ) { |
| 95 | return; |
| 96 | } |
| 97 | |
| 98 | ob_start(); |
| 99 | |
| 100 | $found = false; |
| 101 | $rating_filter = isset( $_GET['rating_filter'] ) ? array_filter( array_map( 'absint', explode( ',', wp_unslash( $_GET['rating_filter'] ) ) ) ) : array(); // WPCS: input var ok, CSRF ok, sanitization ok. |
| 102 | $base_link = remove_query_arg( 'paged', $this->get_current_page_url() ); |
| 103 | |
| 104 | $this->widget_start( $args, $instance ); |
| 105 | |
| 106 | echo '<ul>'; |
| 107 | |
| 108 | for ( $rating = 5; $rating >= 1; $rating-- ) { |
| 109 | $count = $this->get_filtered_product_count( $rating ); |
| 110 | if ( empty( $count ) ) { |
| 111 | continue; |
| 112 | } |
| 113 | $found = true; |
| 114 | $link = $base_link; |
| 115 | |
| 116 | if ( in_array( $rating, $rating_filter, true ) ) { |
| 117 | $link_ratings = implode( ',', array_diff( $rating_filter, array( $rating ) ) ); |
| 118 | } else { |
| 119 | $link_ratings = implode( ',', array_merge( $rating_filter, array( $rating ) ) ); |
| 120 | } |
| 121 | |
| 122 | $class = in_array( $rating, $rating_filter, true ) ? 'wc-layered-nav-rating chosen' : 'wc-layered-nav-rating'; |
| 123 | $link = apply_filters( 'woocommerce_rating_filter_link', $link_ratings ? add_query_arg( 'rating_filter', $link_ratings, $link ) : remove_query_arg( 'rating_filter' ) ); |
| 124 | $rating_html = wc_get_star_rating_html( $rating ); |
| 125 | $count_html = wp_kses( |
| 126 | apply_filters( 'woocommerce_rating_filter_count', "({$count})", $count, $rating ), |
| 127 | array( |
| 128 | 'em' => array(), |
| 129 | 'span' => array(), |
| 130 | 'strong' => array(), |
| 131 | ) |
| 132 | ); |
| 133 | |
| 134 | printf( '<li class="%s"><a href="%s"><span class="star-rating">%s</span> %s</a></li>', esc_attr( $class ), esc_url( $link ), $rating_html, $count_html ); // WPCS: XSS ok. |
| 135 | } |
| 136 | |
| 137 | echo '</ul>'; |
| 138 | |
| 139 | $this->widget_end( $args ); |
| 140 | |
| 141 | if ( ! $found ) { |
| 142 | ob_end_clean(); |
| 143 | } else { |
| 144 | echo ob_get_clean(); // WPCS: XSS ok. |
| 145 | } |
| 146 | } |
| 147 | } |
| 148 |