PluginProbe ʕ •ᴥ•ʔ
WPML Multilingual & Multicurrency for WooCommerce / 5.5.7
WPML Multilingual & Multicurrency for WooCommerce v5.5.7
5.5.7 5.3.8 5.3.9 5.4.3 5.4.4 5.4.5 5.5.1 5.5.1.1 5.5.2.2 5.5.2.3 5.5.3 5.5.3.1 5.5.4 5.5.5 5.5.6 trunk 0.9 1.0 1.1 1.2 1.3 1.4 1.5 2.0 2.2 2.3 2.3.1 2.3.2 3.0 3.0.1 3.1 3.2 3.2.1 3.2.2 3.3 3.3.1 3.3.2 3.3.3 3.3.4 3.4 3.4.1 3.4.2 3.4.3 3.5 3.5.1 3.5.2 3.5.3 3.5.4 3.5.5 3.6 3.6.1 3.6.10 3.6.11 3.6.2 3.6.3 3.6.4 3.6.5 3.6.5.1 3.6.6 3.6.7 3.6.8 3.6.9 3.7 3.7.1 3.7.10 3.7.11 3.7.12 3.7.13 3.7.14 3.7.15 3.7.16 3.7.2 3.7.3 3.7.4 3.7.5 3.7.6 3.7.7 3.7.8 3.7.9 3.8.0 3.8.1 3.8.2 3.8.3 3.8.4 3.8.5 3.8.6 3.9.0 3.9.1 3.9.1.1 3.9.2 3.9.3 3.9.4 3.9.5 4.0.0 4.0.1 4.0.2 4.0.3 4.0.4 4.1.0 4.1.1 4.1.2 4.1.3 4.1.4 4.10.0 4.10.1 4.10.2 4.10.3 4.10.4 4.11.2 4.11.3.2 4.11.5 4.11.6 4.12.1 4.12.4 4.12.5 4.12.6 4.2.0 4.2.0.1 4.2.1 4.2.1.1 4.2.10 4.2.2 4.2.3 4.2.4 4.2.5 4.2.6 4.2.7 4.2.7.1 4.2.8 4.2.8.1 4.2.9 4.3.0 4.3.1 4.3.2 4.3.2.1 4.3.3 4.3.4 4.3.5 4.3.6 4.3.7 4.4.0 4.4.1 4.4.2 4.4.2.1 4.5.0 4.6.0 4.6.1 4.6.2 4.6.2.1 4.6.3 4.6.5 4.6.6 4.6.7 4.7.0 4.7.1 4.7.2 4.7.3 4.7.4 4.7.5 4.7.6 4.7.7 4.7.8 4.7.9 4.8.0 4.9.0 4.9.1 5.0.1 5.0.2 5.1.1 5.1.2 5.1.3 5.2.0 5.2.1 5.3.2 5.3.3.1 5.3.4 5.3.5 5.3.6 5.3.7
woocommerce-multilingual / classes / Multicurrency / UI / Hooks.php
woocommerce-multilingual / classes / Multicurrency / UI Last commit date
Factory.php 1 week ago Hooks.php 1 week ago
Hooks.php
279 lines
1 <?php
2
3 namespace WCML\Multicurrency\UI;
4
5 use WCML\MultiCurrency\Settings;
6 use WCML\StandAlone\IStandAloneAction;
7 use WCML\Utilities\Resources;
8 use WCML_Multi_Currency;
9 use WCML_Currencies_Payment_Gateways;
10 use WPML\Collect\Support\Collection;
11 use WPML\Core\ISitePress;
12 use WCML\StandAlone\NullSitePress;
13 use SitePress;
14 use WPML\FP\Fns;
15 use WPML\FP\Obj;
16 use function WCML\functions\isStandAlone;
17 use function WPML\FP\curryN;
18
19 class Hooks implements \IWPML_Action, IStandAloneAction {
20
21 const HANDLE = 'wcml-multicurrency-options';
22
23 private $multiCurrency;
24
25 private $currenciesPaymentGateways;
26
27 private $sitepress;
28
29 private $wcmlSettings;
30
31 public function __construct(
32 WCML_Multi_Currency $multiCurrency,
33 WCML_Currencies_Payment_Gateways $currenciesPaymentGateways,
34 ISitePress $sitepress,
35 array $wcmlSettings
36 ) {
37 $this->multiCurrency = $multiCurrency;
38 $this->currenciesPaymentGateways = $currenciesPaymentGateways;
39 $this->sitepress = $sitepress;
40 $this->wcmlSettings = $wcmlSettings;
41 }
42
43 public function add_hooks() {
44 add_action( 'admin_enqueue_scripts', [ $this, 'loadAssets' ] );
45 }
46
47 public function loadAssets() {
48 $gateways = $this->getGateways();
49 $enqueue = Resources::enqueueApp( 'multicurrencyOptions' );
50
51 $enqueue( [
52 'name' => 'wcmlMultiCurrency',
53 'data' => [
54 'endpoint' => self::HANDLE,
55 'activeCurrencies' => $this->getActiveCurrencies( $gateways ),
56 'allCurrencies' => $this->getAllCurrencies(),
57 'allCountries' => $this->getAllCountries(),
58 'languages' => $this->getLanguages(),
59 'gateways' => $gateways->toArray(),
60 'strings' => $this->getStrings(),
61 'mode' => Settings::getMode(),
62 'maxMindKeyExist' => $this->checkMaxMindKeyExist(),
63 'isStandalone' => isStandAlone(),
64 'isAutoRateEnabled' => Settings::isAutomaticRateEnabled(),
65 ],
66 ] );
67 }
68
69 private function getActiveCurrencies( Collection $gateways ) {
70 $defaultCurrency = wcml_get_woocommerce_currency_option();
71
72 $addCode = function( $currency, $code ) {
73 return array_merge( $currency, [ 'code' => $code ] );
74 };
75
76 $buildActiveCurrency = function( $currency ) use ( $defaultCurrency ) {
77 return [
78 'isDefault' => $currency['code'] === $defaultCurrency,
79 'languages' => array_map( 'intval', $currency['languages'] ),
80 'gatewaysEnabled' => $this->currenciesPaymentGateways->is_enabled( $currency['code'] ),
81 ];
82 };
83
84 $addGatewaysSettings = function( $currency ) use ( $gateways ) {
85 $addSettingsForGateway = curryN( 2, function( $code, array $gateway ) {
86 return [ $gateway['id'] => Obj::pathOr( [], [ 'settings', $code ], $gateway ) ];
87 } );
88
89 return [ 'gatewaysSettings' => $gateways->mapWithKeys( $addSettingsForGateway( $currency['code'] ) )->toArray() ];
90 };
91
92 $addFormattedLastRateUpdate = function( $currency ) {
93 return [
94 'formattedLastRateUpdate' => isset( $currency['updated'] )
95 ? self::formatLastRateUpdate( $currency['updated'] )
96 : null,
97 ];
98 };
99
100 $merge = function( $fn ) {
101 return Fns::converge( 'array_merge', [ $fn, Fns::identity() ] );
102 };
103
104 return wpml_collect( $this->multiCurrency->get_currencies( true ) )
105 ->map( $addCode )
106 ->map( $merge( $buildActiveCurrency ) )
107 ->map( $merge( $addFormattedLastRateUpdate ) )
108 ->map( $merge( $addGatewaysSettings ) )
109 ->values()
110 ->toArray();
111 }
112
113 private function getAllCurrencies() {
114 $currencyFormats = json_decode( file_get_contents( WCML_PLUGIN_PATH . '/res/currencies/currency_formats.json' ) );
115
116 $buildCurrency = function( $label, $code ) use ( $currencyFormats ) {
117 $getDefault = function( $prop, $default ) use ( $code, $currencyFormats ) {
118 return Obj::pathOr( $default, [ $code, $prop ], $currencyFormats );
119 };
120
121 return (object) [
122 'code' => $code,
123 'label' => html_entity_decode( $label ),
124 'symbol' => html_entity_decode( get_woocommerce_currency_symbol( $code ) ),
125 'position' => $getDefault( 'position', 'left' ),
126 'thousand_sep' => $getDefault( 'thousand_sep', '.' ),
127 'decimal_sep' => $getDefault( 'decimal_sep', ',' ),
128 'num_decimals' => $getDefault( 'num_decimals', 2 ),
129 ];
130 };
131
132 return wpml_collect( get_woocommerce_currencies() )->map( $buildCurrency )->values()->toArray();
133 }
134
135 private function getLanguages() {
136 $buildLanguage = function( $data ) {
137 return (object) [
138 'code' => $data['code'],
139 'displayName' => $data['display_name'],
140 'flagUrl' => $this->sitepress->get_flag_url( $data['code'] ),
141 'defaultCurrency' => $this->wcmlSettings['default_currencies'][ $data['code'] ] ?? false,
142 ];
143 };
144
145 return wpml_collect( $this->sitepress->get_active_languages() )
146 ->map( $buildLanguage )
147 ->values()
148 ->toArray();
149 }
150
151 private function getGateways() {
152 $isSupported = function( \WCML_Payment_Gateway $gateway ) {
153 return ! $gateway instanceof \WCML_Not_Supported_Payment_Gateway;
154 };
155
156 $buildGateway = function( \WCML_Payment_Gateway $gateway ) {
157 return $gateway->get_output_model();
158 };
159
160 return wpml_collect( $this->currenciesPaymentGateways->get_gateways() )
161 ->prioritize( $isSupported )
162 ->map( $buildGateway )
163 ->values();
164 }
165
166 private function getStrings() {
167 $trackingLink = new \WCML_Tracking_Link();
168
169 return [
170 'labelCurrencies' => __( 'Currencies', 'woocommerce-multilingual' ),
171 'labelCurrency' => __( 'Currency', 'woocommerce-multilingual' ),
172 'labelAddCurrency' => __( 'Add currency', 'woocommerce-multilingual' ),
173 'labelRate' => __( 'Rate', 'woocommerce-multilingual' ),
174 'labelDefault' => __( 'default', 'woocommerce-multilingual' ),
175 'labelEdit' => __( 'Edit', 'woocommerce-multilingual' ),
176 'labelDefaultCurrency' => __( 'Currency displayed first', 'woocommerce-multilingual' ),
177 'tooltipDefaultCurrency' => __( 'Choose which currency to display when a client switches languages', 'woocommerce-multilingual' ),
178 'labelKeep' => __( 'Keep', 'woocommerce-multilingual' ),
179 'labelDelete' => __( 'Delete', 'woocommerce-multilingual' ),
180 'labelCurrenciesToDisplay' => __( 'Currencies to display for each language', 'woocommerce-multilingual' ),
181 /* translators: %1$s is for language name and %2$s for currency name */
182 'placeholderEnableFor' => __( 'Enable %1$s for %2$s', 'woocommerce-multilingual' ),
183 /* translators: %1$s is for language name and %2$s for currency name */
184 'placeholderDisableFor' => __( 'Disable %1$s for %2$s', 'woocommerce-multilingual' ),
185 'labelSettings' => __( 'Settings', 'woocommerce-multilingual' ),
186 'labelAddNewCurrency' => __( 'Add new currency', 'woocommerce-multilingual' ),
187 /* translators: %s for currency label */
188 'placeholderCurrencySettingsFor' => __( 'Currency settings for %s', 'woocommerce-multilingual' ),
189 'labelSelectCurrency' => __( 'Select currency', 'woocommerce-multilingual' ),
190 'labelExchangeRate' => __( 'Exchange Rate', 'woocommerce-multilingual' ),
191 'labelOnlyNumeric' => __( 'Only numeric', 'woocommerce-multilingual' ),
192 /* translators: %s for currency exchange rate value */
193 'placeholderPreviousRate' => __( '(previous value: %s)', 'woocommerce-multilingual' ),
194 'labelCurrencyPreview' => __( 'Currency Preview', 'woocommerce-multilingual' ),
195 'labelPosition' => __( 'Currency Position', 'woocommerce-multilingual' ),
196 'optionLeft' => __( 'Left', 'woocommerce-multilingual' ),
197 'optionRight' => __( 'Right', 'woocommerce-multilingual' ),
198 'optionLeftSpace' => __( 'Left with space', 'woocommerce-multilingual' ),
199 'optionRightSpace' => __( 'Right with space', 'woocommerce-multilingual' ),
200 'labelThousandSep' => __( 'Thousand Separator', 'woocommerce-multilingual' ),
201 'labelSpaceSep' => __( '(Space)', 'woocommerce-multilingual' ),
202 'labelDecimalSep' => __( 'Decimal Separator', 'woocommerce-multilingual' ),
203 'labelNumDecimals' => __( 'Number of Decimals', 'woocommerce-multilingual' ),
204 'labelRounding' => __( 'Rounding to the nearest integer', 'woocommerce-multilingual' ),
205 'optionDisabled' => __( 'Disabled', 'woocommerce-multilingual' ),
206 'optionUp' => __( 'Up', 'woocommerce-multilingual' ),
207 'optionDown' => __( 'Down', 'woocommerce-multilingual' ),
208 'optionNearest' => __( 'Nearest', 'woocommerce-multilingual' ),
209 'labelIncrement' => __( 'Increment for nearest integer', 'woocommerce-multilingual' ),
210 /* translators: %s is an HTML break line */
211 'tooltipIncrement' => sprintf( __( 'The resulting price will be an increment of this value after initial rounding.%se.g.:', 'woocommerce-multilingual' ), '<br>' ) . '<br />' .
212 __( '1454.07 &raquo; 1454 when set to 1', 'woocommerce-multilingual' ) . '<br />' .
213 __( '1454.07 &raquo; 1450 when set to 10', 'woocommerce-multilingual' ) . '<br />' .
214 __( '1454.07 &raquo; 1500 when set to 100', 'woocommerce-multilingual' ) . '<br />',
215 /* translators: %s is an HTML break line */
216 'tooltipRounding' => sprintf( __( 'Round the converted price to the closest integer. %se.g. 15.78 becomes 16.00', 'woocommerce-multilingual' ), '<br />' ),
217 'tooltipAutosubtract' => __( 'The value to be subtracted from the amount obtained previously.', 'woocommerce-multilingual' ) . '<br /><br />' .
218 __( 'For 1454.07, when the increment for the nearest integer is 100 and the auto-subtract amount is 1, the resulting amount is 1499.', 'woocommerce-multilingual' ),
219 'labelAutosubtract' => __( 'Autosubtract amount', 'woocommerce-multilingual' ),
220 'labelPaymentGateways' => __( 'Payment Gateways', 'woocommerce-multilingual' ),
221 /* translators: %s is a currency code */
222 'placeholderCustomSettings' => __( 'Custom settings for %s', 'woocommerce-multilingual' ),
223 'linkUrlLearn' => $trackingLink->getWcmlMultiCurrencyDoc( '#payment-gateways-settings' ),
224 'linkLabelLearn' => __( 'Learn more', 'woocommerce-multilingual' ),
225 'errorInvalidNumber' => __( 'Please enter a valid number', 'woocommerce-multilingual' ),
226 'labelCancel' => __( 'Cancel', 'woocommerce-multilingual' ),
227 'labelSave' => __( 'Save', 'woocommerce-multilingual' ),
228 'labelAvailability' => __( 'Currency available in', 'woocommerce-multilingual' ),
229 'labelAllCountries' => __( 'All countries', 'woocommerce-multilingual' ),
230 'labelAllCountriesExcept' => __( 'All countries except: ', 'woocommerce-multilingual' ),
231 'labelAllCountriesExceptDots' => __( 'All countries except...', 'woocommerce-multilingual' ),
232 'labelSpecificCountries' => __( 'Specific countries', 'woocommerce-multilingual' ),
233 'labelModeSelect' => __( 'Show currencies based on', 'woocommerce-multilingual' ),
234 'labelSiteLanguageTooltip' => esc_html__( "You need the WPML plugin to make your store multilingual and display currencies based on site language. Don't have it yet?", 'woocommerce-multilingual' ) . '<br />' .
235 '<a href="' . \WCML_Tracking_Link::getWpmlPurchase( true ) . '" class="wpml-external-link" target="_blank">' . esc_html__( 'Purchase WPML now', 'woocommerce-multilingual' ) . '</a>',
236 'labelSiteLanguage' => __( 'Site Language', 'woocommerce-multilingual' ),
237 'labelClientLocation' => __( 'Client Location', 'woocommerce-multilingual' ),
238 'labelLocationBased' => __( 'Location based', 'woocommerce-multilingual' ),
239 'maxMindDescription' => __( 'WooCommerce integrates with MaxMind Geolocation to reliably determine the location of your customers.', 'woocommerce-multilingual' ),
240 'maxMindSuccess' => __( 'Great! Now you can use Geolocation to determine default currency for chosen languages. You can edit that key in ', 'woocommerce-multilingual' ),
241 'maxMindSettingLink' => \WCML\Utilities\AdminUrl::getWooSettings( 'integration' ),
242 'maxMindSettingLinkText' => __( 'WooCommerce settings page.', 'woocommerce-multilingual' ),
243 'maxMindLabel' => __( 'MaxMind Licence Key', 'woocommerce-multilingual' ),
244 'apply' => __( 'Apply', 'woocommerce-multilingual' ),
245 'maxMindNote' => __( 'Please note: without a free MaxMind key, your geolocation calls will be limited and your site performance may be impacted.', 'woocommerce-multilingual' ),
246 'maxMindDocLink' => 'https://docs.woocommerce.com/document/maxmind-geolocation-integration/',
247 'maxMindDocLinkText' => __( 'Learn how to generate a free license key', 'woocommerce-multilingual' ),
248 ];
249 }
250
251 private function getAllCountries() {
252
253 $buildCountry = function( $label, $code ) {
254 return (object) [
255 'code' => $code,
256 'label' => html_entity_decode( $label ),
257 ];
258 };
259
260 return wpml_collect( WC()->countries->get_countries() )->map( $buildCountry )->values()->toArray();
261 }
262
263 private function checkMaxMindKeyExist() {
264 $integrations = WC()->integrations->get_integrations();
265
266 return isset( $integrations['maxmind_geolocation'] ) ? (bool) $integrations['maxmind_geolocation']->get_option( 'license_key' ) : false;
267 }
268
269 public static function formatLastRateUpdate( $lastRateUpdate ) {
270 return $lastRateUpdate
271 ? sprintf(
272 /* translators: %s is a date */
273 __( 'Set on %s', 'woocommerce-multilingual' ),
274 date( 'F j, Y g:i a', strtotime( $lastRateUpdate ) )
275 )
276 : null;
277 }
278 }
279