/** * Price Filter post filter. * * @param array $filtered_posts * @return array */ public function price_filter($filtered_posts = array()) { global $wpdb; if (isset($_GET['max_price']) || isset($_GET['min_price'])) { $matched_products = array(); $min = isset($_GET['min_price']) ? floatval($_GET['min_price']) : 0; $max = isset($_GET['max_price']) ? floatval($_GET['max_price']) : 9999999999; // If displaying prices in the shop including taxes, but prices don't include taxes.. if (wc_tax_enabled() && 'incl' === get_option('woocommerce_tax_display_shop') && !wc_prices_include_tax()) { $tax_classes = array_merge(array(''), WC_Tax::get_tax_classes()); foreach ($tax_classes as $tax_class) { $tax_rates = WC_Tax::get_rates($tax_class); $min_class = $min - WC_Tax::get_tax_total(WC_Tax::calc_inclusive_tax($min, $tax_rates)); $max_class = $max - WC_Tax::get_tax_total(WC_Tax::calc_inclusive_tax($max, $tax_rates)); $matched_products_query = apply_filters('woocommerce_price_filter_results', $wpdb->get_results($wpdb->prepare("\n\t\t\t\t\t\tSELECT DISTINCT ID, post_parent, post_type FROM {$wpdb->posts}\n\t\t\t\t\t\tINNER JOIN {$wpdb->postmeta} pm1 ON ID = pm1.post_id\n\t\t\t\t\t\tINNER JOIN {$wpdb->postmeta} pm2 ON ID = pm2.post_id\n\t\t\t\t\t\tWHERE post_type IN ( 'product', 'product_variation' )\n\t\t\t\t\t\tAND post_status = 'publish'\n\t\t\t\t\t\tAND pm1.meta_key IN ('" . implode("','", array_map('esc_sql', apply_filters('woocommerce_price_filter_meta_keys', array('_price')))) . "')\n\t\t\t\t\t\tAND pm1.meta_value BETWEEN %f AND %f\n\t\t\t\t\t\tAND pm2.meta_key = '_tax_class'\n\t\t\t\t\t\tAND pm2.meta_value = %s\n\t\t\t\t\t", $min_class, $max_class, sanitize_title($tax_class)), OBJECT_K), $min_class, $max_class); if ($matched_products_query) { foreach ($matched_products_query as $product) { if ($product->post_type == 'product') { $matched_products[] = $product->ID; } if ($product->post_parent > 0) { $matched_products[] = $product->post_parent; } } } } } else { $matched_products_query = apply_filters('woocommerce_price_filter_results', $wpdb->get_results($wpdb->prepare("\n\t\t\t\t\tSELECT DISTINCT ID, post_parent, post_type FROM {$wpdb->posts}\n\t\t\t\t\tINNER JOIN {$wpdb->postmeta} pm1 ON ID = pm1.post_id\n\t\t\t\t\tWHERE post_type IN ( 'product', 'product_variation' )\n\t\t\t\t\tAND post_status = 'publish'\n\t\t\t\t\tAND pm1.meta_key IN ('" . implode("','", array_map('esc_sql', apply_filters('woocommerce_price_filter_meta_keys', array('_price')))) . "')\n\t\t\t\t\tAND pm1.meta_value BETWEEN %d AND %d\n\t\t\t\t", $min, $max), OBJECT_K), $min, $max); if ($matched_products_query) { foreach ($matched_products_query as $product) { if ($product->post_type == 'product') { $matched_products[] = $product->ID; } if ($product->post_parent > 0) { $matched_products[] = $product->post_parent; } } } } $matched_products = array_unique($matched_products); // Filter the id's if (0 === sizeof($filtered_posts)) { $filtered_posts = $matched_products; } else { $filtered_posts = array_intersect($filtered_posts, $matched_products); } $filtered_posts[] = 0; } return (array) $filtered_posts; }
/** * Return a meta query for filtering by price. * @return array */ private function price_filter_meta_query() { if (isset($_GET['max_price']) || isset($_GET['min_price'])) { $min = isset($_GET['min_price']) ? floatval($_GET['min_price']) : 0; $max = isset($_GET['max_price']) ? floatval($_GET['max_price']) : 9999999999.0; // If displaying prices in the shop including taxes, but prices don't include taxes.. if (wc_tax_enabled() && 'incl' === get_option('woocommerce_tax_display_shop') && !wc_prices_include_tax()) { $tax_classes = array_merge(array(''), WC_Tax::get_tax_classes()); foreach ($tax_classes as $tax_class) { $tax_rates = WC_Tax::get_rates($tax_class); $class_min = $min - WC_Tax::get_tax_total(WC_Tax::calc_inclusive_tax($min, $tax_rates)); $class_max = $max - WC_Tax::get_tax_total(WC_Tax::calc_inclusive_tax($max, $tax_rates)); if ($class_min < $min) { $min = $class_min; } if ($class_max > $max) { $max = $class_max; } } } return array('key' => '_price', 'value' => array($min, $max), 'compare' => 'BETWEEN', 'type' => 'DECIMAL', 'price_filter' => true); } return array(); }