WC_Widget_Rating_Filter

Rating Filter Widget and related functions.

Defined (1)

The class is defined in the following location(s).

/includes/widgets/class-wc-widget-rating-filter.php  
  1. class WC_Widget_Rating_Filter extends WC_Widget { 
  2.  
  3. /** 
  4. * Constructor. 
  5. */ 
  6. public function __construct() { 
  7. $this->widget_cssclass = 'woocommerce widget_rating_filter'; 
  8. $this->widget_description = __( 'Filter products by rating when viewing product archives and categories.', 'woocommerce' ); 
  9. $this->widget_id = 'woocommerce_rating_filter'; 
  10. $this->widget_name = __( 'WooCommerce average rating filter', 'woocommerce' ); 
  11. $this->settings = array( 
  12. 'title' => array( 
  13. 'type' => 'text',  
  14. 'std' => __( 'Average rating', 'woocommerce' ),  
  15. 'label' => __( 'Title', 'woocommerce' ),  
  16. ),  
  17. ); 
  18. parent::__construct(); 
  19.  
  20. /** 
  21. * Get current page URL for layered nav items. 
  22. * @return string 
  23. */ 
  24. protected function get_page_base_url() { 
  25. if ( defined( 'SHOP_IS_ON_FRONT' ) ) { 
  26. $link = home_url(); 
  27. } elseif ( is_post_type_archive( 'product' ) || is_page( wc_get_page_id( 'shop' ) ) ) { 
  28. $link = get_post_type_archive_link( 'product' ); 
  29. } else { 
  30. $link = get_term_link( get_query_var( 'term' ), get_query_var( 'taxonomy' ) ); 
  31.  
  32. // Min/Max 
  33. if ( isset( $_GET['min_price'] ) ) { 
  34. $link = add_query_arg( 'min_price', wc_clean( $_GET['min_price'] ), $link ); 
  35.  
  36. if ( isset( $_GET['max_price'] ) ) { 
  37. $link = add_query_arg( 'max_price', wc_clean( $_GET['max_price'] ), $link ); 
  38.  
  39. // Orderby 
  40. if ( isset( $_GET['orderby'] ) ) { 
  41. $link = add_query_arg( 'orderby', wc_clean( $_GET['orderby'] ), $link ); 
  42.  
  43. /** 
  44. * Search Arg. 
  45. * To support quote characters, first they are decoded from " entities, then URL encoded. 
  46. */ 
  47. if ( get_search_query() ) { 
  48. $link = add_query_arg( 's', rawurlencode( htmlspecialchars_decode( get_search_query() ) ), $link ); 
  49.  
  50. // Post Type Arg 
  51. if ( isset( $_GET['post_type'] ) ) { 
  52. $link = add_query_arg( 'post_type', wc_clean( $_GET['post_type'] ), $link ); 
  53.  
  54. // All current filters 
  55. if ( $_chosen_attributes = WC_Query::get_layered_nav_chosen_attributes() ) { 
  56. foreach ( $_chosen_attributes as $name => $data ) { 
  57. $filter_name = sanitize_title( str_replace( 'pa_', '', $name ) ); 
  58. if ( ! empty( $data['terms'] ) ) { 
  59. $link = add_query_arg( 'filter_' . $filter_name, implode( ', ', $data['terms'] ), $link ); 
  60. if ( 'or' == $data['query_type'] ) { 
  61. $link = add_query_arg( 'query_type_' . $filter_name, 'or', $link ); 
  62.  
  63. return $link; 
  64.  
  65. /** 
  66. * Count products after other filters have occurred by adjusting the main query. 
  67. * @param int $rating 
  68. * @return int 
  69. */ 
  70. protected function get_filtered_product_count( $rating ) { 
  71. global $wpdb; 
  72.  
  73. $tax_query = WC_Query::get_main_tax_query(); 
  74. $meta_query = WC_Query::get_main_meta_query(); 
  75.  
  76. // Unset current rating filter. 
  77. foreach ( $tax_query as $key => $query ) { 
  78. if ( ! empty( $query['rating_filter'] ) ) { 
  79. unset( $tax_query[ $key ] ); 
  80. break; 
  81.  
  82. // Set new rating filter. 
  83. $product_visibility_terms = wc_get_product_visibility_term_ids(); 
  84. $tax_query[] = array( 
  85. 'taxonomy' => 'product_visibility',  
  86. 'field' => 'term_taxonomy_id',  
  87. 'terms' => $product_visibility_terms[ 'rated-' . $rating ],  
  88. 'operator' => 'IN',  
  89. 'rating_filter' => true,  
  90. ); 
  91.  
  92. $meta_query = new WP_Meta_Query( $meta_query ); 
  93. $tax_query = new WP_Tax_Query( $tax_query ); 
  94. $meta_query_sql = $meta_query->get_sql( 'post', $wpdb->posts, 'ID' ); 
  95. $tax_query_sql = $tax_query->get_sql( $wpdb->posts, 'ID' ); 
  96.  
  97. $sql = "SELECT COUNT( DISTINCT {$wpdb->posts}.ID ) FROM {$wpdb->posts} "; 
  98. $sql .= $tax_query_sql['join'] . $meta_query_sql['join']; 
  99. $sql .= " WHERE {$wpdb->posts}.post_type = 'product' AND {$wpdb->posts}.post_status = 'publish' "; 
  100. $sql .= $tax_query_sql['where'] . $meta_query_sql['where']; 
  101.  
  102. if ( $search = WC_Query::get_main_search_query_sql() ) { 
  103. $sql .= ' AND ' . $search; 
  104.  
  105. return absint( $wpdb->get_var( $sql ) ); 
  106.  
  107. /** 
  108. * widget function. 
  109. * @see WP_Widget 
  110. * @param array $args 
  111. * @param array $instance 
  112. */ 
  113. public function widget( $args, $instance ) { 
  114. global $wp_the_query; 
  115.  
  116. if ( ! is_post_type_archive( 'product' ) && ! is_tax( get_object_taxonomies( 'product' ) ) ) { 
  117. return; 
  118.  
  119. if ( ! $wp_the_query->post_count ) { 
  120. return; 
  121.  
  122. ob_start(); 
  123.  
  124. $found = false; 
  125. $rating_filter = isset( $_GET['rating_filter'] ) ? array_filter( array_map( 'absint', explode( ', ', $_GET['rating_filter'] ) ) ) : array(); 
  126.  
  127. $this->widget_start( $args, $instance ); 
  128.  
  129. echo '<ul>'; 
  130.  
  131. for ( $rating = 5; $rating >= 1; $rating-- ) { 
  132. $count = $this->get_filtered_product_count( $rating ); 
  133. if ( empty( $count ) ) { 
  134. continue; 
  135. $found = true; 
  136. $link = $this->get_page_base_url(); 
  137.  
  138. if ( in_array( $rating, $rating_filter ) ) { 
  139. $link_ratings = implode( ', ', array_diff( $rating_filter, array( $rating ) ) ); 
  140. } else { 
  141. $link_ratings = implode( ', ', array_merge( $rating_filter, array( $rating ) ) ); 
  142.  
  143. $link = $link_ratings ? add_query_arg( 'rating_filter', $link_ratings ) : remove_query_arg( 'rating_filter' ); 
  144.  
  145. echo '<li class="wc-layered-nav-rating ' . ( in_array( $rating, $rating_filter ) ? 'chosen' : '' ) . '">'; 
  146.  
  147. echo '<a href="' . esc_url( apply_filters( 'woocommerce_rating_filter_link', $link ) ) . '">'; 
  148.  
  149. echo '<span class="star-rating"> 
  150. <span style="width:' . esc_attr( ( $rating / 5 ) * 100 ) . '%">' . sprintf( esc_html__( 'Rated %s out of 5', 'woocommerce' ), $rating ) . '</span> 
  151. </span> (' . esc_html( $count ) . ')'; 
  152.  
  153. echo '</a>'; 
  154.  
  155. echo '</li>'; 
  156.  
  157. echo '</ul>'; 
  158.  
  159. $this->widget_end( $args ); 
  160.  
  161. if ( ! $found ) { 
  162. ob_end_clean(); 
  163. } else { 
  164. echo ob_get_clean();