woo_widget_cssclass = 'widget_price_filter'; $this->woo_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' ); $this->woo_widget_idbase = 'woocommerce_price_filter'; $this->woo_widget_name = __( 'WooCommerce Price Filter', 'woocommerce' ); /* Widget settings. */ $widget_ops = array( 'classname' => $this->woo_widget_cssclass, 'description' => $this->woo_widget_description ); /* Create the widget. */ $this->WP_Widget('price_filter', $this->woo_widget_name, $widget_ops); } /** * widget function. * * @see WP_Widget * @access public * @param array $args * @param array $instance * @return void */ function widget( $args, $instance ) { extract($args); global $_chosen_attributes, $wpdb, $woocommerce, $wp_query, $wp; if (!is_tax( 'product_cat' ) && !is_post_type_archive('product') && !is_tax( 'product_tag' )) return; // Not on product page - return if ( sizeof( $woocommerce->query->unfiltered_product_ids ) == 0 ) return; // None shown - return wp_enqueue_script( 'wc-price-slider' ); wp_localize_script( 'wc-price-slider', 'woocommerce_price_slider_params', array( 'currency_symbol' => get_woocommerce_currency_symbol(), 'currency_pos' => get_option( 'woocommerce_currency_pos' ), 'min_price' => isset( $woocommerce->session->min_price ) ? $woocommerce->session->min_price : '', 'max_price' => isset( $woocommerce->session->max_price ) ? $woocommerce->session->max_price : '' ) ); $title = $instance['title']; $title = apply_filters('widget_title', $title, $instance, $this->id_base); // Remember current filters/search $fields = ''; if (get_search_query()) $fields = ''; if (isset($_GET['post_type'])) $fields .= ''; if (isset($_GET['product_cat'])) $fields .= ''; if (isset($_GET['product_tag'])) $fields .= ''; if ($_chosen_attributes) foreach ($_chosen_attributes as $attribute => $data) : $fields .= ''; if ($data['query_type']=='or') $fields .= ''; endforeach; $min = $max = 0; $post_min = $post_max = ''; if ( sizeof( $woocommerce->query->layered_nav_product_ids ) != 0 ) { $max = ceil( $wpdb->get_var( $wpdb->prepare(' SELECT max(meta_value + 0) FROM %1$s LEFT JOIN %2$s ON %1$s.ID = %2$s.post_id WHERE meta_key = %3$s '), $wpdb->posts, $wpdb->postmeta, '_price' ) ); } else { $max = ceil( $wpdb->get_var( $wpdb->prepare(' SELECT max(meta_value + 0) FROM %1$s LEFT JOIN %2$s ON %1$s.ID = %2$s.post_id WHERE meta_key = %3$s AND ( %1$s.ID IN (%4$s) OR ( %1$s.post_parent IN (%4$s) AND %1$s.post_parent != 0 ) ) '), $wpdb->posts, $wpdb->postmeta, '_price', implode( ',', $woocommerce->query->layered_nav_product_ids ) ) ); } if ( $min == $max ) return; if ( isset( $woocommerce->session->min_price ) ) $post_min = $woocommerce->session->min_price; if ( isset( $woocommerce->session->max_price ) ) $post_max = $woocommerce->session->max_price; echo $before_widget . $before_title . $title . $after_title; 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( $wp->request ) ); echo '
'; echo $after_widget; } /** * update function. * * @see WP_Widget->update * @access public * @param array $new_instance * @param array $old_instance * @return array */ function update( $new_instance, $old_instance ) { if (!isset($new_instance['title']) || empty($new_instance['title'])) $new_instance['title'] = __( 'Filter by price', 'woocommerce' ); $instance['title'] = strip_tags(stripslashes($new_instance['title'])); return $instance; } /** * form function. * * @see WP_Widget->form * @access public * @param array $instance * @return void */ function form( $instance ) { global $wpdb; ?>plugin_url() . '/assets/js/frontend/price-slider' . $suffix . '.js', array( 'jquery-ui' ), '1.6', true ); unset( $woocommerce->session->min_price ); unset( $woocommerce->session->max_price ); if ( isset( $_GET['min_price'] ) ) $woocommerce->session->min_price = esc_attr( $_GET['min_price'] ); if ( isset( $_GET['max_price'] ) ) $woocommerce->session->max_price = esc_attr( $_GET['max_price'] ); add_filter( 'loop_shop_post_in', 'woocommerce_price_filter' ); } } add_action( 'init', 'woocommerce_price_filter_init' ); /** * Price Filter post filter * * @package WooCommerce/Widgets * @access public * @param array $filtered_posts * @return array */ function woocommerce_price_filter($filtered_posts) { global $wpdb; if ( isset( $_GET['max_price'] ) && isset( $_GET['min_price'] ) ) { $matched_products = array(); $min = floatval( $_GET['min_price'] ); $max = floatval( $_GET['max_price'] ); $matched_products_query = $wpdb->get_results( $wpdb->prepare(" SELECT DISTINCT ID, post_parent, post_type FROM $wpdb->posts INNER JOIN $wpdb->postmeta ON ID = post_id WHERE post_type IN ( 'product', 'product_variation' ) AND post_status = 'publish' AND meta_key = %s AND meta_value BETWEEN %d AND %d ", '_price', $min, $max ), OBJECT_K ); if ( $matched_products_query ) { foreach ( $matched_products_query as $product ) { if ( $product->post_type == 'product' ) $matched_products[] = $product->ID; if ( $product->post_parent > 0 && ! in_array( $product->post_parent, $matched_products ) ) $matched_products[] = $product->post_parent; } } // Filter the id's if ( sizeof( $filtered_posts ) == 0) { $filtered_posts = $matched_products; $filtered_posts[] = 0; } else { $filtered_posts = array_intersect( $filtered_posts, $matched_products ); $filtered_posts[] = 0; } } return (array) $filtered_posts; }