false, 'currency' => '', 'decimal_separator' => wc_get_price_decimal_separator(), 'thousand_separator' => wc_get_price_thousand_separator(), 'decimals' => wc_get_price_decimals(), 'price_format' => get_woocommerce_price_format(), ) ); $symbol = apply_filters( 'woocommerce_currency_symbol', get_woocommerce_currency_symbol(), get_woocommerce_currency() ); wp_localize_script( 'wc-price-slider', 'woocommerce_price_slider_params', array( 'currency_format_num_decimals' => $price_args['decimals'], 'currency_format_symbol' => $symbol, 'currency_format_decimal_sep' => esc_attr( $price_args['decimal_separator'] ), 'currency_format_thousand_sep' => esc_attr( $price_args['thousand_separator'] ), 'currency_format' => esc_attr( str_replace( array( '%1$s', '%2$s' ), array( '%s', '%v' ), $price_args['price_format'] ) ), ) ); } /** * Fixes query args set by WooCommerce Price Filter widget. * * These values will be picked up automatically by the JS price slider, so they must be correct at the start. * * @version 2.15.0 * @since 2.15.0 */ public function fix_price_filter_widget_query_args() { if ( isset( $_GET['min_price'] ) && isset( $_GET['max_price'] ) && isset( $_GET['currency_code'] ) && $_GET['currency_code'] !== alg_get_current_currency_code() ) { $currency_from = alg_wc_cs_get_currency_exchange_rate( sanitize_text_field( $_GET['currency_code'] ) ); $currency_to = alg_wc_cs_get_currency_exchange_rate( alg_get_current_currency_code() ); $exchange_rate = $currency_to / $currency_from; wp_safe_redirect( add_query_arg( array( 'min_price' => floatval( $_GET['min_price'] ) * $exchange_rate, 'max_price' => floatval( $_GET['max_price'] ) * $exchange_rate, 'currency_code' => alg_get_current_currency_code(), ), remove_query_arg( array( 'min_price', 'max_price', 'currency_code' ) ) ) ); exit; } } /** * Ensure the widget filters products within the correct price range. * * Since product prices in the DB are always stored in the shop's default currency, we * have to reverse the currency conversion here for searching purposes. * * @version 2.14.0 * @since 2.14.0 * * @see WC_Query::price_filter_post_clauses() * * @param $args * @param $query * * @return mixed */ function posts_clauses_price_filter_compatible( $args, $query ) { if ( is_admin() || ! isset( $args['where'] ) || ! ( isset( $_GET['min_price'] ) || isset( $_GET['max_price'] ) ) || get_option( 'woocommerce_currency' ) === alg_get_current_currency_code() || alg_wc_cs_get_currency_exchange_rate( alg_get_current_currency_code() ) === 1 ) { return $args; } global $wpdb; $current_currency_code = alg_get_current_currency_code(); $exchange_rate = alg_wc_cs_get_currency_exchange_rate( $current_currency_code ); $min_price = isset( $_GET['min_price'] ) ? floatval( wp_unslash( $_GET['min_price'] ) ) : 0; $max_price = isset( $_GET['max_price'] ) ? floatval( wp_unslash( $_GET['max_price'] ) ) : PHP_INT_MAX; $min_price = $min_price / $exchange_rate; $max_price = $max_price / $exchange_rate; /* old WC way: */ $args['where'] = preg_replace( '/AND wc_product_meta_lookup.min_price >= [\d.]* AND wc_product_meta_lookup.max_price <= [\d.]*\s/i', "AND wc_product_meta_lookup.min_price >= $min_price AND wc_product_meta_lookup.max_price <= $max_price", $args['where'] ); /* new WC way (circa WooCommerce 5.1ish): */ $args['where'] = preg_replace( '/AND NOT \([\d.]*wc_product_meta_lookup.max_price \)\s/i', "AND NOT ($max_pricewc_product_meta_lookup.max_price)", $args['where'] ); return $args; } /** * modify_default_price_filter_hook. * * not currently used. * * forces the query to use our price_filter_post_clauses (taken from WooCommerce core), and not * any other 3rd plugin's stuff. See $this->price_filter_post_clauses() for part 2 of this idea. * * @todo just an idea for the future */ function modify_default_price_filter_hook( $query ) { if ( ! isset( $_GET['min_price'] ) || ! isset( $_GET['max_price'] ) ) { return $query; } // Remove Price Filter Meta Query $meta_query = $query->get( 'meta_query' ); $meta_query = empty( $meta_query ) ? array() : $meta_query; foreach ( $meta_query as $key => $value ) { if ( is_array( $value ) ) { if ( isset( $value['price_filter'] ) ) { unset( $meta_query[ $key ]['price_filter'] ); } } } $query->set( 'meta_query', $meta_query ); // Remove Price Filter Hooks wpw_cs_remove_class_filter( 'posts_clauses', 'WC_Query', 'price_filter_post_clauses' ); // Remove Price Filter hooks from "Product Filter for WooCommerce" plugin if ( class_exists( 'XforWC_Product_Filters_Frontend' ) ) { remove_filter( 'posts_clauses', 'XforWC_Product_Filters_Frontend::price_filter_post_clauses', 10, 2 ); } // Add Price Filter Hook add_filter( 'posts_clauses', array( $this, 'price_filter_post_clauses' ), 10, 2 ); } /** * price_filter_post_clauses. * * not currently used. * * @todo just an idea for the future. this might be a solution to taking per-product settings into consideration. */ function price_filter_post_clauses( $args, $wp_query ) { global $wpdb; if ( ! $wp_query->is_main_query() || ( ! isset( $_GET['max_price'] ) && ! isset( $_GET['min_price'] ) ) ) { return $args; } $current_min_price = isset( $_GET['min_price'] ) ? floatval( wp_unslash( $_GET['min_price'] ) ) : 0; // WPCS: input var ok, CSRF ok. $current_max_price = isset( $_GET['max_price'] ) ? floatval( wp_unslash( $_GET['max_price'] ) ) : PHP_INT_MAX; // WPCS: input var ok, CSRF ok. /** * Adjust if the store taxes are not displayed how they are stored. * Kicks in when prices excluding tax are displayed including tax. */ if ( wc_tax_enabled() && 'incl' === get_option( 'woocommerce_tax_display_shop' ) && ! wc_prices_include_tax() ) { $tax_class = apply_filters( 'woocommerce_price_filter_widget_tax_class', '' ); // Uses standard tax class. $tax_rates = WC_Tax::get_rates( $tax_class ); if ( $tax_rates ) { $current_min_price -= WC_Tax::get_tax_total( WC_Tax::calc_inclusive_tax( $current_min_price, $tax_rates ) ); $current_max_price -= WC_Tax::get_tax_total( WC_Tax::calc_inclusive_tax( $current_max_price, $tax_rates ) ); } } // $args['join'] = $this->append_product_sorting_table_join( $args['join'] ); $args['where'] .= $wpdb->prepare( ' AND wc_product_meta_lookup.min_price >= %f AND wc_product_meta_lookup.max_price <= %f ', $current_min_price, $current_max_price ); return $args; /* * @todo just an idea for the future. * the following would take per-product settings into account, but it does not yet consider individual variations. * need to think about this some more. */ // $current_currency_code = alg_get_current_currency_code(); // $exchange_rate = alg_wc_cs_get_currency_exchange_rate( $current_currency_code ); // $args['where'] .= $wpdb->prepare( // " // AND {$wpdb->posts}.ID IN ( // SELECT ID // FROM ( // SELECT p.ID as ID, // IF( pm3.meta_value>0, pm3.meta_value, // IF( pm2.meta_value>0, pm2.meta_value, pm.meta_value/$exchange_rate ) // ) // AS wpw_price // FROM {$wpdb->posts} as p // LEFT JOIN {$wpdb->postmeta} as pm ON (pm.post_id=p.ID) AND (pm.meta_key = '_price') // LEFT JOIN {$wpdb->postmeta} as pm2 ON p.ID = pm2.post_id AND pm2.meta_key = '_alg_currency_switcher_per_product_regular_price_$current_currency_code' // LEFT JOIN {$wpdb->postmeta} as pm3 ON p.ID = pm3.post_id AND pm3.meta_key = '_alg_currency_switcher_per_product_sale_price_$current_currency_code' // WHERE p.post_type = 'product' AND p.post_status = 'publish' // ) wpw_prices // WHERE wpw_price <= %f AND wpw_price >= %f // GROUP BY ID // ) // ", // $current_max_price, // $current_min_price // ); // return $args; } /** * Adds compatibility with WooCommerce Product Add-ons plugin, converting addon prices * * @version 2.15.0 * @since 2.15.0 * @link https://woocommerce.com/products/product-add-ons/ */ function product_addons_convert_addon_prices( $addons ) { if ( isset( $_POST['add-to-cart'] ) && ! empty( $_POST['add-to-cart'] ) ) { // don't adjust when adding to cart... conversion will happen later. $backtrace = debug_backtrace( DEBUG_BACKTRACE_IGNORE_ARGS ); foreach ( $backtrace as $call ) { if ( $call['function'] === 'add_cart_item_data' && $call['class'] === 'WC_Product_Addons_Cart' ) { return $addons; } } } $current_currency_code = alg_get_current_currency_code(); $default_currency = get_option( 'woocommerce_currency' ); foreach ( $addons as $addon_key => $addon ) { foreach ( $addon['options'] as $option_key => $option ) { if ( $option['price_type'] === 'percentage_based' ) { continue; } if ( isset( $option['wpwham_price_curr'] ) && $option['wpwham_price_curr'] === $current_currency_code ) { continue; } $addons[ $addon_key ]['options'][ $option_key ]['price'] = alg_convert_price( array( 'price' => $option['price'], 'currency_from' => $default_currency, 'currency' => $current_currency_code, 'format_price' => 'no' ) ); $addons[ $addon_key ]['options'][ $option_key ]['wpwham_price_curr'] = $current_currency_code; } } return $addons; } /** * Adds compatibility with WooCommerce Product Add-ons plugin, fixing addon prices for display * * @version 2.15.0 * @since 2.15.0 * @link https://woocommerce.com/products/product-add-ons/ */ function product_addons_fix_addon_prices_for_display( $other_data, $cart_item ) { if ( ! is_callable( array( 'WC_Product_Addons_Helper', 'get_product_addon_price_for_display' ) ) ) { return $other_data; } $current_currency_code = alg_get_current_currency_code(); $default_currency = get_option( 'woocommerce_currency' ); if ( ! empty( $cart_item['addons'] ) ) { foreach ( $cart_item['addons'] as $addon ) { $price = isset( $cart_item['addons_price_before_calc'] ) ? $cart_item['addons_price_before_calc'] : $addon['price']; $original_name = $addon['name']; $replaced_name = $addon['name']; if ( $addon['price_type'] !== 'percentage_based' ) { $replaced_price = alg_convert_price( array( 'price' => $addon['price'], 'currency_from' => $default_currency, 'currency' => $current_currency_code, 'format_price' => 'no' ) ); } if ( 0 == $addon['price'] ) { $original_name .= ''; $replaced_name .= ''; } elseif ( 'percentage_based' === $addon['price_type'] && 0 == $price ) { $original_name .= ''; $replaced_name .= ''; } elseif ( 'percentage_based' !== $addon['price_type'] && $addon['price'] && apply_filters( 'woocommerce_addons_add_price_to_name', '__return_true' ) ) { $original_name .= ' (' . wc_price( WC_Product_Addons_Helper::get_product_addon_price_for_display( $addon['price'], $cart_item['data'], true ) ) . ')'; $replaced_name .= ' (' . wc_price( WC_Product_Addons_Helper::get_product_addon_price_for_display( $replaced_price, $cart_item['data'], true ) ) . ')'; } else { $_product = wc_get_product( $cart_item['product_id'] ); $_product->set_price( $price * ( $addon['price'] / 100 ) ); $original_name .= ' (' . WC()->cart->get_product_price( $_product ) . ')'; $replaced_name .= ' (' . WC()->cart->get_product_price( $_product ) . ')'; } foreach ( $other_data as $key => $value ) { if ( $value['name'] === $original_name ) { $other_data[ $key ]['name'] = $replaced_name; } } } } return $other_data; } /** * Adds compatibility with PPOM for WooCommerce plugin, converting values back from plugin, if session was updated * * @version 2.8.8 * @since 2.8.8 * @link https://wordpress.org/plugins/woocommerce-product-addon/ */ public function ppom_product_price( $price ) { if ( $this->updated_session ) { $price = $this->product_addons_convert_price_back( $price ); } return $price; } /** * Fixes product price on PPOM for WooCommerce plugin * * @version 2.8.8 * @since 2.8.8 * @link https://wordpress.org/plugins/woocommerce-product-addon/ */ public function ppom_get_cart_item_from_session( $cart_item ) { if ( ! isset( $cart_item['ppom'] ) || empty( $cart_item['ppom']['as_currency'] ) || $cart_item['ppom']['as_currency'] == alg_get_current_currency_code() ) { return $cart_item; } $option_prices = json_decode( stripslashes( $cart_item['ppom']['ppom_option_price'] ), true ); $additional_price = 0; $wc_product = $cart_item['data']; foreach ( $option_prices as $key => $price ) { $additional_price = $option_prices[ $key ]['price']; $price = alg_convert_price( array( 'price' => $option_prices[ $key ]['price'], 'currency_from' => $cart_item['ppom']['as_currency'], 'currency' => alg_get_current_currency_code(), 'format_price' => 'no' ) ); $option_prices[ $key ]['price'] = $price; } $cart_item['ppom']['ppom_option_price'] = json_encode( $option_prices ); $cart_item['ppom']['as_currency'] = alg_get_current_currency_code(); $final_price = $cart_item['data']->get_price() - $additional_price + $price; $this->updated_session = true; $wc_product->set_price( $final_price ); return $cart_item; } /** * Adds currency meta to PPOM for WooCommerce plugin * * @version 2.8.8 * @since 2.8.8 * @link https://wordpress.org/plugins/woocommerce-product-addon/ */ public function ppom_woocommerce_add_cart_item_data( $ppom, $post ) { if ( 'yes' !== apply_filters( 'alg_wc_currency_switcher_plugin_option', 'no', 'premium_version' ) || ! function_exists( 'PPOM' ) ) { return $ppom; } $ppom['as_currency'] = alg_get_current_currency_code(); return $ppom; } /** * Adds compatibility with PPOM for WooCommerce plugin, converting values back from plugin * * @version 2.8.8 * @since 2.8.8 * @link https://wordpress.org/plugins/woocommerce-product-addon/ */ public function product_addons_convert_price_back( $price ) { if ( 'yes' !== apply_filters( 'alg_wc_currency_switcher_plugin_option', 'no', 'premium_version' ) || ! function_exists( 'PPOM' ) ) { return $price; } if ( alg_get_current_currency_code() != get_option( 'woocommerce_currency' ) ) { $current_currency_code = alg_get_current_currency_code(); $default_currency = get_option( 'woocommerce_currency' ); $price = alg_convert_price( array( 'price' => $price, 'currency_from' => $current_currency_code, 'currency' => $default_currency, 'format_price' => 'no' ) ); } return $price; } /** * Adds compatibility with PPOM for WooCommerce plugin, converting values from plugin * * @version 2.8.8 * @since 2.8.8 * @link https://wordpress.org/plugins/woocommerce-product-addon/ */ public function product_addons_convert_option_price( $price ) { if ( 'yes' !== apply_filters( 'alg_wc_currency_switcher_plugin_option', 'no', 'premium_version' ) || ! function_exists( 'PPOM' ) ) { return $price; } if ( alg_get_current_currency_code() != get_option( 'woocommerce_currency' ) ) { $price = alg_convert_price( array( 'price' => $price, 'format_price' => 'no' ) ); } return $price; } /** * Adds compatibility with WooCommerce Chained Products plugin * @since 2.11.0 */ public static function is_chained_product( $_product ) { global $woocommerce; if ( ! $_product || ! $woocommerce || ! $woocommerce->cart ) { return false; } $items = $woocommerce->cart->get_cart(); $product_id = $_product->get_id(); foreach( $items as $item => $values ) { $cart_product_id = $values['data']->get_id(); if ( $product_id === $cart_product_id && ! empty( $values['chained_item_of'] ) ) { return true; } } return false; } } endif;