WC_Widget_Price_Filter

Price Filter Widget and related functions.

Defined (1)

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

/includes/widgets/class-wc-widget-price-filter.php  
  1. class WC_Widget_Price_Filter extends WC_Widget { 
  2.  
  3. /** 
  4. * Constructor. 
  5. */ 
  6. public function __construct() { 
  7. $this->widget_cssclass = 'woocommerce widget_price_filter'; 
  8. $this->widget_description = __( 'Shows a price filter slider in a widget which lets you narrow down the list of shown products when viewing product categories.', 'woocommerce' ); 
  9. $this->widget_id = 'woocommerce_price_filter'; 
  10. $this->widget_name = __( 'WooCommerce price filter', 'woocommerce' ); 
  11. $this->settings = array( 
  12. 'title' => array( 
  13. 'type' => 'text',  
  14. 'std' => __( 'Filter by price', 'woocommerce' ),  
  15. 'label' => __( 'Title', 'woocommerce' ),  
  16. ),  
  17. ); 
  18. $suffix = defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ? '' : '.min'; 
  19. wp_register_script( 'accounting', WC()->plugin_url() . '/assets/js/accounting/accounting' . $suffix . '.js', array( 'jquery' ), '0.4.2' ); 
  20. wp_register_script( 'wc-jquery-ui-touchpunch', WC()->plugin_url() . '/assets/js/jquery-ui-touch-punch/jquery-ui-touch-punch' . $suffix . '.js', array( 'jquery-ui-slider' ), WC_VERSION, true ); 
  21. wp_register_script( 'wc-price-slider', WC()->plugin_url() . '/assets/js/frontend/price-slider' . $suffix . '.js', array( 'jquery-ui-slider', 'wc-jquery-ui-touchpunch', 'accounting' ), WC_VERSION, true ); 
  22. wp_localize_script( 'wc-price-slider', 'woocommerce_price_slider_params', array( 
  23. 'min_price' => isset( $_GET['min_price'] ) ? esc_attr( $_GET['min_price'] ) : '',  
  24. 'max_price' => isset( $_GET['max_price'] ) ? esc_attr( $_GET['max_price'] ) : '',  
  25. 'currency_format_num_decimals' => 0,  
  26. 'currency_format_symbol' => get_woocommerce_currency_symbol(),  
  27. 'currency_format_decimal_sep' => esc_attr( wc_get_price_decimal_separator() ),  
  28. 'currency_format_thousand_sep' => esc_attr( wc_get_price_thousand_separator() ),  
  29. 'currency_format' => esc_attr( str_replace( array( '%1$s', '%2$s' ), array( '%s', '%v' ), get_woocommerce_price_format() ) ),  
  30. ) ); 
  31. parent::__construct(); 
  32.  
  33. /** 
  34. * Output widget. 
  35. * @see WP_Widget 
  36. * @param array $args 
  37. * @param array $instance 
  38. */ 
  39. public function widget( $args, $instance ) { 
  40. global $wp, $wp_the_query; 
  41.  
  42. if ( ! is_post_type_archive( 'product' ) && ! is_tax( get_object_taxonomies( 'product' ) ) ) { 
  43. return; 
  44.  
  45. if ( ! $wp_the_query->post_count ) { 
  46. return; 
  47.  
  48. $min_price = isset( $_GET['min_price'] ) ? esc_attr( $_GET['min_price'] ) : ''; 
  49. $max_price = isset( $_GET['max_price'] ) ? esc_attr( $_GET['max_price'] ) : ''; 
  50.  
  51. wp_enqueue_script( 'wc-price-slider' ); 
  52.  
  53. // Find min and max price in current result set 
  54. $prices = $this->get_filtered_price(); 
  55. $min = floor( $prices->min_price ); 
  56. $max = ceil( $prices->max_price ); 
  57.  
  58. if ( $min === $max ) { 
  59. return; 
  60.  
  61. $this->widget_start( $args, $instance ); 
  62.  
  63. if ( '' === get_option( 'permalink_structure' ) ) { 
  64. $form_action = remove_query_arg( array( 'page', 'paged' ), add_query_arg( $wp->query_string, '', home_url( $wp->request ) ) ); 
  65. } else { 
  66. $form_action = preg_replace( '%\/page/[0-9]+%', '', home_url( trailingslashit( $wp->request ) ) ); 
  67.  
  68. /** 
  69. * Adjust max if the store taxes are not displayed how they are stored. 
  70. * Min is left alone because the product may not be taxable. 
  71. * Kicks in when prices excluding tax are displayed including tax. 
  72. */ 
  73. if ( wc_tax_enabled() && 'incl' === get_option( 'woocommerce_tax_display_shop' ) && ! wc_prices_include_tax() ) { 
  74. $tax_classes = array_merge( array( '' ), WC_Tax::get_tax_classes() ); 
  75. $class_max = $max; 
  76.  
  77. foreach ( $tax_classes as $tax_class ) { 
  78. if ( $tax_rates = WC_Tax::get_rates( $tax_class ) ) { 
  79. $class_max = $max + WC_Tax::get_tax_total( WC_Tax::calc_exclusive_tax( $max, $tax_rates ) ); 
  80.  
  81. $max = $class_max; 
  82.  
  83. echo '<form method="get" action="' . esc_url( $form_action ) . '"> 
  84. <div class="price_slider_wrapper"> 
  85. <div class="price_slider" style="display:none;"></div> 
  86. <div class="price_slider_amount"> 
  87. <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' ) . '" /> 
  88. <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' ) . '" /> 
  89. <button type="submit" class="button">' . esc_html__( 'Filter', 'woocommerce' ) . '</button> 
  90. <div class="price_label" style="display:none;"> 
  91. ' . esc_html__( 'Price:', 'woocommerce' ) . ' <span class="from"></span> — <span class="to"></span> 
  92. </div> 
  93. ' . wc_query_string_form_fields( null, array( 'min_price', 'max_price' ), '', true ) . ' 
  94. <div class="clear"></div> 
  95. </div> 
  96. </div> 
  97. </form>'; 
  98.  
  99. $this->widget_end( $args ); 
  100.  
  101. /** 
  102. * Get filtered min price for current products. 
  103. * @return int 
  104. */ 
  105. protected function get_filtered_price() { 
  106. global $wpdb, $wp_the_query; 
  107.  
  108. $args = $wp_the_query->query_vars; 
  109. $tax_query = isset( $args['tax_query'] ) ? $args['tax_query'] : array(); 
  110. $meta_query = isset( $args['meta_query'] ) ? $args['meta_query'] : array(); 
  111.  
  112. if ( ! empty( $args['taxonomy'] ) && ! empty( $args['term'] ) ) { 
  113. $tax_query[] = array( 
  114. 'taxonomy' => $args['taxonomy'],  
  115. 'terms' => array( $args['term'] ),  
  116. 'field' => 'slug',  
  117. ); 
  118.  
  119. foreach ( $meta_query + $tax_query as $key => $query ) { 
  120. if ( ! empty( $query['price_filter'] ) || ! empty( $query['rating_filter'] ) ) { 
  121. unset( $meta_query[ $key ] ); 
  122.  
  123. $meta_query = new WP_Meta_Query( $meta_query ); 
  124. $tax_query = new WP_Tax_Query( $tax_query ); 
  125.  
  126. $meta_query_sql = $meta_query->get_sql( 'post', $wpdb->posts, 'ID' ); 
  127. $tax_query_sql = $tax_query->get_sql( $wpdb->posts, 'ID' ); 
  128.  
  129. $sql = "SELECT min( FLOOR( price_meta.meta_value ) ) as min_price, max( CEILING( price_meta.meta_value ) ) as max_price FROM {$wpdb->posts} "; 
  130. $sql .= " LEFT JOIN {$wpdb->postmeta} as price_meta ON {$wpdb->posts}.ID = price_meta.post_id " . $tax_query_sql['join'] . $meta_query_sql['join']; 
  131. $sql .= " WHERE {$wpdb->posts}.post_type IN ('" . implode( "', '", array_map( 'esc_sql', apply_filters( 'woocommerce_price_filter_post_type', array( 'product' ) ) ) ) . "') 
  132. AND {$wpdb->posts}.post_status = 'publish' 
  133. AND price_meta.meta_key IN ('" . implode( "', '", array_map( 'esc_sql', apply_filters( 'woocommerce_price_filter_meta_keys', array( '_price' ) ) ) ) . "') 
  134. AND price_meta.meta_value > '' "; 
  135. $sql .= $tax_query_sql['where'] . $meta_query_sql['where']; 
  136.  
  137. if ( $search = WC_Query::get_main_search_query_sql() ) { 
  138. $sql .= ' AND ' . $search; 
  139.  
  140. return $wpdb->get_row( $sql );