currency-switcher
4 weeks ago
class-wcml-custom-prices.php
4 weeks ago
class-wcml-multi-currency-configuration.php
4 weeks ago
class-wcml-multi-currency-coupons.php
1 year ago
class-wcml-multi-currency-install.php
4 weeks ago
class-wcml-multi-currency-orders.php
4 weeks ago
class-wcml-multi-currency-prices.php
4 weeks ago
class-wcml-multi-currency-reports.php
4 weeks ago
class-wcml-multi-currency-resources.php
4 weeks ago
class-wcml-multi-currency-shipping.php
4 weeks ago
class-wcml-multi-currency-table-rate-shipping.php
4 weeks ago
class-wcml-multi-currency.php
4 weeks ago
class-wcml-price-filter.php
4 weeks ago
class-wcml-w3tc-multi-currency.php
4 weeks ago
class-wcml-multi-currency-configuration.php
402 lines
| 1 | <?php |
| 2 | |
| 3 | use WCML\MultiCurrency\Settings; |
| 4 | use WCML\Multicurrency\UI\Hooks; |
| 5 | use WPML\FP\Obj; |
| 6 | use function WCML\functions\getSitePress; |
| 7 | use function WPML\Container\make; |
| 8 | |
| 9 | class WCML_Multi_Currency_Configuration { |
| 10 | |
| 11 | |
| 12 | private static $multi_currency; |
| 13 | private static $woocommerce_wpml; |
| 14 | |
| 15 | public static function set_up( WCML_Multi_Currency $multi_currency, woocommerce_wpml $woocommerce_wpml ) { |
| 16 | |
| 17 | self::$multi_currency = $multi_currency; |
| 18 | self::$woocommerce_wpml = $woocommerce_wpml; |
| 19 | |
| 20 | if ( isset( $_POST['action'] ) && $_POST['action'] === 'save-mc-options' ) { |
| 21 | self::save_configuration(); |
| 22 | } |
| 23 | |
| 24 | self::set_prices_config(); |
| 25 | |
| 26 | self::add_hooks(); |
| 27 | } |
| 28 | |
| 29 | public static function add_hooks(){ |
| 30 | if ( wp_doing_ajax() ) { |
| 31 | |
| 32 | add_action( 'wp_ajax_legacy_update_custom_rates', [ __CLASS__, 'legacy_update_custom_rates' ] ); |
| 33 | add_action( 'wp_ajax_legacy_remove_custom_rates', [ __CLASS__, 'legacy_remove_custom_rates' ] ); |
| 34 | |
| 35 | add_action( 'wp_ajax_wcml_save_currency', [ __CLASS__, 'save_currency' ] ); |
| 36 | add_action( 'wp_ajax_wcml_delete_currency', [ __CLASS__, 'delete_currency' ] ); |
| 37 | add_action( 'wp_ajax_wcml_update_currency_lang', [ __CLASS__, 'update_currency_lang' ] ); |
| 38 | add_action( 'wp_ajax_wcml_update_default_currency', [ __CLASS__, 'update_default_currency_ajax' ] ); |
| 39 | add_action( 'wp_ajax_wcml_set_currency_mode', [ __CLASS__, 'set_currency_mode' ] ); |
| 40 | add_action( 'wp_ajax_wcml_set_max_mind_key', [ __CLASS__, 'set_max_mind_key' ] ); |
| 41 | add_action( 'wp_ajax_wcml_get_auto_exchange_rate', [ __CLASS__, 'get_auto_exchange_rate' ] ); |
| 42 | } |
| 43 | } |
| 44 | |
| 45 | public static function save_configuration() { |
| 46 | if ( check_admin_referer( 'wcml_mc_options', 'wcml_nonce' ) ) { |
| 47 | |
| 48 | $wcml_settings = self::$woocommerce_wpml->settings; |
| 49 | |
| 50 | $wcml_settings['enable_multi_currency'] = isset( $_POST['multi_currency'] ) ? intval( $_POST['multi_currency'] ) : 0; |
| 51 | $wcml_settings['display_custom_prices'] = isset( $_POST['display_custom_prices'] ) ? intval( $_POST['display_custom_prices'] ) : 0; |
| 52 | |
| 53 | if ( $wcml_settings['enable_multi_currency'] == WCML_MULTI_CURRENCIES_INDEPENDENT ) { |
| 54 | |
| 55 | $options = [ |
| 56 | 'woocommerce_currency_pos' => 'position', |
| 57 | 'woocommerce_price_thousand_sep' => 'thousand_sep', |
| 58 | 'woocommerce_price_decimal_sep' => 'decimal_sep', |
| 59 | 'woocommerce_price_num_decimals' => 'num_decimals', |
| 60 | ]; |
| 61 | |
| 62 | $woocommerce_currency = wcml_get_woocommerce_currency_option(); |
| 63 | |
| 64 | foreach ( $options as $wc_key => $key ) { |
| 65 | $wcml_settings['currency_options'][ $woocommerce_currency ][ $key ] = get_option( $wc_key, true ); |
| 66 | } |
| 67 | |
| 68 | if ( ! isset( $wcml_settings['currency_options'][ $woocommerce_currency ]['location_mode'] ) ) { |
| 69 | $wcml_settings['currency_options'][ $woocommerce_currency ]['location_mode'] = 'all'; |
| 70 | } |
| 71 | } |
| 72 | |
| 73 | $wcml_settings['currency_switcher_product_visibility'] = isset( $_POST['currency_switcher_product_visibility'] ) ? intval( $_POST['currency_switcher_product_visibility'] ) : 0; |
| 74 | $wcml_settings['currency_switcher_additional_css'] = isset( $_POST['currency_switcher_additional_css'] ) ? sanitize_text_field( $_POST['currency_switcher_additional_css'] ) : ''; |
| 75 | |
| 76 | if ( ! isset( $wcml_settings['currencies_order'] ) ) { |
| 77 | $wcml_settings['currencies_order'] = self::$multi_currency->currency_codes; |
| 78 | } |
| 79 | |
| 80 | Settings::setMode( filter_input( INPUT_POST, 'currency_mode', FILTER_SANITIZE_FULL_SPECIAL_CHARS ) ); |
| 81 | self::$woocommerce_wpml->update_settings( $wcml_settings ); |
| 82 | |
| 83 | do_action( 'wcml_saved_mc_options', $_POST ); |
| 84 | |
| 85 | $message = [ |
| 86 | 'id' => 'wcml-settings-saved', |
| 87 | 'text' => __( 'Your settings have been saved.', 'woocommerce-multilingual' ), |
| 88 | 'group' => 'wcml-multi-currency', |
| 89 | 'admin_notice' => true, |
| 90 | 'limit_to_page' => true, |
| 91 | 'classes' => [ 'updated', 'notice', 'notice-success' ], |
| 92 | 'show_once' => true, |
| 93 | ]; |
| 94 | ICL_AdminNotifier::add_message( $message ); |
| 95 | |
| 96 | if ( ! \WCML\functions\isStandAlone() ) { |
| 97 | $wpml_admin_notices = wpml_get_admin_notices(); |
| 98 | $wpml_admin_notices->remove_notice( 'wcml-save-multi-currency-options', 'wcml-fixerio-api-key-required' ); |
| 99 | } |
| 100 | } |
| 101 | |
| 102 | } |
| 103 | |
| 104 | public static function add_currency( $currency_code ) { |
| 105 | $settings = self::$woocommerce_wpml->get_settings(); |
| 106 | |
| 107 | foreach ( getSitePress()->get_active_languages() as $language ) { |
| 108 | if ( ! isset( $settings['currency_options'][ $currency_code ]['languages'][ $language['code'] ] ) ) { |
| 109 | $settings['currency_options'][ $currency_code ]['languages'][ $language['code'] ] = 1; |
| 110 | } |
| 111 | } |
| 112 | $settings['currency_options'][ $currency_code ]['rate'] = (float) filter_input( INPUT_POST, 'currency_value', FILTER_VALIDATE_FLOAT, FILTER_FLAG_ALLOW_FRACTION ); |
| 113 | $settings['currency_options'][ $currency_code ]['updated'] = date( 'Y-m-d H:i:s' ); |
| 114 | |
| 115 | $wc_currency = wcml_get_woocommerce_currency_option(); |
| 116 | if ( ! isset( $settings['currencies_order'] ) ) { |
| 117 | $settings['currencies_order'][] = $wc_currency; |
| 118 | } |
| 119 | |
| 120 | $settings['currencies_order'][] = $currency_code; |
| 121 | |
| 122 | self::$woocommerce_wpml->update_settings( $settings ); |
| 123 | self::$multi_currency->init_currencies(); |
| 124 | |
| 125 | } |
| 126 | |
| 127 | public static function save_currency() { |
| 128 | self::verify_nonce(); |
| 129 | $data = self::get_data(); |
| 130 | |
| 131 | $wc_currency = wcml_get_woocommerce_currency_option(); |
| 132 | |
| 133 | $options = $data['currency_options']; |
| 134 | |
| 135 | $currency_code = $options['code']; |
| 136 | |
| 137 | if ( isset( $options['gatewaysSettings'] ) ) { |
| 138 | |
| 139 | $payment_gateways = self::$multi_currency->currencies_payment_gateways->get_gateways(); |
| 140 | |
| 141 | foreach ( $options['gatewaysSettings'] as $code => $gateways_settings ) { |
| 142 | if ( isset( $payment_gateways[ $code ] ) ) { |
| 143 | $payment_gateways[ $code ]->save_setting( $currency_code, $gateways_settings ); |
| 144 | } |
| 145 | } |
| 146 | |
| 147 | self::$multi_currency->currencies_payment_gateways->set_enabled( $currency_code, $options['gatewaysEnabled'] ); |
| 148 | } |
| 149 | |
| 150 | if ( isset( $options['countries'] ) ) { |
| 151 | $options['countries'] = wc_string_to_array( $options['countries'], ',' ); |
| 152 | } |
| 153 | |
| 154 | if ( isset( $options['num_decimals'] ) ) { |
| 155 | $options['num_decimals'] = absint( $options['num_decimals'] ); |
| 156 | } |
| 157 | |
| 158 | if ( $wc_currency !== $currency_code ) { |
| 159 | $options['thousand_sep'] = wc_format_option_price_separators( null, null, $options['thousand_sep'] ); |
| 160 | $options['decimal_sep'] = wc_format_option_price_separators( null, null, $options['decimal_sep'] ); |
| 161 | |
| 162 | if ( ! isset( self::$multi_currency->currencies[ $currency_code ] ) ) { |
| 163 | self::add_currency( $currency_code ); |
| 164 | } |
| 165 | |
| 166 | foreach ( self::$multi_currency->currencies[ $currency_code ] as $key => $value ) { |
| 167 | |
| 168 | if ( isset( $options[ $key ] ) && $options[ $key ] != $value ) { |
| 169 | if ( $key === 'rate' ) { |
| 170 | $previous_rate = self::$multi_currency->currencies[ $currency_code ][ $key ]; |
| 171 | self::$multi_currency->currencies[ $currency_code ]['previous_rate'] = $previous_rate; |
| 172 | self::$multi_currency->currencies[ $currency_code ]['updated'] = date( 'Y-m-d H:i:s' ); |
| 173 | } |
| 174 | self::$multi_currency->currencies[ $currency_code ][ $key ] = $options[ $key ]; |
| 175 | } |
| 176 | } |
| 177 | } else { |
| 178 | self::$multi_currency->currencies[ $currency_code ]['countries'] = $options['countries']; |
| 179 | self::$multi_currency->currencies[ $currency_code ]['location_mode'] = $options['location_mode']; |
| 180 | } |
| 181 | |
| 182 | self::$woocommerce_wpml->update_setting( 'currency_options', self::$multi_currency->currencies ); |
| 183 | |
| 184 | wp_send_json_success( [ |
| 185 | 'formattedLastRateUpdate' => Hooks::formatLastRateUpdate( |
| 186 | Obj::path( [ $currency_code, 'updated' ], self::$multi_currency->currencies ) |
| 187 | ), |
| 188 | ] ); |
| 189 | } |
| 190 | |
| 191 | public static function delete_currency() { |
| 192 | self::verify_nonce(); |
| 193 | $data = self::get_data(); |
| 194 | |
| 195 | self::$multi_currency->delete_currency_by_code( $data['code'] ); |
| 196 | wp_send_json_success(); |
| 197 | } |
| 198 | |
| 199 | public static function update_currency_lang() { |
| 200 | self::verify_nonce(); |
| 201 | $data = self::get_data(); |
| 202 | |
| 203 | $settings = self::$woocommerce_wpml->get_settings(); |
| 204 | $settings['currency_options'][ $data['code'] ]['languages'][ $data['lang'] ] = (int) $data['value']; |
| 205 | |
| 206 | self::$woocommerce_wpml->update_settings( $settings ); |
| 207 | wp_send_json_success(); |
| 208 | } |
| 209 | |
| 210 | private static function verify_nonce() { |
| 211 | $nonce = filter_input( INPUT_POST, 'nonce', FILTER_SANITIZE_FULL_SPECIAL_CHARS ); |
| 212 | |
| 213 | if ( ! wp_verify_nonce( $nonce, WCML\Multicurrency\UI\Hooks::HANDLE ) ) { |
| 214 | wp_send_json_error( 'Invalid nonce' ); |
| 215 | } |
| 216 | } |
| 217 | |
| 218 | private static function get_data() { |
| 219 | return json_decode( stripslashes( $_POST['data'] ), true ); |
| 220 | } |
| 221 | |
| 222 | public static function update_default_currency_ajax() { |
| 223 | self::verify_nonce(); |
| 224 | self::update_default_currency(); |
| 225 | wp_send_json_success(); |
| 226 | } |
| 227 | |
| 228 | public static function update_default_currency() { |
| 229 | |
| 230 | $data = self::get_data(); |
| 231 | |
| 232 | if ( $data['lang'] === wcml_user_store_get( WCML_Multi_Currency::CURRENCY_LANGUAGE_STORAGE_KEY ) && $data['code'] !== 'location' ) { |
| 233 | |
| 234 | wcml_user_store_set( WCML_Multi_Currency::CURRENCY_STORAGE_KEY, $data['code'] ); |
| 235 | } |
| 236 | |
| 237 | self::$woocommerce_wpml->settings['default_currencies'][ $data['lang'] ] = $data['code']; |
| 238 | self::$woocommerce_wpml->update_settings(); |
| 239 | |
| 240 | } |
| 241 | |
| 242 | public static function currency_options_update_default_currency( $settings, $current_currency, $new_currency ) { |
| 243 | |
| 244 | if ( isset( $settings['currency_options'][ $current_currency ] ) ) { |
| 245 | $currency_settings = $settings['currency_options'][ $current_currency ]; |
| 246 | $settings['currency_options'][ $new_currency ] = $currency_settings; |
| 247 | $settings = self::$woocommerce_wpml->multi_currency->delete_currency_by_code( $current_currency, $settings, false ); |
| 248 | } |
| 249 | |
| 250 | $message_id = 'wcml-woocommerce-default-currency-changed'; |
| 251 | $message_args = [ |
| 252 | 'id' => $message_id, |
| 253 | 'text' => sprintf( |
| 254 | /* translators: %1$s and %2$s are opening and closing HTML link tags */ |
| 255 | __( |
| 256 | 'The default currency was changed. In order to show accurate prices in all currencies, you need to update the exchange rates under the %1$sMulti-currency%2$s configuration.', |
| 257 | 'woocommerce-multilingual' |
| 258 | ), |
| 259 | '<a href="' . \WCML\Utilities\AdminUrl::getMultiCurrencyTab() . '">', |
| 260 | '</a>' |
| 261 | ), |
| 262 | 'type' => 'warning', |
| 263 | 'group' => 'wcml-multi-currency', |
| 264 | 'admin_notice' => true, |
| 265 | 'hide' => true, |
| 266 | ]; |
| 267 | |
| 268 | ICL_AdminNotifier::remove_message( $message_id ); |
| 269 | ICL_AdminNotifier::add_message( $message_args ); |
| 270 | |
| 271 | return $settings; |
| 272 | } |
| 273 | |
| 274 | public static function legacy_update_custom_rates() { |
| 275 | |
| 276 | $nonce = filter_input( INPUT_POST, 'wcml_nonce', FILTER_SANITIZE_FULL_SPECIAL_CHARS ); |
| 277 | if ( ! $nonce || ! wp_verify_nonce( $nonce, 'legacy_update_custom_rates' ) ) { |
| 278 | die( 'Invalid nonce' ); |
| 279 | } |
| 280 | foreach ( $_POST['posts'] as $post_id => $rates ) { |
| 281 | update_post_meta( $post_id, '_custom_conversion_rate', $rates ); |
| 282 | } |
| 283 | |
| 284 | echo json_encode( [] ); |
| 285 | exit; |
| 286 | } |
| 287 | |
| 288 | public static function legacy_remove_custom_rates() { |
| 289 | |
| 290 | $nonce = filter_input( INPUT_POST, 'wcml_nonce', FILTER_SANITIZE_FULL_SPECIAL_CHARS ); |
| 291 | if ( ! $nonce || ! wp_verify_nonce( $nonce, 'legacy_remove_custom_rates' ) ) { |
| 292 | echo json_encode( [ 'error' => __( 'Invalid nonce', 'woocommerce-multilingual' ) ] ); |
| 293 | die(); |
| 294 | } |
| 295 | |
| 296 | delete_post_meta( $_POST['post_id'], '_custom_conversion_rate' ); |
| 297 | echo json_encode( [] ); |
| 298 | |
| 299 | exit; |
| 300 | } |
| 301 | |
| 302 | public static function set_prices_config() { |
| 303 | global $iclTranslationManagement, $sitepress_settings; |
| 304 | |
| 305 | $sitepress = getSitePress(); |
| 306 | $wpml_settings = $sitepress->get_settings(); |
| 307 | |
| 308 | if ( ! isset( $wpml_settings['translation-management'] ) || |
| 309 | ! isset( $iclTranslationManagement ) || |
| 310 | ! ( $iclTranslationManagement instanceof TranslationManagement ) ) { |
| 311 | return; |
| 312 | } |
| 313 | |
| 314 | $keys = [ |
| 315 | '_regular_price', |
| 316 | '_sale_price', |
| 317 | '_price', |
| 318 | '_min_variation_regular_price', |
| 319 | '_min_variation_sale_price', |
| 320 | '_min_variation_price', |
| 321 | '_max_variation_regular_price', |
| 322 | '_max_variation_sale_price', |
| 323 | '_max_variation_price', |
| 324 | '_sale_price_dates_from', |
| 325 | '_sale_price_dates_to', |
| 326 | '_wcml_schedule', |
| 327 | ]; |
| 328 | $save = false; |
| 329 | |
| 330 | foreach ( $keys as $key ) { |
| 331 | $iclTranslationManagement->settings['custom_fields_readonly_config'][] = $key; |
| 332 | if ( ! isset( $sitepress_settings['translation-management']['custom_fields_translation'][ $key ] ) || |
| 333 | $wpml_settings['translation-management']['custom_fields_translation'][ $key ] != WPML_COPY_CUSTOM_FIELD ) { |
| 334 | $wpml_settings['translation-management']['custom_fields_translation'][ $key ] = WPML_COPY_CUSTOM_FIELD; |
| 335 | $save = true; |
| 336 | } |
| 337 | |
| 338 | if ( self::$multi_currency instanceof WCML_Multi_Currency ) { |
| 339 | foreach ( self::$multi_currency->get_currency_codes() as $code ) { |
| 340 | $new_key = $key . '_' . $code; |
| 341 | $iclTranslationManagement->settings['custom_fields_readonly_config'][] = $new_key; |
| 342 | |
| 343 | if ( ! isset( $sitepress_settings['translation-management']['custom_fields_translation'][ $new_key ] ) || |
| 344 | $wpml_settings['translation-management']['custom_fields_translation'][ $new_key ] != WPML_IGNORE_CUSTOM_FIELD ) { |
| 345 | $wpml_settings['translation-management']['custom_fields_translation'][ $new_key ] = WPML_IGNORE_CUSTOM_FIELD; |
| 346 | $save = true; |
| 347 | } |
| 348 | } |
| 349 | } |
| 350 | } |
| 351 | |
| 352 | if ( $save ) { |
| 353 | $sitepress->save_settings( $wpml_settings ); |
| 354 | } |
| 355 | } |
| 356 | |
| 357 | public static function set_currency_mode() { |
| 358 | self::verify_nonce(); |
| 359 | $data = self::get_data(); |
| 360 | |
| 361 | Settings::setMode( $data['mode'] ); |
| 362 | |
| 363 | wp_send_json_success(); |
| 364 | } |
| 365 | |
| 366 | public static function set_max_mind_key() { |
| 367 | self::verify_nonce(); |
| 368 | $data = self::get_data(); |
| 369 | |
| 370 | if ( WC()->integrations instanceof WC_Integrations) { |
| 371 | $integrations = WC()->integrations->get_integrations(); |
| 372 | |
| 373 | if ( isset( $integrations['maxmind_geolocation'] ) ) { |
| 374 | try { |
| 375 | $integrations['maxmind_geolocation']->validate_license_key_field( 'license_key', $data['MaxMindKey'] ); |
| 376 | $integrations['maxmind_geolocation']->update_option( 'license_key', $data['MaxMindKey'] ); |
| 377 | wp_send_json_success(); |
| 378 | } catch ( Exception $e ) { |
| 379 | wp_send_json_error( $e->getMessage() ); |
| 380 | } |
| 381 | } |
| 382 | } |
| 383 | } |
| 384 | |
| 385 | public static function get_auto_exchange_rate() { |
| 386 | self::verify_nonce(); |
| 387 | |
| 388 | try { |
| 389 | $currency = sanitize_text_field( Obj::prop( 'currency', self::get_data() ) ); |
| 390 | $rate = Obj::prop( $currency, make( \WCML_Exchange_Rates::class )->fetch_exchange_rates_from_active_service( [ $currency ] ) ); |
| 391 | |
| 392 | if ( null === $rate ) { |
| 393 | throw new \Exception(); |
| 394 | } |
| 395 | |
| 396 | wp_send_json_success( $rate ); |
| 397 | } catch ( \Exception $e ) { |
| 398 | wp_send_json_error(); |
| 399 | } |
| 400 | } |
| 401 | } |
| 402 |