Changeset 3486633
- Timestamp:
- 03/19/2026 03:42:53 PM (13 days ago)
- Location:
- clonable
- Files:
-
- 136 added
- 15 edited
-
tags/2.9.7 (added)
-
tags/2.9.7/Bootstrap.php (added)
-
tags/2.9.7/clonable-wp.php (added)
-
tags/2.9.7/controllers (added)
-
tags/2.9.7/controllers/Controller.php (added)
-
tags/2.9.7/controllers/DashboardController.php (added)
-
tags/2.9.7/controllers/EmailTranslationsController.php (added)
-
tags/2.9.7/controllers/LandingPageController.php (added)
-
tags/2.9.7/controllers/LanguageSwitcherController.php (added)
-
tags/2.9.7/controllers/LanguageTagController.php (added)
-
tags/2.9.7/controllers/SettingController.php (added)
-
tags/2.9.7/controllers/WoocommerceController.php (added)
-
tags/2.9.7/controllers/index.php (added)
-
tags/2.9.7/exceptions (added)
-
tags/2.9.7/exceptions/ApiException.php (added)
-
tags/2.9.7/exceptions/CurlException.php (added)
-
tags/2.9.7/exceptions/ValidationException.php (added)
-
tags/2.9.7/helpers (added)
-
tags/2.9.7/helpers/Functions.php (added)
-
tags/2.9.7/helpers/Html.php (added)
-
tags/2.9.7/helpers/Json.php (added)
-
tags/2.9.7/helpers/Locales.php (added)
-
tags/2.9.7/helpers/MultiCurrency.php (added)
-
tags/2.9.7/helpers/Session.php (added)
-
tags/2.9.7/helpers/TextTranslator.php (added)
-
tags/2.9.7/helpers/UrlTranslator.php (added)
-
tags/2.9.7/helpers/clonable-locales-list.php (added)
-
tags/2.9.7/helpers/index.php (added)
-
tags/2.9.7/images (added)
-
tags/2.9.7/images/Logo_Icon_white.png (added)
-
tags/2.9.7/images/Logo_Icon_white.svg (added)
-
tags/2.9.7/images/clonable-full-logo.png (added)
-
tags/2.9.7/images/clonable.png (added)
-
tags/2.9.7/images/configure-wordpress-thumbnail.png (added)
-
tags/2.9.7/images/flags.png (added)
-
tags/2.9.7/images/index.php (added)
-
tags/2.9.7/images/language-switcher-thumbnail.png (added)
-
tags/2.9.7/index.php (added)
-
tags/2.9.7/middleware (added)
-
tags/2.9.7/middleware/Auth.php (added)
-
tags/2.9.7/middleware/ClonedSite.php (added)
-
tags/2.9.7/middleware/MiddlewareHandler.php (added)
-
tags/2.9.7/middleware/MiddlewareInterface.php (added)
-
tags/2.9.7/middleware/WooCommerce.php (added)
-
tags/2.9.7/middleware/index.php (added)
-
tags/2.9.7/models (added)
-
tags/2.9.7/models/ApiKey.php (added)
-
tags/2.9.7/models/ClonableWooCommerce.php (added)
-
tags/2.9.7/models/ClonedSite.php (added)
-
tags/2.9.7/models/EmailTranslations.php (added)
-
tags/2.9.7/models/LanguageSwitcher.php (added)
-
tags/2.9.7/models/LanguageTag.php (added)
-
tags/2.9.7/models/Settings.php (added)
-
tags/2.9.7/models/Site.php (added)
-
tags/2.9.7/models/index.php (added)
-
tags/2.9.7/objects (added)
-
tags/2.9.7/objects/ApiResponse.php (added)
-
tags/2.9.7/objects/CircuitBreaker.php (added)
-
tags/2.9.7/objects/ClonableConfig.php (added)
-
tags/2.9.7/objects/ClonableResponse.php (added)
-
tags/2.9.7/objects/CurlBuilder.php (added)
-
tags/2.9.7/objects/ExcludedProductTerm.php (added)
-
tags/2.9.7/objects/Notification.php (added)
-
tags/2.9.7/objects/index.php (added)
-
tags/2.9.7/readme-da_DK.txt (added)
-
tags/2.9.7/readme-de_DE.txt (added)
-
tags/2.9.7/readme-es_ES.txt (added)
-
tags/2.9.7/readme-fr_FR.txt (added)
-
tags/2.9.7/readme-it_IT.txt (added)
-
tags/2.9.7/readme-nb_NO.txt (added)
-
tags/2.9.7/readme-nl_NL.txt (added)
-
tags/2.9.7/readme-sv_SE.txt (added)
-
tags/2.9.7/readme.txt (added)
-
tags/2.9.7/routes (added)
-
tags/2.9.7/routes/Router.php (added)
-
tags/2.9.7/routes/index.php (added)
-
tags/2.9.7/services (added)
-
tags/2.9.7/services/AdminUIService.php (added)
-
tags/2.9.7/services/AllowedHostsService.php (added)
-
tags/2.9.7/services/ApiService.php (added)
-
tags/2.9.7/services/CacheService.php (added)
-
tags/2.9.7/services/ClonableWooCommerceService.php (added)
-
tags/2.9.7/services/EmailTranslationsService.php (added)
-
tags/2.9.7/services/LanguageSwitcherService.php (added)
-
tags/2.9.7/services/LanguageTagService.php (added)
-
tags/2.9.7/services/LocaleService.php (added)
-
tags/2.9.7/services/MultiCurrencyService.php (added)
-
tags/2.9.7/services/ShortCodeService.php (added)
-
tags/2.9.7/services/SubfolderService.php (added)
-
tags/2.9.7/services/SyncService.php (added)
-
tags/2.9.7/services/index.php (added)
-
tags/2.9.7/services/modules (added)
-
tags/2.9.7/services/modules/DataPanelModule.php (added)
-
tags/2.9.7/services/modules/ExclusionModule.php (added)
-
tags/2.9.7/services/modules/ProductImporterModule.php (added)
-
tags/2.9.7/services/modules/TaxonomyModule.php (added)
-
tags/2.9.7/services/modules/index.php (added)
-
tags/2.9.7/traits (added)
-
tags/2.9.7/traits/Forms.php (added)
-
tags/2.9.7/traits/PluginCheck.php (added)
-
tags/2.9.7/traits/Validation.php (added)
-
tags/2.9.7/traits/index.php (added)
-
tags/2.9.7/uninstall.php (added)
-
tags/2.9.7/views (added)
-
tags/2.9.7/views/DashboardView.php (added)
-
tags/2.9.7/views/EmailTranslationsView.php (added)
-
tags/2.9.7/views/LanguageSwitcherView.php (added)
-
tags/2.9.7/views/LanguageTagView.php (added)
-
tags/2.9.7/views/Layout.php (added)
-
tags/2.9.7/views/OnboardingView.php (added)
-
tags/2.9.7/views/SettingsView.php (added)
-
tags/2.9.7/views/ViewInterface.php (added)
-
tags/2.9.7/views/WoocommerceView.php (added)
-
tags/2.9.7/views/css (added)
-
tags/2.9.7/views/css/clonable-admin-bar.css (added)
-
tags/2.9.7/views/css/clonable-extra-button.css (added)
-
tags/2.9.7/views/css/clonable-global.css (added)
-
tags/2.9.7/views/css/clonable-language-switcher.css (added)
-
tags/2.9.7/views/css/clonable-thumbnails.css (added)
-
tags/2.9.7/views/css/clonable-woocommerce.css (added)
-
tags/2.9.7/views/css/clonable.css (added)
-
tags/2.9.7/views/css/fomantic-dropdown.css (added)
-
tags/2.9.7/views/css/fomantic-transition.css (added)
-
tags/2.9.7/views/css/freakflags.css (added)
-
tags/2.9.7/views/css/index.php (added)
-
tags/2.9.7/views/index.php (added)
-
tags/2.9.7/views/scripts (added)
-
tags/2.9.7/views/scripts/alpine.js (added)
-
tags/2.9.7/views/scripts/dohjs.js (added)
-
tags/2.9.7/views/scripts/email-translations.js (added)
-
tags/2.9.7/views/scripts/fomantic-dropdown.js (added)
-
tags/2.9.7/views/scripts/fomantic-transition.js (added)
-
tags/2.9.7/views/scripts/index.php (added)
-
tags/2.9.7/views/scripts/language-switcher.js (added)
-
tags/2.9.7/views/scripts/onload.js (added)
-
tags/2.9.7/views/scripts/woocommerce-clone-field.js (added)
-
trunk/clonable-wp.php (modified) (3 diffs)
-
trunk/objects/ClonableConfig.php (modified) (3 diffs)
-
trunk/readme-da_DK.txt (modified) (2 diffs)
-
trunk/readme-de_DE.txt (modified) (2 diffs)
-
trunk/readme-es_ES.txt (modified) (2 diffs)
-
trunk/readme-fr_FR.txt (modified) (2 diffs)
-
trunk/readme-it_IT.txt (modified) (2 diffs)
-
trunk/readme-nb_NO.txt (modified) (2 diffs)
-
trunk/readme-nl_NL.txt (modified) (2 diffs)
-
trunk/readme-sv_SE.txt (modified) (2 diffs)
-
trunk/readme.txt (modified) (2 diffs)
-
trunk/services/ClonableWooCommerceService.php (modified) (6 diffs)
-
trunk/services/EmailTranslationsService.php (modified) (14 diffs)
-
trunk/traits/PluginCheck.php (modified) (1 diff)
-
trunk/views/EmailTranslationsView.php (modified) (3 diffs)
Legend:
- Unmodified
- Added
- Removed
-
clonable/trunk/clonable-wp.php
r3486465 r3486633 5 5 Description: Official plugin for improving your clones made with Clonable. 6 6 Plugin URI: https://kb.clonable.net/en/introduction/getting-started/wordpress#de-clonable-plug-in-downloaden 7 Version: 2.9. 67 Version: 2.9.7 8 8 Author: Clonable BV 9 9 Author URI: https://www.clonable.net … … 126 126 127 127 define('CLONABLE_NAME', 'Clonable'); 128 define('CLONABLE_VERSION', '2.9. 6');128 define('CLONABLE_VERSION', '2.9.7'); 129 129 130 130 if (defined('WP_CLI') && WP_CLI) { … … 225 225 { 226 226 $domain = ClonableConfig::current_clonable_domain(); 227 if ($domain === ClonableC Onfig::ORIGINAL_SHOP) {227 if ($domain === ClonableConfig::ORIGINAL_SHOP) { 228 228 return $_SERVER['host'] ?? ''; // return the standard host 229 229 } -
clonable/trunk/objects/ClonableConfig.php
r3452753 r3486633 76 76 * @return string|null 77 77 */ 78 public static function get_clone_id_by_current_url(): ?string { 78 public static function get_clone_id_by_current_url(): ?string 79 { 79 80 $clones = self::get_clones(); 80 81 if (empty($clones)) { … … 84 85 $host_header = $_SERVER['HTTP_X_FORWARDED_HOST'] ?? ($_SERVER['HTTP_HOST'] ?? ($_SERVER['SERVER_NAME'] ?? '')); 85 86 $sanitized_host = str_replace('www.', '', $host_header); 86 87 87 88 // Get all clones for this domain. 88 89 $domain_matches = []; … … 97 98 } 98 99 99 if (count($domain_matches) === 1 ) {100 if (count($domain_matches) === 1 && empty($domain_matches[0]['subfolder_clone'])) { 100 101 return $domain_matches[0]['id']; 101 102 } -
clonable/trunk/readme-da_DK.txt
r3486465 r3486633 5 5 Tested up to: 6.9.1 6 6 Requires PHP: 7.2 7 Stable tag: 2.9. 67 Stable tag: 2.9.7 8 8 License: GPL v2 or later 9 9 … … 32 32 33 33 == Changelog == 34 v2.9.6 34 v2.9.7 35 WooCommerce email translation improvements for WC block checkout 36 37 v2.9.6 35 38 Clonable language switcher improvements 36 39 37 v2.9.5 40 v2.9.5 38 41 Clonable language switcher improvements 39 40 v2.9.4 42 43 v2.9.4 41 44 Support for locally set languages in Clonable Language Switcher 42 45 -
clonable/trunk/readme-de_DE.txt
r3486465 r3486633 5 5 Tested up to: 6.9.1 6 6 Requires PHP: 7.2 7 Stable tag: 2.9. 67 Stable tag: 2.9.7 8 8 License: GPL v2 or later 9 9 … … 32 32 33 33 == Changelog == 34 v2.9.6 34 v2.9.7 35 WooCommerce email translation improvements for WC block checkout 36 37 v2.9.6 35 38 Clonable language switcher improvements 36 39 37 v2.9.5 40 v2.9.5 38 41 Clonable language switcher improvements 39 42 40 v2.9.4 43 v2.9.4 41 44 Support for locally set languages in Clonable Language Switcher 42 45 -
clonable/trunk/readme-es_ES.txt
r3486465 r3486633 5 5 Tested up to: 6.9.1 6 6 Requires PHP: 7.2 7 Stable tag: 2.9. 67 Stable tag: 2.9.7 8 8 License: GPL v2 or later 9 9 … … 32 32 33 33 == Changelog == 34 v2.9.6 34 v2.9.7 35 WooCommerce email translation improvements for WC block checkout 36 37 v2.9.6 35 38 Clonable language switcher improvements 36 39 37 v2.9.5 40 v2.9.5 38 41 Clonable language switcher improvements 39 42 -
clonable/trunk/readme-fr_FR.txt
r3486465 r3486633 5 5 Tested up to: 6.9.1 6 6 Requires PHP: 7.2 7 Stable tag: 2.9. 67 Stable tag: 2.9.7 8 8 License: GPL v2 or later 9 9 … … 32 32 33 33 == Changelog == 34 v2.9.6 34 v2.9.7 35 WooCommerce email translation improvements for WC block checkout 36 37 v2.9.6 35 38 Clonable language switcher improvements 36 39 37 v2.9.5 40 v2.9.5 38 41 Clonable language switcher improvements 39 42 -
clonable/trunk/readme-it_IT.txt
r3486465 r3486633 5 5 Tested up to: 6.9.1 6 6 Requires PHP: 7.2 7 Stable tag: 2.9. 67 Stable tag: 2.9.7 8 8 License: GPL v2 or later 9 9 … … 32 32 33 33 == Changelog == 34 v2.9.6 34 v2.9.7 35 WooCommerce email translation improvements for WC block checkout 36 37 v2.9.6 35 38 Clonable language switcher improvements 36 39 37 v2.9.5 40 v2.9.5 38 41 Clonable language switcher improvements 39 42 -
clonable/trunk/readme-nb_NO.txt
r3486465 r3486633 5 5 Tested up to: 6.9.1 6 6 Requires PHP: 7.2 7 Stable tag: 2.9. 67 Stable tag: 2.9.7 8 8 License: GPL v2 or later 9 9 … … 32 32 33 33 == Changelog == 34 v2.9.6 34 v2.9.7 35 WooCommerce email translation improvements for WC block checkout 36 37 v2.9.6 35 38 Clonable language switcher improvements 36 39 37 v2.9.5 40 v2.9.5 38 41 Clonable language switcher improvements 39 42 -
clonable/trunk/readme-nl_NL.txt
r3486465 r3486633 5 5 Tested up to: 6.9.1 6 6 Requires PHP: 7.2 7 Stable tag: 2.9. 67 Stable tag: 2.9.7 8 8 License: GPL v2 or later 9 9 … … 32 32 33 33 == Changelog == 34 v2.9.6 34 v2.9.7 35 WooCommerce email translation improvements for WC block checkout 36 37 v2.9.6 35 38 Clonable language switcher improvements 36 39 37 v2.9.5 40 v2.9.5 38 41 Clonable language switcher improvements 39 42 -
clonable/trunk/readme-sv_SE.txt
r3486465 r3486633 5 5 Tested up to: 6.9.1 6 6 Requires PHP: 7.2 7 Stable tag: 2.9. 67 Stable tag: 2.9.7 8 8 License: GPL v2 or later 9 9 … … 32 32 33 33 == Changelog == 34 v2.9.6 34 v2.9.7 35 WooCommerce email translation improvements for WC block checkout 36 37 v2.9.6 35 38 Clonable language switcher improvements 36 39 37 v2.9.5 40 v2.9.5 38 41 Clonable language switcher improvements 39 42 -
clonable/trunk/readme.txt
r3486465 r3486633 5 5 Tested up to: 6.9.1 6 6 Requires PHP: 7.2 7 Stable tag: 2.9. 67 Stable tag: 2.9.7 8 8 License: GPL v2 or later 9 9 … … 32 32 33 33 == Changelog == 34 v2.9.6 34 v2.9.7 35 WooCommerce email translation improvements for WC block checkout 36 37 v2.9.6 35 38 Clonable language switcher improvements 36 39 37 v2.9.5 40 v2.9.5 38 41 Clonable language switcher improvements 39 42 40 v2.9.4 43 v2.9.4 41 44 Support for locally set languages in Clonable Language Switcher 42 45 -
clonable/trunk/services/ClonableWooCommerceService.php
r3467415 r3486633 30 30 return; 31 31 } 32 32 33 33 $include_woocommerce_analytics = get_option('clonable_woocommerce_analytics_enabled', 'on') === 'on'; 34 34 if ($include_woocommerce_analytics) { 35 35 // Add hidden field with the domain. Will get replaced by Clonable automagically to match actual domain. 36 36 add_action('woocommerce_after_order_notes', array($this, 'add_origin_field')); 37 add_action('woocommerce_checkout_update_order_meta', array($this, 'save_origin_field') );37 add_action('woocommerce_checkout_update_order_meta', array($this, 'save_origin_field'), 10, 1); 38 38 add_action('woocommerce_admin_order_data_after_shipping_address', array($this, 'display_order_origin')); 39 39 … … 77 77 // Add a hidden field containing the current clone ID for use in woocommerce email translations 78 78 add_action('woocommerce_after_order_notes', array($this, 'add_clone_id_field'), 10, 2); 79 79 80 // Add the clone ID to the order meta when saving the order 80 81 add_action('woocommerce_checkout_update_order_meta', array($this, 'save_order_clone_id')); 81 82 83 // Save clone ID for WooCommerce Blocks checkout (Store API doesn't use $_POST) 84 add_action('woocommerce_store_api_checkout_order_processed', array($this, 'save_clone_id_for_block_checkout'), 10, 1); 85 86 // Save origin for WooCommerce Blocks checkout (Store API doesn't use $_POST) 87 add_action('woocommerce_store_api_checkout_order_processed', array($this, 'save_origin_field_for_block_checkout'), 20, 1); 88 82 89 // Support for WooCommerce PDF Invoices & Packing Slips plugin translation 83 $pdf_translations_enabled = get_option('clonable_woocommerce_enable_pdf_invoice_translation', 'off') === 'on';90 $pdf_translations_enabled = get_option('clonable_woocommerce_enable_pdf_invoice_translation', 'off') === 'on'; 84 91 if ($this->pdf_invoices_installed() && $pdf_translations_enabled) { 85 92 add_action('plugins_loaded', [$this, 'register_pdf_translation_hooks'], 20, 0); … … 87 94 } 88 95 89 public function register_pdf_translation_hooks() { 90 $filter_function_map = [ 91 "wpo_wcpdf_shop_phone_number_settings_text" => "shop_phone_number", 92 "wpo_wcpdf_shop_email_address_settings_text" => "shop_email_address", 93 "wpo_wcpdf_shop_name_settings_text" => "shop_name", 94 "wpo_wcpdf_vat_number_settings_text" => "vat_number", 95 "wpo_wcpdf_coc_number_settings_text" => "coc_number", 96 "wpo_wcpdf_shop_address_line_1_settings_text" => "shop_address_line_1", 97 "wpo_wcpdf_shop_address_line_2_settings_text" => "shop_address_line_2", 98 "wpo_wcpdf_shop_address_country_settings_text" => "shop_address_country", 99 "wpo_wcpdf_shop_address_state_settings_text" => "shop_address_state", 100 "wpo_wcpdf_shop_address_city_settings_text" => "shop_address_city", 101 "wpo_wcpdf_shop_address_postcode_settings_text" => "shop_address_postcode", 102 ]; 103 104 add_filter('wpo_wcpdf_get_html', function ($html, $document) { 105 return $this->get_pdf_template_translation($html, $document); 106 }, 10, 2); 107 108 foreach ($filter_function_map as $hook => $field_name) { 109 add_filter($hook, function ($text, $document) use ($field_name) { 110 return $this->get_pdf_field_replacement($field_name, $text, $document); 111 }, 10, 2); 112 } 113 114 // Support different logos per language in PDF documents (use multiple filter names for compatibility) 115 add_filter('wpo_wcpdf_logo', [$this, 'pdf_logo_url'], 10, 2); 116 add_filter('wpo_wcpdf_document_logo', [$this, 'pdf_logo_url'], 10, 2); 117 add_filter('wpo_wcpdf_header_logo', [$this, 'pdf_logo_url'], 10, 2); 118 add_filter('wpo_wcpdf_template_logo', [$this, 'pdf_logo_url'], 10, 2); 119 120 // logo ID filter 121 add_filter('wpo_wcpdf_header_logo_id', [$this, 'pdf_logo_id'], 10, 2); 122 } 96 public function register_pdf_translation_hooks() 97 { 98 $filter_function_map = [ 99 "wpo_wcpdf_shop_phone_number_settings_text" => "shop_phone_number", 100 "wpo_wcpdf_shop_email_address_settings_text" => "shop_email_address", 101 "wpo_wcpdf_shop_name_settings_text" => "shop_name", 102 "wpo_wcpdf_vat_number_settings_text" => "vat_number", 103 "wpo_wcpdf_coc_number_settings_text" => "coc_number", 104 "wpo_wcpdf_shop_address_line_1_settings_text" => "shop_address_line_1", 105 "wpo_wcpdf_shop_address_line_2_settings_text" => "shop_address_line_2", 106 "wpo_wcpdf_shop_address_country_settings_text" => "shop_address_country", 107 "wpo_wcpdf_shop_address_state_settings_text" => "shop_address_state", 108 "wpo_wcpdf_shop_address_city_settings_text" => "shop_address_city", 109 "wpo_wcpdf_shop_address_postcode_settings_text" => "shop_address_postcode", 110 ]; 111 112 add_filter('wpo_wcpdf_get_html', function ($html, $document) { 113 return $this->get_pdf_template_translation($html, $document); 114 }, 10, 2); 115 116 foreach ($filter_function_map as $hook => $field_name) { 117 add_filter($hook, function ($text, $document) use ($field_name) { 118 return $this->get_pdf_field_replacement($field_name, $text, $document); 119 }, 10, 2); 120 } 121 122 // Support different logos per language in PDF documents (use multiple filter names for compatibility) 123 add_filter('wpo_wcpdf_logo', [$this, 'pdf_logo_url'], 10, 2); 124 add_filter('wpo_wcpdf_document_logo', [$this, 'pdf_logo_url'], 10, 2); 125 add_filter('wpo_wcpdf_header_logo', [$this, 'pdf_logo_url'], 10, 2); 126 add_filter('wpo_wcpdf_template_logo', [$this, 'pdf_logo_url'], 10, 2); 127 128 // logo ID filter 129 add_filter('wpo_wcpdf_header_logo_id', [$this, 'pdf_logo_id'], 10, 2); 130 } 123 131 124 132 /** … … 268 276 echo '<input type="hidden" name="clonable_clone_id" value="' . $clone_id . '" />'; 269 277 } 278 270 279 271 280 /** … … 327 336 $order->save(); 328 337 } 338 } 339 340 /** 341 * Save clone ID for orders placed via the WooCommerce Blocks checkout. 342 * The blocks checkout uses the Store API instead of $_POST, so we determine 343 * the clone ID server-side from the current request headers. 344 * 345 * @param WC_Order $order 346 */ 347 public function save_clone_id_for_block_checkout($order) 348 { 349 // Skip if clone_id was already saved (e.g. classic checkout fallback) 350 if ($order->get_meta('clonable_clone_id')) { 351 return; 352 } 353 $clone_id = ClonableConfig::get_clone_id_by_current_url(); 354 if ($clone_id) { 355 $sanitized = sanitize_text_field($clone_id); 356 $order->update_meta_data('clonable_clone_id', $sanitized); 357 $order->save(); 358 } 359 } 360 361 /** 362 * Save order origin for orders placed via the WooCommerce Blocks checkout. 363 * The blocks checkout uses the Store API instead of $_POST, so we determine 364 * the origin server-side from the current request headers. 365 * 366 * @param WC_Order $order 367 */ 368 public function save_origin_field_for_block_checkout($order) 369 { 370 // Skip if origin was already saved (e.g. classic checkout fallback) 371 if ($order->get_meta('clonable_origin')) { 372 return; 373 } 374 375 $origin = null; 376 //get the origin clone URL based on the current request headers (set by Clonable on the frontend) 377 if (isset($_SERVER['HTTP_CLONABLE_CLONE_DOMAIN'])) { 378 $origin = $_SERVER['HTTP_CLONABLE_CLONE_DOMAIN']; 379 if (isset($_SERVER['HTTP_CLONABLE_CLONE_SUBFOLDER']) && !empty($_SERVER['HTTP_CLONABLE_CLONE_SUBFOLDER'])) { 380 $origin .= $_SERVER['HTTP_CLONABLE_CLONE_SUBFOLDER']; 381 } 382 } else { 383 // fallback to original shop domain when header not present 384 $origin = ClonableConfig::ORIGINAL_SHOP; 385 } 386 387 $origin = rtrim($origin, '/'); // remove trailing slash from origin if present 388 389 if (!$this->is_valid_origin($origin)) { 390 return; 391 } 392 393 // save the origin in the order meta 394 $order->update_meta_data('clonable_origin', $origin); 395 $order->save(); 329 396 } 330 397 … … 437 504 private function get_clone_id_from_request(): string 438 505 { 439 return isset($_POST['clonable_clone_id']) ? (string) $_POST['clonable_clone_id'] : '';506 return isset($_POST['clonable_clone_id']) ? (string) $_POST['clonable_clone_id'] : ''; 440 507 } 441 508 -
clonable/trunk/services/EmailTranslationsService.php
r3467415 r3486633 5 5 use Clonable\Helpers\Functions; 6 6 use Clonable\Helpers\TextTranslator; 7 use Clonable\Services\ClonableWooCommerceService; 7 8 use function is_string; 8 9 use function trim; … … 13 14 } 14 15 15 class EmailTranslationsService { 16 class EmailTranslationsService 17 { 16 18 private const OPT_ENABLED = 'clonable_email_translations_enabled'; 17 19 private const OPT_EXCLUDED = 'clonable_email_translations_excluded_addresses'; 18 20 private const OPT_HEADERS_BY_DOMAIN = 'clonable_email_headers_by_domain'; 19 20 public function __construct() { 21 if (!$this->emailTranslationsEnabled()) { 22 return; 23 } 24 25 add_filter('wp_mail' ,[$this ,'translateMail'] ,PHP_INT_MAX); 26 add_filter('wp_mail_from' ,[$this ,'setMailFrom'] ,PHP_INT_MAX); 27 add_filter('wp_mail_from_name' ,[$this ,'setMailSenderName'] ,PHP_INT_MAX); 28 add_filter('option_woocommerce_email_header_image' ,[$this ,'setMailHeaderImage'] ,PHP_INT_MAX); 29 add_action('phpmailer_init' ,[$this ,'override_phpmailer_sender'] ,PHP_INT_MAX); 30 } 31 32 public function translateMail(array $args): array { 33 $clone_id = $this->getCloneIdFromRequest(); 21 private $currentOrderId = null; 22 23 public function __construct() 24 { 25 if (!$this->emailTranslationsEnabled()) { 26 return; 27 } 28 29 add_filter('wp_mail', [$this, 'translateMail'], 20, 1); 30 add_filter('wp_mail_from', [$this, 'setMailFrom'], PHP_INT_MAX); 31 add_filter('wp_mail_from_name', [$this, 'setMailSenderName'], PHP_INT_MAX); 32 add_filter('option_woocommerce_email_header_image', [$this, 'setMailHeaderImage'], PHP_INT_MAX); 33 add_action('phpmailer_init', [$this, 'override_phpmailer_sender'], PHP_INT_MAX); 34 35 // Capture order ID for use in email translations (in case clone ID is not available in the request, e.g. for async emails) 36 add_action('woocommerce_after_order_object_save', [$this, 'captureOrderFromSave'], 10, 1); 37 } 38 39 public function captureOrderFromSave($order) 40 { 41 if ($order instanceof \WC_Order) { 42 $order_id = $order->get_id(); 43 $this->currentOrderId = $order_id; 44 } 45 } 46 47 public function translateMail(array $args): array 48 { 49 $clone_id = $this->getCloneIdFromRequest(); 50 if (!$clone_id) { // no clone ID in $_POST data, so we check if we have a global order ID set by the WooCommerce email hook, and if so, add it to the args for potential use in translation 51 $order_id = $this->currentOrderId; 52 // get the clone id from the order meta, if it exists 53 if (!empty($order_id)) { 54 $order_clone_id = wc_get_order($order_id)->get_meta('clonable_clone_id', true); 55 if (!empty($order_clone_id)) { 56 $clone_id = $order_clone_id; 57 } 58 } 59 } 60 34 61 if (empty($clone_id)) { 35 62 return $args; … … 42 69 $hasSubject = isset($args['subject']) && is_string($args['subject']) && $args['subject'] !== ''; 43 70 if ($hasSubject) { 44 $args['subject'] = TextTranslator::translateText($args['subject'] ,$clone_id);71 $args['subject'] = TextTranslator::translateText($args['subject'], $clone_id); 45 72 } 46 73 … … 48 75 if ($hasMessage) { 49 76 $message = Functions::minify_html($args['message']); 50 $args['message'] = TextTranslator::translateText((string) $message ,$clone_id ,false);77 $args['message'] = TextTranslator::translateText((string) $message, $clone_id, false); 51 78 } 52 79 … … 76 103 } 77 104 78 public function setMailFrom(string $from): string { 105 public function setMailFrom(string $from): string 106 { 79 107 $clone_id = $this->getCloneIdFromRequest(); 80 108 if (empty($clone_id)) { … … 94 122 } 95 123 96 public function setMailSenderName(string $name): string { 124 public function setMailSenderName(string $name): string 125 { 97 126 $clone_id = $this->getCloneIdFromRequest(); 98 127 if (empty($clone_id)) { … … 112 141 } 113 142 114 public function setMailHeaderImage(string $image): string { 143 public function setMailHeaderImage(string $image): string 144 { 115 145 $clone_id = $this->getCloneIdFromRequest(); 116 146 if (empty($clone_id)) { … … 136 166 * @param \PHPMailer PHPMailer instance 137 167 */ 138 public function override_phpmailer_sender($php_mailer) { 168 public function override_phpmailer_sender($php_mailer) 169 { 139 170 $from_name = $this->setMailSenderName($php_mailer->FromName); 140 171 $from_email = $this->setMailFrom($php_mailer->From); … … 162 193 163 194 try { 164 $php_mailer->addReplyTo($reply_to_address ,$from_name);195 $php_mailer->addReplyTo($reply_to_address, $from_name); 165 196 } catch (\Exception $e) { 166 197 // Ignore invalid email address … … 173 204 } 174 205 175 private function getCloneIdFromRequest(): ?string { 206 private function getCloneIdFromRequest(): ?string 207 { 176 208 return isset($_POST['clonable_clone_id']) ? (string) $_POST['clonable_clone_id'] : null; 177 209 } 178 210 179 private function emailTranslationsEnabled(): bool { 180 return get_option(self::OPT_ENABLED ,'on') === 'on'; 181 } 182 183 private function getHeadersByDomain(): array { 184 $raw = get_option(self::OPT_HEADERS_BY_DOMAIN ,'[]'); 185 $decoded = json_decode((string) $raw ,true); 211 private function emailTranslationsEnabled(): bool 212 { 213 return get_option(self::OPT_ENABLED, 'on') === 'on'; 214 } 215 216 private function getHeadersByDomain(): array 217 { 218 $raw = get_option(self::OPT_HEADERS_BY_DOMAIN, '[]'); 219 $decoded = json_decode((string) $raw, true); 186 220 187 221 return is_array($decoded) ? $decoded : []; 188 222 } 189 223 190 private function getHeaderInfoForClone(?string $clone_id): ?array { 224 private function getHeaderInfoForClone(?string $clone_id): ?array 225 { 191 226 if (empty($clone_id)) { 192 227 return null; … … 207 242 } 208 243 209 private function isRecipientExcluded(array $args): bool { 210 $option = get_option(self::OPT_EXCLUDED ,''); 244 private function isRecipientExcluded(array $args): bool 245 { 246 $option = get_option(self::OPT_EXCLUDED, ''); 211 247 if (!is_string($option) || $option === '') { 212 248 return false; … … 222 258 223 259 if (is_string($to) && $to !== '') { 224 $recipients = preg_split('/[\s,;]+/' ,$to ,- 1 ,PREG_SPLIT_NO_EMPTY) ?: [];260 $recipients = preg_split('/[\s,;]+/', $to, -1, PREG_SPLIT_NO_EMPTY) ?: []; 225 261 } elseif (is_array($to)) { 226 262 $recipients = $to; … … 234 270 $recipientLower = Functions::lower($recipient); 235 271 foreach ($excluded as $needle) { 236 if ($needle !== '' && strpos($recipientLower ,$needle) !== false) {272 if ($needle !== '' && strpos($recipientLower, $needle) !== false) { 237 273 return true; 238 274 } … … 243 279 } 244 280 245 private function parseLowercasedList(string $value): array { 246 $parts = preg_split('/[\s,;]+/' ,$value ,- 1 ,PREG_SPLIT_NO_EMPTY) ?: []; 281 private function parseLowercasedList(string $value): array 282 { 283 $parts = preg_split('/[\s,;]+/', $value, -1, PREG_SPLIT_NO_EMPTY) ?: []; 247 284 $out = []; 248 285 -
clonable/trunk/traits/PluginCheck.php
r3455196 r3486633 34 34 } 35 35 36 /** 37 * Check if the Clonable Advanced plugin is installed 38 * @return bool 39 */ 40 public function clonable_advanced_installed() { 41 return $this->check_plugin_by_file('clonable-advanced/clonable-advanced.php'); 42 } 43 36 44 /** 37 45 * Check if the WooCommerce Multi Currency plugin is installed -
clonable/trunk/views/EmailTranslationsView.php
r3452753 r3486633 7 7 use Clonable\models\EmailTranslations; 8 8 use Clonable\Objects\ClonableConfig; 9 use Clonable\Traits\PluginCheck; 9 10 10 11 class EmailTranslationsView implements ViewInterface 11 12 { 12 13 use Forms; 14 use PluginCheck; 13 15 14 16 public function render(): void … … 26 28 { 27 29 echo '<p style="max-width: 75%">Configure the email translation settings used by Clonable.</p>'; 30 /* if clonable advanced is installed, generate warning if the email translations are enabled */ 31 if ($this->clonable_advanced_installed() && $this->emailTranslationsEnabled()) { 32 echo '<p class="warning" style="max-width: 75%; color: red; padding:10px; display:inline-block; border:1px solid red; margin:0;"><strong>Warning</strong> - Woocommerce email translations are enabled, but the Clonable Advanced module also seems to be used.<br>Be aware of potential conflicts regarding Woocommerce Email translations.</p>'; 33 } 34 } 35 36 public function emailTranslationsEnabled() 37 { 38 return get_option('clonable_email_translations_enabled', 'off') === 'on'; 28 39 } 29 40 … … 255 266 Configure order PDF fields for specific clone domains. 256 267 Domains are fixed and based on the Allowed Origins list. 257 <br />268 <br /> 258 269 Leave the fields empty to use the same PDF fields for the 259 270 translated version, as the default version.
Note: See TracChangeset
for help on using the changeset viewer.