Файловый менеджер - Редактировать - /home/harasnat/www/labour/wp-content/plugins/woocommerce-payments/includes/multi-currency/FrontendPrices.php
Назад
<?php /** * WooCommerce Payments Multi-Currency Frontend Prices * * @package WooCommerce\Payments */ namespace WCPay\MultiCurrency; use WC_Order; defined( 'ABSPATH' ) || exit; /** * Class that applies Multi-Currency prices on the frontend. */ class FrontendPrices { /** * Compatibility instance. * * @var Compatibility */ protected $compatibility; /** * Multi-Currency instance. * * @var MultiCurrency */ protected $multi_currency; /** * Constructor. * * @param MultiCurrency $multi_currency The MultiCurrency instance. * @param Compatibility $compatibility The Compatibility instance. */ public function __construct( MultiCurrency $multi_currency, Compatibility $compatibility ) { $this->multi_currency = $multi_currency; $this->compatibility = $compatibility; } /** * Initializes this class' WP hooks. * * @return void */ public function init_hooks() { if ( defined( 'DOING_CRON' ) || is_admin() || Utils::is_admin_api_request() ) { return; } // Simple product price hooks. add_filter( 'woocommerce_product_get_price', [ $this, 'get_product_price_string' ], 99, 2 ); add_filter( 'woocommerce_product_get_regular_price', [ $this, 'get_product_price_string' ], 99, 2 ); add_filter( 'woocommerce_product_get_sale_price', [ $this, 'get_product_price_string' ], 99, 2 ); // Variation price hooks. add_filter( 'woocommerce_product_variation_get_price', [ $this, 'get_product_price_string' ], 99, 2 ); add_filter( 'woocommerce_product_variation_get_regular_price', [ $this, 'get_product_price_string' ], 99, 2 ); add_filter( 'woocommerce_product_variation_get_sale_price', [ $this, 'get_product_price_string' ], 99, 2 ); // Variation price range hooks. add_filter( 'woocommerce_variation_prices', [ $this, 'get_variation_price_range' ], 99 ); add_filter( 'woocommerce_get_variation_prices_hash', [ $this, 'add_exchange_rate_to_variation_prices_hash' ], 99 ); // Shipping methods hooks. add_action( 'init', [ $this, 'register_free_shipping_filters' ], 99 ); add_filter( 'woocommerce_shipping_method_add_rate_args', [ $this, 'convert_shipping_method_rate_cost' ], 99 ); // Coupon hooks. add_filter( 'woocommerce_coupon_get_amount', [ $this, 'get_coupon_amount' ], 99, 2 ); add_filter( 'woocommerce_coupon_get_minimum_amount', [ $this, 'get_coupon_min_max_amount' ], 99 ); add_filter( 'woocommerce_coupon_get_maximum_amount', [ $this, 'get_coupon_min_max_amount' ], 99 ); // Order hooks. add_filter( 'woocommerce_new_order', [ $this, 'add_order_meta' ], 99, 2 ); // Price Filter Hooks. add_filter( 'rest_post_dispatch', [ $this, 'maybe_modify_price_ranges_rest_response' ], 10, 3 ); add_filter( 'query_loop_block_query_vars', [ $this, 'maybe_modify_price_ranges_query_var' ], 10, 3 ); } /** * Modifies the price range query parameters when the selected currency is not the same as the store currency. * * This method converts the '_price' parameters based on the selected currency. * * @param array $query The current query variables. * @param \WP_Block $block The current block instance. * @param int $page The current page number. * * @return array The modified query variables. */ public function maybe_modify_price_ranges_query_var( $query, $block, $page ) { if ( 'product' !== $query['post_type'] ) { return $query; } if ( empty( $query['meta_query'] ) || ! is_array( $query['meta_query'] ) ) { return $query; } $store_currency = $this->multi_currency->get_default_currency()->get_code(); $selected_currency = $this->multi_currency->get_selected_currency()->get_code(); // If currencies are the same, no need to convert prices in the query. if ( $store_currency === $selected_currency ) { return $query; } // Traverse and modify the meta_query array. // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_query $query['meta_query'] = $this->convert_meta_query_price_filters( $query['meta_query'], $store_currency, $selected_currency ); return $query; } /** * Recursively traverses and modifies the meta_query array to adjust '_price' values * from the 'from_currency' to the 'target_currency'. * * @param array $meta_query The meta_query array to traverse. * @param string $from_currency The from currency code. * @param string $target_currency The target currency code. * @param int $depth The current depth of the recursion. * * @return array The modified meta_query array. */ private function convert_meta_query_price_filters( $meta_query, $from_currency, $target_currency, $depth = 0 ) { // Prevent infinite recursion in a malformed meta_query. if ( $depth > 4 ) { return $meta_query; } foreach ( $meta_query as &$mq ) { // If the current element is a nested meta_query with a relation. if ( isset( $mq['relation'] ) && is_array( $mq ) ) { // Recursively modify the nested meta_query. if ( isset( $mq['relation'] ) ) { // Extract the relation and the nested queries. $relation = $mq['relation']; $modified_nested = $this->convert_meta_query_price_filters( $mq, $from_currency, $target_currency, $depth + 1 ); // Reconstruct the meta_query with the modified nested queries. $mq = array_merge( [ 'relation' => $relation ], $modified_nested ); } } elseif ( isset( $mq['key'] ) && '_price' === $mq['key'] && isset( $mq['value'] ) && is_numeric( $mq['value'] ) ) { $converted_price = $this->multi_currency->get_raw_conversion( $mq['value'], $from_currency, $target_currency ); if ( is_numeric( $converted_price ) ) { // Apply floor or ceil based on the 'compare' operator. if ( isset( $mq['compare'] ) ) { if ( '<=' === $mq['compare'] ) { $mq['value'] = (string) ceil( $converted_price ); // max_price. } elseif ( '>=' === $mq['compare'] ) { $mq['value'] = (string) floor( $converted_price ); // min_price. } } } } } unset( $mq ); return $meta_query; } /** * Modify the products/collection-data REST API response to include converted price ranges. * * @param \WP_REST_Response $response The original REST response. * @param \WP_REST_Server $server The REST server instance. * @param \WP_REST_Request $request The REST request instance. * * @return \WP_REST_Response The modified REST response. */ public function maybe_modify_price_ranges_rest_response( $response, $server, $request ) { if ( '/wc/store/v1/products/collection-data' !== $request->get_route() ) { return $response; } $data = $response->get_data(); if ( empty( $data['price_range'] ) || ! is_object( $data['price_range'] ) ) { return $response; } $store_currency = $this->multi_currency->get_default_currency()->get_code(); $selected_currency = $this->multi_currency->get_selected_currency()->get_code(); if ( $store_currency === $selected_currency ) { return $response; } $price_fields = [ 'min_price', 'max_price' ]; foreach ( $price_fields as $field ) { if ( property_exists( $data['price_range'], $field ) && is_numeric( $data['price_range']->$field ) ) { $converted_price = $this->multi_currency->get_price( $data['price_range']->$field, 'product' ); if ( is_numeric( $converted_price ) ) { $data['price_range']->$field = (string) $converted_price; } } } $response->set_data( $data ); return $response; } /** * Returns the price for a product. * * @param mixed $price The product's price. * @param mixed $product WC_Product or null. * * @return mixed The converted product's price. */ public function get_product_price( $price, $product = null ) { if ( ! $price || ! $this->compatibility->should_convert_product_price( $product ) ) { return $price; } return $this->multi_currency->get_price( $price, 'product' ); } /** * Returns the stringified price for a product. * * @param mixed $price The product's price. * @param mixed $product WC_Product or null. * * @return string The converted product's price. */ public function get_product_price_string( $price, $product = null ): string { return (string) $this->get_product_price( $price, $product ); } /** * Returns the price range for a variation. * * @param array $variation_prices The variation's prices. * * @return array The converted variation's prices. */ public function get_variation_price_range( $variation_prices ) { foreach ( $variation_prices as $price_type => $prices ) { foreach ( $prices as $variation_id => $price ) { $variation_prices[ $price_type ][ $variation_id ] = $this->get_product_price_string( $price ); } } return $variation_prices; } /** * Add the exchange rate into account for the variation prices hash. * This is used to recalculate the variation price range when the exchange * rate changes, otherwise the old prices will be cached. * * @param array $prices_hash The variation prices hash. * * @return array The variation prices hash with the current exchange rate. */ public function add_exchange_rate_to_variation_prices_hash( $prices_hash ) { $prices_hash[] = $this->get_product_price( 1 ); return $prices_hash; } /** * Returns the shipping add rate args with cost converted. * * @param array $args Shipping rate args. * * @return array Shipping rate args with converted cost. */ public function convert_shipping_method_rate_cost( $args ) { if ( isset( $args['cost'] ) ) { /** * We need to keep the `cost` structure intact when applying * multi-currency conversions, because downstream it is important * for WooCommerce to keep the taxes flow consistent. */ if ( is_array( $args['cost'] ) ) { $args['cost'] = array_map( function ( $cost ) { return $this->multi_currency->get_price( $cost, 'shipping' ); }, $args['cost'] ); } else { $args['cost'] = $this->multi_currency->get_price( $args['cost'], 'shipping' ); } } return $args; } /** * Returns the amount for a coupon. * * @param mixed $amount The coupon's amount. * @param object $coupon The coupon object. * * @return mixed The converted coupon's amount. */ public function get_coupon_amount( $amount, $coupon ) { $percent_coupon_types = [ 'percent' ]; if ( ! $amount || $coupon->is_type( $percent_coupon_types ) || ! $this->compatibility->should_convert_coupon_amount( $coupon ) ) { return $amount; } return $this->multi_currency->get_price( $amount, 'coupon' ); } /** * Returns the min or max amount for a coupon. * * @param mixed $amount The coupon's min or max amount. * * @return mixed The converted coupon's min or max amount. */ public function get_coupon_min_max_amount( $amount ) { if ( ! $amount ) { return $amount; } // Coupon mix/max prices are treated as products to avoid inconsistencies with charm pricing // making a coupon invalid when the coupon min/max amount is the same as the product's price. return $this->multi_currency->get_price( $amount, 'product' ); } /** * Returns the free shipping zone settings with converted min_amount. * * @param array $data The shipping zone settings. * * @return array The shipping zone settings with converted min_amount. */ public function get_free_shipping_min_amount( $data ) { if ( empty( $data['min_amount'] ) ) { return $data; } // Free shipping min amount is treated as products to avoid inconsistencies with charm pricing // making a method invalid when its min amount is the same as the product's price. $data['min_amount'] = $this->multi_currency->get_price( $data['min_amount'], 'product' ); return $data; } /** * Register the hooks to set the min amount for free shipping methods. */ public function register_free_shipping_filters() { $shipping_zones = \WC_Shipping_Zones::get_zones(); $default_zone = \WC_Shipping_Zones::get_zone( 0 ); if ( $default_zone ) { $shipping_zones[] = [ 'shipping_methods' => $default_zone->get_shipping_methods() ]; } foreach ( $shipping_zones as $shipping_zone ) { foreach ( $shipping_zone['shipping_methods'] as $shipping_method ) { if ( 'free_shipping' === $shipping_method->id ) { $option_name = 'option_woocommerce_' . trim( $shipping_method->id ) . '_' . (int) $shipping_method->instance_id . '_settings'; add_filter( $option_name, [ $this, 'get_free_shipping_min_amount' ], 99 ); } } } } /** * Adds the exchange rate and default currency to the order's meta if prices have been converted. * * @param int $order_id The order ID. * @param WC_Order $order The order object. */ public function add_order_meta( $order_id, $order ) { $default_currency = $this->multi_currency->get_default_currency(); // Do not add exchange rate if order was made in the store's default currency. if ( $default_currency->get_code() === $order->get_currency() ) { return; } $exchange_rate = $this->multi_currency->get_price( 1, 'exchange_rate' ); $order->update_meta_data( '_wcpay_multi_currency_order_exchange_rate', $exchange_rate ); $order->update_meta_data( '_wcpay_multi_currency_order_default_currency', $default_currency->get_code() ); $order->save_meta_data(); } }
| ver. 1.4 |
Github
|
.
| PHP 8.1.33 | Генерация страницы: 0 |
proxy
|
phpinfo
|
Настройка