Version Description
Fixes * Fixed the upgrade routine for the attribute look-up table * Fixed a fatal error that occurred on sites running a WPML version older than 4.5.2 * Removed an obsolete filter on the woocommerce_create_page_id hook * Fixed an issue with duplication of product terms when using WPMLs Classic Translation Editor on WordPress 6.0
Compatibility * WooCommerce Product Bundles: Added translation support for bundle sales
Download this release
Release Info
Developer | strategio |
Plugin | WooCommerce Multilingual – run WooCommerce with WPML |
Version | 5.0.1 |
Comparing to | |
See all releases |
Code changes from version 4.12.6 to 5.0.1
- addons/load-standalone-dependencies.php +48 -0
- addons/vendor/autoload.php +7 -0
- addons/vendor/composer/ClassLoader.php +445 -0
- addons/vendor/composer/LICENSE +21 -0
- addons/vendor/composer/autoload_classmap.php +506 -0
- addons/vendor/composer/autoload_files.php +14 -0
- addons/vendor/composer/autoload_namespaces.php +9 -0
- addons/vendor/composer/autoload_psr4.php +11 -0
- addons/vendor/composer/autoload_real.php +73 -0
- addons/vendor/composer/autoload_static.php +545 -0
- addons/vendor/composer/installed.json +799 -0
- addons/vendor/otgs/auryn/CONTRIBUTING.md +28 -0
- addons/vendor/otgs/auryn/LICENSE +21 -0
- addons/vendor/otgs/auryn/README.md +847 -0
- addons/vendor/otgs/auryn/lib/CachingReflector.php +108 -0
- addons/vendor/otgs/auryn/lib/ConfigException.php +7 -0
- addons/vendor/otgs/auryn/lib/Executable.php +82 -0
- addons/vendor/otgs/auryn/lib/InjectionException.php +67 -0
- addons/vendor/otgs/auryn/lib/Injector.php +757 -0
- addons/vendor/otgs/auryn/lib/InjectorException.php +7 -0
- addons/vendor/otgs/auryn/lib/ReflectionCache.php +9 -0
- addons/vendor/otgs/auryn/lib/ReflectionCacheApc.php +41 -0
- addons/vendor/otgs/auryn/lib/ReflectionCacheArray.php +22 -0
- addons/vendor/otgs/auryn/lib/Reflector.php +61 -0
- addons/vendor/otgs/auryn/lib/StandardReflector.php +53 -0
- addons/vendor/otgs/auryn/phpunit.xml +43 -0
- addons/vendor/otgs/icons +1 -0
- addons/vendor/otgs/ui +1 -0
- addons/vendor/wpml/collect/collect-logo.png +0 -0
- addons/vendor/wpml/collect/phpunit.xml +20 -0
- addons/vendor/wpml/collect/readme.md +19 -0
- addons/vendor/wpml/collect/src/Illuminate/Contracts/Support/Arrayable.php +13 -0
- addons/vendor/wpml/collect/src/Illuminate/Contracts/Support/Jsonable.php +14 -0
- addons/vendor/wpml/collect/src/Illuminate/Support/Arr.php +533 -0
- addons/vendor/wpml/collect/src/Illuminate/Support/Collection.php +1500 -0
- addons/vendor/wpml/collect/src/Illuminate/Support/Traits/Macroable.php +83 -0
- addons/vendor/wpml/collect/src/Illuminate/Support/helpers.php +84 -0
- addons/vendor/wpml/collect/tests/Support/SupportCollectionTest.php +1763 -0
- addons/vendor/wpml/collect/tests/bootstrap.php +5 -0
- addons/vendor/wpml/core-api +1 -0
- addons/vendor/wpml/fp +1 -0
- addons/vendor/wpml/wp +1 -0
- addons/vendor/wpml/wpml-dependencies +1 -0
- classes/AdminDashboard/Hooks.php +2 -2
- classes/AdminNotices/CachePlugins.php +6 -2
- classes/AdminNotices/MultiCurrencyMissing.php +2 -2
- classes/AdminNotices/Review.php +6 -5
- classes/Attributes/LookupFilters.php +36 -0
- classes/Attributes/LookupFiltersFactory.php +31 -0
- classes/Attributes/LookupTable.php +108 -0
- classes/Attributes/LookupTableFactory.php +30 -0
- classes/Block/Convert/Hooks.php +2 -2
- classes/Container/Config.php +25 -1
- classes/Email/Settings/Hooks.php +2 -2
- classes/HomeScreen/Factory.php +18 -0
- classes/HomeScreen/Hooks.php +26 -0
- classes/Multicurrency/Analytics/Factory.php +3 -1
- classes/Multicurrency/Analytics/Hooks.php +9 -5
- classes/Multicurrency/Resolver/ComposedResolver.php +32 -0
- classes/Multicurrency/Resolver/Factory.php +27 -0
- classes/Multicurrency/Resolver/HelperByLanguage.php +49 -0
- classes/Multicurrency/Resolver/HelperByLocation.php +33 -0
- classes/Multicurrency/Resolver/Resolver.php +11 -0
- classes/Multicurrency/Resolver/ResolverForContext.php +123 -0
- classes/Multicurrency/Resolver/ResolverForDefault.php +19 -0
- classes/Multicurrency/Resolver/ResolverForModeLanguage.php +77 -0
- classes/Multicurrency/Resolver/ResolverForModeLocation.php +30 -0
- classes/Multicurrency/Settings.php +203 -0
- classes/Multicurrency/Shipping/AdminHooks.php +3 -2
- classes/Multicurrency/Shipping/FreeShipping.php +4 -0
- classes/Multicurrency/Shipping/FrontEndHooks.php +2 -1
- classes/Multicurrency/Shipping/ShippingClasses.php +5 -2
- classes/Multicurrency/Shipping/ShippingHooksFactory.php +3 -1
- classes/Multicurrency/Shipping/VariableCost.php +2 -0
- classes/Multicurrency/Transient/Hooks.php +50 -0
- classes/Multicurrency/UI/Factory.php +6 -12
- classes/Multicurrency/UI/Hooks.php +29 -23
- classes/Options/WPML.php +8 -0
- classes/PaymentGateways/Hooks.php +3 -2
- classes/Reports/Orders/Factory.php +0 -29
- classes/Reports/Orders/Hooks.php +1 -3
- classes/Reports/Products/Query.php +8 -4
- classes/Rest/Exceptions/InvalidCurrency.php +1 -0
- classes/Rest/Exceptions/InvalidLanguage.php +1 -0
- classes/Rest/Exceptions/InvalidProduct.php +1 -0
- classes/Rest/Exceptions/InvalidTerm.php +1 -0
- classes/Rest/Functions.php +0 -7
- classes/Rest/Generic.php +21 -1
- classes/Rest/ProductSaveActions.php +1 -1
- classes/Rest/Wrapper/ProductTerms.php +1 -1
- classes/Rest/Wrapper/Products/Products.php +1 -1
- classes/Rest/Wrapper/Reports/ProductsCount.php +1 -1
- classes/Rest/Wrapper/Reports/TopSeller.php +1 -1
- classes/Reviews/Translations/Factory.php +1 -1
- classes/RewriteRules/Hooks.php +1 -1
- classes/StandAlone/ActionFilterLoader.php +47 -0
- classes/StandAlone/Container/Config.php +53 -0
- classes/StandAlone/DependencyAssets.php +45 -0
- classes/StandAlone/IStandAloneAction.php +5 -0
- classes/StandAlone/NullSitePress.php +143 -0
- classes/StandAlone/UI/AdminMenu.php +103 -0
- classes/Utilities/AdminPages.php +103 -0
- classes/Utilities/DB.php +38 -0
- classes/Utilities/WcAdminPages.php +53 -0
- classes/Utilities/WpAdminPages.php +15 -0
- classes/class-wcml-tracking-link.php +26 -5
- classes/class-woocommerce-wpml.php +77 -26
- classes/multi-currency/class-wcml-exchange-rates.php +102 -21
- classes/multi-currency/exchange-rate-services/ApiLayerService.php +93 -0
- classes/multi-currency/exchange-rate-services/CurrencyLayer.php +20 -45
- classes/multi-currency/exchange-rate-services/ExchangeRatesApi.php +6 -7
- classes/multi-currency/exchange-rate-services/Fixerio.php +6 -7
- classes/multi-currency/exchange-rate-services/Service.php +111 -21
- classes/multi-currency/geolocation/Geolocation.php +18 -76
- classes/multi-currency/geolocation/GeolocationBackendHooks.php +3 -1
- classes/multi-currency/geolocation/GeolocationFrontendHooks.php +3 -1
- classes/multi-currency/payment-gateways/class-wcml-currencies-payment-gateways.php +8 -5
- classes/multi-currency/payment-gateways/class-wcml-payment-gateway-paypal-v2.php +95 -0
- classes/multi-currency/payment-gateways/class-wcml-payment-gateway-paypal.php +5 -6
- classes/pointers/class-wcml-pointers.php +16 -9
- classes/privacy/class-wcml-privacy-content.php +3 -3
- classes/shortcodes/class-wcml-wc-shortcode-product-category.php +1 -1
- classes/taxonomy-translation/class-wcml-taxonomy-translation-link-filters.php +2 -0
- classes/urls/class-wcml-xdomain-data.php +1 -1
- classes/wcml-setup/class-wcml-setup.php +3 -3
- compatibility/AdventureTours/Factory.php +18 -0
- compatibility/{class-wcml-adventure-tours.php → AdventureTours/class-wcml-adventure-tours.php} +1 -1
- compatibility/Aurum/Factory.php +25 -0
- compatibility/{class-wcml-aurum.php → Aurum/MulticurrencyHooks.php} +8 -4
- compatibility/ComponentFactory.php +58 -0
- compatibility/Flatsome/Factory.php +16 -0
- compatibility/{class-wcml-flatsome.php → Flatsome/class-wcml-flatsome.php} +2 -2
- compatibility/GravityForms/Factory.php +34 -0
- compatibility/GravityForms/MulticurrencyHooks.php +37 -0
- compatibility/{class-wcml-gravityforms.php → GravityForms/class-wcml-gravityforms.php} +4 -22
- compatibility/KlarnaPayments/Factory.php +26 -0
- compatibility/{class-wcml-klarna-gateway.php → KlarnaPayments/MulticurrencyHooks.php} +3 -4
- compatibility/MaxStorePro/Factory.php +16 -0
- compatibility/{class-wcml-maxstore.php → MaxStorePro/class-wcml-maxstore.php} +1 -1
- compatibility/PerProductShipping/Factory.php +16 -0
- compatibility/{class-wcml-per-product-shipping.php → PerProductShipping/class-wcml-per-product-shipping.php} +2 -6
- compatibility/Relevanssi/Factory.php +16 -0
- compatibility/{class-wcml-relevanssi.php → Relevanssi/class-wcml-relevanssi.php} +1 -1
- compatibility/Sensei/Factory.php +18 -0
- compatibility/{class-wcml-sensei.php → Sensei/class-wcml-sensei.php} +1 -1
- compatibility/StripePayments/Factory.php +27 -0
- compatibility/StripePayments/MulticurrencyHooks.php +33 -0
- compatibility/TableRateShipping/Factory.php +36 -0
- compatibility/TableRateShipping/MulticurrencyHooks.php +64 -0
- compatibility/{class-wcml-table-rate-shipping.php → TableRateShipping/class-wcml-table-rate-shipping.php} +3 -46
- compatibility/TheEventsCalendar/Factory.php +34 -0
- compatibility/TheEventsCalendar/MulticurrencyHooks.php +22 -0
- compatibility/{class-wcml-the-events-calendar.php → TheEventsCalendar/class-wcml-the-events-calendar.php} +4 -8
- compatibility/TmExtraProductOptions/Factory.php +16 -0
- compatibility/{class-wcml-extra-product-options.php → TmExtraProductOptions/class-wcml-extra-product-options.php} +3 -3
- compatibility/WcAjaxLayeredNav/Factory.php +16 -0
- compatibility/{class-wcml-ajax-layered-nav-widget.php → WcAjaxLayeredNav/class-wcml-ajax-layered-nav-widget.php} +3 -2
- compatibility/WcBookings/Factory.php +42 -0
- compatibility/WcBookings/MulticurrencyHooks.php +936 -0
- compatibility/WcBookings/SharedHooks.php +86 -0
- compatibility/{class-wcml-accommodation-bookings.php → WcBookings/class-wcml-accommodation-bookings.php} +11 -28
- compatibility/{class-wcml-bookings.php → WcBookings/class-wcml-bookings.php} +109 -1045
- compatibility/WcBulkStockManagement/Factory.php +19 -0
- compatibility/{class-wcml-bulk-stock-management.php → WcBulkStockManagement/class-wcml-bulk-stock-management.php} +3 -2
- compatibility/WcCheckoutAddons/Factory.php +31 -0
- compatibility/WcCheckoutAddons/MulticurrencyHooks.php +30 -0
- compatibility/WcCheckoutAddons/OptionIterator.php +31 -0
- compatibility/WcCheckoutAddons/class-wcml-checkout-addons.php +47 -0
- compatibility/WcCheckoutFieldEditor/Factory.php +16 -0
- compatibility/{class-wcml-checkout-field-editor.php → WcCheckoutFieldEditor/class-wcml-checkout-field-editor.php} +1 -1
- compatibility/WcCompositeProducts/Factory.php +33 -0
- compatibility/WcCompositeProducts/MulticurrencyHooks.php +117 -0
- compatibility/{class-wcml-composite-products.php → WcCompositeProducts/class-wcml-composite-products.php} +139 -197
- compatibility/WcDynamicPricing/Factory.php +31 -0
- compatibility/WcDynamicPricing/MulticurrencyHooks.php +78 -0
- compatibility/{class-wcml-dynamic-pricing.php → WcDynamicPricing/class-wcml-dynamic-pricing.php} +2 -76
- compatibility/WcExporter/Factory.php +21 -0
- compatibility/{class-wcml-wcexporter.php → WcExporter/class-wcml-wcexporter.php} +1 -1
- compatibility/WcMemberships/Factory.php +15 -0
- compatibility/{class-wcml-wc-memberships.php → WcMemberships/class-wcml-wc-memberships.php} +1 -1
- compatibility/WcMixAndMatch/Factory.php +30 -0
- compatibility/WcMixAndMatch/MulticurrencyHooks.php +74 -0
- compatibility/WcMixAndMatch/class-wcml-mix-and-match-products.php +235 -0
- compatibility/WcNameYourPrice/Factory.php +26 -0
- compatibility/WcNameYourPrice/MulticurrencyHooks.php +110 -0
- compatibility/WcOrderStatusManager/Factory.php +17 -0
- compatibility/{class-wcml-order-status-manager.php → WcOrderStatusManager/class-wcml-order-status-manager.php} +1 -1
- compatibility/WcPip/Factory.php +31 -0
- compatibility/WcPip/Helper.php +28 -0
- compatibility/WcPip/MulticurrencyHooks.php +69 -0
- compatibility/WcPip/class-wcml-pip.php +29 -0
- compatibility/WcProductAddons/Factory.php +34 -0
- compatibility/WcProductAddons/MulticurrencyHooks.php +341 -0
- compatibility/WcProductAddons/SharedHooks.php +75 -0
- compatibility/WcProductAddons/class-wcml-product-addons.php +397 -0
- compatibility/WcProductBundles/Factory.php +31 -0
- compatibility/WcProductBundles/MulticurrencyHooks.php +65 -0
- compatibility/{class-wcml-product-bundles.php → WcProductBundles/class-wcml-product-bundles.php} +224 -93
- compatibility/{includes → WcProductBundles}/class-wcml-wc-product-bundles-items.php +0 -0
- compatibility/WcProductTypeColumn/Factory.php +16 -0
- compatibility/{class-wcml-wc-product-type-column.php → WcProductTypeColumn/class-wcml-wc-product-type-column.php} +1 -1
- compatibility/WcShowSingleVariations/Factory.php +19 -0
- compatibility/{class-wcml-jck-wssv.php → WcShowSingleVariations/class-wcml-jck-wssv.php} +2 -3
- compatibility/WcSubscriptions/Factory.php +34 -0
- compatibility/WcSubscriptions/MulticurrencyHooks.php +265 -0
- compatibility/WcSubscriptions/SharedHooks.php +41 -0
- compatibility/WcSubscriptions/class-wcml-wc-subscriptions.php +198 -0
- compatibility/WcSwatches/Factory.php +17 -0
- compatibility/{class-wcml-variation-swatches-and-photos.php → WcSwatches/class-wcml-variation-swatches-and-photos.php} +1 -1
- compatibility/WcTabManager/Factory.php +18 -0
- compatibility/{class-wcml-tab-manager.php → WcTabManager/class-wcml-tab-manager.php} +2 -1
- compatibility/WooVariationsTable/Factory.php +16 -0
- compatibility/{class-wcml-woo-var-table.php → WooVariationsTable/class-wcml-woo-var-table.php} +1 -1
- compatibility/WoobeBulkEditor/Factory.php +17 -0
- compatibility/{class-wcml-woobe.php → WoobeBulkEditor/class-wcml-woobe.php} +1 -1
- compatibility/WoofWcProductFilter/Factory.php +26 -0
- compatibility/{class-wcml-woof-woocommerce-product-filter.php → WoofWcProductFilter/MulticurrencyHooks.php} +9 -12
- compatibility/WpBakery/Factory.php +16 -0
- compatibility/{class-wcml-wpb-vc.php → WpBakery/class-wcml-wpb-vc.php} +1 -1
- compatibility/WpFastestCache/Factory.php +25 -0
- compatibility/{class-wcml-wpfastest-cache.php → WpFastestCache/MulticurrencyHooks.php} +3 -1
- compatibility/WpSeo/Factory.php +16 -0
- compatibility/{class-wcml-wpseo.php → WpSeo/class-wcml-wpseo.php} +2 -2
- compatibility/YikesCustomProductTabs/Factory.php +17 -0
- compatibility/{class-wcml-yikes-custom-product-tabs.php → YikesCustomProductTabs/class-wcml-yikes-custom-product-tabs.php} +2 -1
- compatibility/YithWcQuickView/Factory.php +25 -0
- compatibility/{class-wcml-yith-wcqv.php → YithWcQuickView/MulticurrencyHooks.php} +8 -5
- compatibility/class-wcml-checkout-addons.php +0 -61
- compatibility/class-wcml-compatibility-helper.php +1 -1
- compatibility/class-wcml-litespeed-cache.php +0 -26
- compatibility/class-wcml-mix-and-match-products.php +0 -53
- compatibility/class-wcml-pip.php +0 -104
- compatibility/class-wcml-product-addons.php +0 -664
- compatibility/class-wcml-wc-name-your-price.php +0 -29
- compatibility/class-wcml-wc-subscriptions.php +0 -460
- dist/css/homeScreen/styles.css +1 -0
- dist/css/multicurrencyOptions/styles.css +3 -1
- dist/js/homeScreen/app.js +1 -0
- dist/js/multicurrencyOptions/app.js +2 -2
addons/load-standalone-dependencies.php
ADDED
@@ -0,0 +1,48 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* This bootstrap file is loaded only when WCML is running in the Standalone mode.
|
4 |
+
* It's executed on `plugins_loaded` priority 10000.
|
5 |
+
*
|
6 |
+
* @see load_wcml_without_wpml
|
7 |
+
*/
|
8 |
+
|
9 |
+
/**
|
10 |
+
* This constant `WCML_WPML_DEPENDENCY_URL` is used in several places inside
|
11 |
+
* the dependency files (it replaces hard-coded URL base).
|
12 |
+
*/
|
13 |
+
define( 'WCML_WPML_DEPENDENCY_URL', WCML_PLUGIN_URL . '/addons/vendor/wpml/wpml-dependencies/lib' );
|
14 |
+
|
15 |
+
require_once WCML_PLUGIN_PATH . '/addons/vendor/autoload.php';
|
16 |
+
require_once WCML_PLUGIN_PATH . '/addons/vendor/wpml/wpml-dependencies/lib/missing-functions.php';
|
17 |
+
|
18 |
+
$setPartialDicConfigFromCore = function() {
|
19 |
+
\WPML\Container\share( \WCML\StandAlone\Container\Config::getSharedInstances() );
|
20 |
+
\WPML\Container\share( \WCML\StandAlone\Container\Config::getSharedClasses() );
|
21 |
+
\WPML\Container\alias( \WCML\StandAlone\Container\Config::getAliases() );
|
22 |
+
\WPML\Container\delegate( \WCML\StandAlone\Container\Config::getDelegated() );
|
23 |
+
};
|
24 |
+
|
25 |
+
$setPartialDicConfigFromCore();
|
26 |
+
|
27 |
+
if ( is_admin() ) {
|
28 |
+
require_once WCML_PLUGIN_PATH . '/addons/vendor/wpml/wpml-dependencies/lib/inc/icl-admin-notifier.php';
|
29 |
+
|
30 |
+
$loadOtgsIconsStyles = function() {
|
31 |
+
$vendor_root_url = WCML_PLUGIN_URL . '/addons/vendor';
|
32 |
+
require_once WCML_PLUGIN_PATH . '/addons/vendor/otgs/icons/loader.php';
|
33 |
+
|
34 |
+
add_action( 'admin_init', function() {
|
35 |
+
wp_enqueue_style( OTGS_ASSETS_ICONS_STYLES );
|
36 |
+
}, PHP_INT_MAX );
|
37 |
+
};
|
38 |
+
|
39 |
+
$loadOtgsIconsStyles();
|
40 |
+
|
41 |
+
( new \WCML\StandAlone\DependencyAssets( WCML_WPML_DEPENDENCY_URL ) )->add_hooks();
|
42 |
+
|
43 |
+
wcml_wpml_get_admin_notices(); // Initialize the notices hooks
|
44 |
+
|
45 |
+
( new WPML_Action_Filter_Loader() )->load( [
|
46 |
+
\WPML\Notices\DismissNotices::class,
|
47 |
+
] );
|
48 |
+
}
|
addons/vendor/autoload.php
ADDED
@@ -0,0 +1,7 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
// autoload.php @generated by Composer
|
4 |
+
|
5 |
+
require_once __DIR__ . '/composer/autoload_real.php';
|
6 |
+
|
7 |
+
return ComposerAutoloaderInit4821ed1a7ed1caf1298338b695908544::getLoader();
|
addons/vendor/composer/ClassLoader.php
ADDED
@@ -0,0 +1,445 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/*
|
4 |
+
* This file is part of Composer.
|
5 |
+
*
|
6 |
+
* (c) Nils Adermann <naderman@naderman.de>
|
7 |
+
* Jordi Boggiano <j.boggiano@seld.be>
|
8 |
+
*
|
9 |
+
* For the full copyright and license information, please view the LICENSE
|
10 |
+
* file that was distributed with this source code.
|
11 |
+
*/
|
12 |
+
|
13 |
+
namespace Composer\Autoload;
|
14 |
+
|
15 |
+
/**
|
16 |
+
* ClassLoader implements a PSR-0, PSR-4 and classmap class loader.
|
17 |
+
*
|
18 |
+
* $loader = new \Composer\Autoload\ClassLoader();
|
19 |
+
*
|
20 |
+
* // register classes with namespaces
|
21 |
+
* $loader->add('Symfony\Component', __DIR__.'/component');
|
22 |
+
* $loader->add('Symfony', __DIR__.'/framework');
|
23 |
+
*
|
24 |
+
* // activate the autoloader
|
25 |
+
* $loader->register();
|
26 |
+
*
|
27 |
+
* // to enable searching the include path (eg. for PEAR packages)
|
28 |
+
* $loader->setUseIncludePath(true);
|
29 |
+
*
|
30 |
+
* In this example, if you try to use a class in the Symfony\Component
|
31 |
+
* namespace or one of its children (Symfony\Component\Console for instance),
|
32 |
+
* the autoloader will first look for the class under the component/
|
33 |
+
* directory, and it will then fallback to the framework/ directory if not
|
34 |
+
* found before giving up.
|
35 |
+
*
|
36 |
+
* This class is loosely based on the Symfony UniversalClassLoader.
|
37 |
+
*
|
38 |
+
* @author Fabien Potencier <fabien@symfony.com>
|
39 |
+
* @author Jordi Boggiano <j.boggiano@seld.be>
|
40 |
+
* @see http://www.php-fig.org/psr/psr-0/
|
41 |
+
* @see http://www.php-fig.org/psr/psr-4/
|
42 |
+
*/
|
43 |
+
class ClassLoader
|
44 |
+
{
|
45 |
+
// PSR-4
|
46 |
+
private $prefixLengthsPsr4 = array();
|
47 |
+
private $prefixDirsPsr4 = array();
|
48 |
+
private $fallbackDirsPsr4 = array();
|
49 |
+
|
50 |
+
// PSR-0
|
51 |
+
private $prefixesPsr0 = array();
|
52 |
+
private $fallbackDirsPsr0 = array();
|
53 |
+
|
54 |
+
private $useIncludePath = false;
|
55 |
+
private $classMap = array();
|
56 |
+
private $classMapAuthoritative = false;
|
57 |
+
private $missingClasses = array();
|
58 |
+
private $apcuPrefix;
|
59 |
+
|
60 |
+
public function getPrefixes()
|
61 |
+
{
|
62 |
+
if (!empty($this->prefixesPsr0)) {
|
63 |
+
return call_user_func_array('array_merge', $this->prefixesPsr0);
|
64 |
+
}
|
65 |
+
|
66 |
+
return array();
|
67 |
+
}
|
68 |
+
|
69 |
+
public function getPrefixesPsr4()
|
70 |
+
{
|
71 |
+
return $this->prefixDirsPsr4;
|
72 |
+
}
|
73 |
+
|
74 |
+
public function getFallbackDirs()
|
75 |
+
{
|
76 |
+
return $this->fallbackDirsPsr0;
|
77 |
+
}
|
78 |
+
|
79 |
+
public function getFallbackDirsPsr4()
|
80 |
+
{
|
81 |
+
return $this->fallbackDirsPsr4;
|
82 |
+
}
|
83 |
+
|
84 |
+
public function getClassMap()
|
85 |
+
{
|
86 |
+
return $this->classMap;
|
87 |
+
}
|
88 |
+
|
89 |
+
/**
|
90 |
+
* @param array $classMap Class to filename map
|
91 |
+
*/
|
92 |
+
public function addClassMap(array $classMap)
|
93 |
+
{
|
94 |
+
if ($this->classMap) {
|
95 |
+
$this->classMap = array_merge($this->classMap, $classMap);
|
96 |
+
} else {
|
97 |
+
$this->classMap = $classMap;
|
98 |
+
}
|
99 |
+
}
|
100 |
+
|
101 |
+
/**
|
102 |
+
* Registers a set of PSR-0 directories for a given prefix, either
|
103 |
+
* appending or prepending to the ones previously set for this prefix.
|
104 |
+
*
|
105 |
+
* @param string $prefix The prefix
|
106 |
+
* @param array|string $paths The PSR-0 root directories
|
107 |
+
* @param bool $prepend Whether to prepend the directories
|
108 |
+
*/
|
109 |
+
public function add($prefix, $paths, $prepend = false)
|
110 |
+
{
|
111 |
+
if (!$prefix) {
|
112 |
+
if ($prepend) {
|
113 |
+
$this->fallbackDirsPsr0 = array_merge(
|
114 |
+
(array) $paths,
|
115 |
+
$this->fallbackDirsPsr0
|
116 |
+
);
|
117 |
+
} else {
|
118 |
+
$this->fallbackDirsPsr0 = array_merge(
|
119 |
+
$this->fallbackDirsPsr0,
|
120 |
+
(array) $paths
|
121 |
+
);
|
122 |
+
}
|
123 |
+
|
124 |
+
return;
|
125 |
+
}
|
126 |
+
|
127 |
+
$first = $prefix[0];
|
128 |
+
if (!isset($this->prefixesPsr0[$first][$prefix])) {
|
129 |
+
$this->prefixesPsr0[$first][$prefix] = (array) $paths;
|
130 |
+
|
131 |
+
return;
|
132 |
+
}
|
133 |
+
if ($prepend) {
|
134 |
+
$this->prefixesPsr0[$first][$prefix] = array_merge(
|
135 |
+
(array) $paths,
|
136 |
+
$this->prefixesPsr0[$first][$prefix]
|
137 |
+
);
|
138 |
+
} else {
|
139 |
+
$this->prefixesPsr0[$first][$prefix] = array_merge(
|
140 |
+
$this->prefixesPsr0[$first][$prefix],
|
141 |
+
(array) $paths
|
142 |
+
);
|
143 |
+
}
|
144 |
+
}
|
145 |
+
|
146 |
+
/**
|
147 |
+
* Registers a set of PSR-4 directories for a given namespace, either
|
148 |
+
* appending or prepending to the ones previously set for this namespace.
|
149 |
+
*
|
150 |
+
* @param string $prefix The prefix/namespace, with trailing '\\'
|
151 |
+
* @param array|string $paths The PSR-4 base directories
|
152 |
+
* @param bool $prepend Whether to prepend the directories
|
153 |
+
*
|
154 |
+
* @throws \InvalidArgumentException
|
155 |
+
*/
|
156 |
+
public function addPsr4($prefix, $paths, $prepend = false)
|
157 |
+
{
|
158 |
+
if (!$prefix) {
|
159 |
+
// Register directories for the root namespace.
|
160 |
+
if ($prepend) {
|
161 |
+
$this->fallbackDirsPsr4 = array_merge(
|
162 |
+
(array) $paths,
|
163 |
+
$this->fallbackDirsPsr4
|
164 |
+
);
|
165 |
+
} else {
|
166 |
+
$this->fallbackDirsPsr4 = array_merge(
|
167 |
+
$this->fallbackDirsPsr4,
|
168 |
+
(array) $paths
|
169 |
+
);
|
170 |
+
}
|
171 |
+
} elseif (!isset($this->prefixDirsPsr4[$prefix])) {
|
172 |
+
// Register directories for a new namespace.
|
173 |
+
$length = strlen($prefix);
|
174 |
+
if ('\\' !== $prefix[$length - 1]) {
|
175 |
+
throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator.");
|
176 |
+
}
|
177 |
+
$this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length;
|
178 |
+
$this->prefixDirsPsr4[$prefix] = (array) $paths;
|
179 |
+
} elseif ($prepend) {
|
180 |
+
// Prepend directories for an already registered namespace.
|
181 |
+
$this->prefixDirsPsr4[$prefix] = array_merge(
|
182 |
+
(array) $paths,
|
183 |
+
$this->prefixDirsPsr4[$prefix]
|
184 |
+
);
|
185 |
+
} else {
|
186 |
+
// Append directories for an already registered namespace.
|
187 |
+
$this->prefixDirsPsr4[$prefix] = array_merge(
|
188 |
+
$this->prefixDirsPsr4[$prefix],
|
189 |
+
(array) $paths
|
190 |
+
);
|
191 |
+
}
|
192 |
+
}
|
193 |
+
|
194 |
+
/**
|
195 |
+
* Registers a set of PSR-0 directories for a given prefix,
|
196 |
+
* replacing any others previously set for this prefix.
|
197 |
+
*
|
198 |
+
* @param string $prefix The prefix
|
199 |
+
* @param array|string $paths The PSR-0 base directories
|
200 |
+
*/
|
201 |
+
public function set($prefix, $paths)
|
202 |
+
{
|
203 |
+
if (!$prefix) {
|
204 |
+
$this->fallbackDirsPsr0 = (array) $paths;
|
205 |
+
} else {
|
206 |
+
$this->prefixesPsr0[$prefix[0]][$prefix] = (array) $paths;
|
207 |
+
}
|
208 |
+
}
|
209 |
+
|
210 |
+
/**
|
211 |
+
* Registers a set of PSR-4 directories for a given namespace,
|
212 |
+
* replacing any others previously set for this namespace.
|
213 |
+
*
|
214 |
+
* @param string $prefix The prefix/namespace, with trailing '\\'
|
215 |
+
* @param array|string $paths The PSR-4 base directories
|
216 |
+
*
|
217 |
+
* @throws \InvalidArgumentException
|
218 |
+
*/
|
219 |
+
public function setPsr4($prefix, $paths)
|
220 |
+
{
|
221 |
+
if (!$prefix) {
|
222 |
+
$this->fallbackDirsPsr4 = (array) $paths;
|
223 |
+
} else {
|
224 |
+
$length = strlen($prefix);
|
225 |
+
if ('\\' !== $prefix[$length - 1]) {
|
226 |
+
throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator.");
|
227 |
+
}
|
228 |
+
$this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length;
|
229 |
+
$this->prefixDirsPsr4[$prefix] = (array) $paths;
|
230 |
+
}
|
231 |
+
}
|
232 |
+
|
233 |
+
/**
|
234 |
+
* Turns on searching the include path for class files.
|
235 |
+
*
|
236 |
+
* @param bool $useIncludePath
|
237 |
+
*/
|
238 |
+
public function setUseIncludePath($useIncludePath)
|
239 |
+
{
|
240 |
+
$this->useIncludePath = $useIncludePath;
|
241 |
+
}
|
242 |
+
|
243 |
+
/**
|
244 |
+
* Can be used to check if the autoloader uses the include path to check
|
245 |
+
* for classes.
|
246 |
+
*
|
247 |
+
* @return bool
|
248 |
+
*/
|
249 |
+
public function getUseIncludePath()
|
250 |
+
{
|
251 |
+
return $this->useIncludePath;
|
252 |
+
}
|
253 |
+
|
254 |
+
/**
|
255 |
+
* Turns off searching the prefix and fallback directories for classes
|
256 |
+
* that have not been registered with the class map.
|
257 |
+
*
|
258 |
+
* @param bool $classMapAuthoritative
|
259 |
+
*/
|
260 |
+
public function setClassMapAuthoritative($classMapAuthoritative)
|
261 |
+
{
|
262 |
+
$this->classMapAuthoritative = $classMapAuthoritative;
|
263 |
+
}
|
264 |
+
|
265 |
+
/**
|
266 |
+
* Should class lookup fail if not found in the current class map?
|
267 |
+
*
|
268 |
+
* @return bool
|
269 |
+
*/
|
270 |
+
public function isClassMapAuthoritative()
|
271 |
+
{
|
272 |
+
return $this->classMapAuthoritative;
|
273 |
+
}
|
274 |
+
|
275 |
+
/**
|
276 |
+
* APCu prefix to use to cache found/not-found classes, if the extension is enabled.
|
277 |
+
*
|
278 |
+
* @param string|null $apcuPrefix
|
279 |
+
*/
|
280 |
+
public function setApcuPrefix($apcuPrefix)
|
281 |
+
{
|
282 |
+
$this->apcuPrefix = function_exists('apcu_fetch') && filter_var(ini_get('apc.enabled'), FILTER_VALIDATE_BOOLEAN) ? $apcuPrefix : null;
|
283 |
+
}
|
284 |
+
|
285 |
+
/**
|
286 |
+
* The APCu prefix in use, or null if APCu caching is not enabled.
|
287 |
+
*
|
288 |
+
* @return string|null
|
289 |
+
*/
|
290 |
+
public function getApcuPrefix()
|
291 |
+
{
|
292 |
+
return $this->apcuPrefix;
|
293 |
+
}
|
294 |
+
|
295 |
+
/**
|
296 |
+
* Registers this instance as an autoloader.
|
297 |
+
*
|
298 |
+
* @param bool $prepend Whether to prepend the autoloader or not
|
299 |
+
*/
|
300 |
+
public function register($prepend = false)
|
301 |
+
{
|
302 |
+
spl_autoload_register(array($this, 'loadClass'), true, $prepend);
|
303 |
+
}
|
304 |
+
|
305 |
+
/**
|
306 |
+
* Unregisters this instance as an autoloader.
|
307 |
+
*/
|
308 |
+
public function unregister()
|
309 |
+
{
|
310 |
+
spl_autoload_unregister(array($this, 'loadClass'));
|
311 |
+
}
|
312 |
+
|
313 |
+
/**
|
314 |
+
* Loads the given class or interface.
|
315 |
+
*
|
316 |
+
* @param string $class The name of the class
|
317 |
+
* @return bool|null True if loaded, null otherwise
|
318 |
+
*/
|
319 |
+
public function loadClass($class)
|
320 |
+
{
|
321 |
+
if ($file = $this->findFile($class)) {
|
322 |
+
includeFile($file);
|
323 |
+
|
324 |
+
return true;
|
325 |
+
}
|
326 |
+
}
|
327 |
+
|
328 |
+
/**
|
329 |
+
* Finds the path to the file where the class is defined.
|
330 |
+
*
|
331 |
+
* @param string $class The name of the class
|
332 |
+
*
|
333 |
+
* @return string|false The path if found, false otherwise
|
334 |
+
*/
|
335 |
+
public function findFile($class)
|
336 |
+
{
|
337 |
+
// class map lookup
|
338 |
+
if (isset($this->classMap[$class])) {
|
339 |
+
return $this->classMap[$class];
|
340 |
+
}
|
341 |
+
if ($this->classMapAuthoritative || isset($this->missingClasses[$class])) {
|
342 |
+
return false;
|
343 |
+
}
|
344 |
+
if (null !== $this->apcuPrefix) {
|
345 |
+
$file = apcu_fetch($this->apcuPrefix.$class, $hit);
|
346 |
+
if ($hit) {
|
347 |
+
return $file;
|
348 |
+
}
|
349 |
+
}
|
350 |
+
|
351 |
+
$file = $this->findFileWithExtension($class, '.php');
|
352 |
+
|
353 |
+
// Search for Hack files if we are running on HHVM
|
354 |
+
if (false === $file && defined('HHVM_VERSION')) {
|
355 |
+
$file = $this->findFileWithExtension($class, '.hh');
|
356 |
+
}
|
357 |
+
|
358 |
+
if (null !== $this->apcuPrefix) {
|
359 |
+
apcu_add($this->apcuPrefix.$class, $file);
|
360 |
+
}
|
361 |
+
|
362 |
+
if (false === $file) {
|
363 |
+
// Remember that this class does not exist.
|
364 |
+
$this->missingClasses[$class] = true;
|
365 |
+
}
|
366 |
+
|
367 |
+
return $file;
|
368 |
+
}
|
369 |
+
|
370 |
+
private function findFileWithExtension($class, $ext)
|
371 |
+
{
|
372 |
+
// PSR-4 lookup
|
373 |
+
$logicalPathPsr4 = strtr($class, '\\', DIRECTORY_SEPARATOR) . $ext;
|
374 |
+
|
375 |
+
$first = $class[0];
|
376 |
+
if (isset($this->prefixLengthsPsr4[$first])) {
|
377 |
+
$subPath = $class;
|
378 |
+
while (false !== $lastPos = strrpos($subPath, '\\')) {
|
379 |
+
$subPath = substr($subPath, 0, $lastPos);
|
380 |
+
$search = $subPath . '\\';
|
381 |
+
if (isset($this->prefixDirsPsr4[$search])) {
|
382 |
+
$pathEnd = DIRECTORY_SEPARATOR . substr($logicalPathPsr4, $lastPos + 1);
|
383 |
+
foreach ($this->prefixDirsPsr4[$search] as $dir) {
|
384 |
+
if (file_exists($file = $dir . $pathEnd)) {
|
385 |
+
return $file;
|
386 |
+
}
|
387 |
+
}
|
388 |
+
}
|
389 |
+
}
|
390 |
+
}
|
391 |
+
|
392 |
+
// PSR-4 fallback dirs
|
393 |
+
foreach ($this->fallbackDirsPsr4 as $dir) {
|
394 |
+
if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr4)) {
|
395 |
+
return $file;
|
396 |
+
}
|
397 |
+
}
|
398 |
+
|
399 |
+
// PSR-0 lookup
|
400 |
+
if (false !== $pos = strrpos($class, '\\')) {
|
401 |
+
// namespaced class name
|
402 |
+
$logicalPathPsr0 = substr($logicalPathPsr4, 0, $pos + 1)
|
403 |
+
. strtr(substr($logicalPathPsr4, $pos + 1), '_', DIRECTORY_SEPARATOR);
|
404 |
+
} else {
|
405 |
+
// PEAR-like class name
|
406 |
+
$logicalPathPsr0 = strtr($class, '_', DIRECTORY_SEPARATOR) . $ext;
|
407 |
+
}
|
408 |
+
|
409 |
+
if (isset($this->prefixesPsr0[$first])) {
|
410 |
+
foreach ($this->prefixesPsr0[$first] as $prefix => $dirs) {
|
411 |
+
if (0 === strpos($class, $prefix)) {
|
412 |
+
foreach ($dirs as $dir) {
|
413 |
+
if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) {
|
414 |
+
return $file;
|
415 |
+
}
|
416 |
+
}
|
417 |
+
}
|
418 |
+
}
|
419 |
+
}
|
420 |
+
|
421 |
+
// PSR-0 fallback dirs
|
422 |
+
foreach ($this->fallbackDirsPsr0 as $dir) {
|
423 |
+
if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) {
|
424 |
+
return $file;
|
425 |
+
}
|
426 |
+
}
|
427 |
+
|
428 |
+
// PSR-0 include paths.
|
429 |
+
if ($this->useIncludePath && $file = stream_resolve_include_path($logicalPathPsr0)) {
|
430 |
+
return $file;
|
431 |
+
}
|
432 |
+
|
433 |
+
return false;
|
434 |
+
}
|
435 |
+
}
|
436 |
+
|
437 |
+
/**
|
438 |
+
* Scope isolated include.
|
439 |
+
*
|
440 |
+
* Prevents access to $this/self from included files.
|
441 |
+
*/
|
442 |
+
function includeFile($file)
|
443 |
+
{
|
444 |
+
include $file;
|
445 |
+
}
|
addons/vendor/composer/LICENSE
ADDED
@@ -0,0 +1,21 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
|
2 |
+
Copyright (c) Nils Adermann, Jordi Boggiano
|
3 |
+
|
4 |
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
5 |
+
of this software and associated documentation files (the "Software"), to deal
|
6 |
+
in the Software without restriction, including without limitation the rights
|
7 |
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
8 |
+
copies of the Software, and to permit persons to whom the Software is furnished
|
9 |
+
to do so, subject to the following conditions:
|
10 |
+
|
11 |
+
The above copyright notice and this permission notice shall be included in all
|
12 |
+
copies or substantial portions of the Software.
|
13 |
+
|
14 |
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
15 |
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
16 |
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
17 |
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
18 |
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
19 |
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
20 |
+
THE SOFTWARE.
|
21 |
+
|
addons/vendor/composer/autoload_classmap.php
ADDED
@@ -0,0 +1,506 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
// autoload_classmap.php @generated by Composer
|
4 |
+
|
5 |
+
$vendorDir = dirname(dirname(__FILE__));
|
6 |
+
$baseDir = dirname($vendorDir);
|
7 |
+
|
8 |
+
return array(
|
9 |
+
'ICL_AdminNotifier' => $vendorDir . '/wpml/wpml-dependencies/lib/inc/icl-admin-notifier.php',
|
10 |
+
'IWPML_AJAX_Action' => $vendorDir . '/wpml/core-api/core/interfaces/actions/interface-iwpml-ajax-action.php',
|
11 |
+
'IWPML_AJAX_Action_Loader' => $vendorDir . '/wpml/core-api/core/interfaces/actions/interface-iwpml-ajax-action-loader.php',
|
12 |
+
'IWPML_Action' => $vendorDir . '/wpml/core-api/core/interfaces/actions/interface-iwpml-action.php',
|
13 |
+
'IWPML_Action_Loader_Factory' => $vendorDir . '/wpml/core-api/core/interfaces/actions/interface-iwpml-action-loader-factory.php',
|
14 |
+
'IWPML_Backend_Action' => $vendorDir . '/wpml/core-api/core/interfaces/actions/interface-iwpml-backend-action.php',
|
15 |
+
'IWPML_Backend_Action_Loader' => $vendorDir . '/wpml/core-api/core/interfaces/actions/interface-iwpml-backend-action-loader.php',
|
16 |
+
'IWPML_CLI_Action' => $vendorDir . '/wpml/core-api/core/interfaces/actions/interface-iwpml-cli-action.php',
|
17 |
+
'IWPML_CLI_Action_Loader' => $vendorDir . '/wpml/core-api/core/interfaces/actions/interface-iwpml-cli-action-loader.php',
|
18 |
+
'IWPML_Current_Language' => $vendorDir . '/wpml/wpml-dependencies/lib/classes/languages/interface-iwpml-current-language.php',
|
19 |
+
'IWPML_DIC_Action' => $vendorDir . '/wpml/core-api/core/interfaces/actions/interface-iwpml-dic-action.php',
|
20 |
+
'IWPML_Deferred_Action_Loader' => $vendorDir . '/wpml/core-api/core/interfaces/actions/interface-iwpml-deferred-action-loader.php',
|
21 |
+
'IWPML_Frontend_Action' => $vendorDir . '/wpml/core-api/core/interfaces/actions/interface-iwpml-frontend-action.php',
|
22 |
+
'IWPML_Frontend_Action_Loader' => $vendorDir . '/wpml/core-api/core/interfaces/actions/interface-iwpml-frontend-action-loader.php',
|
23 |
+
'IWPML_REST_Action' => $vendorDir . '/wpml/core-api/core/interfaces/actions/interface-iwpml-rest-action.php',
|
24 |
+
'IWPML_REST_Action_Loader' => $vendorDir . '/wpml/core-api/core/interfaces/actions/interface-iwpml-rest-action-loader.php',
|
25 |
+
'IWPML_Template_Service' => $vendorDir . '/wpml/wpml-dependencies/lib/classes/templates/interface-iwpml-template-service.php',
|
26 |
+
'IWPML_WP_Element_Type' => $vendorDir . '/wpml/wpml-dependencies/lib/classes/wpml-wp/iwpml-wp-element-type.php',
|
27 |
+
'OTGS_Assets_Handles' => $vendorDir . '/otgs/ui/src/php/OTGS_Assets_Handles.php',
|
28 |
+
'OTGS_Assets_Store' => $vendorDir . '/otgs/ui/src/php/OTGS_Assets_Store.php',
|
29 |
+
'OTGS_UI_Assets' => $vendorDir . '/otgs/ui/src/php/OTGS_UI_Assets.php',
|
30 |
+
'OTGS_UI_Loader' => $vendorDir . '/otgs/ui/src/php/OTGS_UI_Loader.php',
|
31 |
+
'WPML\\API\\PostTypes' => $vendorDir . '/wpml/core-api/core/PostTypes.php',
|
32 |
+
'WPML\\API\\Settings' => $vendorDir . '/wpml/core-api/core/Settings.php',
|
33 |
+
'WPML\\API\\Version' => $vendorDir . '/wpml/core-api/core/Version.php',
|
34 |
+
'WPML\\Action\\Type' => $vendorDir . '/wpml/wpml-dependencies/lib/classes/action-filter-loader/class-wpml-action-type.php',
|
35 |
+
'WPML\\Ajax\\IHandler' => $vendorDir . '/wpml/core-api/core/interfaces/ajax/Handler.php',
|
36 |
+
'WPML\\Container\\Config' => $vendorDir . '/wpml/wpml-dependencies/lib/classes/container/class-config.php',
|
37 |
+
'WPML\\Container\\Container' => $vendorDir . '/wpml/wpml-dependencies/lib/classes/container/class-wpml-container.php',
|
38 |
+
'WPML\\Core\\BackgroundTask' => $vendorDir . '/wpml/core-api/core/utility/BackgroundTask.php',
|
39 |
+
'WPML\\Core\\ISitePress' => $vendorDir . '/wpml/wpml-dependencies/lib/classes/ISitePress.php',
|
40 |
+
'WPML\\Core\\Twig\\Cache\\CacheInterface' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/src/Cache/CacheInterface.php',
|
41 |
+
'WPML\\Core\\Twig\\Cache\\FilesystemCache' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/src/Cache/FilesystemCache.php',
|
42 |
+
'WPML\\Core\\Twig\\Cache\\NullCache' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/src/Cache/NullCache.php',
|
43 |
+
'WPML\\Core\\Twig\\Compiler' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/src/Compiler.php',
|
44 |
+
'WPML\\Core\\Twig\\Environment' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/src/Environment.php',
|
45 |
+
'WPML\\Core\\Twig\\Error\\Error' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/src/Error/Error.php',
|
46 |
+
'WPML\\Core\\Twig\\Error\\LoaderError' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/src/Error/LoaderError.php',
|
47 |
+
'WPML\\Core\\Twig\\Error\\RuntimeError' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/src/Error/RuntimeError.php',
|
48 |
+
'WPML\\Core\\Twig\\Error\\SyntaxError' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/src/Error/SyntaxError.php',
|
49 |
+
'WPML\\Core\\Twig\\ExpressionParser' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/src/ExpressionParser.php',
|
50 |
+
'WPML\\Core\\Twig\\Extension\\AbstractExtension' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/src/Extension/AbstractExtension.php',
|
51 |
+
'WPML\\Core\\Twig\\Extension\\CoreExtension' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/src/Extension/CoreExtension.php',
|
52 |
+
'WPML\\Core\\Twig\\Extension\\DebugExtension' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/src/Extension/DebugExtension.php',
|
53 |
+
'WPML\\Core\\Twig\\Extension\\EscaperExtension' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/src/Extension/EscaperExtension.php',
|
54 |
+
'WPML\\Core\\Twig\\Extension\\ExtensionInterface' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/src/Extension/ExtensionInterface.php',
|
55 |
+
'WPML\\Core\\Twig\\Extension\\GlobalsInterface' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/src/Extension/GlobalsInterface.php',
|
56 |
+
'WPML\\Core\\Twig\\Extension\\InitRuntimeInterface' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/src/Extension/InitRuntimeInterface.php',
|
57 |
+
'WPML\\Core\\Twig\\Extension\\OptimizerExtension' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/src/Extension/OptimizerExtension.php',
|
58 |
+
'WPML\\Core\\Twig\\Extension\\ProfilerExtension' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/src/Extension/ProfilerExtension.php',
|
59 |
+
'WPML\\Core\\Twig\\Extension\\RuntimeExtensionInterface' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/src/Extension/RuntimeExtensionInterface.php',
|
60 |
+
'WPML\\Core\\Twig\\Extension\\SandboxExtension' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/src/Extension/SandboxExtension.php',
|
61 |
+
'WPML\\Core\\Twig\\Extension\\StagingExtension' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/src/Extension/StagingExtension.php',
|
62 |
+
'WPML\\Core\\Twig\\Extension\\StringLoaderExtension' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/src/Extension/StringLoaderExtension.php',
|
63 |
+
'WPML\\Core\\Twig\\FileExtensionEscapingStrategy' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/src/FileExtensionEscapingStrategy.php',
|
64 |
+
'WPML\\Core\\Twig\\Lexer' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/src/Lexer.php',
|
65 |
+
'WPML\\Core\\Twig\\Loader\\ArrayLoader' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/src/Loader/ArrayLoader.php',
|
66 |
+
'WPML\\Core\\Twig\\Loader\\ChainLoader' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/src/Loader/ChainLoader.php',
|
67 |
+
'WPML\\Core\\Twig\\Loader\\ExistsLoaderInterface' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/src/Loader/ExistsLoaderInterface.php',
|
68 |
+
'WPML\\Core\\Twig\\Loader\\FilesystemLoader' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/src/Loader/FilesystemLoader.php',
|
69 |
+
'WPML\\Core\\Twig\\Loader\\LoaderInterface' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/src/Loader/LoaderInterface.php',
|
70 |
+
'WPML\\Core\\Twig\\Loader\\SourceContextLoaderInterface' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/src/Loader/SourceContextLoaderInterface.php',
|
71 |
+
'WPML\\Core\\Twig\\Markup' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/src/Markup.php',
|
72 |
+
'WPML\\Core\\Twig\\NodeTraverser' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/src/NodeTraverser.php',
|
73 |
+
'WPML\\Core\\Twig\\NodeVisitor\\AbstractNodeVisitor' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/src/NodeVisitor/AbstractNodeVisitor.php',
|
74 |
+
'WPML\\Core\\Twig\\NodeVisitor\\EscaperNodeVisitor' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/src/NodeVisitor/EscaperNodeVisitor.php',
|
75 |
+
'WPML\\Core\\Twig\\NodeVisitor\\NodeVisitorInterface' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/src/NodeVisitor/NodeVisitorInterface.php',
|
76 |
+
'WPML\\Core\\Twig\\NodeVisitor\\OptimizerNodeVisitor' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/src/NodeVisitor/OptimizerNodeVisitor.php',
|
77 |
+
'WPML\\Core\\Twig\\NodeVisitor\\SafeAnalysisNodeVisitor' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/src/NodeVisitor/SafeAnalysisNodeVisitor.php',
|
78 |
+
'WPML\\Core\\Twig\\NodeVisitor\\SandboxNodeVisitor' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/src/NodeVisitor/SandboxNodeVisitor.php',
|
79 |
+
'WPML\\Core\\Twig\\Node\\AutoEscapeNode' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/src/Node/AutoEscapeNode.php',
|
80 |
+
'WPML\\Core\\Twig\\Node\\BlockNode' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/src/Node/BlockNode.php',
|
81 |
+
'WPML\\Core\\Twig\\Node\\BlockReferenceNode' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/src/Node/BlockReferenceNode.php',
|
82 |
+
'WPML\\Core\\Twig\\Node\\BodyNode' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/src/Node/BodyNode.php',
|
83 |
+
'WPML\\Core\\Twig\\Node\\CheckSecurityNode' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/src/Node/CheckSecurityNode.php',
|
84 |
+
'WPML\\Core\\Twig\\Node\\CheckToStringNode' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/src/Node/CheckToStringNode.php',
|
85 |
+
'WPML\\Core\\Twig\\Node\\DeprecatedNode' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/src/Node/DeprecatedNode.php',
|
86 |
+
'WPML\\Core\\Twig\\Node\\DoNode' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/src/Node/DoNode.php',
|
87 |
+
'WPML\\Core\\Twig\\Node\\EmbedNode' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/src/Node/EmbedNode.php',
|
88 |
+
'WPML\\Core\\Twig\\Node\\Expression\\AbstractExpression' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/src/Node/Expression/AbstractExpression.php',
|
89 |
+
'WPML\\Core\\Twig\\Node\\Expression\\ArrayExpression' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/src/Node/Expression/ArrayExpression.php',
|
90 |
+
'WPML\\Core\\Twig\\Node\\Expression\\ArrowFunctionExpression' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/src/Node/Expression/ArrowFunctionExpression.php',
|
91 |
+
'WPML\\Core\\Twig\\Node\\Expression\\AssignNameExpression' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/src/Node/Expression/AssignNameExpression.php',
|
92 |
+
'WPML\\Core\\Twig\\Node\\Expression\\Binary\\AbstractBinary' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/src/Node/Expression/Binary/AbstractBinary.php',
|
93 |
+
'WPML\\Core\\Twig\\Node\\Expression\\Binary\\AddBinary' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/src/Node/Expression/Binary/AddBinary.php',
|
94 |
+
'WPML\\Core\\Twig\\Node\\Expression\\Binary\\AndBinary' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/src/Node/Expression/Binary/AndBinary.php',
|
95 |
+
'WPML\\Core\\Twig\\Node\\Expression\\Binary\\BitwiseAndBinary' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/src/Node/Expression/Binary/BitwiseAndBinary.php',
|
96 |
+
'WPML\\Core\\Twig\\Node\\Expression\\Binary\\BitwiseOrBinary' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/src/Node/Expression/Binary/BitwiseOrBinary.php',
|
97 |
+
'WPML\\Core\\Twig\\Node\\Expression\\Binary\\BitwiseXorBinary' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/src/Node/Expression/Binary/BitwiseXorBinary.php',
|
98 |
+
'WPML\\Core\\Twig\\Node\\Expression\\Binary\\ConcatBinary' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/src/Node/Expression/Binary/ConcatBinary.php',
|
99 |
+
'WPML\\Core\\Twig\\Node\\Expression\\Binary\\DivBinary' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/src/Node/Expression/Binary/DivBinary.php',
|
100 |
+
'WPML\\Core\\Twig\\Node\\Expression\\Binary\\EndsWithBinary' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/src/Node/Expression/Binary/EndsWithBinary.php',
|
101 |
+
'WPML\\Core\\Twig\\Node\\Expression\\Binary\\EqualBinary' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/src/Node/Expression/Binary/EqualBinary.php',
|
102 |
+
'WPML\\Core\\Twig\\Node\\Expression\\Binary\\FloorDivBinary' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/src/Node/Expression/Binary/FloorDivBinary.php',
|
103 |
+
'WPML\\Core\\Twig\\Node\\Expression\\Binary\\GreaterBinary' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/src/Node/Expression/Binary/GreaterBinary.php',
|
104 |
+
'WPML\\Core\\Twig\\Node\\Expression\\Binary\\GreaterEqualBinary' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/src/Node/Expression/Binary/GreaterEqualBinary.php',
|
105 |
+
'WPML\\Core\\Twig\\Node\\Expression\\Binary\\InBinary' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/src/Node/Expression/Binary/InBinary.php',
|
106 |
+
'WPML\\Core\\Twig\\Node\\Expression\\Binary\\LessBinary' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/src/Node/Expression/Binary/LessBinary.php',
|
107 |
+
'WPML\\Core\\Twig\\Node\\Expression\\Binary\\LessEqualBinary' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/src/Node/Expression/Binary/LessEqualBinary.php',
|
108 |
+
'WPML\\Core\\Twig\\Node\\Expression\\Binary\\MatchesBinary' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/src/Node/Expression/Binary/MatchesBinary.php',
|
109 |
+
'WPML\\Core\\Twig\\Node\\Expression\\Binary\\ModBinary' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/src/Node/Expression/Binary/ModBinary.php',
|
110 |
+
'WPML\\Core\\Twig\\Node\\Expression\\Binary\\MulBinary' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/src/Node/Expression/Binary/MulBinary.php',
|
111 |
+
'WPML\\Core\\Twig\\Node\\Expression\\Binary\\NotEqualBinary' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/src/Node/Expression/Binary/NotEqualBinary.php',
|
112 |
+
'WPML\\Core\\Twig\\Node\\Expression\\Binary\\NotInBinary' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/src/Node/Expression/Binary/NotInBinary.php',
|
113 |
+
'WPML\\Core\\Twig\\Node\\Expression\\Binary\\OrBinary' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/src/Node/Expression/Binary/OrBinary.php',
|
114 |
+
'WPML\\Core\\Twig\\Node\\Expression\\Binary\\PowerBinary' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/src/Node/Expression/Binary/PowerBinary.php',
|
115 |
+
'WPML\\Core\\Twig\\Node\\Expression\\Binary\\RangeBinary' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/src/Node/Expression/Binary/RangeBinary.php',
|
116 |
+
'WPML\\Core\\Twig\\Node\\Expression\\Binary\\StartsWithBinary' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/src/Node/Expression/Binary/StartsWithBinary.php',
|
117 |
+
'WPML\\Core\\Twig\\Node\\Expression\\Binary\\SubBinary' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/src/Node/Expression/Binary/SubBinary.php',
|
118 |
+
'WPML\\Core\\Twig\\Node\\Expression\\BlockReferenceExpression' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/src/Node/Expression/BlockReferenceExpression.php',
|
119 |
+
'WPML\\Core\\Twig\\Node\\Expression\\CallExpression' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/src/Node/Expression/CallExpression.php',
|
120 |
+
'WPML\\Core\\Twig\\Node\\Expression\\ConditionalExpression' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/src/Node/Expression/ConditionalExpression.php',
|
121 |
+
'WPML\\Core\\Twig\\Node\\Expression\\ConstantExpression' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/src/Node/Expression/ConstantExpression.php',
|
122 |
+
'WPML\\Core\\Twig\\Node\\Expression\\FilterExpression' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/src/Node/Expression/FilterExpression.php',
|
123 |
+
'WPML\\Core\\Twig\\Node\\Expression\\Filter\\DefaultFilter' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/src/Node/Expression/Filter/DefaultFilter.php',
|
124 |
+
'WPML\\Core\\Twig\\Node\\Expression\\FunctionExpression' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/src/Node/Expression/FunctionExpression.php',
|
125 |
+
'WPML\\Core\\Twig\\Node\\Expression\\GetAttrExpression' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/src/Node/Expression/GetAttrExpression.php',
|
126 |
+
'WPML\\Core\\Twig\\Node\\Expression\\InlinePrint' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/src/Node/Expression/InlinePrint.php',
|
127 |
+
'WPML\\Core\\Twig\\Node\\Expression\\MethodCallExpression' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/src/Node/Expression/MethodCallExpression.php',
|
128 |
+
'WPML\\Core\\Twig\\Node\\Expression\\NameExpression' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/src/Node/Expression/NameExpression.php',
|
129 |
+
'WPML\\Core\\Twig\\Node\\Expression\\NullCoalesceExpression' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/src/Node/Expression/NullCoalesceExpression.php',
|
130 |
+
'WPML\\Core\\Twig\\Node\\Expression\\ParentExpression' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/src/Node/Expression/ParentExpression.php',
|
131 |
+
'WPML\\Core\\Twig\\Node\\Expression\\TempNameExpression' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/src/Node/Expression/TempNameExpression.php',
|
132 |
+
'WPML\\Core\\Twig\\Node\\Expression\\TestExpression' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/src/Node/Expression/TestExpression.php',
|
133 |
+
'WPML\\Core\\Twig\\Node\\Expression\\Test\\ConstantTest' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/src/Node/Expression/Test/ConstantTest.php',
|
134 |
+
'WPML\\Core\\Twig\\Node\\Expression\\Test\\DefinedTest' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/src/Node/Expression/Test/DefinedTest.php',
|
135 |
+
'WPML\\Core\\Twig\\Node\\Expression\\Test\\DivisiblebyTest' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/src/Node/Expression/Test/DivisiblebyTest.php',
|
136 |
+
'WPML\\Core\\Twig\\Node\\Expression\\Test\\EvenTest' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/src/Node/Expression/Test/EvenTest.php',
|
137 |
+
'WPML\\Core\\Twig\\Node\\Expression\\Test\\NullTest' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/src/Node/Expression/Test/NullTest.php',
|
138 |
+
'WPML\\Core\\Twig\\Node\\Expression\\Test\\OddTest' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/src/Node/Expression/Test/OddTest.php',
|
139 |
+
'WPML\\Core\\Twig\\Node\\Expression\\Test\\SameasTest' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/src/Node/Expression/Test/SameasTest.php',
|
140 |
+
'WPML\\Core\\Twig\\Node\\Expression\\Unary\\AbstractUnary' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/src/Node/Expression/Unary/AbstractUnary.php',
|
141 |
+
'WPML\\Core\\Twig\\Node\\Expression\\Unary\\NegUnary' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/src/Node/Expression/Unary/NegUnary.php',
|
142 |
+
'WPML\\Core\\Twig\\Node\\Expression\\Unary\\NotUnary' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/src/Node/Expression/Unary/NotUnary.php',
|
143 |
+
'WPML\\Core\\Twig\\Node\\Expression\\Unary\\PosUnary' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/src/Node/Expression/Unary/PosUnary.php',
|
144 |
+
'WPML\\Core\\Twig\\Node\\FlushNode' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/src/Node/FlushNode.php',
|
145 |
+
'WPML\\Core\\Twig\\Node\\ForLoopNode' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/src/Node/ForLoopNode.php',
|
146 |
+
'WPML\\Core\\Twig\\Node\\ForNode' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/src/Node/ForNode.php',
|
147 |
+
'WPML\\Core\\Twig\\Node\\IfNode' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/src/Node/IfNode.php',
|
148 |
+
'WPML\\Core\\Twig\\Node\\ImportNode' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/src/Node/ImportNode.php',
|
149 |
+
'WPML\\Core\\Twig\\Node\\IncludeNode' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/src/Node/IncludeNode.php',
|
150 |
+
'WPML\\Core\\Twig\\Node\\MacroNode' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/src/Node/MacroNode.php',
|
151 |
+
'WPML\\Core\\Twig\\Node\\ModuleNode' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/src/Node/ModuleNode.php',
|
152 |
+
'WPML\\Core\\Twig\\Node\\Node' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/src/Node/Node.php',
|
153 |
+
'WPML\\Core\\Twig\\Node\\NodeCaptureInterface' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/src/Node/NodeCaptureInterface.php',
|
154 |
+
'WPML\\Core\\Twig\\Node\\NodeOutputInterface' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/src/Node/NodeOutputInterface.php',
|
155 |
+
'WPML\\Core\\Twig\\Node\\PrintNode' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/src/Node/PrintNode.php',
|
156 |
+
'WPML\\Core\\Twig\\Node\\SandboxNode' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/src/Node/SandboxNode.php',
|
157 |
+
'WPML\\Core\\Twig\\Node\\SandboxedPrintNode' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/src/Node/SandboxedPrintNode.php',
|
158 |
+
'WPML\\Core\\Twig\\Node\\SetNode' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/src/Node/SetNode.php',
|
159 |
+
'WPML\\Core\\Twig\\Node\\SetTempNode' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/src/Node/SetTempNode.php',
|
160 |
+
'WPML\\Core\\Twig\\Node\\SpacelessNode' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/src/Node/SpacelessNode.php',
|
161 |
+
'WPML\\Core\\Twig\\Node\\TextNode' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/src/Node/TextNode.php',
|
162 |
+
'WPML\\Core\\Twig\\Node\\WithNode' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/src/Node/WithNode.php',
|
163 |
+
'WPML\\Core\\Twig\\Parser' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/src/Parser.php',
|
164 |
+
'WPML\\Core\\Twig\\Profiler\\Dumper\\BaseDumper' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/src/Profiler/Dumper/BaseDumper.php',
|
165 |
+
'WPML\\Core\\Twig\\Profiler\\Dumper\\BlackfireDumper' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/src/Profiler/Dumper/BlackfireDumper.php',
|
166 |
+
'WPML\\Core\\Twig\\Profiler\\Dumper\\HtmlDumper' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/src/Profiler/Dumper/HtmlDumper.php',
|
167 |
+
'WPML\\Core\\Twig\\Profiler\\Dumper\\TextDumper' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/src/Profiler/Dumper/TextDumper.php',
|
168 |
+
'WPML\\Core\\Twig\\Profiler\\NodeVisitor\\ProfilerNodeVisitor' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/src/Profiler/NodeVisitor/ProfilerNodeVisitor.php',
|
169 |
+
'WPML\\Core\\Twig\\Profiler\\Node\\EnterProfileNode' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/src/Profiler/Node/EnterProfileNode.php',
|
170 |
+
'WPML\\Core\\Twig\\Profiler\\Node\\LeaveProfileNode' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/src/Profiler/Node/LeaveProfileNode.php',
|
171 |
+
'WPML\\Core\\Twig\\Profiler\\Profile' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/src/Profiler/Profile.php',
|
172 |
+
'WPML\\Core\\Twig\\RuntimeLoader\\ContainerRuntimeLoader' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/src/RuntimeLoader/ContainerRuntimeLoader.php',
|
173 |
+
'WPML\\Core\\Twig\\RuntimeLoader\\FactoryRuntimeLoader' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/src/RuntimeLoader/FactoryRuntimeLoader.php',
|
174 |
+
'WPML\\Core\\Twig\\RuntimeLoader\\RuntimeLoaderInterface' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/src/RuntimeLoader/RuntimeLoaderInterface.php',
|
175 |
+
'WPML\\Core\\Twig\\Sandbox\\SecurityError' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/src/Sandbox/SecurityError.php',
|
176 |
+
'WPML\\Core\\Twig\\Sandbox\\SecurityNotAllowedFilterError' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/src/Sandbox/SecurityNotAllowedFilterError.php',
|
177 |
+
'WPML\\Core\\Twig\\Sandbox\\SecurityNotAllowedFunctionError' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/src/Sandbox/SecurityNotAllowedFunctionError.php',
|
178 |
+
'WPML\\Core\\Twig\\Sandbox\\SecurityNotAllowedMethodError' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/src/Sandbox/SecurityNotAllowedMethodError.php',
|
179 |
+
'WPML\\Core\\Twig\\Sandbox\\SecurityNotAllowedPropertyError' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/src/Sandbox/SecurityNotAllowedPropertyError.php',
|
180 |
+
'WPML\\Core\\Twig\\Sandbox\\SecurityNotAllowedTagError' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/src/Sandbox/SecurityNotAllowedTagError.php',
|
181 |
+
'WPML\\Core\\Twig\\Sandbox\\SecurityPolicy' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/src/Sandbox/SecurityPolicy.php',
|
182 |
+
'WPML\\Core\\Twig\\Sandbox\\SecurityPolicyInterface' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/src/Sandbox/SecurityPolicyInterface.php',
|
183 |
+
'WPML\\Core\\Twig\\Source' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/src/Source.php',
|
184 |
+
'WPML\\Core\\Twig\\Template' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/src/Template.php',
|
185 |
+
'WPML\\Core\\Twig\\TemplateWrapper' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/src/TemplateWrapper.php',
|
186 |
+
'WPML\\Core\\Twig\\Test\\IntegrationTestCase' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/src/Test/IntegrationTestCase.php',
|
187 |
+
'WPML\\Core\\Twig\\Test\\NodeTestCase' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/src/Test/NodeTestCase.php',
|
188 |
+
'WPML\\Core\\Twig\\Token' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/src/Token.php',
|
189 |
+
'WPML\\Core\\Twig\\TokenParser\\AbstractTokenParser' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/src/TokenParser/AbstractTokenParser.php',
|
190 |
+
'WPML\\Core\\Twig\\TokenParser\\ApplyTokenParser' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/src/TokenParser/ApplyTokenParser.php',
|
191 |
+
'WPML\\Core\\Twig\\TokenParser\\AutoEscapeTokenParser' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/src/TokenParser/AutoEscapeTokenParser.php',
|
192 |
+
'WPML\\Core\\Twig\\TokenParser\\BlockTokenParser' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/src/TokenParser/BlockTokenParser.php',
|
193 |
+
'WPML\\Core\\Twig\\TokenParser\\DeprecatedTokenParser' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/src/TokenParser/DeprecatedTokenParser.php',
|
194 |
+
'WPML\\Core\\Twig\\TokenParser\\DoTokenParser' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/src/TokenParser/DoTokenParser.php',
|
195 |
+
'WPML\\Core\\Twig\\TokenParser\\EmbedTokenParser' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/src/TokenParser/EmbedTokenParser.php',
|
196 |
+
'WPML\\Core\\Twig\\TokenParser\\ExtendsTokenParser' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/src/TokenParser/ExtendsTokenParser.php',
|
197 |
+
'WPML\\Core\\Twig\\TokenParser\\FilterTokenParser' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/src/TokenParser/FilterTokenParser.php',
|
198 |
+
'WPML\\Core\\Twig\\TokenParser\\FlushTokenParser' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/src/TokenParser/FlushTokenParser.php',
|
199 |
+
'WPML\\Core\\Twig\\TokenParser\\ForTokenParser' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/src/TokenParser/ForTokenParser.php',
|
200 |
+
'WPML\\Core\\Twig\\TokenParser\\FromTokenParser' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/src/TokenParser/FromTokenParser.php',
|
201 |
+
'WPML\\Core\\Twig\\TokenParser\\IfTokenParser' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/src/TokenParser/IfTokenParser.php',
|
202 |
+
'WPML\\Core\\Twig\\TokenParser\\ImportTokenParser' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/src/TokenParser/ImportTokenParser.php',
|
203 |
+
'WPML\\Core\\Twig\\TokenParser\\IncludeTokenParser' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/src/TokenParser/IncludeTokenParser.php',
|
204 |
+
'WPML\\Core\\Twig\\TokenParser\\MacroTokenParser' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/src/TokenParser/MacroTokenParser.php',
|
205 |
+
'WPML\\Core\\Twig\\TokenParser\\SandboxTokenParser' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/src/TokenParser/SandboxTokenParser.php',
|
206 |
+
'WPML\\Core\\Twig\\TokenParser\\SetTokenParser' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/src/TokenParser/SetTokenParser.php',
|
207 |
+
'WPML\\Core\\Twig\\TokenParser\\SpacelessTokenParser' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/src/TokenParser/SpacelessTokenParser.php',
|
208 |
+
'WPML\\Core\\Twig\\TokenParser\\TokenParserInterface' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/src/TokenParser/TokenParserInterface.php',
|
209 |
+
'WPML\\Core\\Twig\\TokenParser\\UseTokenParser' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/src/TokenParser/UseTokenParser.php',
|
210 |
+
'WPML\\Core\\Twig\\TokenParser\\WithTokenParser' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/src/TokenParser/WithTokenParser.php',
|
211 |
+
'WPML\\Core\\Twig\\TokenStream' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/src/TokenStream.php',
|
212 |
+
'WPML\\Core\\Twig\\TwigFilter' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/src/TwigFilter.php',
|
213 |
+
'WPML\\Core\\Twig\\TwigFunction' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/src/TwigFunction.php',
|
214 |
+
'WPML\\Core\\Twig\\TwigTest' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/src/TwigTest.php',
|
215 |
+
'WPML\\Core\\Twig\\Util\\DeprecationCollector' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/src/Util/DeprecationCollector.php',
|
216 |
+
'WPML\\Core\\Twig\\Util\\TemplateDirIterator' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/src/Util/TemplateDirIterator.php',
|
217 |
+
'WPML\\Core\\Twig_Autoloader' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Autoloader.php',
|
218 |
+
'WPML\\Core\\Twig_BaseNodeVisitor' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/BaseNodeVisitor.php',
|
219 |
+
'WPML\\Core\\Twig_CacheInterface' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/CacheInterface.php',
|
220 |
+
'WPML\\Core\\Twig_Cache_Filesystem' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Cache/Filesystem.php',
|
221 |
+
'WPML\\Core\\Twig_Cache_Null' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Cache/Null.php',
|
222 |
+
'WPML\\Core\\Twig_Compiler' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Compiler.php',
|
223 |
+
'WPML\\Core\\Twig_CompilerInterface' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/CompilerInterface.php',
|
224 |
+
'WPML\\Core\\Twig_ContainerRuntimeLoader' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/ContainerRuntimeLoader.php',
|
225 |
+
'WPML\\Core\\Twig_Environment' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Environment.php',
|
226 |
+
'WPML\\Core\\Twig_Error' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Error.php',
|
227 |
+
'WPML\\Core\\Twig_Error_Loader' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Error/Loader.php',
|
228 |
+
'WPML\\Core\\Twig_Error_Runtime' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Error/Runtime.php',
|
229 |
+
'WPML\\Core\\Twig_Error_Syntax' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Error/Syntax.php',
|
230 |
+
'WPML\\Core\\Twig_ExistsLoaderInterface' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/ExistsLoaderInterface.php',
|
231 |
+
'WPML\\Core\\Twig_ExpressionParser' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/ExpressionParser.php',
|
232 |
+
'WPML\\Core\\Twig_Extension' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Extension.php',
|
233 |
+
'WPML\\Core\\Twig_ExtensionInterface' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/ExtensionInterface.php',
|
234 |
+
'WPML\\Core\\Twig_Extension_Core' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Extension/Core.php',
|
235 |
+
'WPML\\Core\\Twig_Extension_Debug' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Extension/Debug.php',
|
236 |
+
'WPML\\Core\\Twig_Extension_Escaper' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Extension/Escaper.php',
|
237 |
+
'WPML\\Core\\Twig_Extension_GlobalsInterface' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Extension/GlobalsInterface.php',
|
238 |
+
'WPML\\Core\\Twig_Extension_InitRuntimeInterface' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Extension/InitRuntimeInterface.php',
|
239 |
+
'WPML\\Core\\Twig_Extension_Optimizer' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Extension/Optimizer.php',
|
240 |
+
'WPML\\Core\\Twig_Extension_Profiler' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Extension/Profiler.php',
|
241 |
+
'WPML\\Core\\Twig_Extension_Sandbox' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Extension/Sandbox.php',
|
242 |
+
'WPML\\Core\\Twig_Extension_Staging' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Extension/Staging.php',
|
243 |
+
'WPML\\Core\\Twig_Extension_StringLoader' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Extension/StringLoader.php',
|
244 |
+
'WPML\\Core\\Twig_FactoryRuntimeLoader' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/FactoryRuntimeLoader.php',
|
245 |
+
'WPML\\Core\\Twig_FileExtensionEscapingStrategy' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/FileExtensionEscapingStrategy.php',
|
246 |
+
'WPML\\Core\\Twig_Filter' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Filter.php',
|
247 |
+
'WPML\\Core\\Twig_FilterCallableInterface' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/FilterCallableInterface.php',
|
248 |
+
'WPML\\Core\\Twig_FilterInterface' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/FilterInterface.php',
|
249 |
+
'WPML\\Core\\Twig_Filter_Function' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Filter/Function.php',
|
250 |
+
'WPML\\Core\\Twig_Filter_Method' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Filter/Method.php',
|
251 |
+
'WPML\\Core\\Twig_Filter_Node' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Filter/Node.php',
|
252 |
+
'WPML\\Core\\Twig_Function' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Function.php',
|
253 |
+
'WPML\\Core\\Twig_FunctionCallableInterface' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/FunctionCallableInterface.php',
|
254 |
+
'WPML\\Core\\Twig_FunctionInterface' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/FunctionInterface.php',
|
255 |
+
'WPML\\Core\\Twig_Function_Function' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Function/Function.php',
|
256 |
+
'WPML\\Core\\Twig_Function_Method' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Function/Method.php',
|
257 |
+
'WPML\\Core\\Twig_Function_Node' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Function/Node.php',
|
258 |
+
'WPML\\Core\\Twig_Lexer' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Lexer.php',
|
259 |
+
'WPML\\Core\\Twig_LexerInterface' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/LexerInterface.php',
|
260 |
+
'WPML\\Core\\Twig_LoaderInterface' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/LoaderInterface.php',
|
261 |
+
'WPML\\Core\\Twig_Loader_Array' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Loader/Array.php',
|
262 |
+
'WPML\\Core\\Twig_Loader_Chain' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Loader/Chain.php',
|
263 |
+
'WPML\\Core\\Twig_Loader_Filesystem' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Loader/Filesystem.php',
|
264 |
+
'WPML\\Core\\Twig_Loader_String' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Loader/String.php',
|
265 |
+
'WPML\\Core\\Twig_Markup' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Markup.php',
|
266 |
+
'WPML\\Core\\Twig_Node' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Node.php',
|
267 |
+
'WPML\\Core\\Twig_NodeCaptureInterface' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/NodeCaptureInterface.php',
|
268 |
+
'WPML\\Core\\Twig_NodeInterface' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/NodeInterface.php',
|
269 |
+
'WPML\\Core\\Twig_NodeOutputInterface' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/NodeOutputInterface.php',
|
270 |
+
'WPML\\Core\\Twig_NodeTraverser' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/NodeTraverser.php',
|
271 |
+
'WPML\\Core\\Twig_NodeVisitorInterface' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/NodeVisitorInterface.php',
|
272 |
+
'WPML\\Core\\Twig_NodeVisitor_Escaper' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/NodeVisitor/Escaper.php',
|
273 |
+
'WPML\\Core\\Twig_NodeVisitor_Optimizer' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/NodeVisitor/Optimizer.php',
|
274 |
+
'WPML\\Core\\Twig_NodeVisitor_SafeAnalysis' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/NodeVisitor/SafeAnalysis.php',
|
275 |
+
'WPML\\Core\\Twig_NodeVisitor_Sandbox' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/NodeVisitor/Sandbox.php',
|
276 |
+
'WPML\\Core\\Twig_Node_AutoEscape' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Node/AutoEscape.php',
|
277 |
+
'WPML\\Core\\Twig_Node_Block' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Node/Block.php',
|
278 |
+
'WPML\\Core\\Twig_Node_BlockReference' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Node/BlockReference.php',
|
279 |
+
'WPML\\Core\\Twig_Node_Body' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Node/Body.php',
|
280 |
+
'WPML\\Core\\Twig_Node_CheckSecurity' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Node/CheckSecurity.php',
|
281 |
+
'WPML\\Core\\Twig_Node_Deprecated' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Node/Deprecated.php',
|
282 |
+
'WPML\\Core\\Twig_Node_Do' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Node/Do.php',
|
283 |
+
'WPML\\Core\\Twig_Node_Embed' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Node/Embed.php',
|
284 |
+
'WPML\\Core\\Twig_Node_Expression' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Node/Expression.php',
|
285 |
+
'WPML\\Core\\Twig_Node_Expression_Array' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Node/Expression/Array.php',
|
286 |
+
'WPML\\Core\\Twig_Node_Expression_AssignName' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Node/Expression/AssignName.php',
|
287 |
+
'WPML\\Core\\Twig_Node_Expression_Binary' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Node/Expression/Binary.php',
|
288 |
+
'WPML\\Core\\Twig_Node_Expression_Binary_Add' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Node/Expression/Binary/Add.php',
|
289 |
+
'WPML\\Core\\Twig_Node_Expression_Binary_And' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Node/Expression/Binary/And.php',
|
290 |
+
'WPML\\Core\\Twig_Node_Expression_Binary_BitwiseAnd' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Node/Expression/Binary/BitwiseAnd.php',
|
291 |
+
'WPML\\Core\\Twig_Node_Expression_Binary_BitwiseOr' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Node/Expression/Binary/BitwiseOr.php',
|
292 |
+
'WPML\\Core\\Twig_Node_Expression_Binary_BitwiseXor' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Node/Expression/Binary/BitwiseXor.php',
|
293 |
+
'WPML\\Core\\Twig_Node_Expression_Binary_Concat' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Node/Expression/Binary/Concat.php',
|
294 |
+
'WPML\\Core\\Twig_Node_Expression_Binary_Div' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Node/Expression/Binary/Div.php',
|
295 |
+
'WPML\\Core\\Twig_Node_Expression_Binary_EndsWith' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Node/Expression/Binary/EndsWith.php',
|
296 |
+
'WPML\\Core\\Twig_Node_Expression_Binary_Equal' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Node/Expression/Binary/Equal.php',
|
297 |
+
'WPML\\Core\\Twig_Node_Expression_Binary_FloorDiv' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Node/Expression/Binary/FloorDiv.php',
|
298 |
+
'WPML\\Core\\Twig_Node_Expression_Binary_Greater' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Node/Expression/Binary/Greater.php',
|
299 |
+
'WPML\\Core\\Twig_Node_Expression_Binary_GreaterEqual' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Node/Expression/Binary/GreaterEqual.php',
|
300 |
+
'WPML\\Core\\Twig_Node_Expression_Binary_In' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Node/Expression/Binary/In.php',
|
301 |
+
'WPML\\Core\\Twig_Node_Expression_Binary_Less' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Node/Expression/Binary/Less.php',
|
302 |
+
'WPML\\Core\\Twig_Node_Expression_Binary_LessEqual' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Node/Expression/Binary/LessEqual.php',
|
303 |
+
'WPML\\Core\\Twig_Node_Expression_Binary_Matches' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Node/Expression/Binary/Matches.php',
|
304 |
+
'WPML\\Core\\Twig_Node_Expression_Binary_Mod' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Node/Expression/Binary/Mod.php',
|
305 |
+
'WPML\\Core\\Twig_Node_Expression_Binary_Mul' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Node/Expression/Binary/Mul.php',
|
306 |
+
'WPML\\Core\\Twig_Node_Expression_Binary_NotEqual' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Node/Expression/Binary/NotEqual.php',
|
307 |
+
'WPML\\Core\\Twig_Node_Expression_Binary_NotIn' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Node/Expression/Binary/NotIn.php',
|
308 |
+
'WPML\\Core\\Twig_Node_Expression_Binary_Or' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Node/Expression/Binary/Or.php',
|
309 |
+
'WPML\\Core\\Twig_Node_Expression_Binary_Power' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Node/Expression/Binary/Power.php',
|
310 |
+
'WPML\\Core\\Twig_Node_Expression_Binary_Range' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Node/Expression/Binary/Range.php',
|
311 |
+
'WPML\\Core\\Twig_Node_Expression_Binary_StartsWith' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Node/Expression/Binary/StartsWith.php',
|
312 |
+
'WPML\\Core\\Twig_Node_Expression_Binary_Sub' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Node/Expression/Binary/Sub.php',
|
313 |
+
'WPML\\Core\\Twig_Node_Expression_BlockReference' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Node/Expression/BlockReference.php',
|
314 |
+
'WPML\\Core\\Twig_Node_Expression_Call' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Node/Expression/Call.php',
|
315 |
+
'WPML\\Core\\Twig_Node_Expression_Conditional' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Node/Expression/Conditional.php',
|
316 |
+
'WPML\\Core\\Twig_Node_Expression_Constant' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Node/Expression/Constant.php',
|
317 |
+
'WPML\\Core\\Twig_Node_Expression_ExtensionReference' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Node/Expression/ExtensionReference.php',
|
318 |
+
'WPML\\Core\\Twig_Node_Expression_Filter' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Node/Expression/Filter.php',
|
319 |
+
'WPML\\Core\\Twig_Node_Expression_Filter_Default' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Node/Expression/Filter/Default.php',
|
320 |
+
'WPML\\Core\\Twig_Node_Expression_Function' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Node/Expression/Function.php',
|
321 |
+
'WPML\\Core\\Twig_Node_Expression_GetAttr' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Node/Expression/GetAttr.php',
|
322 |
+
'WPML\\Core\\Twig_Node_Expression_MethodCall' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Node/Expression/MethodCall.php',
|
323 |
+
'WPML\\Core\\Twig_Node_Expression_Name' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Node/Expression/Name.php',
|
324 |
+
'WPML\\Core\\Twig_Node_Expression_NullCoalesce' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Node/Expression/NullCoalesce.php',
|
325 |
+
'WPML\\Core\\Twig_Node_Expression_Parent' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Node/Expression/Parent.php',
|
326 |
+
'WPML\\Core\\Twig_Node_Expression_TempName' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Node/Expression/TempName.php',
|
327 |
+
'WPML\\Core\\Twig_Node_Expression_Test' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Node/Expression/Test.php',
|
328 |
+
'WPML\\Core\\Twig_Node_Expression_Test_Constant' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Node/Expression/Test/Constant.php',
|
329 |
+
'WPML\\Core\\Twig_Node_Expression_Test_Defined' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Node/Expression/Test/Defined.php',
|
330 |
+
'WPML\\Core\\Twig_Node_Expression_Test_Divisibleby' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Node/Expression/Test/Divisibleby.php',
|
331 |
+
'WPML\\Core\\Twig_Node_Expression_Test_Even' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Node/Expression/Test/Even.php',
|
332 |
+
'WPML\\Core\\Twig_Node_Expression_Test_Null' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Node/Expression/Test/Null.php',
|
333 |
+
'WPML\\Core\\Twig_Node_Expression_Test_Odd' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Node/Expression/Test/Odd.php',
|
334 |
+
'WPML\\Core\\Twig_Node_Expression_Test_Sameas' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Node/Expression/Test/Sameas.php',
|
335 |
+
'WPML\\Core\\Twig_Node_Expression_Unary' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Node/Expression/Unary.php',
|
336 |
+
'WPML\\Core\\Twig_Node_Expression_Unary_Neg' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Node/Expression/Unary/Neg.php',
|
337 |
+
'WPML\\Core\\Twig_Node_Expression_Unary_Not' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Node/Expression/Unary/Not.php',
|
338 |
+
'WPML\\Core\\Twig_Node_Expression_Unary_Pos' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Node/Expression/Unary/Pos.php',
|
339 |
+
'WPML\\Core\\Twig_Node_Flush' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Node/Flush.php',
|
340 |
+
'WPML\\Core\\Twig_Node_For' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Node/For.php',
|
341 |
+
'WPML\\Core\\Twig_Node_ForLoop' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Node/ForLoop.php',
|
342 |
+
'WPML\\Core\\Twig_Node_If' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Node/If.php',
|
343 |
+
'WPML\\Core\\Twig_Node_Import' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Node/Import.php',
|
344 |
+
'WPML\\Core\\Twig_Node_Include' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Node/Include.php',
|
345 |
+
'WPML\\Core\\Twig_Node_Macro' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Node/Macro.php',
|
346 |
+
'WPML\\Core\\Twig_Node_Module' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Node/Module.php',
|
347 |
+
'WPML\\Core\\Twig_Node_Print' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Node/Print.php',
|
348 |
+
'WPML\\Core\\Twig_Node_Sandbox' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Node/Sandbox.php',
|
349 |
+
'WPML\\Core\\Twig_Node_SandboxedPrint' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Node/SandboxedPrint.php',
|
350 |
+
'WPML\\Core\\Twig_Node_Set' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Node/Set.php',
|
351 |
+
'WPML\\Core\\Twig_Node_SetTemp' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Node/SetTemp.php',
|
352 |
+
'WPML\\Core\\Twig_Node_Spaceless' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Node/Spaceless.php',
|
353 |
+
'WPML\\Core\\Twig_Node_Text' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Node/Text.php',
|
354 |
+
'WPML\\Core\\Twig_Node_With' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Node/With.php',
|
355 |
+
'WPML\\Core\\Twig_Parser' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Parser.php',
|
356 |
+
'WPML\\Core\\Twig_ParserInterface' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/ParserInterface.php',
|
357 |
+
'WPML\\Core\\Twig_Profiler_Dumper_Base' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Profiler/Dumper/Base.php',
|
358 |
+
'WPML\\Core\\Twig_Profiler_Dumper_Blackfire' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Profiler/Dumper/Blackfire.php',
|
359 |
+
'WPML\\Core\\Twig_Profiler_Dumper_Html' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Profiler/Dumper/Html.php',
|
360 |
+
'WPML\\Core\\Twig_Profiler_Dumper_Text' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Profiler/Dumper/Text.php',
|
361 |
+
'WPML\\Core\\Twig_Profiler_NodeVisitor_Profiler' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Profiler/NodeVisitor/Profiler.php',
|
362 |
+
'WPML\\Core\\Twig_Profiler_Node_EnterProfile' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Profiler/Node/EnterProfile.php',
|
363 |
+
'WPML\\Core\\Twig_Profiler_Node_LeaveProfile' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Profiler/Node/LeaveProfile.php',
|
364 |
+
'WPML\\Core\\Twig_Profiler_Profile' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Profiler/Profile.php',
|
365 |
+
'WPML\\Core\\Twig_RuntimeLoaderInterface' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/RuntimeLoaderInterface.php',
|
366 |
+
'WPML\\Core\\Twig_Sandbox_SecurityError' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Sandbox/SecurityError.php',
|
367 |
+
'WPML\\Core\\Twig_Sandbox_SecurityNotAllowedFilterError' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Sandbox/SecurityNotAllowedFilterError.php',
|
368 |
+
'WPML\\Core\\Twig_Sandbox_SecurityNotAllowedFunctionError' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Sandbox/SecurityNotAllowedFunctionError.php',
|
369 |
+
'WPML\\Core\\Twig_Sandbox_SecurityNotAllowedMethodError' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Sandbox/SecurityNotAllowedMethodError.php',
|
370 |
+
'WPML\\Core\\Twig_Sandbox_SecurityNotAllowedPropertyError' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Sandbox/SecurityNotAllowedPropertyError.php',
|
371 |
+
'WPML\\Core\\Twig_Sandbox_SecurityNotAllowedTagError' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Sandbox/SecurityNotAllowedTagError.php',
|
372 |
+
'WPML\\Core\\Twig_Sandbox_SecurityPolicy' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Sandbox/SecurityPolicy.php',
|
373 |
+
'WPML\\Core\\Twig_Sandbox_SecurityPolicyInterface' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Sandbox/SecurityPolicyInterface.php',
|
374 |
+
'WPML\\Core\\Twig_SimpleFilter' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/SimpleFilter.php',
|
375 |
+
'WPML\\Core\\Twig_SimpleFunction' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/SimpleFunction.php',
|
376 |
+
'WPML\\Core\\Twig_SimpleTest' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/SimpleTest.php',
|
377 |
+
'WPML\\Core\\Twig_Source' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Source.php',
|
378 |
+
'WPML\\Core\\Twig_SourceContextLoaderInterface' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/SourceContextLoaderInterface.php',
|
379 |
+
'WPML\\Core\\Twig_Template' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Template.php',
|
380 |
+
'WPML\\Core\\Twig_TemplateInterface' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/TemplateInterface.php',
|
381 |
+
'WPML\\Core\\Twig_TemplateWrapper' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/TemplateWrapper.php',
|
382 |
+
'WPML\\Core\\Twig_Test' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Test.php',
|
383 |
+
'WPML\\Core\\Twig_TestCallableInterface' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/TestCallableInterface.php',
|
384 |
+
'WPML\\Core\\Twig_TestInterface' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/TestInterface.php',
|
385 |
+
'WPML\\Core\\Twig_Test_Function' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Test/Function.php',
|
386 |
+
'WPML\\Core\\Twig_Test_IntegrationTestCase' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Test/IntegrationTestCase.php',
|
387 |
+
'WPML\\Core\\Twig_Test_Method' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Test/Method.php',
|
388 |
+
'WPML\\Core\\Twig_Test_Node' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Test/Node.php',
|
389 |
+
'WPML\\Core\\Twig_Test_NodeTestCase' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Test/NodeTestCase.php',
|
390 |
+
'WPML\\Core\\Twig_Token' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Token.php',
|
391 |
+
'WPML\\Core\\Twig_TokenParser' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/TokenParser.php',
|
392 |
+
'WPML\\Core\\Twig_TokenParserBroker' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/TokenParserBroker.php',
|
393 |
+
'WPML\\Core\\Twig_TokenParserBrokerInterface' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/TokenParserBrokerInterface.php',
|
394 |
+
'WPML\\Core\\Twig_TokenParserInterface' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/TokenParserInterface.php',
|
395 |
+
'WPML\\Core\\Twig_TokenParser_AutoEscape' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/TokenParser/AutoEscape.php',
|
396 |
+
'WPML\\Core\\Twig_TokenParser_Block' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/TokenParser/Block.php',
|
397 |
+
'WPML\\Core\\Twig_TokenParser_Deprecated' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/TokenParser/Deprecated.php',
|
398 |
+
'WPML\\Core\\Twig_TokenParser_Do' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/TokenParser/Do.php',
|
399 |
+
'WPML\\Core\\Twig_TokenParser_Embed' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/TokenParser/Embed.php',
|
400 |
+
'WPML\\Core\\Twig_TokenParser_Extends' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/TokenParser/Extends.php',
|
401 |
+
'WPML\\Core\\Twig_TokenParser_Filter' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/TokenParser/Filter.php',
|
402 |
+
'WPML\\Core\\Twig_TokenParser_Flush' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/TokenParser/Flush.php',
|
403 |
+
'WPML\\Core\\Twig_TokenParser_For' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/TokenParser/For.php',
|
404 |
+
'WPML\\Core\\Twig_TokenParser_From' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/TokenParser/From.php',
|
405 |
+
'WPML\\Core\\Twig_TokenParser_If' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/TokenParser/If.php',
|
406 |
+
'WPML\\Core\\Twig_TokenParser_Import' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/TokenParser/Import.php',
|
407 |
+
'WPML\\Core\\Twig_TokenParser_Include' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/TokenParser/Include.php',
|
408 |
+
'WPML\\Core\\Twig_TokenParser_Macro' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/TokenParser/Macro.php',
|
409 |
+
'WPML\\Core\\Twig_TokenParser_Sandbox' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/TokenParser/Sandbox.php',
|
410 |
+
'WPML\\Core\\Twig_TokenParser_Set' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/TokenParser/Set.php',
|
411 |
+
'WPML\\Core\\Twig_TokenParser_Spaceless' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/TokenParser/Spaceless.php',
|
412 |
+
'WPML\\Core\\Twig_TokenParser_Use' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/TokenParser/Use.php',
|
413 |
+
'WPML\\Core\\Twig_TokenParser_With' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/TokenParser/With.php',
|
414 |
+
'WPML\\Core\\Twig_TokenStream' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/TokenStream.php',
|
415 |
+
'WPML\\Core\\Twig_Util_DeprecationCollector' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Util/DeprecationCollector.php',
|
416 |
+
'WPML\\Core\\Twig_Util_TemplateDirIterator' => $vendorDir . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Util/TemplateDirIterator.php',
|
417 |
+
'WPML\\DocPage' => $vendorDir . '/wpml/core-api/core/DocPage.php',
|
418 |
+
'WPML\\Element\\API\\Entity\\LanguageMapping' => $vendorDir . '/wpml/core-api/core/Entity/LanguageMapping.php',
|
419 |
+
'WPML\\Element\\API\\IfOriginalPost' => $vendorDir . '/wpml/core-api/core/IfOriginalPost.php',
|
420 |
+
'WPML\\Element\\API\\Languages' => $vendorDir . '/wpml/core-api/core/Languages.php',
|
421 |
+
'WPML\\Element\\API\\Post' => $vendorDir . '/wpml/core-api/core/Post.php',
|
422 |
+
'WPML\\Element\\API\\PostTranslations' => $vendorDir . '/wpml/core-api/core/PostTranslations.php',
|
423 |
+
'WPML\\Element\\API\\Translations' => $vendorDir . '/wpml/core-api/core/Translations.php',
|
424 |
+
'WPML\\Element\\API\\TranslationsRepository' => $vendorDir . '/wpml/core-api/core/TranslationsRepository.php',
|
425 |
+
'WPML\\FP\\Applicative' => $vendorDir . '/wpml/fp/core/Functor/Applicative.php',
|
426 |
+
'WPML\\FP\\Cast' => $vendorDir . '/wpml/fp/core/Cast.php',
|
427 |
+
'WPML\\FP\\ConstApplicative' => $vendorDir . '/wpml/fp/core/Functor/ConstApplicative.php',
|
428 |
+
'WPML\\FP\\Curryable' => $vendorDir . '/wpml/fp/core/traits/Curryable.php',
|
429 |
+
'WPML\\FP\\Debug' => $vendorDir . '/wpml/fp/core/Debug.php',
|
430 |
+
'WPML\\FP\\Either' => $vendorDir . '/wpml/fp/core/Either.php',
|
431 |
+
'WPML\\FP\\FP' => $vendorDir . '/wpml/fp/core/FP.php',
|
432 |
+
'WPML\\FP\\Fns' => $vendorDir . '/wpml/fp/core/Fns.php',
|
433 |
+
'WPML\\FP\\Functor\\ConstFunctor' => $vendorDir . '/wpml/fp/core/Functor/ConstFunctor.php',
|
434 |
+
'WPML\\FP\\Functor\\Functor' => $vendorDir . '/wpml/fp/core/Functor/Functor.php',
|
435 |
+
'WPML\\FP\\Functor\\IdentityFunctor' => $vendorDir . '/wpml/fp/core/Functor/IdentityFunctor.php',
|
436 |
+
'WPML\\FP\\Functor\\Pointed' => $vendorDir . '/wpml/fp/core/Functor/Pointed.php',
|
437 |
+
'WPML\\FP\\Json' => $vendorDir . '/wpml/fp/core/Json.php',
|
438 |
+
'WPML\\FP\\Just' => $vendorDir . '/wpml/fp/core/Maybe.php',
|
439 |
+
'WPML\\FP\\Left' => $vendorDir . '/wpml/fp/core/Either.php',
|
440 |
+
'WPML\\FP\\Logic' => $vendorDir . '/wpml/fp/core/Logic.php',
|
441 |
+
'WPML\\FP\\Lst' => $vendorDir . '/wpml/fp/core/Lst.php',
|
442 |
+
'WPML\\FP\\Math' => $vendorDir . '/wpml/fp/core/Math.php',
|
443 |
+
'WPML\\FP\\Maybe' => $vendorDir . '/wpml/fp/core/Maybe.php',
|
444 |
+
'WPML\\FP\\Nothing' => $vendorDir . '/wpml/fp/core/Maybe.php',
|
445 |
+
'WPML\\FP\\Obj' => $vendorDir . '/wpml/fp/core/Obj.php',
|
446 |
+
'WPML\\FP\\Promise' => $vendorDir . '/wpml/fp/core/Promise.php',
|
447 |
+
'WPML\\FP\\Relation' => $vendorDir . '/wpml/fp/core/Relation.php',
|
448 |
+
'WPML\\FP\\Right' => $vendorDir . '/wpml/fp/core/Either.php',
|
449 |
+
'WPML\\FP\\Str' => $vendorDir . '/wpml/fp/core/Strings.php',
|
450 |
+
'WPML\\FP\\System\\System' => $vendorDir . '/wpml/fp/core/SystemClass.php',
|
451 |
+
'WPML\\FP\\System\\_Filter' => $vendorDir . '/wpml/fp/core/Filter.php',
|
452 |
+
'WPML\\FP\\System\\_Validator' => $vendorDir . '/wpml/fp/core/Validator.php',
|
453 |
+
'WPML\\FP\\Undefined' => $vendorDir . '/wpml/fp/core/Undefined.php',
|
454 |
+
'WPML\\FP\\Wrapper' => $vendorDir . '/wpml/fp/core/Wrapper.php',
|
455 |
+
'WPML\\FP\\_Invoker' => $vendorDir . '/wpml/fp/core/Invoker.php',
|
456 |
+
'WPML\\LIB\\WP\\App\\Resources' => $vendorDir . '/wpml/wp/classes/Resources.php',
|
457 |
+
'WPML\\LIB\\WP\\Attachment' => $vendorDir . '/wpml/wp/classes/Attachment.php',
|
458 |
+
'WPML\\LIB\\WP\\Cache' => $vendorDir . '/wpml/wp/classes/Cache.php',
|
459 |
+
'WPML\\LIB\\WP\\Gutenberg' => $vendorDir . '/wpml/wp/classes/Gutenberg.php',
|
460 |
+
'WPML\\LIB\\WP\\Hooks' => $vendorDir . '/wpml/wp/classes/Hooks.php',
|
461 |
+
'WPML\\LIB\\WP\\Http' => $vendorDir . '/wpml/wp/classes/Http.php',
|
462 |
+
'WPML\\LIB\\WP\\Nonce' => $vendorDir . '/wpml/wp/classes/Nonce.php',
|
463 |
+
'WPML\\LIB\\WP\\Option' => $vendorDir . '/wpml/wp/classes/Option.php',
|
464 |
+
'WPML\\LIB\\WP\\Post' => $vendorDir . '/wpml/wp/classes/Post.php',
|
465 |
+
'WPML\\LIB\\WP\\PostType' => $vendorDir . '/wpml/wp/classes/PostType.php',
|
466 |
+
'WPML\\LIB\\WP\\Roles' => $vendorDir . '/wpml/wp/classes/Roles.php',
|
467 |
+
'WPML\\LIB\\WP\\Transient' => $vendorDir . '/wpml/wp/classes/Transient.php',
|
468 |
+
'WPML\\LIB\\WP\\User' => $vendorDir . '/wpml/wp/classes/User.php',
|
469 |
+
'WPML\\LIB\\WP\\WPDB' => $vendorDir . '/wpml/wp/classes/WPDB.php',
|
470 |
+
'WPML\\LIB\\WP\\WordPress' => $vendorDir . '/wpml/wp/classes/WP.php',
|
471 |
+
'WPML\\Media\\Option' => $vendorDir . '/wpml/core-api/core/media/Option.php',
|
472 |
+
'WPML\\Notices\\DismissNotices' => $vendorDir . '/wpml/wpml-dependencies/lib/classes/notices/DismissNotices.php',
|
473 |
+
'WPML\\Records\\Translations' => $vendorDir . '/wpml/core-api/core/Records/Translations.php',
|
474 |
+
'WPML\\Settings\\PostType\\Automatic' => $vendorDir . '/wpml/core-api/core/settings/Automatic.php',
|
475 |
+
'WPML\\Setup\\Option' => $vendorDir . '/wpml/core-api/core/setup/Option.php',
|
476 |
+
'WPML\\Timer' => $vendorDir . '/wpml/core-api/core/Timer.php',
|
477 |
+
'WPML\\UIPage' => $vendorDir . '/wpml/core-api/core/UIPage.php',
|
478 |
+
'WPML\\Utilities\\ILock' => $vendorDir . '/wpml/core-api/core/utility/ILock.php',
|
479 |
+
'WPML\\Utilities\\Lock' => $vendorDir . '/wpml/core-api/core/utility/Lock.php',
|
480 |
+
'WPML\\WP\\OptionManager' => $vendorDir . '/wpml/core-api/core/OptionManager.php',
|
481 |
+
'WPML_AJAX_Action_Validation' => $vendorDir . '/wpml/wpml-dependencies/lib/classes/action-filter-loader/class-wpml-ajax-action-validation.php',
|
482 |
+
'WPML_AJAX_Base_Factory' => $vendorDir . '/wpml/wpml-dependencies/lib/classes/action-filter-loader/class-wpml-ajax-action-base-factory.php',
|
483 |
+
'WPML_Action_Filter_Loader' => $vendorDir . '/wpml/wpml-dependencies/lib/classes/action-filter-loader/class-wpml-action-filter-loader.php',
|
484 |
+
'WPML_Block_Editor_Helper' => $vendorDir . '/wpml/wpml-dependencies/lib/classes/block-editor/class-wpml-block-editor-helper.php',
|
485 |
+
'WPML_Cookie' => $vendorDir . '/wpml/wpml-dependencies/lib/classes/cookie/class-wpml-cookie.php',
|
486 |
+
'WPML_Core_Privacy_Content' => $vendorDir . '/wpml/wpml-dependencies/lib/classes/privacy/class-wpml-core-privacy-content.php',
|
487 |
+
'WPML_Current_Screen_Loader_Factory' => $vendorDir . '/wpml/wpml-dependencies/lib/classes/action-filter-loader/class-wpml-current-screen-loader-factory.php',
|
488 |
+
'WPML_File' => $vendorDir . '/wpml/wpml-dependencies/lib/classes/class-wpml-file.php',
|
489 |
+
'WPML_Notice' => $vendorDir . '/wpml/wpml-dependencies/lib/classes/notices/class-wpml-notice.php',
|
490 |
+
'WPML_Notice_Action' => $vendorDir . '/wpml/wpml-dependencies/lib/classes/notices/class-wpml-notice-action.php',
|
491 |
+
'WPML_Notice_Render' => $vendorDir . '/wpml/wpml-dependencies/lib/classes/notices/class-wpml-notice-render.php',
|
492 |
+
'WPML_Notice_Show_On_Dashboard_And_WPML_Pages' => $vendorDir . '/wpml/wpml-dependencies/lib/classes/notices/pages/class-wpml-notice-show-on-dashboard-and-wpml-pages.php',
|
493 |
+
'WPML_Notices' => $vendorDir . '/wpml/wpml-dependencies/lib/classes/notices/class-wpml-notices.php',
|
494 |
+
'WPML_PHP_Functions' => $vendorDir . '/wpml/wpml-dependencies/lib/classes/wpml-wp/wpml-php-functions.php',
|
495 |
+
'WPML_Privacy_Content' => $vendorDir . '/wpml/wpml-dependencies/lib/classes/privacy/class-wpml-privacy-content.php',
|
496 |
+
'WPML_Privacy_Content_Factory' => $vendorDir . '/wpml/wpml-dependencies/lib/classes/privacy/class-wpml-privacy-content-factory.php',
|
497 |
+
'WPML_Templates_Factory' => $vendorDir . '/wpml/wpml-dependencies/lib/classes/templating/class-wpml-templates-factory.php',
|
498 |
+
'WPML_Twig_Template' => $vendorDir . '/wpml/wpml-dependencies/lib/classes/templates/class-wpml-twig-template.php',
|
499 |
+
'WPML_Twig_Template_Loader' => $vendorDir . '/wpml/wpml-dependencies/lib/classes/templates/wpml-twig-template-loader.php',
|
500 |
+
'WPML_Twig_WP_Plugin_Extension' => $vendorDir . '/wpml/wpml-dependencies/lib/classes/twig-extensions/wpml-twig-wp-plugin-extension.php',
|
501 |
+
'WPML_WP_API' => $vendorDir . '/wpml/wpml-dependencies/lib/classes/wpml-wp/class-wpml-wp-api.php',
|
502 |
+
'WPML_WP_Cache' => $vendorDir . '/wpml/wpml-dependencies/lib/classes/utilities/class-wpml-wp-cache.php',
|
503 |
+
'WPML_WP_Post_Type' => $vendorDir . '/wpml/wpml-dependencies/lib/classes/wpml-wp/wpml-wp-post-type.php',
|
504 |
+
'WPML_WP_Roles' => $vendorDir . '/wpml/wpml-dependencies/lib/classes/wpml-wp/class-wpml-wp-roles.php',
|
505 |
+
'WPML_WP_Taxonomy' => $vendorDir . '/wpml/wpml-dependencies/lib/classes/wpml-wp/class-wpml-wp-taxonomy.php',
|
506 |
+
);
|
addons/vendor/composer/autoload_files.php
ADDED
@@ -0,0 +1,14 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
// autoload_files.php @generated by Composer
|
4 |
+
|
5 |
+
$vendorDir = dirname(dirname(__FILE__));
|
6 |
+
$baseDir = dirname($vendorDir);
|
7 |
+
|
8 |
+
return array(
|
9 |
+
'5f5b8f7c1db2e892006e8805f0ed573c' => $vendorDir . '/wpml/collect/src/Illuminate/Support/helpers.php',
|
10 |
+
'914c4a8cb7e06f7d6e1ddf6997c1785f' => $vendorDir . '/wpml/fp/core/functions.php',
|
11 |
+
'348332d63f916da7598941d18c24311d' => $vendorDir . '/wpml/fp/core/strings_functions.php',
|
12 |
+
'766b758ee51e52c53cf3312a1dba9e34' => $vendorDir . '/wpml/fp/core/system.php',
|
13 |
+
'4f861be014c38ae526415a9a3c62913a' => $vendorDir . '/wpml/wpml-dependencies/lib/classes/container/functions.php',
|
14 |
+
);
|
addons/vendor/composer/autoload_namespaces.php
ADDED
@@ -0,0 +1,9 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
// autoload_namespaces.php @generated by Composer
|
4 |
+
|
5 |
+
$vendorDir = dirname(dirname(__FILE__));
|
6 |
+
$baseDir = dirname($vendorDir);
|
7 |
+
|
8 |
+
return array(
|
9 |
+
);
|
addons/vendor/composer/autoload_psr4.php
ADDED
@@ -0,0 +1,11 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
// autoload_psr4.php @generated by Composer
|
4 |
+
|
5 |
+
$vendorDir = dirname(dirname(__FILE__));
|
6 |
+
$baseDir = dirname($vendorDir);
|
7 |
+
|
8 |
+
return array(
|
9 |
+
'WPML\\Collect\\' => array($vendorDir . '/wpml/collect/src/Illuminate'),
|
10 |
+
'WPML\\Auryn\\' => array($vendorDir . '/otgs/auryn/lib'),
|
11 |
+
);
|
addons/vendor/composer/autoload_real.php
ADDED
@@ -0,0 +1,73 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
// autoload_real.php @generated by Composer
|
4 |
+
|
5 |
+
class ComposerAutoloaderInit4821ed1a7ed1caf1298338b695908544
|
6 |
+
{
|
7 |
+
private static $loader;
|
8 |
+
|
9 |
+
public static function loadClassLoader($class)
|
10 |
+
{
|
11 |
+
if ('Composer\Autoload\ClassLoader' === $class) {
|
12 |
+
require __DIR__ . '/ClassLoader.php';
|
13 |
+
}
|
14 |
+
}
|
15 |
+
|
16 |
+
/**
|
17 |
+
* @return \Composer\Autoload\ClassLoader
|
18 |
+
*/
|
19 |
+
public static function getLoader()
|
20 |
+
{
|
21 |
+
if (null !== self::$loader) {
|
22 |
+
return self::$loader;
|
23 |
+
}
|
24 |
+
|
25 |
+
spl_autoload_register(array('ComposerAutoloaderInit4821ed1a7ed1caf1298338b695908544', 'loadClassLoader'), true, true);
|
26 |
+
self::$loader = $loader = new \Composer\Autoload\ClassLoader();
|
27 |
+
spl_autoload_unregister(array('ComposerAutoloaderInit4821ed1a7ed1caf1298338b695908544', 'loadClassLoader'));
|
28 |
+
|
29 |
+
$useStaticLoader = PHP_VERSION_ID >= 50600 && !defined('HHVM_VERSION') && (!function_exists('zend_loader_file_encoded') || !zend_loader_file_encoded());
|
30 |
+
if ($useStaticLoader) {
|
31 |
+
require_once __DIR__ . '/autoload_static.php';
|
32 |
+
|
33 |
+
call_user_func(\Composer\Autoload\ComposerStaticInit4821ed1a7ed1caf1298338b695908544::getInitializer($loader));
|
34 |
+
} else {
|
35 |
+
$map = require __DIR__ . '/autoload_namespaces.php';
|
36 |
+
foreach ($map as $namespace => $path) {
|
37 |
+
$loader->set($namespace, $path);
|
38 |
+
}
|
39 |
+
|
40 |
+
$map = require __DIR__ . '/autoload_psr4.php';
|
41 |
+
foreach ($map as $namespace => $path) {
|
42 |
+
$loader->setPsr4($namespace, $path);
|
43 |
+
}
|
44 |
+
|
45 |
+
$classMap = require __DIR__ . '/autoload_classmap.php';
|
46 |
+
if ($classMap) {
|
47 |
+
$loader->addClassMap($classMap);
|
48 |
+
}
|
49 |
+
}
|
50 |
+
|
51 |
+
$loader->register(true);
|
52 |
+
|
53 |
+
if ($useStaticLoader) {
|
54 |
+
$includeFiles = Composer\Autoload\ComposerStaticInit4821ed1a7ed1caf1298338b695908544::$files;
|
55 |
+
} else {
|
56 |
+
$includeFiles = require __DIR__ . '/autoload_files.php';
|
57 |
+
}
|
58 |
+
foreach ($includeFiles as $fileIdentifier => $file) {
|
59 |
+
composerRequire4821ed1a7ed1caf1298338b695908544($fileIdentifier, $file);
|
60 |
+
}
|
61 |
+
|
62 |
+
return $loader;
|
63 |
+
}
|
64 |
+
}
|
65 |
+
|
66 |
+
function composerRequire4821ed1a7ed1caf1298338b695908544($fileIdentifier, $file)
|
67 |
+
{
|
68 |
+
if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) {
|
69 |
+
require $file;
|
70 |
+
|
71 |
+
$GLOBALS['__composer_autoload_files'][$fileIdentifier] = true;
|
72 |
+
}
|
73 |
+
}
|
addons/vendor/composer/autoload_static.php
ADDED
@@ -0,0 +1,545 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
// autoload_static.php @generated by Composer
|
4 |
+
|
5 |
+
namespace Composer\Autoload;
|
6 |
+
|
7 |
+
class ComposerStaticInit4821ed1a7ed1caf1298338b695908544
|
8 |
+
{
|
9 |
+
public static $files = array (
|
10 |
+
'5f5b8f7c1db2e892006e8805f0ed573c' => __DIR__ . '/..' . '/wpml/collect/src/Illuminate/Support/helpers.php',
|
11 |
+
'914c4a8cb7e06f7d6e1ddf6997c1785f' => __DIR__ . '/..' . '/wpml/fp/core/functions.php',
|
12 |
+
'348332d63f916da7598941d18c24311d' => __DIR__ . '/..' . '/wpml/fp/core/strings_functions.php',
|
13 |
+
'766b758ee51e52c53cf3312a1dba9e34' => __DIR__ . '/..' . '/wpml/fp/core/system.php',
|
14 |
+
'4f861be014c38ae526415a9a3c62913a' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/classes/container/functions.php',
|
15 |
+
);
|
16 |
+
|
17 |
+
public static $prefixLengthsPsr4 = array (
|
18 |
+
'W' =>
|
19 |
+
array (
|
20 |
+
'WPML\\Collect\\' => 13,
|
21 |
+
'WPML\\Auryn\\' => 11,
|
22 |
+
),
|
23 |
+
);
|
24 |
+
|
25 |
+
public static $prefixDirsPsr4 = array (
|
26 |
+
'WPML\\Collect\\' =>
|
27 |
+
array (
|
28 |
+
0 => __DIR__ . '/..' . '/wpml/collect/src/Illuminate',
|
29 |
+
),
|
30 |
+
'WPML\\Auryn\\' =>
|
31 |
+
array (
|
32 |
+
0 => __DIR__ . '/..' . '/otgs/auryn/lib',
|
33 |
+
),
|
34 |
+
);
|
35 |
+
|
36 |
+
public static $classMap = array (
|
37 |
+
'ICL_AdminNotifier' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/inc/icl-admin-notifier.php',
|
38 |
+
'IWPML_AJAX_Action' => __DIR__ . '/..' . '/wpml/core-api/core/interfaces/actions/interface-iwpml-ajax-action.php',
|
39 |
+
'IWPML_AJAX_Action_Loader' => __DIR__ . '/..' . '/wpml/core-api/core/interfaces/actions/interface-iwpml-ajax-action-loader.php',
|
40 |
+
'IWPML_Action' => __DIR__ . '/..' . '/wpml/core-api/core/interfaces/actions/interface-iwpml-action.php',
|
41 |
+
'IWPML_Action_Loader_Factory' => __DIR__ . '/..' . '/wpml/core-api/core/interfaces/actions/interface-iwpml-action-loader-factory.php',
|
42 |
+
'IWPML_Backend_Action' => __DIR__ . '/..' . '/wpml/core-api/core/interfaces/actions/interface-iwpml-backend-action.php',
|
43 |
+
'IWPML_Backend_Action_Loader' => __DIR__ . '/..' . '/wpml/core-api/core/interfaces/actions/interface-iwpml-backend-action-loader.php',
|
44 |
+
'IWPML_CLI_Action' => __DIR__ . '/..' . '/wpml/core-api/core/interfaces/actions/interface-iwpml-cli-action.php',
|
45 |
+
'IWPML_CLI_Action_Loader' => __DIR__ . '/..' . '/wpml/core-api/core/interfaces/actions/interface-iwpml-cli-action-loader.php',
|
46 |
+
'IWPML_Current_Language' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/classes/languages/interface-iwpml-current-language.php',
|
47 |
+
'IWPML_DIC_Action' => __DIR__ . '/..' . '/wpml/core-api/core/interfaces/actions/interface-iwpml-dic-action.php',
|
48 |
+
'IWPML_Deferred_Action_Loader' => __DIR__ . '/..' . '/wpml/core-api/core/interfaces/actions/interface-iwpml-deferred-action-loader.php',
|
49 |
+
'IWPML_Frontend_Action' => __DIR__ . '/..' . '/wpml/core-api/core/interfaces/actions/interface-iwpml-frontend-action.php',
|
50 |
+
'IWPML_Frontend_Action_Loader' => __DIR__ . '/..' . '/wpml/core-api/core/interfaces/actions/interface-iwpml-frontend-action-loader.php',
|
51 |
+
'IWPML_REST_Action' => __DIR__ . '/..' . '/wpml/core-api/core/interfaces/actions/interface-iwpml-rest-action.php',
|
52 |
+
'IWPML_REST_Action_Loader' => __DIR__ . '/..' . '/wpml/core-api/core/interfaces/actions/interface-iwpml-rest-action-loader.php',
|
53 |
+
'IWPML_Template_Service' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/classes/templates/interface-iwpml-template-service.php',
|
54 |
+
'IWPML_WP_Element_Type' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/classes/wpml-wp/iwpml-wp-element-type.php',
|
55 |
+
'OTGS_Assets_Handles' => __DIR__ . '/..' . '/otgs/ui/src/php/OTGS_Assets_Handles.php',
|
56 |
+
'OTGS_Assets_Store' => __DIR__ . '/..' . '/otgs/ui/src/php/OTGS_Assets_Store.php',
|
57 |
+
'OTGS_UI_Assets' => __DIR__ . '/..' . '/otgs/ui/src/php/OTGS_UI_Assets.php',
|
58 |
+
'OTGS_UI_Loader' => __DIR__ . '/..' . '/otgs/ui/src/php/OTGS_UI_Loader.php',
|
59 |
+
'WPML\\API\\PostTypes' => __DIR__ . '/..' . '/wpml/core-api/core/PostTypes.php',
|
60 |
+
'WPML\\API\\Settings' => __DIR__ . '/..' . '/wpml/core-api/core/Settings.php',
|
61 |
+
'WPML\\API\\Version' => __DIR__ . '/..' . '/wpml/core-api/core/Version.php',
|
62 |
+
'WPML\\Action\\Type' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/classes/action-filter-loader/class-wpml-action-type.php',
|
63 |
+
'WPML\\Ajax\\IHandler' => __DIR__ . '/..' . '/wpml/core-api/core/interfaces/ajax/Handler.php',
|
64 |
+
'WPML\\Container\\Config' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/classes/container/class-config.php',
|
65 |
+
'WPML\\Container\\Container' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/classes/container/class-wpml-container.php',
|
66 |
+
'WPML\\Core\\BackgroundTask' => __DIR__ . '/..' . '/wpml/core-api/core/utility/BackgroundTask.php',
|
67 |
+
'WPML\\Core\\ISitePress' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/classes/ISitePress.php',
|
68 |
+
'WPML\\Core\\Twig\\Cache\\CacheInterface' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/src/Cache/CacheInterface.php',
|
69 |
+
'WPML\\Core\\Twig\\Cache\\FilesystemCache' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/src/Cache/FilesystemCache.php',
|
70 |
+
'WPML\\Core\\Twig\\Cache\\NullCache' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/src/Cache/NullCache.php',
|
71 |
+
'WPML\\Core\\Twig\\Compiler' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/src/Compiler.php',
|
72 |
+
'WPML\\Core\\Twig\\Environment' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/src/Environment.php',
|
73 |
+
'WPML\\Core\\Twig\\Error\\Error' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/src/Error/Error.php',
|
74 |
+
'WPML\\Core\\Twig\\Error\\LoaderError' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/src/Error/LoaderError.php',
|
75 |
+
'WPML\\Core\\Twig\\Error\\RuntimeError' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/src/Error/RuntimeError.php',
|
76 |
+
'WPML\\Core\\Twig\\Error\\SyntaxError' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/src/Error/SyntaxError.php',
|
77 |
+
'WPML\\Core\\Twig\\ExpressionParser' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/src/ExpressionParser.php',
|
78 |
+
'WPML\\Core\\Twig\\Extension\\AbstractExtension' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/src/Extension/AbstractExtension.php',
|
79 |
+
'WPML\\Core\\Twig\\Extension\\CoreExtension' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/src/Extension/CoreExtension.php',
|
80 |
+
'WPML\\Core\\Twig\\Extension\\DebugExtension' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/src/Extension/DebugExtension.php',
|
81 |
+
'WPML\\Core\\Twig\\Extension\\EscaperExtension' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/src/Extension/EscaperExtension.php',
|
82 |
+
'WPML\\Core\\Twig\\Extension\\ExtensionInterface' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/src/Extension/ExtensionInterface.php',
|
83 |
+
'WPML\\Core\\Twig\\Extension\\GlobalsInterface' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/src/Extension/GlobalsInterface.php',
|
84 |
+
'WPML\\Core\\Twig\\Extension\\InitRuntimeInterface' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/src/Extension/InitRuntimeInterface.php',
|
85 |
+
'WPML\\Core\\Twig\\Extension\\OptimizerExtension' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/src/Extension/OptimizerExtension.php',
|
86 |
+
'WPML\\Core\\Twig\\Extension\\ProfilerExtension' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/src/Extension/ProfilerExtension.php',
|
87 |
+
'WPML\\Core\\Twig\\Extension\\RuntimeExtensionInterface' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/src/Extension/RuntimeExtensionInterface.php',
|
88 |
+
'WPML\\Core\\Twig\\Extension\\SandboxExtension' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/src/Extension/SandboxExtension.php',
|
89 |
+
'WPML\\Core\\Twig\\Extension\\StagingExtension' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/src/Extension/StagingExtension.php',
|
90 |
+
'WPML\\Core\\Twig\\Extension\\StringLoaderExtension' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/src/Extension/StringLoaderExtension.php',
|
91 |
+
'WPML\\Core\\Twig\\FileExtensionEscapingStrategy' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/src/FileExtensionEscapingStrategy.php',
|
92 |
+
'WPML\\Core\\Twig\\Lexer' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/src/Lexer.php',
|
93 |
+
'WPML\\Core\\Twig\\Loader\\ArrayLoader' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/src/Loader/ArrayLoader.php',
|
94 |
+
'WPML\\Core\\Twig\\Loader\\ChainLoader' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/src/Loader/ChainLoader.php',
|
95 |
+
'WPML\\Core\\Twig\\Loader\\ExistsLoaderInterface' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/src/Loader/ExistsLoaderInterface.php',
|
96 |
+
'WPML\\Core\\Twig\\Loader\\FilesystemLoader' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/src/Loader/FilesystemLoader.php',
|
97 |
+
'WPML\\Core\\Twig\\Loader\\LoaderInterface' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/src/Loader/LoaderInterface.php',
|
98 |
+
'WPML\\Core\\Twig\\Loader\\SourceContextLoaderInterface' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/src/Loader/SourceContextLoaderInterface.php',
|
99 |
+
'WPML\\Core\\Twig\\Markup' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/src/Markup.php',
|
100 |
+
'WPML\\Core\\Twig\\NodeTraverser' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/src/NodeTraverser.php',
|
101 |
+
'WPML\\Core\\Twig\\NodeVisitor\\AbstractNodeVisitor' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/src/NodeVisitor/AbstractNodeVisitor.php',
|
102 |
+
'WPML\\Core\\Twig\\NodeVisitor\\EscaperNodeVisitor' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/src/NodeVisitor/EscaperNodeVisitor.php',
|
103 |
+
'WPML\\Core\\Twig\\NodeVisitor\\NodeVisitorInterface' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/src/NodeVisitor/NodeVisitorInterface.php',
|
104 |
+
'WPML\\Core\\Twig\\NodeVisitor\\OptimizerNodeVisitor' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/src/NodeVisitor/OptimizerNodeVisitor.php',
|
105 |
+
'WPML\\Core\\Twig\\NodeVisitor\\SafeAnalysisNodeVisitor' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/src/NodeVisitor/SafeAnalysisNodeVisitor.php',
|
106 |
+
'WPML\\Core\\Twig\\NodeVisitor\\SandboxNodeVisitor' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/src/NodeVisitor/SandboxNodeVisitor.php',
|
107 |
+
'WPML\\Core\\Twig\\Node\\AutoEscapeNode' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/src/Node/AutoEscapeNode.php',
|
108 |
+
'WPML\\Core\\Twig\\Node\\BlockNode' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/src/Node/BlockNode.php',
|
109 |
+
'WPML\\Core\\Twig\\Node\\BlockReferenceNode' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/src/Node/BlockReferenceNode.php',
|
110 |
+
'WPML\\Core\\Twig\\Node\\BodyNode' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/src/Node/BodyNode.php',
|
111 |
+
'WPML\\Core\\Twig\\Node\\CheckSecurityNode' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/src/Node/CheckSecurityNode.php',
|
112 |
+
'WPML\\Core\\Twig\\Node\\CheckToStringNode' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/src/Node/CheckToStringNode.php',
|
113 |
+
'WPML\\Core\\Twig\\Node\\DeprecatedNode' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/src/Node/DeprecatedNode.php',
|
114 |
+
'WPML\\Core\\Twig\\Node\\DoNode' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/src/Node/DoNode.php',
|
115 |
+
'WPML\\Core\\Twig\\Node\\EmbedNode' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/src/Node/EmbedNode.php',
|
116 |
+
'WPML\\Core\\Twig\\Node\\Expression\\AbstractExpression' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/src/Node/Expression/AbstractExpression.php',
|
117 |
+
'WPML\\Core\\Twig\\Node\\Expression\\ArrayExpression' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/src/Node/Expression/ArrayExpression.php',
|
118 |
+
'WPML\\Core\\Twig\\Node\\Expression\\ArrowFunctionExpression' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/src/Node/Expression/ArrowFunctionExpression.php',
|
119 |
+
'WPML\\Core\\Twig\\Node\\Expression\\AssignNameExpression' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/src/Node/Expression/AssignNameExpression.php',
|
120 |
+
'WPML\\Core\\Twig\\Node\\Expression\\Binary\\AbstractBinary' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/src/Node/Expression/Binary/AbstractBinary.php',
|
121 |
+
'WPML\\Core\\Twig\\Node\\Expression\\Binary\\AddBinary' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/src/Node/Expression/Binary/AddBinary.php',
|
122 |
+
'WPML\\Core\\Twig\\Node\\Expression\\Binary\\AndBinary' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/src/Node/Expression/Binary/AndBinary.php',
|
123 |
+
'WPML\\Core\\Twig\\Node\\Expression\\Binary\\BitwiseAndBinary' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/src/Node/Expression/Binary/BitwiseAndBinary.php',
|
124 |
+
'WPML\\Core\\Twig\\Node\\Expression\\Binary\\BitwiseOrBinary' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/src/Node/Expression/Binary/BitwiseOrBinary.php',
|
125 |
+
'WPML\\Core\\Twig\\Node\\Expression\\Binary\\BitwiseXorBinary' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/src/Node/Expression/Binary/BitwiseXorBinary.php',
|
126 |
+
'WPML\\Core\\Twig\\Node\\Expression\\Binary\\ConcatBinary' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/src/Node/Expression/Binary/ConcatBinary.php',
|
127 |
+
'WPML\\Core\\Twig\\Node\\Expression\\Binary\\DivBinary' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/src/Node/Expression/Binary/DivBinary.php',
|
128 |
+
'WPML\\Core\\Twig\\Node\\Expression\\Binary\\EndsWithBinary' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/src/Node/Expression/Binary/EndsWithBinary.php',
|
129 |
+
'WPML\\Core\\Twig\\Node\\Expression\\Binary\\EqualBinary' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/src/Node/Expression/Binary/EqualBinary.php',
|
130 |
+
'WPML\\Core\\Twig\\Node\\Expression\\Binary\\FloorDivBinary' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/src/Node/Expression/Binary/FloorDivBinary.php',
|
131 |
+
'WPML\\Core\\Twig\\Node\\Expression\\Binary\\GreaterBinary' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/src/Node/Expression/Binary/GreaterBinary.php',
|
132 |
+
'WPML\\Core\\Twig\\Node\\Expression\\Binary\\GreaterEqualBinary' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/src/Node/Expression/Binary/GreaterEqualBinary.php',
|
133 |
+
'WPML\\Core\\Twig\\Node\\Expression\\Binary\\InBinary' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/src/Node/Expression/Binary/InBinary.php',
|
134 |
+
'WPML\\Core\\Twig\\Node\\Expression\\Binary\\LessBinary' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/src/Node/Expression/Binary/LessBinary.php',
|
135 |
+
'WPML\\Core\\Twig\\Node\\Expression\\Binary\\LessEqualBinary' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/src/Node/Expression/Binary/LessEqualBinary.php',
|
136 |
+
'WPML\\Core\\Twig\\Node\\Expression\\Binary\\MatchesBinary' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/src/Node/Expression/Binary/MatchesBinary.php',
|
137 |
+
'WPML\\Core\\Twig\\Node\\Expression\\Binary\\ModBinary' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/src/Node/Expression/Binary/ModBinary.php',
|
138 |
+
'WPML\\Core\\Twig\\Node\\Expression\\Binary\\MulBinary' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/src/Node/Expression/Binary/MulBinary.php',
|
139 |
+
'WPML\\Core\\Twig\\Node\\Expression\\Binary\\NotEqualBinary' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/src/Node/Expression/Binary/NotEqualBinary.php',
|
140 |
+
'WPML\\Core\\Twig\\Node\\Expression\\Binary\\NotInBinary' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/src/Node/Expression/Binary/NotInBinary.php',
|
141 |
+
'WPML\\Core\\Twig\\Node\\Expression\\Binary\\OrBinary' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/src/Node/Expression/Binary/OrBinary.php',
|
142 |
+
'WPML\\Core\\Twig\\Node\\Expression\\Binary\\PowerBinary' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/src/Node/Expression/Binary/PowerBinary.php',
|
143 |
+
'WPML\\Core\\Twig\\Node\\Expression\\Binary\\RangeBinary' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/src/Node/Expression/Binary/RangeBinary.php',
|
144 |
+
'WPML\\Core\\Twig\\Node\\Expression\\Binary\\StartsWithBinary' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/src/Node/Expression/Binary/StartsWithBinary.php',
|
145 |
+
'WPML\\Core\\Twig\\Node\\Expression\\Binary\\SubBinary' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/src/Node/Expression/Binary/SubBinary.php',
|
146 |
+
'WPML\\Core\\Twig\\Node\\Expression\\BlockReferenceExpression' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/src/Node/Expression/BlockReferenceExpression.php',
|
147 |
+
'WPML\\Core\\Twig\\Node\\Expression\\CallExpression' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/src/Node/Expression/CallExpression.php',
|
148 |
+
'WPML\\Core\\Twig\\Node\\Expression\\ConditionalExpression' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/src/Node/Expression/ConditionalExpression.php',
|
149 |
+
'WPML\\Core\\Twig\\Node\\Expression\\ConstantExpression' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/src/Node/Expression/ConstantExpression.php',
|
150 |
+
'WPML\\Core\\Twig\\Node\\Expression\\FilterExpression' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/src/Node/Expression/FilterExpression.php',
|
151 |
+
'WPML\\Core\\Twig\\Node\\Expression\\Filter\\DefaultFilter' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/src/Node/Expression/Filter/DefaultFilter.php',
|
152 |
+
'WPML\\Core\\Twig\\Node\\Expression\\FunctionExpression' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/src/Node/Expression/FunctionExpression.php',
|
153 |
+
'WPML\\Core\\Twig\\Node\\Expression\\GetAttrExpression' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/src/Node/Expression/GetAttrExpression.php',
|
154 |
+
'WPML\\Core\\Twig\\Node\\Expression\\InlinePrint' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/src/Node/Expression/InlinePrint.php',
|
155 |
+
'WPML\\Core\\Twig\\Node\\Expression\\MethodCallExpression' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/src/Node/Expression/MethodCallExpression.php',
|
156 |
+
'WPML\\Core\\Twig\\Node\\Expression\\NameExpression' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/src/Node/Expression/NameExpression.php',
|
157 |
+
'WPML\\Core\\Twig\\Node\\Expression\\NullCoalesceExpression' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/src/Node/Expression/NullCoalesceExpression.php',
|
158 |
+
'WPML\\Core\\Twig\\Node\\Expression\\ParentExpression' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/src/Node/Expression/ParentExpression.php',
|
159 |
+
'WPML\\Core\\Twig\\Node\\Expression\\TempNameExpression' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/src/Node/Expression/TempNameExpression.php',
|
160 |
+
'WPML\\Core\\Twig\\Node\\Expression\\TestExpression' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/src/Node/Expression/TestExpression.php',
|
161 |
+
'WPML\\Core\\Twig\\Node\\Expression\\Test\\ConstantTest' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/src/Node/Expression/Test/ConstantTest.php',
|
162 |
+
'WPML\\Core\\Twig\\Node\\Expression\\Test\\DefinedTest' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/src/Node/Expression/Test/DefinedTest.php',
|
163 |
+
'WPML\\Core\\Twig\\Node\\Expression\\Test\\DivisiblebyTest' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/src/Node/Expression/Test/DivisiblebyTest.php',
|
164 |
+
'WPML\\Core\\Twig\\Node\\Expression\\Test\\EvenTest' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/src/Node/Expression/Test/EvenTest.php',
|
165 |
+
'WPML\\Core\\Twig\\Node\\Expression\\Test\\NullTest' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/src/Node/Expression/Test/NullTest.php',
|
166 |
+
'WPML\\Core\\Twig\\Node\\Expression\\Test\\OddTest' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/src/Node/Expression/Test/OddTest.php',
|
167 |
+
'WPML\\Core\\Twig\\Node\\Expression\\Test\\SameasTest' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/src/Node/Expression/Test/SameasTest.php',
|
168 |
+
'WPML\\Core\\Twig\\Node\\Expression\\Unary\\AbstractUnary' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/src/Node/Expression/Unary/AbstractUnary.php',
|
169 |
+
'WPML\\Core\\Twig\\Node\\Expression\\Unary\\NegUnary' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/src/Node/Expression/Unary/NegUnary.php',
|
170 |
+
'WPML\\Core\\Twig\\Node\\Expression\\Unary\\NotUnary' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/src/Node/Expression/Unary/NotUnary.php',
|
171 |
+
'WPML\\Core\\Twig\\Node\\Expression\\Unary\\PosUnary' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/src/Node/Expression/Unary/PosUnary.php',
|
172 |
+
'WPML\\Core\\Twig\\Node\\FlushNode' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/src/Node/FlushNode.php',
|
173 |
+
'WPML\\Core\\Twig\\Node\\ForLoopNode' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/src/Node/ForLoopNode.php',
|
174 |
+
'WPML\\Core\\Twig\\Node\\ForNode' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/src/Node/ForNode.php',
|
175 |
+
'WPML\\Core\\Twig\\Node\\IfNode' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/src/Node/IfNode.php',
|
176 |
+
'WPML\\Core\\Twig\\Node\\ImportNode' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/src/Node/ImportNode.php',
|
177 |
+
'WPML\\Core\\Twig\\Node\\IncludeNode' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/src/Node/IncludeNode.php',
|
178 |
+
'WPML\\Core\\Twig\\Node\\MacroNode' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/src/Node/MacroNode.php',
|
179 |
+
'WPML\\Core\\Twig\\Node\\ModuleNode' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/src/Node/ModuleNode.php',
|
180 |
+
'WPML\\Core\\Twig\\Node\\Node' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/src/Node/Node.php',
|
181 |
+
'WPML\\Core\\Twig\\Node\\NodeCaptureInterface' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/src/Node/NodeCaptureInterface.php',
|
182 |
+
'WPML\\Core\\Twig\\Node\\NodeOutputInterface' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/src/Node/NodeOutputInterface.php',
|
183 |
+
'WPML\\Core\\Twig\\Node\\PrintNode' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/src/Node/PrintNode.php',
|
184 |
+
'WPML\\Core\\Twig\\Node\\SandboxNode' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/src/Node/SandboxNode.php',
|
185 |
+
'WPML\\Core\\Twig\\Node\\SandboxedPrintNode' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/src/Node/SandboxedPrintNode.php',
|
186 |
+
'WPML\\Core\\Twig\\Node\\SetNode' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/src/Node/SetNode.php',
|
187 |
+
'WPML\\Core\\Twig\\Node\\SetTempNode' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/src/Node/SetTempNode.php',
|
188 |
+
'WPML\\Core\\Twig\\Node\\SpacelessNode' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/src/Node/SpacelessNode.php',
|
189 |
+
'WPML\\Core\\Twig\\Node\\TextNode' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/src/Node/TextNode.php',
|
190 |
+
'WPML\\Core\\Twig\\Node\\WithNode' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/src/Node/WithNode.php',
|
191 |
+
'WPML\\Core\\Twig\\Parser' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/src/Parser.php',
|
192 |
+
'WPML\\Core\\Twig\\Profiler\\Dumper\\BaseDumper' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/src/Profiler/Dumper/BaseDumper.php',
|
193 |
+
'WPML\\Core\\Twig\\Profiler\\Dumper\\BlackfireDumper' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/src/Profiler/Dumper/BlackfireDumper.php',
|
194 |
+
'WPML\\Core\\Twig\\Profiler\\Dumper\\HtmlDumper' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/src/Profiler/Dumper/HtmlDumper.php',
|
195 |
+
'WPML\\Core\\Twig\\Profiler\\Dumper\\TextDumper' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/src/Profiler/Dumper/TextDumper.php',
|
196 |
+
'WPML\\Core\\Twig\\Profiler\\NodeVisitor\\ProfilerNodeVisitor' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/src/Profiler/NodeVisitor/ProfilerNodeVisitor.php',
|
197 |
+
'WPML\\Core\\Twig\\Profiler\\Node\\EnterProfileNode' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/src/Profiler/Node/EnterProfileNode.php',
|
198 |
+
'WPML\\Core\\Twig\\Profiler\\Node\\LeaveProfileNode' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/src/Profiler/Node/LeaveProfileNode.php',
|
199 |
+
'WPML\\Core\\Twig\\Profiler\\Profile' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/src/Profiler/Profile.php',
|
200 |
+
'WPML\\Core\\Twig\\RuntimeLoader\\ContainerRuntimeLoader' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/src/RuntimeLoader/ContainerRuntimeLoader.php',
|
201 |
+
'WPML\\Core\\Twig\\RuntimeLoader\\FactoryRuntimeLoader' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/src/RuntimeLoader/FactoryRuntimeLoader.php',
|
202 |
+
'WPML\\Core\\Twig\\RuntimeLoader\\RuntimeLoaderInterface' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/src/RuntimeLoader/RuntimeLoaderInterface.php',
|
203 |
+
'WPML\\Core\\Twig\\Sandbox\\SecurityError' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/src/Sandbox/SecurityError.php',
|
204 |
+
'WPML\\Core\\Twig\\Sandbox\\SecurityNotAllowedFilterError' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/src/Sandbox/SecurityNotAllowedFilterError.php',
|
205 |
+
'WPML\\Core\\Twig\\Sandbox\\SecurityNotAllowedFunctionError' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/src/Sandbox/SecurityNotAllowedFunctionError.php',
|
206 |
+
'WPML\\Core\\Twig\\Sandbox\\SecurityNotAllowedMethodError' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/src/Sandbox/SecurityNotAllowedMethodError.php',
|
207 |
+
'WPML\\Core\\Twig\\Sandbox\\SecurityNotAllowedPropertyError' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/src/Sandbox/SecurityNotAllowedPropertyError.php',
|
208 |
+
'WPML\\Core\\Twig\\Sandbox\\SecurityNotAllowedTagError' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/src/Sandbox/SecurityNotAllowedTagError.php',
|
209 |
+
'WPML\\Core\\Twig\\Sandbox\\SecurityPolicy' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/src/Sandbox/SecurityPolicy.php',
|
210 |
+
'WPML\\Core\\Twig\\Sandbox\\SecurityPolicyInterface' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/src/Sandbox/SecurityPolicyInterface.php',
|
211 |
+
'WPML\\Core\\Twig\\Source' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/src/Source.php',
|
212 |
+
'WPML\\Core\\Twig\\Template' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/src/Template.php',
|
213 |
+
'WPML\\Core\\Twig\\TemplateWrapper' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/src/TemplateWrapper.php',
|
214 |
+
'WPML\\Core\\Twig\\Test\\IntegrationTestCase' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/src/Test/IntegrationTestCase.php',
|
215 |
+
'WPML\\Core\\Twig\\Test\\NodeTestCase' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/src/Test/NodeTestCase.php',
|
216 |
+
'WPML\\Core\\Twig\\Token' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/src/Token.php',
|
217 |
+
'WPML\\Core\\Twig\\TokenParser\\AbstractTokenParser' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/src/TokenParser/AbstractTokenParser.php',
|
218 |
+
'WPML\\Core\\Twig\\TokenParser\\ApplyTokenParser' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/src/TokenParser/ApplyTokenParser.php',
|
219 |
+
'WPML\\Core\\Twig\\TokenParser\\AutoEscapeTokenParser' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/src/TokenParser/AutoEscapeTokenParser.php',
|
220 |
+
'WPML\\Core\\Twig\\TokenParser\\BlockTokenParser' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/src/TokenParser/BlockTokenParser.php',
|
221 |
+
'WPML\\Core\\Twig\\TokenParser\\DeprecatedTokenParser' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/src/TokenParser/DeprecatedTokenParser.php',
|
222 |
+
'WPML\\Core\\Twig\\TokenParser\\DoTokenParser' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/src/TokenParser/DoTokenParser.php',
|
223 |
+
'WPML\\Core\\Twig\\TokenParser\\EmbedTokenParser' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/src/TokenParser/EmbedTokenParser.php',
|
224 |
+
'WPML\\Core\\Twig\\TokenParser\\ExtendsTokenParser' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/src/TokenParser/ExtendsTokenParser.php',
|
225 |
+
'WPML\\Core\\Twig\\TokenParser\\FilterTokenParser' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/src/TokenParser/FilterTokenParser.php',
|
226 |
+
'WPML\\Core\\Twig\\TokenParser\\FlushTokenParser' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/src/TokenParser/FlushTokenParser.php',
|
227 |
+
'WPML\\Core\\Twig\\TokenParser\\ForTokenParser' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/src/TokenParser/ForTokenParser.php',
|
228 |
+
'WPML\\Core\\Twig\\TokenParser\\FromTokenParser' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/src/TokenParser/FromTokenParser.php',
|
229 |
+
'WPML\\Core\\Twig\\TokenParser\\IfTokenParser' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/src/TokenParser/IfTokenParser.php',
|
230 |
+
'WPML\\Core\\Twig\\TokenParser\\ImportTokenParser' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/src/TokenParser/ImportTokenParser.php',
|
231 |
+
'WPML\\Core\\Twig\\TokenParser\\IncludeTokenParser' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/src/TokenParser/IncludeTokenParser.php',
|
232 |
+
'WPML\\Core\\Twig\\TokenParser\\MacroTokenParser' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/src/TokenParser/MacroTokenParser.php',
|
233 |
+
'WPML\\Core\\Twig\\TokenParser\\SandboxTokenParser' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/src/TokenParser/SandboxTokenParser.php',
|
234 |
+
'WPML\\Core\\Twig\\TokenParser\\SetTokenParser' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/src/TokenParser/SetTokenParser.php',
|
235 |
+
'WPML\\Core\\Twig\\TokenParser\\SpacelessTokenParser' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/src/TokenParser/SpacelessTokenParser.php',
|
236 |
+
'WPML\\Core\\Twig\\TokenParser\\TokenParserInterface' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/src/TokenParser/TokenParserInterface.php',
|
237 |
+
'WPML\\Core\\Twig\\TokenParser\\UseTokenParser' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/src/TokenParser/UseTokenParser.php',
|
238 |
+
'WPML\\Core\\Twig\\TokenParser\\WithTokenParser' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/src/TokenParser/WithTokenParser.php',
|
239 |
+
'WPML\\Core\\Twig\\TokenStream' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/src/TokenStream.php',
|
240 |
+
'WPML\\Core\\Twig\\TwigFilter' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/src/TwigFilter.php',
|
241 |
+
'WPML\\Core\\Twig\\TwigFunction' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/src/TwigFunction.php',
|
242 |
+
'WPML\\Core\\Twig\\TwigTest' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/src/TwigTest.php',
|
243 |
+
'WPML\\Core\\Twig\\Util\\DeprecationCollector' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/src/Util/DeprecationCollector.php',
|
244 |
+
'WPML\\Core\\Twig\\Util\\TemplateDirIterator' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/src/Util/TemplateDirIterator.php',
|
245 |
+
'WPML\\Core\\Twig_Autoloader' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Autoloader.php',
|
246 |
+
'WPML\\Core\\Twig_BaseNodeVisitor' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/BaseNodeVisitor.php',
|
247 |
+
'WPML\\Core\\Twig_CacheInterface' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/CacheInterface.php',
|
248 |
+
'WPML\\Core\\Twig_Cache_Filesystem' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Cache/Filesystem.php',
|
249 |
+
'WPML\\Core\\Twig_Cache_Null' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Cache/Null.php',
|
250 |
+
'WPML\\Core\\Twig_Compiler' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Compiler.php',
|
251 |
+
'WPML\\Core\\Twig_CompilerInterface' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/CompilerInterface.php',
|
252 |
+
'WPML\\Core\\Twig_ContainerRuntimeLoader' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/ContainerRuntimeLoader.php',
|
253 |
+
'WPML\\Core\\Twig_Environment' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Environment.php',
|
254 |
+
'WPML\\Core\\Twig_Error' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Error.php',
|
255 |
+
'WPML\\Core\\Twig_Error_Loader' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Error/Loader.php',
|
256 |
+
'WPML\\Core\\Twig_Error_Runtime' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Error/Runtime.php',
|
257 |
+
'WPML\\Core\\Twig_Error_Syntax' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Error/Syntax.php',
|
258 |
+
'WPML\\Core\\Twig_ExistsLoaderInterface' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/ExistsLoaderInterface.php',
|
259 |
+
'WPML\\Core\\Twig_ExpressionParser' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/ExpressionParser.php',
|
260 |
+
'WPML\\Core\\Twig_Extension' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Extension.php',
|
261 |
+
'WPML\\Core\\Twig_ExtensionInterface' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/ExtensionInterface.php',
|
262 |
+
'WPML\\Core\\Twig_Extension_Core' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Extension/Core.php',
|
263 |
+
'WPML\\Core\\Twig_Extension_Debug' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Extension/Debug.php',
|
264 |
+
'WPML\\Core\\Twig_Extension_Escaper' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Extension/Escaper.php',
|
265 |
+
'WPML\\Core\\Twig_Extension_GlobalsInterface' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Extension/GlobalsInterface.php',
|
266 |
+
'WPML\\Core\\Twig_Extension_InitRuntimeInterface' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Extension/InitRuntimeInterface.php',
|
267 |
+
'WPML\\Core\\Twig_Extension_Optimizer' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Extension/Optimizer.php',
|
268 |
+
'WPML\\Core\\Twig_Extension_Profiler' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Extension/Profiler.php',
|
269 |
+
'WPML\\Core\\Twig_Extension_Sandbox' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Extension/Sandbox.php',
|
270 |
+
'WPML\\Core\\Twig_Extension_Staging' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Extension/Staging.php',
|
271 |
+
'WPML\\Core\\Twig_Extension_StringLoader' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Extension/StringLoader.php',
|
272 |
+
'WPML\\Core\\Twig_FactoryRuntimeLoader' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/FactoryRuntimeLoader.php',
|
273 |
+
'WPML\\Core\\Twig_FileExtensionEscapingStrategy' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/FileExtensionEscapingStrategy.php',
|
274 |
+
'WPML\\Core\\Twig_Filter' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Filter.php',
|
275 |
+
'WPML\\Core\\Twig_FilterCallableInterface' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/FilterCallableInterface.php',
|
276 |
+
'WPML\\Core\\Twig_FilterInterface' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/FilterInterface.php',
|
277 |
+
'WPML\\Core\\Twig_Filter_Function' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Filter/Function.php',
|
278 |
+
'WPML\\Core\\Twig_Filter_Method' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Filter/Method.php',
|
279 |
+
'WPML\\Core\\Twig_Filter_Node' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Filter/Node.php',
|
280 |
+
'WPML\\Core\\Twig_Function' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Function.php',
|
281 |
+
'WPML\\Core\\Twig_FunctionCallableInterface' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/FunctionCallableInterface.php',
|
282 |
+
'WPML\\Core\\Twig_FunctionInterface' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/FunctionInterface.php',
|
283 |
+
'WPML\\Core\\Twig_Function_Function' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Function/Function.php',
|
284 |
+
'WPML\\Core\\Twig_Function_Method' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Function/Method.php',
|
285 |
+
'WPML\\Core\\Twig_Function_Node' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Function/Node.php',
|
286 |
+
'WPML\\Core\\Twig_Lexer' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Lexer.php',
|
287 |
+
'WPML\\Core\\Twig_LexerInterface' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/LexerInterface.php',
|
288 |
+
'WPML\\Core\\Twig_LoaderInterface' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/LoaderInterface.php',
|
289 |
+
'WPML\\Core\\Twig_Loader_Array' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Loader/Array.php',
|
290 |
+
'WPML\\Core\\Twig_Loader_Chain' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Loader/Chain.php',
|
291 |
+
'WPML\\Core\\Twig_Loader_Filesystem' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Loader/Filesystem.php',
|
292 |
+
'WPML\\Core\\Twig_Loader_String' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Loader/String.php',
|
293 |
+
'WPML\\Core\\Twig_Markup' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Markup.php',
|
294 |
+
'WPML\\Core\\Twig_Node' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Node.php',
|
295 |
+
'WPML\\Core\\Twig_NodeCaptureInterface' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/NodeCaptureInterface.php',
|
296 |
+
'WPML\\Core\\Twig_NodeInterface' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/NodeInterface.php',
|
297 |
+
'WPML\\Core\\Twig_NodeOutputInterface' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/NodeOutputInterface.php',
|
298 |
+
'WPML\\Core\\Twig_NodeTraverser' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/NodeTraverser.php',
|
299 |
+
'WPML\\Core\\Twig_NodeVisitorInterface' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/NodeVisitorInterface.php',
|
300 |
+
'WPML\\Core\\Twig_NodeVisitor_Escaper' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/NodeVisitor/Escaper.php',
|
301 |
+
'WPML\\Core\\Twig_NodeVisitor_Optimizer' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/NodeVisitor/Optimizer.php',
|
302 |
+
'WPML\\Core\\Twig_NodeVisitor_SafeAnalysis' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/NodeVisitor/SafeAnalysis.php',
|
303 |
+
'WPML\\Core\\Twig_NodeVisitor_Sandbox' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/NodeVisitor/Sandbox.php',
|
304 |
+
'WPML\\Core\\Twig_Node_AutoEscape' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Node/AutoEscape.php',
|
305 |
+
'WPML\\Core\\Twig_Node_Block' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Node/Block.php',
|
306 |
+
'WPML\\Core\\Twig_Node_BlockReference' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Node/BlockReference.php',
|
307 |
+
'WPML\\Core\\Twig_Node_Body' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Node/Body.php',
|
308 |
+
'WPML\\Core\\Twig_Node_CheckSecurity' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Node/CheckSecurity.php',
|
309 |
+
'WPML\\Core\\Twig_Node_Deprecated' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Node/Deprecated.php',
|
310 |
+
'WPML\\Core\\Twig_Node_Do' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Node/Do.php',
|
311 |
+
'WPML\\Core\\Twig_Node_Embed' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Node/Embed.php',
|
312 |
+
'WPML\\Core\\Twig_Node_Expression' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Node/Expression.php',
|
313 |
+
'WPML\\Core\\Twig_Node_Expression_Array' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Node/Expression/Array.php',
|
314 |
+
'WPML\\Core\\Twig_Node_Expression_AssignName' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Node/Expression/AssignName.php',
|
315 |
+
'WPML\\Core\\Twig_Node_Expression_Binary' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Node/Expression/Binary.php',
|
316 |
+
'WPML\\Core\\Twig_Node_Expression_Binary_Add' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Node/Expression/Binary/Add.php',
|
317 |
+
'WPML\\Core\\Twig_Node_Expression_Binary_And' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Node/Expression/Binary/And.php',
|
318 |
+
'WPML\\Core\\Twig_Node_Expression_Binary_BitwiseAnd' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Node/Expression/Binary/BitwiseAnd.php',
|
319 |
+
'WPML\\Core\\Twig_Node_Expression_Binary_BitwiseOr' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Node/Expression/Binary/BitwiseOr.php',
|
320 |
+
'WPML\\Core\\Twig_Node_Expression_Binary_BitwiseXor' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Node/Expression/Binary/BitwiseXor.php',
|
321 |
+
'WPML\\Core\\Twig_Node_Expression_Binary_Concat' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Node/Expression/Binary/Concat.php',
|
322 |
+
'WPML\\Core\\Twig_Node_Expression_Binary_Div' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Node/Expression/Binary/Div.php',
|
323 |
+
'WPML\\Core\\Twig_Node_Expression_Binary_EndsWith' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Node/Expression/Binary/EndsWith.php',
|
324 |
+
'WPML\\Core\\Twig_Node_Expression_Binary_Equal' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Node/Expression/Binary/Equal.php',
|
325 |
+
'WPML\\Core\\Twig_Node_Expression_Binary_FloorDiv' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Node/Expression/Binary/FloorDiv.php',
|
326 |
+
'WPML\\Core\\Twig_Node_Expression_Binary_Greater' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Node/Expression/Binary/Greater.php',
|
327 |
+
'WPML\\Core\\Twig_Node_Expression_Binary_GreaterEqual' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Node/Expression/Binary/GreaterEqual.php',
|
328 |
+
'WPML\\Core\\Twig_Node_Expression_Binary_In' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Node/Expression/Binary/In.php',
|
329 |
+
'WPML\\Core\\Twig_Node_Expression_Binary_Less' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Node/Expression/Binary/Less.php',
|
330 |
+
'WPML\\Core\\Twig_Node_Expression_Binary_LessEqual' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Node/Expression/Binary/LessEqual.php',
|
331 |
+
'WPML\\Core\\Twig_Node_Expression_Binary_Matches' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Node/Expression/Binary/Matches.php',
|
332 |
+
'WPML\\Core\\Twig_Node_Expression_Binary_Mod' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Node/Expression/Binary/Mod.php',
|
333 |
+
'WPML\\Core\\Twig_Node_Expression_Binary_Mul' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Node/Expression/Binary/Mul.php',
|
334 |
+
'WPML\\Core\\Twig_Node_Expression_Binary_NotEqual' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Node/Expression/Binary/NotEqual.php',
|
335 |
+
'WPML\\Core\\Twig_Node_Expression_Binary_NotIn' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Node/Expression/Binary/NotIn.php',
|
336 |
+
'WPML\\Core\\Twig_Node_Expression_Binary_Or' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Node/Expression/Binary/Or.php',
|
337 |
+
'WPML\\Core\\Twig_Node_Expression_Binary_Power' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Node/Expression/Binary/Power.php',
|
338 |
+
'WPML\\Core\\Twig_Node_Expression_Binary_Range' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Node/Expression/Binary/Range.php',
|
339 |
+
'WPML\\Core\\Twig_Node_Expression_Binary_StartsWith' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Node/Expression/Binary/StartsWith.php',
|
340 |
+
'WPML\\Core\\Twig_Node_Expression_Binary_Sub' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Node/Expression/Binary/Sub.php',
|
341 |
+
'WPML\\Core\\Twig_Node_Expression_BlockReference' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Node/Expression/BlockReference.php',
|
342 |
+
'WPML\\Core\\Twig_Node_Expression_Call' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Node/Expression/Call.php',
|
343 |
+
'WPML\\Core\\Twig_Node_Expression_Conditional' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Node/Expression/Conditional.php',
|
344 |
+
'WPML\\Core\\Twig_Node_Expression_Constant' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Node/Expression/Constant.php',
|
345 |
+
'WPML\\Core\\Twig_Node_Expression_ExtensionReference' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Node/Expression/ExtensionReference.php',
|
346 |
+
'WPML\\Core\\Twig_Node_Expression_Filter' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Node/Expression/Filter.php',
|
347 |
+
'WPML\\Core\\Twig_Node_Expression_Filter_Default' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Node/Expression/Filter/Default.php',
|
348 |
+
'WPML\\Core\\Twig_Node_Expression_Function' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Node/Expression/Function.php',
|
349 |
+
'WPML\\Core\\Twig_Node_Expression_GetAttr' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Node/Expression/GetAttr.php',
|
350 |
+
'WPML\\Core\\Twig_Node_Expression_MethodCall' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Node/Expression/MethodCall.php',
|
351 |
+
'WPML\\Core\\Twig_Node_Expression_Name' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Node/Expression/Name.php',
|
352 |
+
'WPML\\Core\\Twig_Node_Expression_NullCoalesce' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Node/Expression/NullCoalesce.php',
|
353 |
+
'WPML\\Core\\Twig_Node_Expression_Parent' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Node/Expression/Parent.php',
|
354 |
+
'WPML\\Core\\Twig_Node_Expression_TempName' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Node/Expression/TempName.php',
|
355 |
+
'WPML\\Core\\Twig_Node_Expression_Test' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Node/Expression/Test.php',
|
356 |
+
'WPML\\Core\\Twig_Node_Expression_Test_Constant' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Node/Expression/Test/Constant.php',
|
357 |
+
'WPML\\Core\\Twig_Node_Expression_Test_Defined' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Node/Expression/Test/Defined.php',
|
358 |
+
'WPML\\Core\\Twig_Node_Expression_Test_Divisibleby' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Node/Expression/Test/Divisibleby.php',
|
359 |
+
'WPML\\Core\\Twig_Node_Expression_Test_Even' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Node/Expression/Test/Even.php',
|
360 |
+
'WPML\\Core\\Twig_Node_Expression_Test_Null' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Node/Expression/Test/Null.php',
|
361 |
+
'WPML\\Core\\Twig_Node_Expression_Test_Odd' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Node/Expression/Test/Odd.php',
|
362 |
+
'WPML\\Core\\Twig_Node_Expression_Test_Sameas' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Node/Expression/Test/Sameas.php',
|
363 |
+
'WPML\\Core\\Twig_Node_Expression_Unary' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Node/Expression/Unary.php',
|
364 |
+
'WPML\\Core\\Twig_Node_Expression_Unary_Neg' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Node/Expression/Unary/Neg.php',
|
365 |
+
'WPML\\Core\\Twig_Node_Expression_Unary_Not' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Node/Expression/Unary/Not.php',
|
366 |
+
'WPML\\Core\\Twig_Node_Expression_Unary_Pos' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Node/Expression/Unary/Pos.php',
|
367 |
+
'WPML\\Core\\Twig_Node_Flush' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Node/Flush.php',
|
368 |
+
'WPML\\Core\\Twig_Node_For' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Node/For.php',
|
369 |
+
'WPML\\Core\\Twig_Node_ForLoop' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Node/ForLoop.php',
|
370 |
+
'WPML\\Core\\Twig_Node_If' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Node/If.php',
|
371 |
+
'WPML\\Core\\Twig_Node_Import' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Node/Import.php',
|
372 |
+
'WPML\\Core\\Twig_Node_Include' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Node/Include.php',
|
373 |
+
'WPML\\Core\\Twig_Node_Macro' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Node/Macro.php',
|
374 |
+
'WPML\\Core\\Twig_Node_Module' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Node/Module.php',
|
375 |
+
'WPML\\Core\\Twig_Node_Print' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Node/Print.php',
|
376 |
+
'WPML\\Core\\Twig_Node_Sandbox' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Node/Sandbox.php',
|
377 |
+
'WPML\\Core\\Twig_Node_SandboxedPrint' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Node/SandboxedPrint.php',
|
378 |
+
'WPML\\Core\\Twig_Node_Set' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Node/Set.php',
|
379 |
+
'WPML\\Core\\Twig_Node_SetTemp' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Node/SetTemp.php',
|
380 |
+
'WPML\\Core\\Twig_Node_Spaceless' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Node/Spaceless.php',
|
381 |
+
'WPML\\Core\\Twig_Node_Text' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Node/Text.php',
|
382 |
+
'WPML\\Core\\Twig_Node_With' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Node/With.php',
|
383 |
+
'WPML\\Core\\Twig_Parser' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Parser.php',
|
384 |
+
'WPML\\Core\\Twig_ParserInterface' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/ParserInterface.php',
|
385 |
+
'WPML\\Core\\Twig_Profiler_Dumper_Base' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Profiler/Dumper/Base.php',
|
386 |
+
'WPML\\Core\\Twig_Profiler_Dumper_Blackfire' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Profiler/Dumper/Blackfire.php',
|
387 |
+
'WPML\\Core\\Twig_Profiler_Dumper_Html' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Profiler/Dumper/Html.php',
|
388 |
+
'WPML\\Core\\Twig_Profiler_Dumper_Text' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Profiler/Dumper/Text.php',
|
389 |
+
'WPML\\Core\\Twig_Profiler_NodeVisitor_Profiler' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Profiler/NodeVisitor/Profiler.php',
|
390 |
+
'WPML\\Core\\Twig_Profiler_Node_EnterProfile' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Profiler/Node/EnterProfile.php',
|
391 |
+
'WPML\\Core\\Twig_Profiler_Node_LeaveProfile' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Profiler/Node/LeaveProfile.php',
|
392 |
+
'WPML\\Core\\Twig_Profiler_Profile' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Profiler/Profile.php',
|
393 |
+
'WPML\\Core\\Twig_RuntimeLoaderInterface' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/RuntimeLoaderInterface.php',
|
394 |
+
'WPML\\Core\\Twig_Sandbox_SecurityError' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Sandbox/SecurityError.php',
|
395 |
+
'WPML\\Core\\Twig_Sandbox_SecurityNotAllowedFilterError' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Sandbox/SecurityNotAllowedFilterError.php',
|
396 |
+
'WPML\\Core\\Twig_Sandbox_SecurityNotAllowedFunctionError' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Sandbox/SecurityNotAllowedFunctionError.php',
|
397 |
+
'WPML\\Core\\Twig_Sandbox_SecurityNotAllowedMethodError' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Sandbox/SecurityNotAllowedMethodError.php',
|
398 |
+
'WPML\\Core\\Twig_Sandbox_SecurityNotAllowedPropertyError' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Sandbox/SecurityNotAllowedPropertyError.php',
|
399 |
+
'WPML\\Core\\Twig_Sandbox_SecurityNotAllowedTagError' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Sandbox/SecurityNotAllowedTagError.php',
|
400 |
+
'WPML\\Core\\Twig_Sandbox_SecurityPolicy' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Sandbox/SecurityPolicy.php',
|
401 |
+
'WPML\\Core\\Twig_Sandbox_SecurityPolicyInterface' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Sandbox/SecurityPolicyInterface.php',
|
402 |
+
'WPML\\Core\\Twig_SimpleFilter' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/SimpleFilter.php',
|
403 |
+
'WPML\\Core\\Twig_SimpleFunction' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/SimpleFunction.php',
|
404 |
+
'WPML\\Core\\Twig_SimpleTest' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/SimpleTest.php',
|
405 |
+
'WPML\\Core\\Twig_Source' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Source.php',
|
406 |
+
'WPML\\Core\\Twig_SourceContextLoaderInterface' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/SourceContextLoaderInterface.php',
|
407 |
+
'WPML\\Core\\Twig_Template' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Template.php',
|
408 |
+
'WPML\\Core\\Twig_TemplateInterface' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/TemplateInterface.php',
|
409 |
+
'WPML\\Core\\Twig_TemplateWrapper' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/TemplateWrapper.php',
|
410 |
+
'WPML\\Core\\Twig_Test' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Test.php',
|
411 |
+
'WPML\\Core\\Twig_TestCallableInterface' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/TestCallableInterface.php',
|
412 |
+
'WPML\\Core\\Twig_TestInterface' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/TestInterface.php',
|
413 |
+
'WPML\\Core\\Twig_Test_Function' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Test/Function.php',
|
414 |
+
'WPML\\Core\\Twig_Test_IntegrationTestCase' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Test/IntegrationTestCase.php',
|
415 |
+
'WPML\\Core\\Twig_Test_Method' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Test/Method.php',
|
416 |
+
'WPML\\Core\\Twig_Test_Node' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Test/Node.php',
|
417 |
+
'WPML\\Core\\Twig_Test_NodeTestCase' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Test/NodeTestCase.php',
|
418 |
+
'WPML\\Core\\Twig_Token' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Token.php',
|
419 |
+
'WPML\\Core\\Twig_TokenParser' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/TokenParser.php',
|
420 |
+
'WPML\\Core\\Twig_TokenParserBroker' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/TokenParserBroker.php',
|
421 |
+
'WPML\\Core\\Twig_TokenParserBrokerInterface' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/TokenParserBrokerInterface.php',
|
422 |
+
'WPML\\Core\\Twig_TokenParserInterface' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/TokenParserInterface.php',
|
423 |
+
'WPML\\Core\\Twig_TokenParser_AutoEscape' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/TokenParser/AutoEscape.php',
|
424 |
+
'WPML\\Core\\Twig_TokenParser_Block' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/TokenParser/Block.php',
|
425 |
+
'WPML\\Core\\Twig_TokenParser_Deprecated' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/TokenParser/Deprecated.php',
|
426 |
+
'WPML\\Core\\Twig_TokenParser_Do' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/TokenParser/Do.php',
|
427 |
+
'WPML\\Core\\Twig_TokenParser_Embed' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/TokenParser/Embed.php',
|
428 |
+
'WPML\\Core\\Twig_TokenParser_Extends' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/TokenParser/Extends.php',
|
429 |
+
'WPML\\Core\\Twig_TokenParser_Filter' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/TokenParser/Filter.php',
|
430 |
+
'WPML\\Core\\Twig_TokenParser_Flush' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/TokenParser/Flush.php',
|
431 |
+
'WPML\\Core\\Twig_TokenParser_For' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/TokenParser/For.php',
|
432 |
+
'WPML\\Core\\Twig_TokenParser_From' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/TokenParser/From.php',
|
433 |
+
'WPML\\Core\\Twig_TokenParser_If' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/TokenParser/If.php',
|
434 |
+
'WPML\\Core\\Twig_TokenParser_Import' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/TokenParser/Import.php',
|
435 |
+
'WPML\\Core\\Twig_TokenParser_Include' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/TokenParser/Include.php',
|
436 |
+
'WPML\\Core\\Twig_TokenParser_Macro' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/TokenParser/Macro.php',
|
437 |
+
'WPML\\Core\\Twig_TokenParser_Sandbox' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/TokenParser/Sandbox.php',
|
438 |
+
'WPML\\Core\\Twig_TokenParser_Set' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/TokenParser/Set.php',
|
439 |
+
'WPML\\Core\\Twig_TokenParser_Spaceless' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/TokenParser/Spaceless.php',
|
440 |
+
'WPML\\Core\\Twig_TokenParser_Use' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/TokenParser/Use.php',
|
441 |
+
'WPML\\Core\\Twig_TokenParser_With' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/TokenParser/With.php',
|
442 |
+
'WPML\\Core\\Twig_TokenStream' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/TokenStream.php',
|
443 |
+
'WPML\\Core\\Twig_Util_DeprecationCollector' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Util/DeprecationCollector.php',
|
444 |
+
'WPML\\Core\\Twig_Util_TemplateDirIterator' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/lib/twig/lib/Twig/Util/TemplateDirIterator.php',
|
445 |
+
'WPML\\DocPage' => __DIR__ . '/..' . '/wpml/core-api/core/DocPage.php',
|
446 |
+
'WPML\\Element\\API\\Entity\\LanguageMapping' => __DIR__ . '/..' . '/wpml/core-api/core/Entity/LanguageMapping.php',
|
447 |
+
'WPML\\Element\\API\\IfOriginalPost' => __DIR__ . '/..' . '/wpml/core-api/core/IfOriginalPost.php',
|
448 |
+
'WPML\\Element\\API\\Languages' => __DIR__ . '/..' . '/wpml/core-api/core/Languages.php',
|
449 |
+
'WPML\\Element\\API\\Post' => __DIR__ . '/..' . '/wpml/core-api/core/Post.php',
|
450 |
+
'WPML\\Element\\API\\PostTranslations' => __DIR__ . '/..' . '/wpml/core-api/core/PostTranslations.php',
|
451 |
+
'WPML\\Element\\API\\Translations' => __DIR__ . '/..' . '/wpml/core-api/core/Translations.php',
|
452 |
+
'WPML\\Element\\API\\TranslationsRepository' => __DIR__ . '/..' . '/wpml/core-api/core/TranslationsRepository.php',
|
453 |
+
'WPML\\FP\\Applicative' => __DIR__ . '/..' . '/wpml/fp/core/Functor/Applicative.php',
|
454 |
+
'WPML\\FP\\Cast' => __DIR__ . '/..' . '/wpml/fp/core/Cast.php',
|
455 |
+
'WPML\\FP\\ConstApplicative' => __DIR__ . '/..' . '/wpml/fp/core/Functor/ConstApplicative.php',
|
456 |
+
'WPML\\FP\\Curryable' => __DIR__ . '/..' . '/wpml/fp/core/traits/Curryable.php',
|
457 |
+
'WPML\\FP\\Debug' => __DIR__ . '/..' . '/wpml/fp/core/Debug.php',
|
458 |
+
'WPML\\FP\\Either' => __DIR__ . '/..' . '/wpml/fp/core/Either.php',
|
459 |
+
'WPML\\FP\\FP' => __DIR__ . '/..' . '/wpml/fp/core/FP.php',
|
460 |
+
'WPML\\FP\\Fns' => __DIR__ . '/..' . '/wpml/fp/core/Fns.php',
|
461 |
+
'WPML\\FP\\Functor\\ConstFunctor' => __DIR__ . '/..' . '/wpml/fp/core/Functor/ConstFunctor.php',
|
462 |
+
'WPML\\FP\\Functor\\Functor' => __DIR__ . '/..' . '/wpml/fp/core/Functor/Functor.php',
|
463 |
+
'WPML\\FP\\Functor\\IdentityFunctor' => __DIR__ . '/..' . '/wpml/fp/core/Functor/IdentityFunctor.php',
|
464 |
+
'WPML\\FP\\Functor\\Pointed' => __DIR__ . '/..' . '/wpml/fp/core/Functor/Pointed.php',
|
465 |
+
'WPML\\FP\\Json' => __DIR__ . '/..' . '/wpml/fp/core/Json.php',
|
466 |
+
'WPML\\FP\\Just' => __DIR__ . '/..' . '/wpml/fp/core/Maybe.php',
|
467 |
+
'WPML\\FP\\Left' => __DIR__ . '/..' . '/wpml/fp/core/Either.php',
|
468 |
+
'WPML\\FP\\Logic' => __DIR__ . '/..' . '/wpml/fp/core/Logic.php',
|
469 |
+
'WPML\\FP\\Lst' => __DIR__ . '/..' . '/wpml/fp/core/Lst.php',
|
470 |
+
'WPML\\FP\\Math' => __DIR__ . '/..' . '/wpml/fp/core/Math.php',
|
471 |
+
'WPML\\FP\\Maybe' => __DIR__ . '/..' . '/wpml/fp/core/Maybe.php',
|
472 |
+
'WPML\\FP\\Nothing' => __DIR__ . '/..' . '/wpml/fp/core/Maybe.php',
|
473 |
+
'WPML\\FP\\Obj' => __DIR__ . '/..' . '/wpml/fp/core/Obj.php',
|
474 |
+
'WPML\\FP\\Promise' => __DIR__ . '/..' . '/wpml/fp/core/Promise.php',
|
475 |
+
'WPML\\FP\\Relation' => __DIR__ . '/..' . '/wpml/fp/core/Relation.php',
|
476 |
+
'WPML\\FP\\Right' => __DIR__ . '/..' . '/wpml/fp/core/Either.php',
|
477 |
+
'WPML\\FP\\Str' => __DIR__ . '/..' . '/wpml/fp/core/Strings.php',
|
478 |
+
'WPML\\FP\\System\\System' => __DIR__ . '/..' . '/wpml/fp/core/SystemClass.php',
|
479 |
+
'WPML\\FP\\System\\_Filter' => __DIR__ . '/..' . '/wpml/fp/core/Filter.php',
|
480 |
+
'WPML\\FP\\System\\_Validator' => __DIR__ . '/..' . '/wpml/fp/core/Validator.php',
|
481 |
+
'WPML\\FP\\Undefined' => __DIR__ . '/..' . '/wpml/fp/core/Undefined.php',
|
482 |
+
'WPML\\FP\\Wrapper' => __DIR__ . '/..' . '/wpml/fp/core/Wrapper.php',
|
483 |
+
'WPML\\FP\\_Invoker' => __DIR__ . '/..' . '/wpml/fp/core/Invoker.php',
|
484 |
+
'WPML\\LIB\\WP\\App\\Resources' => __DIR__ . '/..' . '/wpml/wp/classes/Resources.php',
|
485 |
+
'WPML\\LIB\\WP\\Attachment' => __DIR__ . '/..' . '/wpml/wp/classes/Attachment.php',
|
486 |
+
'WPML\\LIB\\WP\\Cache' => __DIR__ . '/..' . '/wpml/wp/classes/Cache.php',
|
487 |
+
'WPML\\LIB\\WP\\Gutenberg' => __DIR__ . '/..' . '/wpml/wp/classes/Gutenberg.php',
|
488 |
+
'WPML\\LIB\\WP\\Hooks' => __DIR__ . '/..' . '/wpml/wp/classes/Hooks.php',
|
489 |
+
'WPML\\LIB\\WP\\Http' => __DIR__ . '/..' . '/wpml/wp/classes/Http.php',
|
490 |
+
'WPML\\LIB\\WP\\Nonce' => __DIR__ . '/..' . '/wpml/wp/classes/Nonce.php',
|
491 |
+
'WPML\\LIB\\WP\\Option' => __DIR__ . '/..' . '/wpml/wp/classes/Option.php',
|
492 |
+
'WPML\\LIB\\WP\\Post' => __DIR__ . '/..' . '/wpml/wp/classes/Post.php',
|
493 |
+
'WPML\\LIB\\WP\\PostType' => __DIR__ . '/..' . '/wpml/wp/classes/PostType.php',
|
494 |
+
'WPML\\LIB\\WP\\Roles' => __DIR__ . '/..' . '/wpml/wp/classes/Roles.php',
|
495 |
+
'WPML\\LIB\\WP\\Transient' => __DIR__ . '/..' . '/wpml/wp/classes/Transient.php',
|
496 |
+
'WPML\\LIB\\WP\\User' => __DIR__ . '/..' . '/wpml/wp/classes/User.php',
|
497 |
+
'WPML\\LIB\\WP\\WPDB' => __DIR__ . '/..' . '/wpml/wp/classes/WPDB.php',
|
498 |
+
'WPML\\LIB\\WP\\WordPress' => __DIR__ . '/..' . '/wpml/wp/classes/WP.php',
|
499 |
+
'WPML\\Media\\Option' => __DIR__ . '/..' . '/wpml/core-api/core/media/Option.php',
|
500 |
+
'WPML\\Notices\\DismissNotices' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/classes/notices/DismissNotices.php',
|
501 |
+
'WPML\\Records\\Translations' => __DIR__ . '/..' . '/wpml/core-api/core/Records/Translations.php',
|
502 |
+
'WPML\\Settings\\PostType\\Automatic' => __DIR__ . '/..' . '/wpml/core-api/core/settings/Automatic.php',
|
503 |
+
'WPML\\Setup\\Option' => __DIR__ . '/..' . '/wpml/core-api/core/setup/Option.php',
|
504 |
+
'WPML\\Timer' => __DIR__ . '/..' . '/wpml/core-api/core/Timer.php',
|
505 |
+
'WPML\\UIPage' => __DIR__ . '/..' . '/wpml/core-api/core/UIPage.php',
|
506 |
+
'WPML\\Utilities\\ILock' => __DIR__ . '/..' . '/wpml/core-api/core/utility/ILock.php',
|
507 |
+
'WPML\\Utilities\\Lock' => __DIR__ . '/..' . '/wpml/core-api/core/utility/Lock.php',
|
508 |
+
'WPML\\WP\\OptionManager' => __DIR__ . '/..' . '/wpml/core-api/core/OptionManager.php',
|
509 |
+
'WPML_AJAX_Action_Validation' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/classes/action-filter-loader/class-wpml-ajax-action-validation.php',
|
510 |
+
'WPML_AJAX_Base_Factory' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/classes/action-filter-loader/class-wpml-ajax-action-base-factory.php',
|
511 |
+
'WPML_Action_Filter_Loader' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/classes/action-filter-loader/class-wpml-action-filter-loader.php',
|
512 |
+
'WPML_Block_Editor_Helper' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/classes/block-editor/class-wpml-block-editor-helper.php',
|
513 |
+
'WPML_Cookie' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/classes/cookie/class-wpml-cookie.php',
|
514 |
+
'WPML_Core_Privacy_Content' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/classes/privacy/class-wpml-core-privacy-content.php',
|
515 |
+
'WPML_Current_Screen_Loader_Factory' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/classes/action-filter-loader/class-wpml-current-screen-loader-factory.php',
|
516 |
+
'WPML_File' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/classes/class-wpml-file.php',
|
517 |
+
'WPML_Notice' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/classes/notices/class-wpml-notice.php',
|
518 |
+
'WPML_Notice_Action' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/classes/notices/class-wpml-notice-action.php',
|
519 |
+
'WPML_Notice_Render' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/classes/notices/class-wpml-notice-render.php',
|
520 |
+
'WPML_Notice_Show_On_Dashboard_And_WPML_Pages' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/classes/notices/pages/class-wpml-notice-show-on-dashboard-and-wpml-pages.php',
|
521 |
+
'WPML_Notices' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/classes/notices/class-wpml-notices.php',
|
522 |
+
'WPML_PHP_Functions' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/classes/wpml-wp/wpml-php-functions.php',
|
523 |
+
'WPML_Privacy_Content' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/classes/privacy/class-wpml-privacy-content.php',
|
524 |
+
'WPML_Privacy_Content_Factory' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/classes/privacy/class-wpml-privacy-content-factory.php',
|
525 |
+
'WPML_Templates_Factory' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/classes/templating/class-wpml-templates-factory.php',
|
526 |
+
'WPML_Twig_Template' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/classes/templates/class-wpml-twig-template.php',
|
527 |
+
'WPML_Twig_Template_Loader' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/classes/templates/wpml-twig-template-loader.php',
|
528 |
+
'WPML_Twig_WP_Plugin_Extension' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/classes/twig-extensions/wpml-twig-wp-plugin-extension.php',
|
529 |
+
'WPML_WP_API' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/classes/wpml-wp/class-wpml-wp-api.php',
|
530 |
+
'WPML_WP_Cache' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/classes/utilities/class-wpml-wp-cache.php',
|
531 |
+
'WPML_WP_Post_Type' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/classes/wpml-wp/wpml-wp-post-type.php',
|
532 |
+
'WPML_WP_Roles' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/classes/wpml-wp/class-wpml-wp-roles.php',
|
533 |
+
'WPML_WP_Taxonomy' => __DIR__ . '/..' . '/wpml/wpml-dependencies/lib/classes/wpml-wp/class-wpml-wp-taxonomy.php',
|
534 |
+
);
|
535 |
+
|
536 |
+
public static function getInitializer(ClassLoader $loader)
|
537 |
+
{
|
538 |
+
return \Closure::bind(function () use ($loader) {
|
539 |
+
$loader->prefixLengthsPsr4 = ComposerStaticInit4821ed1a7ed1caf1298338b695908544::$prefixLengthsPsr4;
|
540 |
+
$loader->prefixDirsPsr4 = ComposerStaticInit4821ed1a7ed1caf1298338b695908544::$prefixDirsPsr4;
|
541 |
+
$loader->classMap = ComposerStaticInit4821ed1a7ed1caf1298338b695908544::$classMap;
|
542 |
+
|
543 |
+
}, null, ClassLoader::class);
|
544 |
+
}
|
545 |
+
}
|
addons/vendor/composer/installed.json
ADDED
@@ -0,0 +1,799 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
[
|
2 |
+
{
|
3 |
+
"name": "otgs/auryn",
|
4 |
+
"version": "dev-master",
|
5 |
+
"version_normalized": "9999999-dev",
|
6 |
+
"source": {
|
7 |
+
"type": "git",
|
8 |
+
"url": "https://github.com/OnTheGoSystems/auryn.git",
|
9 |
+
"reference": "82dca7f4674d5a283947620892597c1f4325bb76"
|
10 |
+
},
|
11 |
+
"dist": {
|
12 |
+
"type": "zip",
|
13 |
+
"url": "https://api.github.com/repos/OnTheGoSystems/auryn/zipball/82dca7f4674d5a283947620892597c1f4325bb76",
|
14 |
+
"reference": "82dca7f4674d5a283947620892597c1f4325bb76",
|
15 |
+
"shasum": ""
|
16 |
+
},
|
17 |
+
"require": {
|
18 |
+
"php": ">=5.3.0"
|
19 |
+
},
|
20 |
+
"require-dev": {
|
21 |
+
"athletic/athletic": "~0.1",
|
22 |
+
"fabpot/php-cs-fixer": "~1.9",
|
23 |
+
"phpunit/phpunit": "^4.8"
|
24 |
+
},
|
25 |
+
"time": "2020-10-29T12:28:42+00:00",
|
26 |
+
"type": "library",
|
27 |
+
"installation-source": "dist",
|
28 |
+
"autoload": {
|
29 |
+
"psr-4": {
|
30 |
+
"WPML\\Auryn\\": "lib/"
|
31 |
+
}
|
32 |
+
},
|
33 |
+
"notification-url": "https://packagist.org/downloads/",
|
34 |
+
"license": [
|
35 |
+
"MIT"
|
36 |
+
],
|
37 |
+
"authors": [
|
38 |
+
{
|
39 |
+
"name": "Daniel Lowrey",
|
40 |
+
"email": "rdlowrey@gmail.com",
|
41 |
+
"homepage": "https://github.com/rdlowrey",
|
42 |
+
"role": "Creator / Main Developer"
|
43 |
+
},
|
44 |
+
{
|
45 |
+
"name": "Levi Morrison",
|
46 |
+
"email": "levim@php.net",
|
47 |
+
"homepage": "http://morrisonlevi.github.com/",
|
48 |
+
"role": "Developer"
|
49 |
+
},
|
50 |
+
{
|
51 |
+
"name": "Dan Ackroyd",
|
52 |
+
"email": "Danack@basereality.com",
|
53 |
+
"homepage": "http://www.basereality.com",
|
54 |
+
"role": "Developer"
|
55 |
+
}
|
56 |
+
],
|
57 |
+
"description": "Auryn is a dependency injector for bootstrapping object-oriented PHP applications.",
|
58 |
+
"homepage": "https://github.com/rdlowrey/auryn",
|
59 |
+
"keywords": [
|
60 |
+
"dependency injection",
|
61 |
+
"dic",
|
62 |
+
"ioc"
|
63 |
+
],
|
64 |
+
"support": {
|
65 |
+
"source": "https://github.com/OnTheGoSystems/auryn/tree/master"
|
66 |
+
}
|
67 |
+
},
|
68 |
+
{
|
69 |
+
"name": "otgs/icons",
|
70 |
+
"version": "1.0.2",
|
71 |
+
"version_normalized": "1.0.2.0",
|
72 |
+
"source": {
|
73 |
+
"type": "git",
|
74 |
+
"url": "https://git.onthegosystems.com/otgs-public/otgs-icons.git",
|
75 |
+
"reference": "4dbce75c1ba493c7d4d2c86f318d2ad10fa4f24b"
|
76 |
+
},
|
77 |
+
"time": "2020-03-20T16:45:00+00:00",
|
78 |
+
"type": "library",
|
79 |
+
"installation-source": "source",
|
80 |
+
"notification-url": "https://packagist.org/downloads/",
|
81 |
+
"license": [
|
82 |
+
"GPL-2.0"
|
83 |
+
],
|
84 |
+
"description": "Toolset and WPML icons"
|
85 |
+
},
|
86 |
+
{
|
87 |
+
"name": "otgs/ui",
|
88 |
+
"version": "dev-master",
|
89 |
+
"version_normalized": "9999999-dev",
|
90 |
+
"source": {
|
91 |
+
"type": "git",
|
92 |
+
"url": "https://git.onthegosystems.com/otgs-public/otgs-ui.git",
|
93 |
+
"reference": "d8b11b073ba3247f25108b0dd88742ca3b0d4628"
|
94 |
+
},
|
95 |
+
"require": {
|
96 |
+
"roave/security-advisories": "dev-master"
|
97 |
+
},
|
98 |
+
"require-dev": {
|
99 |
+
"dealerdirect/phpcodesniffer-composer-installer": "*",
|
100 |
+
"otgs/unit-tests-framework": "~1.2.0",
|
101 |
+
"phpcompatibility/php-compatibility": "*",
|
102 |
+
"phpunit/phpunit": "~5.7",
|
103 |
+
"sebastian/phpcpd": "^3.0",
|
104 |
+
"squizlabs/php_codesniffer": "~3",
|
105 |
+
"wp-coding-standards/wpcs": "^0"
|
106 |
+
},
|
107 |
+
"suggest": {
|
108 |
+
"otgs/icons": "Needed for displaying Company's glyphs and icons,"
|
109 |
+
},
|
110 |
+
"time": "2020-11-26T14:58:07+00:00",
|
111 |
+
"type": "library",
|
112 |
+
"installation-source": "source",
|
113 |
+
"autoload": {
|
114 |
+
"classmap": [
|
115 |
+
"src/php/"
|
116 |
+
]
|
117 |
+
},
|
118 |
+
"notification-url": "https://packagist.org/downloads/",
|
119 |
+
"license": [
|
120 |
+
"GPL-2.0-or-later"
|
121 |
+
],
|
122 |
+
"authors": [
|
123 |
+
{
|
124 |
+
"name": "Andrea Sciamanna",
|
125 |
+
"email": "andrea.s@onthegosystems.com",
|
126 |
+
"homepage": "https://onthegosystems.com"
|
127 |
+
},
|
128 |
+
{
|
129 |
+
"name": "Kasia Janoska",
|
130 |
+
"email": "kasia.j@onthegosystems.com",
|
131 |
+
"homepage": "https://onthegosystems.com"
|
132 |
+
}
|
133 |
+
],
|
134 |
+
"description": "UI library from OnTheGoSystems",
|
135 |
+
"homepage": "https://git.onthegosystems.com/otgs-public/otgs-ui",
|
136 |
+
"keywords": [
|
137 |
+
"ui"
|
138 |
+
]
|
139 |
+
},
|
140 |
+
{
|
141 |
+
"name": "roave/security-advisories",
|
142 |
+
"version": "dev-master",
|
143 |
+
"version_normalized": "9999999-dev",
|
144 |
+
"source": {
|
145 |
+
"type": "git",
|
146 |
+
"url": "https://github.com/Roave/SecurityAdvisories.git",
|
147 |
+
"reference": "fa60732bcafd446e9ff858eefa06cdcbae8d9823"
|
148 |
+
},
|
149 |
+
"dist": {
|
150 |
+
"type": "zip",
|
151 |
+
"url": "https://api.github.com/repos/Roave/SecurityAdvisories/zipball/fa60732bcafd446e9ff858eefa06cdcbae8d9823",
|
152 |
+
"reference": "fa60732bcafd446e9ff858eefa06cdcbae8d9823",
|
153 |
+
"shasum": ""
|
154 |
+
},
|
155 |
+
"conflict": {
|
156 |
+
"3f/pygmentize": "<1.2",
|
157 |
+
"adodb/adodb-php": "<=5.20.20|>=5.21,<=5.21.3",
|
158 |
+
"akaunting/akaunting": "<2.1.13",
|
159 |
+
"alterphp/easyadmin-extension-bundle": ">=1.2,<1.2.11|>=1.3,<1.3.1",
|
160 |
+
"amazing/media2click": ">=1,<1.3.3",
|
161 |
+
"amphp/artax": "<1.0.6|>=2,<2.0.6",
|
162 |
+
"amphp/http": "<1.0.1",
|
163 |
+
"amphp/http-client": ">=4,<4.4",
|
164 |
+
"anchorcms/anchor-cms": "<=0.12.7",
|
165 |
+
"api-platform/core": ">=2.2,<2.2.10|>=2.3,<2.3.6",
|
166 |
+
"area17/twill": "<1.2.5|>=2,<2.5.3",
|
167 |
+
"asymmetricrypt/asymmetricrypt": ">=0,<9.9.99",
|
168 |
+
"aws/aws-sdk-php": ">=3,<3.2.1",
|
169 |
+
"bagisto/bagisto": "<0.1.5",
|
170 |
+
"barrelstrength/sprout-base-email": "<1.2.7",
|
171 |
+
"barrelstrength/sprout-forms": "<3.9",
|
172 |
+
"baserproject/basercms": "<4.5.4",
|
173 |
+
"billz/raspap-webgui": "<=2.6.6",
|
174 |
+
"bk2k/bootstrap-package": ">=7.1,<7.1.2|>=8,<8.0.8|>=9,<9.0.4|>=9.1,<9.1.3|>=10,<10.0.10|>=11,<11.0.3",
|
175 |
+
"bolt/bolt": "<3.7.2",
|
176 |
+
"bolt/core": "<4.1.13",
|
177 |
+
"bottelet/flarepoint": "<2.2.1",
|
178 |
+
"brightlocal/phpwhois": "<=4.2.5",
|
179 |
+
"buddypress/buddypress": "<7.2.1",
|
180 |
+
"bugsnag/bugsnag-laravel": ">=2,<2.0.2",
|
181 |
+
"bytefury/crater": "<6",
|
182 |
+
"cachethq/cachet": "<2.5.1",
|
183 |
+
"cakephp/cakephp": ">=1.3,<1.3.18|>=2,<2.4.99|>=2.5,<2.5.99|>=2.6,<2.6.12|>=2.7,<2.7.6|>=3,<3.5.18|>=3.6,<3.6.15|>=3.7,<3.7.7",
|
184 |
+
"cardgate/magento2": "<2.0.33",
|
185 |
+
"cart2quote/module-quotation": ">=4.1.6,<=4.4.5|>=5,<5.4.4",
|
186 |
+
"cartalyst/sentry": "<=2.1.6",
|
187 |
+
"catfan/medoo": "<1.7.5",
|
188 |
+
"centreon/centreon": "<20.10.7",
|
189 |
+
"cesnet/simplesamlphp-module-proxystatistics": "<3.1",
|
190 |
+
"codeception/codeception": "<3.1.3|>=4,<4.1.22",
|
191 |
+
"codeigniter/framework": "<=3.0.6",
|
192 |
+
"codeigniter4/framework": "<4.1.8",
|
193 |
+
"codiad/codiad": "<=2.8.4",
|
194 |
+
"composer/composer": "<1.10.23|>=2-alpha.1,<2.1.9",
|
195 |
+
"concrete5/concrete5": "<8.5.5",
|
196 |
+
"concrete5/core": "<8.5.7",
|
197 |
+
"contao-components/mediaelement": ">=2.14.2,<2.21.1",
|
198 |
+
"contao/core": ">=2,<3.5.39",
|
199 |
+
"contao/core-bundle": ">=4,<4.4.56|>=4.5,<4.9.18|>=4.10,<4.11.7|= 4.10.0",
|
200 |
+
"contao/listing-bundle": ">=4,<4.4.8",
|
201 |
+
"craftcms/cms": "<3.7.14",
|
202 |
+
"croogo/croogo": "<3.0.7",
|
203 |
+
"datadog/dd-trace": ">=0.30,<0.30.2",
|
204 |
+
"david-garcia/phpwhois": "<=4.3.1",
|
205 |
+
"derhansen/sf_event_mgt": "<4.3.1|>=5,<5.1.1",
|
206 |
+
"directmailteam/direct-mail": "<5.2.4",
|
207 |
+
"doctrine/annotations": ">=1,<1.2.7",
|
208 |
+
"doctrine/cache": ">=1,<1.3.2|>=1.4,<1.4.2",
|
209 |
+
"doctrine/common": ">=2,<2.4.3|>=2.5,<2.5.1",
|
210 |
+
"doctrine/dbal": ">=2,<2.0.8|>=2.1,<2.1.2|>=3,<3.1.4",
|
211 |
+
"doctrine/doctrine-bundle": "<1.5.2",
|
212 |
+
"doctrine/doctrine-module": "<=0.7.1",
|
213 |
+
"doctrine/mongodb-odm": ">=1,<1.0.2",
|
214 |
+
"doctrine/mongodb-odm-bundle": ">=2,<3.0.1",
|
215 |
+
"doctrine/orm": ">=2,<2.4.8|>=2.5,<2.5.1|>=2.8.3,<2.8.4",
|
216 |
+
"dolibarr/dolibarr": "<=14.0.5|>= 3.3.beta1, < 13.0.2",
|
217 |
+
"dompdf/dompdf": ">=0.6,<0.6.2",
|
218 |
+
"drupal/core": ">=7,<7.80|>=8,<8.9.16|>=9,<9.1.12|>=9.2,<9.2.4",
|
219 |
+
"drupal/drupal": ">=7,<7.80|>=8,<8.9.16|>=9,<9.1.12|>=9.2,<9.2.4",
|
220 |
+
"dweeves/magmi": "<=0.7.24",
|
221 |
+
"ecodev/newsletter": "<=4",
|
222 |
+
"elgg/elgg": "<3.3.24|>=4,<4.0.5",
|
223 |
+
"endroid/qr-code-bundle": "<3.4.2",
|
224 |
+
"enshrined/svg-sanitize": "<0.13.1",
|
225 |
+
"erusev/parsedown": "<1.7.2",
|
226 |
+
"ether/logs": "<3.0.4",
|
227 |
+
"ezsystems/demobundle": ">=5.4,<5.4.6.1",
|
228 |
+
"ezsystems/ez-support-tools": ">=2.2,<2.2.3",
|
229 |
+
"ezsystems/ezdemo-ls-extension": ">=5.4,<5.4.2.1",
|
230 |
+
"ezsystems/ezfind-ls": ">=5.3,<5.3.6.1|>=5.4,<5.4.11.1|>=2017.12,<2017.12.0.1",
|
231 |
+
"ezsystems/ezplatform": "<=1.13.6|>=2,<=2.5.24",
|
232 |
+
"ezsystems/ezplatform-admin-ui": ">=1.3,<1.3.5|>=1.4,<1.4.6|>=1.5,<=1.5.25",
|
233 |
+
"ezsystems/ezplatform-admin-ui-assets": ">=4,<4.2.1|>=5,<5.0.1|>=5.1,<5.1.1",
|
234 |
+
"ezsystems/ezplatform-kernel": "<=1.2.5|>=1.3,<=1.3.1",
|
235 |
+
"ezsystems/ezplatform-rest": ">=1.2,<=1.2.2|>=1.3,<1.3.8",
|
236 |
+
"ezsystems/ezplatform-richtext": ">=2.3,<=2.3.7",
|
237 |
+
"ezsystems/ezplatform-user": ">=1,<1.0.1",
|
238 |
+
"ezsystems/ezpublish-kernel": "<=6.13.8.1|>=7,<7.5.26",
|
239 |
+
"ezsystems/ezpublish-legacy": "<=2017.12.7.3|>=2018.6,<=2019.3.5.1",
|
240 |
+
"ezsystems/platform-ui-assets-bundle": ">=4.2,<4.2.3",
|
241 |
+
"ezsystems/repository-forms": ">=2.3,<2.3.2.1",
|
242 |
+
"ezyang/htmlpurifier": "<4.1.1",
|
243 |
+
"facade/ignition": "<1.16.15|>=2,<2.4.2|>=2.5,<2.5.2",
|
244 |
+
"feehi/cms": "<=2.1.1",
|
245 |
+
"feehi/feehicms": "<=0.1.3",
|
246 |
+
"firebase/php-jwt": "<2",
|
247 |
+
"flarum/core": ">=1,<=1.0.1",
|
248 |
+
"flarum/sticky": ">=0.1-beta.14,<=0.1-beta.15",
|
249 |
+
"flarum/tags": "<=0.1-beta.13",
|
250 |
+
"fluidtypo3/vhs": "<5.1.1",
|
251 |
+
"fooman/tcpdf": "<6.2.22",
|
252 |
+
"forkcms/forkcms": "<=5.9.2",
|
253 |
+
"fossar/tcpdf-parser": "<6.2.22",
|
254 |
+
"francoisjacquet/rosariosis": "<8.1.1",
|
255 |
+
"friendsofsymfony/oauth2-php": "<1.3",
|
256 |
+
"friendsofsymfony/rest-bundle": ">=1.2,<1.2.2",
|
257 |
+
"friendsofsymfony/user-bundle": ">=1.2,<1.3.5",
|
258 |
+
"friendsoftypo3/mediace": ">=7.6.2,<7.6.5",
|
259 |
+
"froala/wysiwyg-editor": "<3.2.7",
|
260 |
+
"fuel/core": "<1.8.1",
|
261 |
+
"gaoming13/wechat-php-sdk": "<=1.10.2",
|
262 |
+
"getgrav/grav": "<1.7.28",
|
263 |
+
"getkirby/cms": "<3.5.8",
|
264 |
+
"getkirby/panel": "<2.5.14",
|
265 |
+
"gilacms/gila": "<=1.11.4",
|
266 |
+
"globalpayments/php-sdk": "<2",
|
267 |
+
"gos/web-socket-bundle": "<1.10.4|>=2,<2.6.1|>=3,<3.3",
|
268 |
+
"gree/jose": "<=2.2",
|
269 |
+
"gregwar/rst": "<1.0.3",
|
270 |
+
"grumpydictator/firefly-iii": "<5.6.5",
|
271 |
+
"guzzlehttp/guzzle": ">=4-rc.2,<4.2.4|>=5,<5.3.1|>=6,<6.2.1",
|
272 |
+
"helloxz/imgurl": "<=2.31",
|
273 |
+
"hillelcoren/invoice-ninja": "<5.3.35",
|
274 |
+
"hjue/justwriting": "<=1",
|
275 |
+
"hov/jobfair": "<1.0.13|>=2,<2.0.2",
|
276 |
+
"ibexa/post-install": "<=1.0.4",
|
277 |
+
"icecoder/icecoder": "<=8.1",
|
278 |
+
"illuminate/auth": ">=4,<4.0.99|>=4.1,<=4.1.31|>=4.2,<=4.2.22|>=5,<=5.0.35|>=5.1,<=5.1.46|>=5.2,<=5.2.45|>=5.3,<=5.3.31|>=5.4,<=5.4.36|>=5.5,<5.5.10",
|
279 |
+
"illuminate/cookie": ">=4,<=4.0.11|>=4.1,<=4.1.99999|>=4.2,<=4.2.99999|>=5,<=5.0.99999|>=5.1,<=5.1.99999|>=5.2,<=5.2.99999|>=5.3,<=5.3.99999|>=5.4,<=5.4.99999|>=5.5,<=5.5.49|>=5.6,<=5.6.99999|>=5.7,<=5.7.99999|>=5.8,<=5.8.99999|>=6,<6.18.31|>=7,<7.22.4",
|
280 |
+
"illuminate/database": "<6.20.26|>=7,<7.30.5|>=8,<8.40",
|
281 |
+
"illuminate/encryption": ">=4,<=4.0.11|>=4.1,<=4.1.31|>=4.2,<=4.2.22|>=5,<=5.0.35|>=5.1,<=5.1.46|>=5.2,<=5.2.45|>=5.3,<=5.3.31|>=5.4,<=5.4.36|>=5.5,<5.5.40|>=5.6,<5.6.15",
|
282 |
+
"illuminate/view": "<6.20.42|>=7,<7.30.6|>=8,<8.75",
|
283 |
+
"impresscms/impresscms": "<=1.4.2",
|
284 |
+
"in2code/femanager": "<5.5.1|>=6,<6.3.1",
|
285 |
+
"intelliants/subrion": "<=4.2.1",
|
286 |
+
"ivankristianto/phpwhois": "<=4.3",
|
287 |
+
"jackalope/jackalope-doctrine-dbal": "<1.7.4",
|
288 |
+
"james-heinrich/getid3": "<1.9.21",
|
289 |
+
"joomla/archive": "<1.1.10",
|
290 |
+
"joomla/session": "<1.3.1",
|
291 |
+
"jsmitty12/phpwhois": "<5.1",
|
292 |
+
"kazist/phpwhois": "<=4.2.6",
|
293 |
+
"kevinpapst/kimai2": "<1.16.7",
|
294 |
+
"kitodo/presentation": "<3.1.2",
|
295 |
+
"klaviyo/magento2-extension": ">=1,<3",
|
296 |
+
"kreait/firebase-php": ">=3.2,<3.8.1",
|
297 |
+
"la-haute-societe/tcpdf": "<6.2.22",
|
298 |
+
"laminas/laminas-form": "<2.17.2|>=3,<3.0.2|>=3.1,<3.1.1",
|
299 |
+
"laminas/laminas-http": "<2.14.2",
|
300 |
+
"laravel/framework": "<6.20.42|>=7,<7.30.6|>=8,<8.75",
|
301 |
+
"laravel/socialite": ">=1,<1.0.99|>=2,<2.0.10",
|
302 |
+
"latte/latte": "<2.10.8",
|
303 |
+
"lavalite/cms": "<=5.8",
|
304 |
+
"lcobucci/jwt": ">=3.4,<3.4.6|>=4,<4.0.4|>=4.1,<4.1.5",
|
305 |
+
"league/commonmark": "<0.18.3",
|
306 |
+
"league/flysystem": "<1.1.4|>=2,<2.1.1",
|
307 |
+
"lexik/jwt-authentication-bundle": "<2.10.7|>=2.11,<2.11.3",
|
308 |
+
"librenms/librenms": "<=21.11",
|
309 |
+
"limesurvey/limesurvey": "<3.27.19",
|
310 |
+
"livehelperchat/livehelperchat": "<=3.91",
|
311 |
+
"livewire/livewire": ">2.2.4,<2.2.6",
|
312 |
+
"lms/routes": "<2.1.1",
|
313 |
+
"localizationteam/l10nmgr": "<7.4|>=8,<8.7|>=9,<9.2",
|
314 |
+
"magento/community-edition": ">=2,<2.2.10|>=2.3,<2.3.3",
|
315 |
+
"magento/magento1ce": "<1.9.4.3",
|
316 |
+
"magento/magento1ee": ">=1,<1.14.4.3",
|
317 |
+
"magento/product-community-edition": ">=2,<2.2.10|>=2.3,<2.3.2-p.2",
|
318 |
+
"marcwillmann/turn": "<0.3.3",
|
319 |
+
"mautic/core": "<4|= 2.13.1",
|
320 |
+
"mediawiki/core": ">=1.27,<1.27.6|>=1.29,<1.29.3|>=1.30,<1.30.2|>=1.31,<1.31.9|>=1.32,<1.32.6|>=1.32.99,<1.33.3|>=1.33.99,<1.34.3|>=1.34.99,<1.35",
|
321 |
+
"microweber/microweber": "<1.2.11",
|
322 |
+
"miniorange/miniorange-saml": "<1.4.3",
|
323 |
+
"mittwald/typo3_forum": "<1.2.1",
|
324 |
+
"modx/revolution": "<2.8",
|
325 |
+
"monolog/monolog": ">=1.8,<1.12",
|
326 |
+
"moodle/moodle": "<3.9.11|>=3.10-beta,<3.10.8|>=3.11,<3.11.5",
|
327 |
+
"mustache/mustache": ">=2,<2.14.1",
|
328 |
+
"namshi/jose": "<2.2",
|
329 |
+
"neoan3-apps/template": "<1.1.1",
|
330 |
+
"neos/flow": ">=1,<1.0.4|>=1.1,<1.1.1|>=2,<2.0.1|>=2.3,<2.3.16|>=3,<3.0.12|>=3.1,<3.1.10|>=3.2,<3.2.13|>=3.3,<3.3.13|>=4,<4.0.6",
|
331 |
+
"neos/form": ">=1.2,<4.3.3|>=5,<5.0.9|>=5.1,<5.1.3",
|
332 |
+
"neos/neos": ">=1.1,<1.1.3|>=1.2,<1.2.13|>=2,<2.0.4|>=2.3,<2.9.99|>=3,<3.0.20|>=3.1,<3.1.18|>=3.2,<3.2.14|>=3.3,<3.3.23|>=4,<4.0.17|>=4.1,<4.1.16|>=4.2,<4.2.12|>=4.3,<4.3.3",
|
333 |
+
"neos/swiftmailer": ">=4.1,<4.1.99|>=5.4,<5.4.5",
|
334 |
+
"netgen/tagsbundle": ">=3.4,<3.4.11|>=4,<4.0.15",
|
335 |
+
"nette/application": ">=2,<2.0.19|>=2.1,<2.1.13|>=2.2,<2.2.10|>=2.3,<2.3.14|>=2.4,<2.4.16|>=3,<3.0.6",
|
336 |
+
"nette/nette": ">=2,<2.0.19|>=2.1,<2.1.13",
|
337 |
+
"nilsteampassnet/teampass": "<=2.1.27.36",
|
338 |
+
"nukeviet/nukeviet": "<4.3.4",
|
339 |
+
"nystudio107/craft-seomatic": "<3.3",
|
340 |
+
"nzo/url-encryptor-bundle": ">=4,<4.3.2|>=5,<5.0.1",
|
341 |
+
"october/backend": "<1.1.2",
|
342 |
+
"october/cms": "= 1.1.1|= 1.0.471|= 1.0.469|>=1.0.319,<1.0.469",
|
343 |
+
"october/october": ">=1.0.319,<1.0.466|>=2.1,<2.1.12",
|
344 |
+
"october/rain": "<1.0.472|>=1.1,<1.1.2",
|
345 |
+
"october/system": "<1.0.473|>=1.1,<1.1.6|>=2.1,<2.1.12",
|
346 |
+
"onelogin/php-saml": "<2.10.4",
|
347 |
+
"oneup/uploader-bundle": "<1.9.3|>=2,<2.1.5",
|
348 |
+
"opencart/opencart": "<=3.0.3.2",
|
349 |
+
"openid/php-openid": "<2.3",
|
350 |
+
"openmage/magento-lts": "<19.4.15|>=20,<20.0.13",
|
351 |
+
"orchid/platform": ">=9,<9.4.4",
|
352 |
+
"oro/crm": ">=1.7,<1.7.4|>=3.1,<4.1.17|>=4.2,<4.2.7",
|
353 |
+
"oro/platform": ">=1.7,<1.7.4|>=3.1,<3.1.29|>=4.1,<4.1.17|>=4.2,<4.2.8",
|
354 |
+
"padraic/humbug_get_contents": "<1.1.2",
|
355 |
+
"pagarme/pagarme-php": ">=0,<3",
|
356 |
+
"pagekit/pagekit": "<=1.0.18",
|
357 |
+
"paragonie/random_compat": "<2",
|
358 |
+
"passbolt/passbolt_api": "<2.11",
|
359 |
+
"paypal/merchant-sdk-php": "<3.12",
|
360 |
+
"pear/archive_tar": "<1.4.14",
|
361 |
+
"pegasus/google-for-jobs": "<1.5.1|>=2,<2.1.1",
|
362 |
+
"personnummer/personnummer": "<3.0.2",
|
363 |
+
"phanan/koel": "<5.1.4",
|
364 |
+
"phpfastcache/phpfastcache": "<6.1.5|>=7,<7.1.2|>=8,<8.0.7",
|
365 |
+
"phpmailer/phpmailer": "<6.5",
|
366 |
+
"phpmussel/phpmussel": ">=1,<1.6",
|
367 |
+
"phpmyadmin/phpmyadmin": "<4.9.8|>=5,<5.0.3|>=5.1,<5.1.2",
|
368 |
+
"phpoffice/phpexcel": "<1.8.2",
|
369 |
+
"phpoffice/phpspreadsheet": "<1.16",
|
370 |
+
"phpseclib/phpseclib": "<2.0.31|>=3,<3.0.7",
|
371 |
+
"phpservermon/phpservermon": "<=3.5.2",
|
372 |
+
"phpunit/phpunit": ">=4.8.19,<4.8.28|>=5.0.10,<5.6.3",
|
373 |
+
"phpwhois/phpwhois": "<=4.2.5",
|
374 |
+
"phpxmlrpc/extras": "<0.6.1",
|
375 |
+
"pimcore/pimcore": "<=10.2.9",
|
376 |
+
"pocketmine/pocketmine-mp": "<4.0.7",
|
377 |
+
"pressbooks/pressbooks": "<5.18",
|
378 |
+
"prestashop/autoupgrade": ">=4,<4.10.1",
|
379 |
+
"prestashop/contactform": ">1.0.1,<4.3",
|
380 |
+
"prestashop/gamification": "<2.3.2",
|
381 |
+
"prestashop/prestashop": ">=1.7,<=1.7.8.2",
|
382 |
+
"prestashop/productcomments": ">=4,<4.2.1",
|
383 |
+
"prestashop/ps_emailsubscription": "<2.6.1",
|
384 |
+
"prestashop/ps_facetedsearch": "<3.4.1",
|
385 |
+
"prestashop/ps_linklist": "<3.1",
|
386 |
+
"privatebin/privatebin": "<1.2.2|>=1.3,<1.3.2",
|
387 |
+
"propel/propel": ">=2-alpha.1,<=2-alpha.7",
|
388 |
+
"propel/propel1": ">=1,<=1.7.1",
|
389 |
+
"pterodactyl/panel": "<1.7",
|
390 |
+
"pusher/pusher-php-server": "<2.2.1",
|
391 |
+
"pwweb/laravel-core": "<=0.3.6-beta",
|
392 |
+
"rainlab/debugbar-plugin": "<3.1",
|
393 |
+
"remdex/livehelperchat": "<3.93",
|
394 |
+
"rmccue/requests": ">=1.6,<1.8",
|
395 |
+
"robrichards/xmlseclibs": "<3.0.4",
|
396 |
+
"sabberworm/php-css-parser": ">=1,<1.0.1|>=2,<2.0.1|>=3,<3.0.1|>=4,<4.0.1|>=5,<5.0.9|>=5.1,<5.1.3|>=5.2,<5.2.1|>=6,<6.0.2|>=7,<7.0.4|>=8,<8.0.1|>=8.1,<8.1.1|>=8.2,<8.2.1|>=8.3,<8.3.1",
|
397 |
+
"sabre/dav": ">=1.6,<1.6.99|>=1.7,<1.7.11|>=1.8,<1.8.9",
|
398 |
+
"scheb/two-factor-bundle": ">=0,<3.26|>=4,<4.11",
|
399 |
+
"sensiolabs/connect": "<4.2.3",
|
400 |
+
"serluck/phpwhois": "<=4.2.6",
|
401 |
+
"shopware/core": "<=6.4.6",
|
402 |
+
"shopware/platform": "<=6.4.6",
|
403 |
+
"shopware/production": "<=6.3.5.2",
|
404 |
+
"shopware/shopware": "<5.7.7",
|
405 |
+
"showdoc/showdoc": "<2.10.2",
|
406 |
+
"silverstripe/admin": ">=1,<1.8.1",
|
407 |
+
"silverstripe/assets": ">=1,<1.4.7|>=1.5,<1.5.2",
|
408 |
+
"silverstripe/cms": "<4.3.6|>=4.4,<4.4.4",
|
409 |
+
"silverstripe/comments": ">=1.3,<1.9.99|>=2,<2.9.99|>=3,<3.1.1",
|
410 |
+
"silverstripe/forum": "<=0.6.1|>=0.7,<=0.7.3",
|
411 |
+
"silverstripe/framework": "<4.7.4",
|
412 |
+
"silverstripe/graphql": "<3.5.2|>=4-alpha.1,<4-alpha.2",
|
413 |
+
"silverstripe/registry": ">=2.1,<2.1.2|>=2.2,<2.2.1",
|
414 |
+
"silverstripe/restfulserver": ">=1,<1.0.9|>=2,<2.0.4",
|
415 |
+
"silverstripe/subsites": ">=2,<2.1.1",
|
416 |
+
"silverstripe/taxonomy": ">=1.3,<1.3.1|>=2,<2.0.1",
|
417 |
+
"silverstripe/userforms": "<3",
|
418 |
+
"simple-updates/phpwhois": "<=1",
|
419 |
+
"simplesamlphp/saml2": "<1.10.6|>=2,<2.3.8|>=3,<3.1.4",
|
420 |
+
"simplesamlphp/simplesamlphp": "<1.18.6",
|
421 |
+
"simplesamlphp/simplesamlphp-module-infocard": "<1.0.1",
|
422 |
+
"simplito/elliptic-php": "<1.0.6",
|
423 |
+
"slim/slim": "<2.6",
|
424 |
+
"smarty/smarty": "<3.1.43|>=4,<4.0.3",
|
425 |
+
"snipe/snipe-it": "<=5.3.7",
|
426 |
+
"socalnick/scn-social-auth": "<1.15.2",
|
427 |
+
"socialiteproviders/steam": "<1.1",
|
428 |
+
"spipu/html2pdf": "<5.2.4",
|
429 |
+
"spoonity/tcpdf": "<6.2.22",
|
430 |
+
"squizlabs/php_codesniffer": ">=1,<2.8.1|>=3,<3.0.1",
|
431 |
+
"ssddanbrown/bookstack": "<21.12.1",
|
432 |
+
"stormpath/sdk": ">=0,<9.9.99",
|
433 |
+
"studio-42/elfinder": "<2.1.59",
|
434 |
+
"subrion/cms": "<=4.2.1",
|
435 |
+
"sulu/sulu": "= 2.4.0-RC1|<1.6.44|>=2,<2.2.18|>=2.3,<2.3.8",
|
436 |
+
"swiftmailer/swiftmailer": ">=4,<5.4.5",
|
437 |
+
"sylius/admin-bundle": ">=1,<1.0.17|>=1.1,<1.1.9|>=1.2,<1.2.2",
|
438 |
+
"sylius/grid": ">=1,<1.1.19|>=1.2,<1.2.18|>=1.3,<1.3.13|>=1.4,<1.4.5|>=1.5,<1.5.1",
|
439 |
+
"sylius/grid-bundle": ">=1,<1.1.19|>=1.2,<1.2.18|>=1.3,<1.3.13|>=1.4,<1.4.5|>=1.5,<1.5.1",
|
440 |
+
"sylius/paypal-plugin": ">=1,<1.2.4|>=1.3,<1.3.1",
|
441 |
+
"sylius/resource-bundle": "<1.3.14|>=1.4,<1.4.7|>=1.5,<1.5.2|>=1.6,<1.6.4",
|
442 |
+
"sylius/sylius": "<1.6.9|>=1.7,<1.7.9|>=1.8,<1.8.3|>=1.9,<1.9.5",
|
443 |
+
"symbiote/silverstripe-multivaluefield": ">=3,<3.0.99",
|
444 |
+
"symbiote/silverstripe-queuedjobs": ">=3,<3.0.2|>=3.1,<3.1.4|>=4,<4.0.7|>=4.1,<4.1.2|>=4.2,<4.2.4|>=4.3,<4.3.3|>=4.4,<4.4.3|>=4.5,<4.5.1|>=4.6,<4.6.4",
|
445 |
+
"symbiote/silverstripe-versionedfiles": "<=2.0.3",
|
446 |
+
"symfont/process": ">=0,<4",
|
447 |
+
"symfony/cache": ">=3.1,<3.4.35|>=4,<4.2.12|>=4.3,<4.3.8",
|
448 |
+
"symfony/dependency-injection": ">=2,<2.0.17|>=2.7,<2.7.51|>=2.8,<2.8.50|>=3,<3.4.26|>=4,<4.1.12|>=4.2,<4.2.7",
|
449 |
+
"symfony/error-handler": ">=4.4,<4.4.4|>=5,<5.0.4",
|
450 |
+
"symfony/form": ">=2.3,<2.3.35|>=2.4,<2.6.12|>=2.7,<2.7.50|>=2.8,<2.8.49|>=3,<3.4.20|>=4,<4.0.15|>=4.1,<4.1.9|>=4.2,<4.2.1",
|
451 |
+
"symfony/framework-bundle": "<5.3.15|>=5.4,<5.4.4|>=6,<6.0.4",
|
452 |
+
"symfony/http-foundation": ">=2,<2.8.52|>=3,<3.4.35|>=4,<4.2.12|>=4.3,<4.3.8|>=4.4,<4.4.7|>=5,<5.0.7",
|
453 |
+
"symfony/http-kernel": ">=2,<2.8.52|>=3,<3.4.35|>=4,<4.2.12|>=4.3,<4.4.13|>=5,<5.1.5|>=5.2,<5.3.12",
|
454 |
+
"symfony/intl": ">=2.7,<2.7.38|>=2.8,<2.8.31|>=3,<3.2.14|>=3.3,<3.3.13",
|
455 |
+
"symfony/maker-bundle": ">=1.27,<1.29.2|>=1.30,<1.31.1",
|
456 |
+
"symfony/mime": ">=4.3,<4.3.8",
|
457 |
+
"symfony/phpunit-bridge": ">=2.8,<2.8.50|>=3,<3.4.26|>=4,<4.1.12|>=4.2,<4.2.7",
|
458 |
+
"symfony/polyfill": ">=1,<1.10",
|
459 |
+
"symfony/polyfill-php55": ">=1,<1.10",
|
460 |
+
"symfony/proxy-manager-bridge": ">=2.7,<2.7.51|>=2.8,<2.8.50|>=3,<3.4.26|>=4,<4.1.12|>=4.2,<4.2.7",
|
461 |
+
"symfony/routing": ">=2,<2.0.19",
|
462 |
+
"symfony/security": ">=2,<2.7.51|>=2.8,<3.4.49|>=4,<4.4.24|>=5,<5.2.8",
|
463 |
+
"symfony/security-bundle": ">=2,<2.7.48|>=2.8,<2.8.41|>=3,<3.3.17|>=3.4,<3.4.11|>=4,<4.0.11|>=5.3,<5.3.12",
|
464 |
+
"symfony/security-core": ">=2.4,<2.6.13|>=2.7,<2.7.9|>=2.7.30,<2.7.32|>=2.8,<3.4.49|>=4,<4.4.24|>=5,<5.2.9",
|
465 |
+
"symfony/security-csrf": ">=2.4,<2.7.48|>=2.8,<2.8.41|>=3,<3.3.17|>=3.4,<3.4.11|>=4,<4.0.11",
|
466 |
+
"symfony/security-guard": ">=2.8,<3.4.48|>=4,<4.4.23|>=5,<5.2.8",
|
467 |
+
"symfony/security-http": ">=2.3,<2.3.41|>=2.4,<2.7.51|>=2.8,<3.4.48|>=4,<4.4.23|>=5,<5.2.8|>=5.3,<5.3.2",
|
468 |
+
"symfony/serializer": ">=2,<2.0.11|>=4.1,<4.4.35|>=5,<5.3.12",
|
469 |
+
"symfony/symfony": ">=2,<3.4.49|>=4,<4.4.35|>=5,<5.3.12|>=5.3.14,<=5.3.14|>=5.4.3,<=5.4.3|>=6.0.3,<=6.0.3",
|
470 |
+
"symfony/translation": ">=2,<2.0.17",
|
471 |
+
"symfony/validator": ">=2,<2.0.24|>=2.1,<2.1.12|>=2.2,<2.2.5|>=2.3,<2.3.3",
|
472 |
+
"symfony/var-exporter": ">=4.2,<4.2.12|>=4.3,<4.3.8",
|
473 |
+
"symfony/web-profiler-bundle": ">=2,<2.3.19|>=2.4,<2.4.9|>=2.5,<2.5.4",
|
474 |
+
"symfony/yaml": ">=2,<2.0.22|>=2.1,<2.1.7",
|
475 |
+
"t3/dce": ">=2.2,<2.6.2",
|
476 |
+
"t3g/svg-sanitizer": "<1.0.3",
|
477 |
+
"tecnickcom/tcpdf": "<6.2.22",
|
478 |
+
"thelia/backoffice-default-template": ">=2.1,<2.1.2",
|
479 |
+
"thelia/thelia": ">=2.1-beta.1,<2.1.3",
|
480 |
+
"theonedemon/phpwhois": "<=4.2.5",
|
481 |
+
"tinymce/tinymce": "<5.10",
|
482 |
+
"titon/framework": ">=0,<9.9.99",
|
483 |
+
"topthink/framework": "<6.0.9",
|
484 |
+
"topthink/think": "<=6.0.9",
|
485 |
+
"topthink/thinkphp": "<=3.2.3",
|
486 |
+
"tribalsystems/zenario": "<8.8.53370",
|
487 |
+
"truckersmp/phpwhois": "<=4.3.1",
|
488 |
+
"twig/twig": "<1.38|>=2,<2.7",
|
489 |
+
"typo3/cms": ">=6.2,<6.2.30|>=7,<7.6.32|>=8,<8.7.38|>=9,<9.5.29|>=10,<10.4.19|>=11,<11.5",
|
490 |
+
"typo3/cms-backend": ">=7,<=7.6.50|>=8,<=8.7.39|>=9,<=9.5.24|>=10,<=10.4.13|>=11,<=11.1",
|
491 |
+
"typo3/cms-core": ">=6.2,<=6.2.56|>=7,<=7.6.52|>=8,<=8.7.41|>=9,<9.5.29|>=10,<10.4.19|>=11,<11.5",
|
492 |
+
"typo3/cms-form": ">=8,<=8.7.39|>=9,<=9.5.24|>=10,<=10.4.13|>=11,<=11.1",
|
493 |
+
"typo3/flow": ">=1,<1.0.4|>=1.1,<1.1.1|>=2,<2.0.1|>=2.3,<2.3.16|>=3,<3.0.12|>=3.1,<3.1.10|>=3.2,<3.2.13|>=3.3,<3.3.13|>=4,<4.0.6",
|
494 |
+
"typo3/neos": ">=1.1,<1.1.3|>=1.2,<1.2.13|>=2,<2.0.4|>=2.3,<2.3.99|>=3,<3.0.20|>=3.1,<3.1.18|>=3.2,<3.2.14|>=3.3,<3.3.23|>=4,<4.0.17|>=4.1,<4.1.16|>=4.2,<4.2.12|>=4.3,<4.3.3",
|
495 |
+
"typo3/phar-stream-wrapper": ">=1,<2.1.1|>=3,<3.1.1",
|
496 |
+
"typo3/swiftmailer": ">=4.1,<4.1.99|>=5.4,<5.4.5",
|
497 |
+
"typo3fluid/fluid": ">=2,<2.0.8|>=2.1,<2.1.7|>=2.2,<2.2.4|>=2.3,<2.3.7|>=2.4,<2.4.4|>=2.5,<2.5.11|>=2.6,<2.6.10",
|
498 |
+
"ua-parser/uap-php": "<3.8",
|
499 |
+
"unisharp/laravel-filemanager": "<=2.3",
|
500 |
+
"userfrosting/userfrosting": ">=0.3.1,<4.6.3",
|
501 |
+
"usmanhalalit/pixie": "<1.0.3|>=2,<2.0.2",
|
502 |
+
"vanilla/safecurl": "<0.9.2",
|
503 |
+
"verot/class.upload.php": "<=1.0.3|>=2,<=2.0.4",
|
504 |
+
"vrana/adminer": "<4.7.9",
|
505 |
+
"wallabag/tcpdf": "<6.2.22",
|
506 |
+
"wanglelecc/laracms": "<=1.0.3",
|
507 |
+
"web-auth/webauthn-framework": ">=3.3,<3.3.4",
|
508 |
+
"webcoast/deferred-image-processing": "<1.0.2",
|
509 |
+
"wikimedia/parsoid": "<0.12.2",
|
510 |
+
"willdurand/js-translation-bundle": "<2.1.1",
|
511 |
+
"wp-cli/wp-cli": "<2.5",
|
512 |
+
"yetiforce/yetiforce-crm": "<=6.3",
|
513 |
+
"yidashi/yii2cmf": "<=2",
|
514 |
+
"yii2mod/yii2-cms": "<1.9.2",
|
515 |
+
"yiisoft/yii": ">=1.1.14,<1.1.15",
|
516 |
+
"yiisoft/yii2": "<2.0.38",
|
517 |
+
"yiisoft/yii2-bootstrap": "<2.0.4",
|
518 |
+
"yiisoft/yii2-dev": "<2.0.43",
|
519 |
+
"yiisoft/yii2-elasticsearch": "<2.0.5",
|
520 |
+
"yiisoft/yii2-gii": "<2.0.4",
|
521 |
+
"yiisoft/yii2-jui": "<2.0.4",
|
522 |
+
"yiisoft/yii2-redis": "<2.0.8",
|
523 |
+
"yoast-seo-for-typo3/yoast_seo": "<7.2.3",
|
524 |
+
"yourls/yourls": "<=1.8.2",
|
525 |
+
"zendesk/zendesk_api_client_php": "<2.2.11",
|
526 |
+
"zendframework/zend-cache": ">=2.4,<2.4.8|>=2.5,<2.5.3",
|
527 |
+
"zendframework/zend-captcha": ">=2,<2.4.9|>=2.5,<2.5.2",
|
528 |
+
"zendframework/zend-crypt": ">=2,<2.4.9|>=2.5,<2.5.2",
|
529 |
+
"zendframework/zend-db": ">=2,<2.0.99|>=2.1,<2.1.99|>=2.2,<2.2.10|>=2.3,<2.3.5",
|
530 |
+
"zendframework/zend-developer-tools": ">=1.2.2,<1.2.3",
|
531 |
+
"zendframework/zend-diactoros": ">=1,<1.8.4",
|
532 |
+
"zendframework/zend-feed": ">=1,<2.10.3",
|
533 |
+
"zendframework/zend-form": ">=2,<2.2.7|>=2.3,<2.3.1",
|
534 |
+
"zendframework/zend-http": ">=1,<2.8.1",
|
535 |
+
"zendframework/zend-json": ">=2.1,<2.1.6|>=2.2,<2.2.6",
|
536 |
+
"zendframework/zend-ldap": ">=2,<2.0.99|>=2.1,<2.1.99|>=2.2,<2.2.8|>=2.3,<2.3.3",
|
537 |
+
"zendframework/zend-mail": ">=2,<2.4.11|>=2.5,<2.7.2",
|
538 |
+
"zendframework/zend-navigation": ">=2,<2.2.7|>=2.3,<2.3.1",
|
539 |
+
"zendframework/zend-session": ">=2,<2.0.99|>=2.1,<2.1.99|>=2.2,<2.2.9|>=2.3,<2.3.4",
|
540 |
+
"zendframework/zend-validator": ">=2.3,<2.3.6",
|
541 |
+
"zendframework/zend-view": ">=2,<2.2.7|>=2.3,<2.3.1",
|
542 |
+
"zendframework/zend-xmlrpc": ">=2.1,<2.1.6|>=2.2,<2.2.6",
|
543 |
+
"zendframework/zendframework": "<=3",
|
544 |
+
"zendframework/zendframework1": "<1.12.20",
|
545 |
+
"zendframework/zendopenid": ">=2,<2.0.2",
|
546 |
+
"zendframework/zendxml": ">=1,<1.0.1",
|
547 |
+
"zetacomponents/mail": "<1.8.2",
|
548 |
+
"zf-commons/zfc-user": "<1.2.2",
|
549 |
+
"zfcampus/zf-apigility-doctrine": ">=1,<1.0.3",
|
550 |
+
"zfr/zfr-oauth2-server-module": "<0.1.2",
|
551 |
+
"zoujingli/thinkadmin": "<6.0.22"
|
552 |
+
},
|
553 |
+
"time": "2022-02-01T15:19:50+00:00",
|
554 |
+
"type": "metapackage",
|
555 |
+
"notification-url": "https://packagist.org/downloads/",
|
556 |
+
"license": [
|
557 |
+
"MIT"
|
558 |
+
],
|
559 |
+
"authors": [
|
560 |
+
{
|
561 |
+
"name": "Marco Pivetta",
|
562 |
+
"email": "ocramius@gmail.com",
|
563 |
+
"role": "maintainer"
|
564 |
+
},
|
565 |
+
{
|
566 |
+
"name": "Ilya Tribusean",
|
567 |
+
"email": "slash3b@gmail.com",
|
568 |
+
"role": "maintainer"
|
569 |
+
}
|
570 |
+
],
|
571 |
+
"description": "Prevents installation of composer packages with known security vulnerabilities: no API, simply require it",
|
572 |
+
"support": {
|
573 |
+
"issues": "https://github.com/Roave/SecurityAdvisories/issues",
|
574 |
+
"source": "https://github.com/Roave/SecurityAdvisories/tree/latest"
|
575 |
+
},
|
576 |
+
"funding": [
|
577 |
+
{
|
578 |
+
"url": "https://github.com/Ocramius",
|
579 |
+
"type": "github"
|
580 |
+
},
|
581 |
+
{
|
582 |
+
"url": "https://tidelift.com/funding/github/packagist/roave/security-advisories",
|
583 |
+
"type": "tidelift"
|
584 |
+
}
|
585 |
+
]
|
586 |
+
},
|
587 |
+
{
|
588 |
+
"name": "wpml/collect",
|
589 |
+
"version": "dev-wpml-collect-rename",
|
590 |
+
"version_normalized": "dev-wpml-collect-rename",
|
591 |
+
"source": {
|
592 |
+
"type": "git",
|
593 |
+
"url": "https://github.com/OnTheGoSystems/collect.git",
|
594 |
+
"reference": "c822762bb9dcc581b26e16cc19226d7a6087c23c"
|
595 |
+
},
|
596 |
+
"dist": {
|
597 |
+
"type": "zip",
|
598 |
+
"url": "https://api.github.com/repos/OnTheGoSystems/collect/zipball/c822762bb9dcc581b26e16cc19226d7a6087c23c",
|
599 |
+
"reference": "c822762bb9dcc581b26e16cc19226d7a6087c23c",
|
600 |
+
"shasum": ""
|
601 |
+
},
|
602 |
+
"require": {
|
603 |
+
"php": ">=5.5.9"
|
604 |
+
},
|
605 |
+
"require-dev": {
|
606 |
+
"mockery/mockery": "~0.9.4",
|
607 |
+
"phpunit/phpunit": "~4.1"
|
608 |
+
},
|
609 |
+
"time": "2020-10-28T08:07:38+00:00",
|
610 |
+
"type": "library",
|
611 |
+
"installation-source": "dist",
|
612 |
+
"autoload": {
|
613 |
+
"files": [
|
614 |
+
"src/Illuminate/Support/helpers.php"
|
615 |
+
],
|
616 |
+
"psr-4": {
|
617 |
+
"WPML\\Collect\\": "src/Illuminate"
|
618 |
+
}
|
619 |
+
},
|
620 |
+
"notification-url": "https://packagist.org/downloads/",
|
621 |
+
"license": [
|
622 |
+
"MIT"
|
623 |
+
],
|
624 |
+
"authors": [
|
625 |
+
{
|
626 |
+
"name": "Taylor Otwell",
|
627 |
+
"email": "taylorotwell@gmail.com"
|
628 |
+
}
|
629 |
+
],
|
630 |
+
"description": "Collect - Illuminate Collections as a separate package.",
|
631 |
+
"keywords": [
|
632 |
+
"collection",
|
633 |
+
"laravel"
|
634 |
+
],
|
635 |
+
"support": {
|
636 |
+
"source": "https://github.com/OnTheGoSystems/collect/tree/wpml-collect-rename"
|
637 |
+
}
|
638 |
+
},
|
639 |
+
{
|
640 |
+
"name": "wpml/core-api",
|
641 |
+
"version": "0.1.5",
|
642 |
+
"version_normalized": "0.1.5.0",
|
643 |
+
"source": {
|
644 |
+
"type": "git",
|
645 |
+
"url": "https://git.onthegosystems.com/wpml-packages/core-api.git",
|
646 |
+
"reference": "369cfd53dba15e4dceb55e0e0458c16a5a142eab"
|
647 |
+
},
|
648 |
+
"require-dev": {
|
649 |
+
"10up/wp_mock": "0.2.0",
|
650 |
+
"antecedent/patchwork": "^2.0",
|
651 |
+
"cvuorinen/phpdoc-markdown-public": "^0.2.0",
|
652 |
+
"otgs/unit-tests-framework": "~1.2.0",
|
653 |
+
"wpml/collect": "dev-wpml-collect-rename",
|
654 |
+
"wpml/fp": "dev-develop",
|
655 |
+
"wpml/wp": "dev-develop"
|
656 |
+
},
|
657 |
+
"time": "2021-11-16T12:50:12+00:00",
|
658 |
+
"type": "library",
|
659 |
+
"installation-source": "source",
|
660 |
+
"autoload": {
|
661 |
+
"classmap": [
|
662 |
+
"core"
|
663 |
+
],
|
664 |
+
"files": []
|
665 |
+
},
|
666 |
+
"notification-url": "https://packagist.org/downloads/",
|
667 |
+
"license": [
|
668 |
+
"MIT"
|
669 |
+
],
|
670 |
+
"authors": [
|
671 |
+
{
|
672 |
+
"name": "Bruce Pearson",
|
673 |
+
"email": "bruce@onthegosystems.com"
|
674 |
+
}
|
675 |
+
],
|
676 |
+
"description": "Class and utilities to interface with WPML core functionality"
|
677 |
+
},
|
678 |
+
{
|
679 |
+
"name": "wpml/fp",
|
680 |
+
"version": "0.1.8",
|
681 |
+
"version_normalized": "0.1.8.0",
|
682 |
+
"source": {
|
683 |
+
"type": "git",
|
684 |
+
"url": "https://git.onthegosystems.com/wpml-packages/fp.git",
|
685 |
+
"reference": "5f233620422988ca47f3180d2fc1c2aa18191bee"
|
686 |
+
},
|
687 |
+
"require-dev": {
|
688 |
+
"cvuorinen/phpdoc-markdown-public": "^0.2.0",
|
689 |
+
"lucatume/function-mocker": "~1.0",
|
690 |
+
"phpunit/phpunit": "^5",
|
691 |
+
"wpml/collect": "dev-wpml-collect-rename"
|
692 |
+
},
|
693 |
+
"time": "2021-10-19T01:39:15+00:00",
|
694 |
+
"type": "library",
|
695 |
+
"installation-source": "source",
|
696 |
+
"autoload": {
|
697 |
+
"classmap": [
|
698 |
+
"core"
|
699 |
+
],
|
700 |
+
"files": [
|
701 |
+
"core/functions.php",
|
702 |
+
"core/strings_functions.php",
|
703 |
+
"core/system.php"
|
704 |
+
]
|
705 |
+
},
|
706 |
+
"notification-url": "https://packagist.org/downloads/"
|
707 |
+
},
|
708 |
+
{
|
709 |
+
"name": "wpml/wp",
|
710 |
+
"version": "0.1.7",
|
711 |
+
"version_normalized": "0.1.7.0",
|
712 |
+
"source": {
|
713 |
+
"type": "git",
|
714 |
+
"url": "https://git.onthegosystems.com/wpml-packages/wp.git",
|
715 |
+
"reference": "dc2fbeb965133f5e569f51009b919a585a5fc1a9"
|
716 |
+
},
|
717 |
+
"require-dev": {
|
718 |
+
"antecedent/patchwork": "^2.0",
|
719 |
+
"otgs/unit-tests-framework": "~1.2.0",
|
720 |
+
"wpml/collect": "dev-wpml-collect-rename",
|
721 |
+
"wpml/fp": "dev-develop"
|
722 |
+
},
|
723 |
+
"time": "2021-10-08T07:51:31+00:00",
|
724 |
+
"type": "library",
|
725 |
+
"installation-source": "source",
|
726 |
+
"autoload": {
|
727 |
+
"classmap": [
|
728 |
+
"classes/"
|
729 |
+
],
|
730 |
+
"files": []
|
731 |
+
},
|
732 |
+
"notification-url": "https://packagist.org/downloads/",
|
733 |
+
"license": [
|
734 |
+
"MIT"
|
735 |
+
],
|
736 |
+
"authors": [
|
737 |
+
{
|
738 |
+
"name": "Bruce Pearson",
|
739 |
+
"email": "bruce@onthegosystems.com"
|
740 |
+
}
|
741 |
+
],
|
742 |
+
"description": "Class and utilities to interface with WordPress from WPML"
|
743 |
+
},
|
744 |
+
{
|
745 |
+
"name": "wpml/wpml-dependencies",
|
746 |
+
"version": "dev-master",
|
747 |
+
"version_normalized": "9999999-dev",
|
748 |
+
"source": {
|
749 |
+
"type": "git",
|
750 |
+
"url": "ssh://git@git.onthegosystems.com:10022/glue-plugins/wpml/packages/wpml-dependencies.git",
|
751 |
+
"reference": "bd11271851a380365a6d97c5920c4cd089a07427"
|
752 |
+
},
|
753 |
+
"require": {
|
754 |
+
"otgs/auryn": "dev-master",
|
755 |
+
"otgs/icons": "~1.0",
|
756 |
+
"otgs/ui": "dev-master",
|
757 |
+
"wpml/collect": "dev-wpml-collect-rename",
|
758 |
+
"wpml/core-api": "0.1.5",
|
759 |
+
"wpml/fp": "0.1.8",
|
760 |
+
"wpml/wp": "0.1.7"
|
761 |
+
},
|
762 |
+
"require-dev": {
|
763 |
+
"bamarni/composer-bin-plugin": "^1.4",
|
764 |
+
"composer/composer": "~2.0"
|
765 |
+
},
|
766 |
+
"time": "2022-04-22T19:51:13+00:00",
|
767 |
+
"type": "library",
|
768 |
+
"installation-source": "source",
|
769 |
+
"autoload": {
|
770 |
+
"classmap": [
|
771 |
+
"lib/"
|
772 |
+
],
|
773 |
+
"files": [
|
774 |
+
"lib/classes/container/functions.php"
|
775 |
+
]
|
776 |
+
},
|
777 |
+
"scripts": {
|
778 |
+
"make": [
|
779 |
+
"make githooks"
|
780 |
+
],
|
781 |
+
"post-install-cmd": [
|
782 |
+
"@make",
|
783 |
+
"@composer bin all install --ansi"
|
784 |
+
],
|
785 |
+
"post-update-cmd": [
|
786 |
+
"@composer bin all update --ansi"
|
787 |
+
]
|
788 |
+
},
|
789 |
+
"authors": [
|
790 |
+
{
|
791 |
+
"name": "WPML",
|
792 |
+
"email": "hello@wpml.com",
|
793 |
+
"homepage": "http://wpml.org"
|
794 |
+
}
|
795 |
+
],
|
796 |
+
"description": "WPML dependencies for running WCML independently.",
|
797 |
+
"homepage": "https://git.onthegosystems.com/glue-plugins/wpml/packages/wpml-dependencies"
|
798 |
+
}
|
799 |
+
]
|
addons/vendor/otgs/auryn/CONTRIBUTING.md
ADDED
@@ -0,0 +1,28 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
## Submitting useful bug reports
|
2 |
+
|
3 |
+
Please search existing issues first to make sure this is not a duplicate.
|
4 |
+
Every issue report has a cost for the developers required to field it; be
|
5 |
+
respectful of others' time and ensure your report isn't spurious prior to
|
6 |
+
submission. Additionally, please do us all a favor by adhering to the
|
7 |
+
principles of sound bug reporting laid out by Simon Tatham here:
|
8 |
+
|
9 |
+
http://www.chiark.greenend.org.uk/~sgtatham/bugs.html
|
10 |
+
|
11 |
+
## Development ideology
|
12 |
+
|
13 |
+
Truths which we believe to be self-evident:
|
14 |
+
|
15 |
+
- **The answer is not more options.** If you feel compelled to expose
|
16 |
+
new preferences to the user it's very possible you've made a wrong
|
17 |
+
turn somewhere.
|
18 |
+
|
19 |
+
- **There are no power users.** The idea that some users "understand"
|
20 |
+
concepts better than others has proven to be, for the most part, false.
|
21 |
+
If anything, "power users" are more dangerous than the rest, and we
|
22 |
+
should avoid exposing dangerous functionality to them.
|
23 |
+
|
24 |
+
## Code style
|
25 |
+
|
26 |
+
Please ensure any submissions adhere to the PSR-2 code style standard:
|
27 |
+
|
28 |
+
https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-2-coding-style-guide.md
|
addons/vendor/otgs/auryn/LICENSE
ADDED
@@ -0,0 +1,21 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
The MIT License (MIT)
|
2 |
+
|
3 |
+
Copyright (c) 2013-2014 Daniel Lowrey, Levi Morrison, Dan Ackroyd
|
4 |
+
|
5 |
+
Permission is hereby granted, free of charge, to any person obtaining a
|
6 |
+
copy of this software and associated documentation files (the "Software"),
|
7 |
+
to deal in the Software without restriction, including without limitation
|
8 |
+
the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
9 |
+
and/or sell copies of the Software, and to permit persons to whom the
|
10 |
+
Software is furnished to do so, subject to the following conditions:
|
11 |
+
|
12 |
+
The above copyright notice and this permission notice shall be included
|
13 |
+
in all copies or substantial portions of the Software.
|
14 |
+
|
15 |
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16 |
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17 |
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18 |
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19 |
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
20 |
+
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
21 |
+
IN THE SOFTWARE.
|
addons/vendor/otgs/auryn/README.md
ADDED
@@ -0,0 +1,847 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# auryn [![Build Status](https://travis-ci.org/rdlowrey/auryn.svg?branch=master)](https://travis-ci.org/rdlowrey/auryn)
|
2 |
+
|
3 |
+
auryn is a recursive dependency injector. Use auryn to bootstrap and wire together
|
4 |
+
S.O.L.I.D., object-oriented PHP applications.
|
5 |
+
|
6 |
+
##### How It Works
|
7 |
+
|
8 |
+
Among other things, auryn recursively instantiates class dependencies based on the parameter
|
9 |
+
type-hints specified in class constructor signatures. This requires the use of Reflection. You may
|
10 |
+
have heard that "reflection is slow". Let's clear something up: *anything* can be "slow" if you're
|
11 |
+
doing it wrong. Reflection is an order of magnitude faster than disk access and several orders of
|
12 |
+
magnitude faster than retrieving information (for example) from a remote database. Additionally,
|
13 |
+
each reflection offers the opportunity to cache the results if you're worried about speed. auryn
|
14 |
+
caches any reflections it generates to minimize the potential performance impact.
|
15 |
+
|
16 |
+
> auryn **is NOT** a Service Locator. DO NOT turn it into one by passing the injector into your
|
17 |
+
> application classes. Service Locator is an anti-pattern; it hides class dependencies, makes code
|
18 |
+
> more difficult to maintain and makes a liar of your API! You should *only* use an injector for
|
19 |
+
> wiring together the disparate parts of your application during your bootstrap phase.
|
20 |
+
|
21 |
+
## The Guide
|
22 |
+
|
23 |
+
**Basic Usage**
|
24 |
+
|
25 |
+
* [Basic Instantiation](#basic-instantiation)
|
26 |
+
* [Injection Definitions](#injection-definitions)
|
27 |
+
* [Type-Hint Aliasing](#type-hint-aliasing)
|
28 |
+
* [Non-Class Parameters](#non-class-parameters)
|
29 |
+
* [Global Parameter Definitions](#global-parameter-definitions)
|
30 |
+
|
31 |
+
**Advanced Usage**
|
32 |
+
|
33 |
+
* [Instance Sharing](#instance-sharing)
|
34 |
+
* [Instantiation Delegates](#instantiation-delegates)
|
35 |
+
* [Prepares and Setter Injection](#prepares-and-setter-injection)
|
36 |
+
* [Injecting for Execution](#injecting-for-execution)
|
37 |
+
* [Dependency Resolution](#dependency-resolution)
|
38 |
+
|
39 |
+
**Example Use Cases**
|
40 |
+
|
41 |
+
* [Avoiding Evil Singletons](#avoiding-evil-singletons)
|
42 |
+
* [Application Bootstrapping](#app-bootstrapping)
|
43 |
+
|
44 |
+
|
45 |
+
## Requirements and Installation
|
46 |
+
|
47 |
+
- auryn requires PHP 5.3 or higher.
|
48 |
+
|
49 |
+
#### Installation
|
50 |
+
|
51 |
+
###### Github
|
52 |
+
|
53 |
+
You can clone the latest auryn iteration at anytime from the github repository:
|
54 |
+
|
55 |
+
```bash
|
56 |
+
$ git clone git://github.com/rdlowrey/auryn.git
|
57 |
+
```
|
58 |
+
|
59 |
+
###### Composer
|
60 |
+
|
61 |
+
You may also use composer to include auryn as a dependency in your projects `composer.json`. The relevant package is `rdlowrey/auryn`.
|
62 |
+
|
63 |
+
Alternatively require the package using composer cli:
|
64 |
+
|
65 |
+
```bash
|
66 |
+
composer require rdlowrey/auryn
|
67 |
+
```
|
68 |
+
|
69 |
+
##### Manual Download
|
70 |
+
|
71 |
+
Archived tagged release versions are also available for manual download on the project
|
72 |
+
[tags page](https://github.com/rdlowrey/auryn/tags)
|
73 |
+
|
74 |
+
|
75 |
+
## Basic Usage
|
76 |
+
|
77 |
+
To start using the injector, simply create a new instance of the `Auryn\Injector` ("the Injector")
|
78 |
+
class:
|
79 |
+
|
80 |
+
```php
|
81 |
+
<?php
|
82 |
+
$injector = new Auryn\Injector;
|
83 |
+
```
|
84 |
+
|
85 |
+
### Basic Instantiation
|
86 |
+
|
87 |
+
If a class doesn't specify any dependencies in its constructor signature there's little point in
|
88 |
+
using the Injector to generate it. However, for the sake of completeness consider that you can do
|
89 |
+
the following with equivalent results:
|
90 |
+
|
91 |
+
```php
|
92 |
+
<?php
|
93 |
+
$injector = new Auryn\Injector;
|
94 |
+
$obj1 = new SomeNamespace\MyClass;
|
95 |
+
$obj2 = $injector->make('SomeNamespace\MyClass');
|
96 |
+
|
97 |
+
var_dump($obj2 instanceof SomeNamespace\MyClass); // true
|
98 |
+
```
|
99 |
+
|
100 |
+
###### Concrete Type-hinted Dependencies
|
101 |
+
|
102 |
+
If a class only asks for concrete dependencies you can use the Injector to inject them without
|
103 |
+
specifying any injection definitions. For example, in the following scenario you can use the
|
104 |
+
Injector to automatically provision `MyClass` with the required `SomeDependency` and `AnotherDependency`
|
105 |
+
class instances:
|
106 |
+
|
107 |
+
```php
|
108 |
+
<?php
|
109 |
+
class SomeDependency {}
|
110 |
+
|
111 |
+
class AnotherDependency {}
|
112 |
+
|
113 |
+
class MyClass {
|
114 |
+
public $dep1;
|
115 |
+
public $dep2;
|
116 |
+
public function __construct(SomeDependency $dep1, AnotherDependency $dep2) {
|
117 |
+
$this->dep1 = $dep1;
|
118 |
+
$this->dep2 = $dep2;
|
119 |
+
}
|
120 |
+
}
|
121 |
+
|
122 |
+
$injector = new Auryn\Injector;
|
123 |
+
$myObj = $injector->make('MyClass');
|
124 |
+
|
125 |
+
var_dump($myObj->dep1 instanceof SomeDependency); // true
|
126 |
+
var_dump($myObj->dep2 instanceof AnotherDependency); // true
|
127 |
+
```
|
128 |
+
|
129 |
+
###### Recursive Dependency Instantiation
|
130 |
+
|
131 |
+
One of the Injector's key attributes is that it recursively traverses class dependency trees to
|
132 |
+
instantiate objects. This is just a fancy way of saying, "if you instantiate object A which asks for
|
133 |
+
object B, the Injector will instantiate any of object B's dependencies so that B can be instantiated
|
134 |
+
and provided to A". This is perhaps best understood with a simple example. Consider the following
|
135 |
+
classes in which a `Car` asks for `Engine` and the `Engine` class has concrete dependencies of its
|
136 |
+
own:
|
137 |
+
|
138 |
+
```php
|
139 |
+
<?php
|
140 |
+
class Car {
|
141 |
+
private $engine;
|
142 |
+
public function __construct(Engine $engine) {
|
143 |
+
$this->engine = $engine;
|
144 |
+
}
|
145 |
+
}
|
146 |
+
|
147 |
+
class Engine {
|
148 |
+
private $sparkPlug;
|
149 |
+
private $piston;
|
150 |
+
public function __construct(SparkPlug $sparkPlug, Piston $piston) {
|
151 |
+
$this->sparkPlug = $sparkPlug;
|
152 |
+
$this->piston = $piston;
|
153 |
+
}
|
154 |
+
}
|
155 |
+
|
156 |
+
$injector = new Auryn\Injector;
|
157 |
+
$car = $injector->make('Car');
|
158 |
+
var_dump($car instanceof Car); // true
|
159 |
+
```
|
160 |
+
|
161 |
+
### Injection Definitions
|
162 |
+
|
163 |
+
You may have noticed that the previous examples all demonstrated instantiation of classes with
|
164 |
+
explicit, type-hinted, concrete constructor parameters. Obviously, many of your classes won't fit
|
165 |
+
this mold. Some classes will type-hint interfaces and abstract classes. Some will specify scalar
|
166 |
+
parameters which offer no possibility of type-hinting in PHP. Still other parameters will be arrays,
|
167 |
+
etc. In such cases we need to assist the Injector by telling it exactly what we want to inject.
|
168 |
+
|
169 |
+
###### Defining Class Names for Constructor Parameters
|
170 |
+
|
171 |
+
Let's look at how to provision a class with non-concrete type-hints in its constructor signature.
|
172 |
+
Consider the following code in which a `Car` needs an `Engine` and `Engine` is an interface:
|
173 |
+
|
174 |
+
```php
|
175 |
+
<?php
|
176 |
+
interface Engine {}
|
177 |
+
|
178 |
+
class V8 implements Engine {}
|
179 |
+
|
180 |
+
class Car {
|
181 |
+
private $engine;
|
182 |
+
public function __construct(Engine $engine) {
|
183 |
+
$this->engine = $engine;
|
184 |
+
}
|
185 |
+
}
|
186 |
+
```
|
187 |
+
|
188 |
+
To instantiate a `Car` in this case, we simply need to define an injection definition for the class
|
189 |
+
ahead of time:
|
190 |
+
|
191 |
+
```php
|
192 |
+
<?php
|
193 |
+
$injector = new Auryn\Injector;
|
194 |
+
$injector->define('Car', ['engine' => 'V8']);
|
195 |
+
$car = $injector->make('Car');
|
196 |
+
|
197 |
+
var_dump($car instanceof Car); // true
|
198 |
+
```
|
199 |
+
|
200 |
+
The most important points to notice here are:
|
201 |
+
|
202 |
+
1. A custom definition is an `array` whose keys match constructor parameter names
|
203 |
+
2. The values in the definition array represent the class names to inject for the specified
|
204 |
+
parameter key
|
205 |
+
|
206 |
+
Because the `Car` constructor parameter we needed to define was named `$engine`, our definition
|
207 |
+
specified an `engine` key whose value was the name of the class (`V8`) that we want to inject.
|
208 |
+
|
209 |
+
Custom injection definitions are only necessary on a per-parameter basis. For example, in the
|
210 |
+
following class we only need to define the injectable class for `$arg2` because `$arg1` specifies a
|
211 |
+
concrete class type-hint:
|
212 |
+
|
213 |
+
```php
|
214 |
+
<?php
|
215 |
+
class MyClass {
|
216 |
+
private $arg1;
|
217 |
+
private $arg2;
|
218 |
+
public function __construct(SomeConcreteClass $arg1, SomeInterface $arg2) {
|
219 |
+
$this->arg1 = $arg1;
|
220 |
+
$this->arg2 = $arg2;
|
221 |
+
}
|
222 |
+
}
|
223 |
+
|
224 |
+
$injector = new Auryn\Injector;
|
225 |
+
$injector->define('MyClass', ['arg2' => 'SomeImplementationClass']);
|
226 |
+
|
227 |
+
$myObj = $injector->make('MyClass');
|
228 |
+
```
|
229 |
+
|
230 |
+
> **NOTE:** Injecting instances where an abstract class is type-hinted works in exactly the same way
|
231 |
+
as the above examples for interface type-hints.
|
232 |
+
|
233 |
+
###### Using Existing Instances in Injection Definitions
|
234 |
+
|
235 |
+
Injection definitions may also specify a pre-existing instance of the requisite class instead of the
|
236 |
+
string class name:
|
237 |
+
|
238 |
+
```php
|
239 |
+
<?php
|
240 |
+
interface SomeInterface {}
|
241 |
+
|
242 |
+
class SomeImplementation implements SomeInterface {}
|
243 |
+
|
244 |
+
class MyClass {
|
245 |
+
private $dependency;
|
246 |
+
public function __construct(SomeInterface $dependency) {
|
247 |
+
$this->dependency = $dependency;
|
248 |
+
}
|
249 |
+
}
|
250 |
+
|
251 |
+
$injector = new Auryn\Injector;
|
252 |
+
$dependencyInstance = new SomeImplementation;
|
253 |
+
$injector->define('MyClass', [':dependency' => $dependencyInstance]);
|
254 |
+
|
255 |
+
$myObj = $injector->make('MyClass');
|
256 |
+
|
257 |
+
var_dump($myObj instanceof MyClass); // true
|
258 |
+
```
|
259 |
+
|
260 |
+
> **NOTE:** Since this `define()` call is passing raw values (as evidenced by the colon `:` usage),
|
261 |
+
you can achieve the same result by omitting the array key(s) and relying on parameter order rather
|
262 |
+
than name. Like so: `$injector->define('MyClass', [$dependencyInstance]);`
|
263 |
+
|
264 |
+
###### Specifying Injection Definitions On the Fly
|
265 |
+
|
266 |
+
You may also specify injection definitions at call-time with `Auryn\Injector::make`. Consider:
|
267 |
+
|
268 |
+
```php
|
269 |
+
<?php
|
270 |
+
interface SomeInterface {}
|
271 |
+
|
272 |
+
class SomeImplementationClass implements SomeInterface {}
|
273 |
+
|
274 |
+
class MyClass {
|
275 |
+
private $dependency;
|
276 |
+
public function __construct(SomeInterface $dependency) {
|
277 |
+
$this->dependency = $dependency;
|
278 |
+
}
|
279 |
+
}
|
280 |
+
|
281 |
+
$injector = new Auryn\Injector;
|
282 |
+
$myObj = $injector->make('MyClass', ['dependency' => 'SomeImplementationClass']);
|
283 |
+
|
284 |
+
var_dump($myObj instanceof MyClass); // true
|
285 |
+
```
|
286 |
+
|
287 |
+
The above code shows how even though we haven't called the Injector's `define` method, the
|
288 |
+
call-time specification allows us to instantiate `MyClass`.
|
289 |
+
|
290 |
+
> **NOTE:** on-the-fly instantiation definitions will override a pre-defined definition for the
|
291 |
+
specified class, but only in the context of that particular call to `Auryn\Injector::make`.
|
292 |
+
|
293 |
+
### Type-Hint Aliasing
|
294 |
+
|
295 |
+
Programming to interfaces is one of the most useful concepts in object-oriented design (OOD), and
|
296 |
+
well-designed code should type-hint interfaces whenever possible. But does this mean we have to
|
297 |
+
assign injection definitions for every class in our application to reap the benefits of abstracted
|
298 |
+
dependencies? Thankfully the answer to this question is, "NO." The Injector accommodates this goal
|
299 |
+
by accepting "aliases". Consider:
|
300 |
+
|
301 |
+
```php
|
302 |
+
<?php
|
303 |
+
interface Engine {}
|
304 |
+
class V8 implements Engine {}
|
305 |
+
class Car {
|
306 |
+
private $engine;
|
307 |
+
public function __construct(Engine $engine) {
|
308 |
+
$this->engine = $engine;
|
309 |
+
}
|
310 |
+
}
|
311 |
+
|
312 |
+
$injector = new Auryn\Injector;
|
313 |
+
|
314 |
+
// Tell the Injector class to inject an instance of V8 any time
|
315 |
+
// it encounters an Engine type-hint
|
316 |
+
$injector->alias('Engine', 'V8');
|
317 |
+
|
318 |
+
$car = $injector->make('Car');
|
319 |
+
var_dump($car instanceof Car); // bool(true)
|
320 |
+
```
|
321 |
+
|
322 |
+
In this example we've demonstrated how to specify an alias class for any occurrence of a particular
|
323 |
+
interface or abstract class type-hint. Once an implementation is assigned, the Injector will use it
|
324 |
+
to provision any parameter with a matching type-hint.
|
325 |
+
|
326 |
+
> **IMPORTANT:** If an injection definition is defined for a parameter covered by an implementation
|
327 |
+
assignment, the definition takes precedence over the implementation.
|
328 |
+
|
329 |
+
### Non-Class Parameters
|
330 |
+
|
331 |
+
All of the previous examples have demonstrated how the Injector class instantiates parameters based
|
332 |
+
on type-hints, class name definitions and existing instances. But what happens if we want to inject
|
333 |
+
a scalar or other non-object variable into a class? First, let's establish the following behavioral
|
334 |
+
rule:
|
335 |
+
|
336 |
+
> **IMPORTANT:** The Injector assumes all named-parameter definitions are class names by default.
|
337 |
+
|
338 |
+
If you want the Injector to treat a named-parameter definition as a "raw" value and not a class name,
|
339 |
+
you must prefix the parameter name in your definition with a colon character `:`. For example,
|
340 |
+
consider the following code in which we tell the Injector to share a `PDO` database connection
|
341 |
+
instance and define its scalar constructor parameters:
|
342 |
+
|
343 |
+
```php
|
344 |
+
<?php
|
345 |
+
$injector = new Auryn\Injector;
|
346 |
+
$injector->share('PDO');
|
347 |
+
$injector->define('PDO', [
|
348 |
+
':dsn' => 'mysql:dbname=testdb;host=127.0.0.1',
|
349 |
+
':username' => 'dbuser',
|
350 |
+
':passwd' => 'dbpass'
|
351 |
+
]);
|
352 |
+
|
353 |
+
$db = $injector->make('PDO');
|
354 |
+
```
|
355 |
+
|
356 |
+
The colon character preceding the parameter names tells the Injector that the associated values ARE
|
357 |
+
NOT class names. If the colons had been omitted above, auryn would attempt to instantiate classes of
|
358 |
+
the names specified in the string and an exception would result. Also, note that we could just as
|
359 |
+
easily specified arrays or integers or any other data type in the above definitions. As long as the
|
360 |
+
parameter name is prefixed with a `:`, auryn will inject the value directly without attempting to
|
361 |
+
instantiate it.
|
362 |
+
|
363 |
+
> **NOTE:** As mentioned previously, since this `define()` call is passing raw values, you may opt to
|
364 |
+
assign the values by parameter order rather than name. Since PDO's first three parameters are `$dsn`,
|
365 |
+
`$username`, and `$password`, in that order, you could accomplish the same result by leaving out the
|
366 |
+
array keys, like so:
|
367 |
+
`$injector->define('PDO', ['mysql:dbname=testdb;host=127.0.0.1', 'dbuser', 'dbpass']);`
|
368 |
+
|
369 |
+
### Global Parameter Definitions
|
370 |
+
|
371 |
+
Sometimes applications may reuse the same value everywhere. However, it can be a hassle to manually
|
372 |
+
specify definitions for this sort of thing everywhere it might be used in the app. auryn mitigates
|
373 |
+
this problem by exposing the `Injector::defineParam()` method. Consider the following example ...
|
374 |
+
|
375 |
+
```php
|
376 |
+
<?php
|
377 |
+
$myUniversalValue = 42;
|
378 |
+
|
379 |
+
class MyClass {
|
380 |
+
public $myValue;
|
381 |
+
public function __construct($myValue) {
|
382 |
+
$this->myValue = $myValue;
|
383 |
+
}
|
384 |
+
}
|
385 |
+
|
386 |
+
$injector = new Auryn\Injector;
|
387 |
+
$injector->defineParam('myValue', $myUniversalValue);
|
388 |
+
$obj = $injector->make('MyClass');
|
389 |
+
var_dump($obj->myValue === 42); // bool(true)
|
390 |
+
```
|
391 |
+
|
392 |
+
Because we specified a global definition for `myValue`, all parameters that are not in some other
|
393 |
+
way defined (as below) that match the specified parameter name are auto-filled with the global value.
|
394 |
+
If a parameter matches any of the following criteria the global value is not used:
|
395 |
+
|
396 |
+
- A typehint
|
397 |
+
- A predefined injection definition
|
398 |
+
- A custom call time definition
|
399 |
+
|
400 |
+
|
401 |
+
## Advanced Usage
|
402 |
+
|
403 |
+
### Instance Sharing
|
404 |
+
|
405 |
+
One of the more ubiquitous plagues in modern OOP is the Singleton anti-pattern. Coders looking to
|
406 |
+
limit classes to a single instance often fall into the trap of using `static` Singleton
|
407 |
+
implementations for things like configuration classes and database connections. While it's often
|
408 |
+
necessary to prevent multiple instances of a class, the Singleton method spells death to testability
|
409 |
+
and should generally be avoided. `Auryn\Injector` makes sharing class instances across contexts a
|
410 |
+
triviality while allowing maximum testability and API transparency.
|
411 |
+
|
412 |
+
Let's consider how a typical problem facing object-oriented web applications is easily solved by
|
413 |
+
wiring together your application using auryn. Here, we want to inject a single database connection
|
414 |
+
instance across multiple layers of an application. We have a controller class that asks for a
|
415 |
+
DataMapper that requires a `PDO` database connection instance:
|
416 |
+
|
417 |
+
```php
|
418 |
+
<?php
|
419 |
+
class DataMapper {
|
420 |
+
private $pdo;
|
421 |
+
public function __construct(PDO $pdo) {
|
422 |
+
$this->pdo = $pdo;
|
423 |
+
}
|
424 |
+
}
|
425 |
+
|
426 |
+
class MyController {
|
427 |
+
private $mapper;
|
428 |
+
public function __construct(DataMapper $mapper) {
|
429 |
+
$this->mapper = $mapper;
|
430 |
+
}
|
431 |
+
}
|
432 |
+
|
433 |
+
$db = new PDO('mysql:host=localhost;dbname=mydb', 'user', 'pass');
|
434 |
+
|
435 |
+
$injector = new Auryn\Injector;
|
436 |
+
$injector->share($db);
|
437 |
+
|
438 |
+
$myController = $injector->make('MyController');
|
439 |
+
```
|
440 |
+
|
441 |
+
In the above code, the `DataMapper` instance will be provisioned with the same `PDO` database
|
442 |
+
connection instance we originally shared. This example is contrived and overly simple, but the
|
443 |
+
implication should be clear:
|
444 |
+
|
445 |
+
> By sharing an instance of a class, `Auryn\Injector` will always use that instance when
|
446 |
+
> provisioning classes that type-hint the shared class.
|
447 |
+
|
448 |
+
###### A Simpler Example
|
449 |
+
|
450 |
+
Let's look at a simple proof of concept:
|
451 |
+
|
452 |
+
```php
|
453 |
+
<?php
|
454 |
+
class Person {
|
455 |
+
public $name = 'John Snow';
|
456 |
+
}
|
457 |
+
|
458 |
+
$injector = new Auryn\Injector;
|
459 |
+
$injector->share('Person');
|
460 |
+
|
461 |
+
$person = $injector->make('Person');
|
462 |
+
var_dump($person->name); // John Snow
|
463 |
+
|
464 |
+
$person->name = 'Arya Stark';
|
465 |
+
|
466 |
+
$anotherPerson = $injector->make('Person');
|
467 |
+
var_dump($anotherPerson->name); // Arya Stark
|
468 |
+
var_dump($person === $anotherPerson); // bool(true) because it's the same instance!
|
469 |
+
```
|
470 |
+
|
471 |
+
Defining an object as shared will store the provisioned instance in the Injector's shared cache and
|
472 |
+
all future requests to the provider for an injected instance of that class will return the
|
473 |
+
originally created object. Note that in the above code, we shared the class name (`Person`)
|
474 |
+
instead of an actual instance. Sharing works with either a class name or an instance of a class.
|
475 |
+
The difference is that when you specify a class name, the Injector
|
476 |
+
will cache the shared instance the first time it is asked to create it.
|
477 |
+
|
478 |
+
> **NOTE:** Once the Injector caches a shared instance, call-time definitions passed to
|
479 |
+
`Auryn\Injector::make` will have no effect. Once shared, an instance will always be returned for
|
480 |
+
instantiations of its type until the object is un-shared or refreshed:
|
481 |
+
|
482 |
+
### Instantiation Delegates
|
483 |
+
|
484 |
+
Often factory classes/methods are used to prepare an object for use after instantiation. auryn
|
485 |
+
allows you to integrate factories and builders directly into the injection process by specifying
|
486 |
+
callable instantiation delegates on a per-class basis. Let's look at a very basic example to
|
487 |
+
demonstrate the concept of injection delegates:
|
488 |
+
|
489 |
+
```php
|
490 |
+
<?php
|
491 |
+
class MyComplexClass {
|
492 |
+
public $verification = false;
|
493 |
+
public function doSomethingAfterInstantiation() {
|
494 |
+
$this->verification = true;
|
495 |
+
}
|
496 |
+
}
|
497 |
+
|
498 |
+
$complexClassFactory = function() {
|
499 |
+
$obj = new MyComplexClass;
|
500 |
+
$obj->doSomethingAfterInstantiation();
|
501 |
+
|
502 |
+
return $obj;
|
503 |
+
};
|
504 |
+
|
505 |
+
$injector = new Auryn\Injector;
|
506 |
+
$injector->delegate('MyComplexClass', $complexClassFactory);
|
507 |
+
|
508 |
+
$obj = $injector->make('MyComplexClass');
|
509 |
+
var_dump($obj->verification); // bool(true)
|
510 |
+
```
|
511 |
+
|
512 |
+
In the above code we delegate instantiation of the `MyComplexClass` class to a closure,
|
513 |
+
`$complexClassFactory`. Once this delegation is made, the Injector will return the results of the
|
514 |
+
specified closure when asked to instantiate `MyComplexClass`.
|
515 |
+
|
516 |
+
###### Available Delegate Types
|
517 |
+
|
518 |
+
Any valid PHP callable may be registered as a class instantiation delegate using
|
519 |
+
`Auryn\Injector::delegate`. Additionally you may specify the name of a delegate class that
|
520 |
+
specifies an `__invoke` method and it will be automatically provisioned and have its `__invoke`
|
521 |
+
method called at delegation time. Instance methods from uninstantiated classes may also be specified
|
522 |
+
using the `['NonStaticClassName', 'factoryMethod']` construction. For example:
|
523 |
+
|
524 |
+
```php
|
525 |
+
<?php
|
526 |
+
class SomeClassWithDelegatedInstantiation {
|
527 |
+
public $value = 0;
|
528 |
+
}
|
529 |
+
class SomeFactoryDependency {}
|
530 |
+
class MyFactory {
|
531 |
+
private $dependency;
|
532 |
+
function __construct(SomeFactoryDependency $dep) {
|
533 |
+
$this->dependency = $dep;
|
534 |
+
}
|
535 |
+
function __invoke() {
|
536 |
+
$obj = new SomeClassWithDelegatedInstantiation;
|
537 |
+
$obj->value = 1;
|
538 |
+
return $obj;
|
539 |
+
}
|
540 |
+
function factoryMethod() {
|
541 |
+
$obj = new SomeClassWithDelegatedInstantiation;
|
542 |
+
$obj->value = 2;
|
543 |
+
return $obj;
|
544 |
+
}
|
545 |
+
}
|
546 |
+
|
547 |
+
// Works because MyFactory specifies a magic __invoke method
|
548 |
+
$injector->delegate('SomeClassWithDelegatedInstantiation', 'MyFactory');
|
549 |
+
$obj = $injector->make('SomeClassWithDelegatedInstantiation');
|
550 |
+
var_dump($obj->value); // int(1)
|
551 |
+
|
552 |
+
// This also works
|
553 |
+
$injector->delegate('SomeClassWithDelegatedInstantiation', 'MyFactory::factoryMethod');
|
554 |
+
$obj = $injector->make('SomeClassWithDelegatedInstantiation');
|
555 |
+
$obj = $injector->make('SomeClassWithDelegatedInstantiation');
|
556 |
+
var_dump($obj->value); // int(2)
|
557 |
+
```
|
558 |
+
|
559 |
+
### Prepares and Setter Injection
|
560 |
+
|
561 |
+
Constructor injection is almost always preferable to setter injection. However, some APIs require
|
562 |
+
additional post-instantiation mutations. auryn accommodates these use cases with its
|
563 |
+
`Injector::prepare()` method. Users may register any class or interface name for post-instantiation
|
564 |
+
modification. Consider:
|
565 |
+
|
566 |
+
```php
|
567 |
+
<?php
|
568 |
+
|
569 |
+
class MyClass {
|
570 |
+
public $myProperty = 0;
|
571 |
+
}
|
572 |
+
|
573 |
+
$injector->prepare('MyClass', function($myObj, $injector) {
|
574 |
+
$myObj->myProperty = 42;
|
575 |
+
});
|
576 |
+
|
577 |
+
$myObj = $injector->make('MyClass');
|
578 |
+
var_dump($myObj->myProperty); // int(42)
|
579 |
+
```
|
580 |
+
|
581 |
+
While the above example is contrived, the usefulness should be clear.
|
582 |
+
|
583 |
+
|
584 |
+
### Injecting for Execution
|
585 |
+
|
586 |
+
In addition to provisioning class instances using constructors, auryn can also recursively instantiate
|
587 |
+
the parameters of any [valid PHP callable](http://php.net/manual/en/language.types.callable.php).
|
588 |
+
The following examples all work:
|
589 |
+
|
590 |
+
```php
|
591 |
+
<?php
|
592 |
+
$injector = new Auryn\Injector;
|
593 |
+
$injector->execute(function(){});
|
594 |
+
$injector->execute([$objectInstance, 'methodName']);
|
595 |
+
$injector->execute('globalFunctionName');
|
596 |
+
$injector->execute('MyStaticClass::myStaticMethod');
|
597 |
+
$injector->execute(['MyStaticClass', 'myStaticMethod']);
|
598 |
+
$injector->execute(['MyChildStaticClass', 'parent::myStaticMethod']);
|
599 |
+
$injector->execute('ClassThatHasMagicInvoke');
|
600 |
+
$injector->execute($instanceOfClassThatHasMagicInvoke);
|
601 |
+
$injector->execute('MyClass::myInstanceMethod');
|
602 |
+
```
|
603 |
+
|
604 |
+
Additionally, you can pass in the name of a class for a non-static method and the injector will
|
605 |
+
automatically provision an instance of the class (subject to any definitions or shared instances
|
606 |
+
already stored by the injector) before provisioning and invoking the specified method:
|
607 |
+
|
608 |
+
```php
|
609 |
+
<?php
|
610 |
+
class Dependency {}
|
611 |
+
class AnotherDependency {}
|
612 |
+
class Example {
|
613 |
+
function __construct(Dependency $dep){}
|
614 |
+
function myMethod(AnotherDependency $arg1, $arg2) {
|
615 |
+
return $arg2;
|
616 |
+
}
|
617 |
+
}
|
618 |
+
|
619 |
+
$injector = new Auryn\Injector;
|
620 |
+
|
621 |
+
// outputs: int(42)
|
622 |
+
var_dump($injector->execute('Example::myMethod', $args = [':arg2' => 42]));
|
623 |
+
```
|
624 |
+
|
625 |
+
|
626 |
+
### Dependency Resolution
|
627 |
+
|
628 |
+
`Auryn\Injector` resolves dependencies in the following order:
|
629 |
+
|
630 |
+
1. If a shared instance exists for the class in question, the shared instance will always be returned
|
631 |
+
2. If a delegate callable is assigned for a class, its return result will always be used
|
632 |
+
3. If a call-time definition is passed to `Auryn\Injector::make`, that definition will be used
|
633 |
+
4. If a pre-defined definition exists, it will be used
|
634 |
+
5. If a dependency is type-hinted, the Injector will recursively instantiate it subject to any implementations or definitions
|
635 |
+
6. If no type-hint exists and the parameter has a default value, the default value is injected
|
636 |
+
7. If a global parameter value is defined that value is used
|
637 |
+
8. Throw an exception because you did something stupid
|
638 |
+
|
639 |
+
## Example Use Cases
|
640 |
+
|
641 |
+
Dependency Injection Containers (DIC) are generally misunderstood in the PHP community. One of the
|
642 |
+
primary culprits is the misuse of such containers in the mainstream application frameworks. Often,
|
643 |
+
these frameworks warp their DICs into Service Locator anti-patterns. This is a shame because a
|
644 |
+
good DIC should be the exact opposite of a Service Locator.
|
645 |
+
|
646 |
+
###### auryn Is NOT A Service Locator!
|
647 |
+
|
648 |
+
There's a galaxy of differences between using a DIC to wire together your application versus
|
649 |
+
passing the DIC as a dependency to your objects (Service Locator). Service Locator (SL) is an
|
650 |
+
anti-pattern -- it hides class dependencies, makes code difficult to maintain and makes a liar of
|
651 |
+
your API.
|
652 |
+
|
653 |
+
When you pass a SL into your constructors it makes it difficult to determine what the class dependencies
|
654 |
+
really are. A `House` object depends on `Door` and `Window` objects. A `House` object DOES NOT depend
|
655 |
+
on an instance of `ServiceLocator` regardless of whether the `ServiceLocator` can provide `Door` and
|
656 |
+
`Window` objects.
|
657 |
+
|
658 |
+
In real life you wouldn't build a house by transporting the entire hardware store (hopefully) to
|
659 |
+
the construction site so you can access any parts you need. Instead, the foreman (`__construct()`)
|
660 |
+
asks for the specific parts that will be needed (`Door` and `Window`) and goes about procuring them.
|
661 |
+
Your objects should function in the same way; they should ask only for the specific dependencies
|
662 |
+
required to do their jobs. Giving the `House` access to the entire hardware store is at best poor
|
663 |
+
OOP style and at worst a maintainability nightmare. The takeaway here is this:
|
664 |
+
|
665 |
+
> **IMPORTANT:** do not use auryn like a Service Locator!
|
666 |
+
|
667 |
+
|
668 |
+
### Avoiding Evil Singletons
|
669 |
+
|
670 |
+
A common difficulty in web applications is limiting the number of database connection instances.
|
671 |
+
It's wasteful and slow to open up new connections each time we need to talk to a database.
|
672 |
+
Unfortunately, using singletons to limit these instances makes code brittle and hard to test. Let's
|
673 |
+
see how we can use auryn to inject the same `PDO` instance across the entire scope of our application.
|
674 |
+
|
675 |
+
Say we have a service class that requires two separate data mappers to persist information to a database:
|
676 |
+
|
677 |
+
```php
|
678 |
+
<?php
|
679 |
+
|
680 |
+
class HouseMapper {
|
681 |
+
private $pdo;
|
682 |
+
public function __construct(PDO $pdo) {
|
683 |
+
$this->pdo = $pdo;
|
684 |
+
}
|
685 |
+
public function find($houseId) {
|
686 |
+
$query = 'SELECT * FROM houses WHERE houseId = :houseId';
|
687 |
+
|
688 |
+
$stmt = $this->pdo->prepare($query);
|
689 |
+
$stmt->bindValue(':houseId', $houseId);
|
690 |
+
|
691 |
+
$stmt->setFetchMode(PDO::FETCH_CLASS, 'Model\\Entities\\House');
|
692 |
+
$stmt->execute();
|
693 |
+
$house = $stmt->fetch(PDO::FETCH_CLASS);
|
694 |
+
|
695 |
+
if (false === $house) {
|
696 |
+
throw new RecordNotFoundException(
|
697 |
+
'No houses exist for the specified ID'
|
698 |
+
);
|
699 |
+
}
|
700 |
+
|
701 |
+
return $house;
|
702 |
+
}
|
703 |
+
|
704 |
+
// more data mapper methods here ...
|
705 |
+
}
|
706 |
+
|
707 |
+
class PersonMapper {
|
708 |
+
private $pdo;
|
709 |
+
public function __construct(PDO $pdo) {
|
710 |
+
$this->pdo = $pdo;
|
711 |
+
}
|
712 |
+
// data mapper methods here
|
713 |
+
}
|
714 |
+
|
715 |
+
class SomeService {
|
716 |
+
private $houseMapper;
|
717 |
+
private $personMapper;
|
718 |
+
public function __construct(HouseMapper $hm, PersonMapper $pm) {
|
719 |
+
$this->houseMapper = $hm;
|
720 |
+
$this->personMapper = $pm;
|
721 |
+
}
|
722 |
+
public function doSomething() {
|
723 |
+
// do something with the mappers
|
724 |
+
}
|
725 |
+
}
|
726 |
+
```
|
727 |
+
|
728 |
+
In our wiring/bootstrap code, we simply instantiate the `PDO` instance once and share it in the
|
729 |
+
context of the `Injector`:
|
730 |
+
|
731 |
+
```php
|
732 |
+
<?php
|
733 |
+
$pdo = new PDO('sqlite:some_sqlite_file.db');
|
734 |
+
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
|
735 |
+
|
736 |
+
$injector = new Auryn\Injector;
|
737 |
+
|
738 |
+
$injector->share($pdo);
|
739 |
+
$mapper = $injector->make('SomeService');
|
740 |
+
```
|
741 |
+
|
742 |
+
In the above code, the DIC instantiates our service class. More importantly, the data mapper classes
|
743 |
+
it generates to do so are injected *with the same database connection instance we originally shared*.
|
744 |
+
|
745 |
+
Of course, we don't have to manually instantiate our `PDO` instance. We could just as easily seed
|
746 |
+
the container with a definition for how to create the `PDO` object and let it handle things for us:
|
747 |
+
|
748 |
+
```php
|
749 |
+
<?php
|
750 |
+
$injector->define('PDO', [
|
751 |
+
':dsn' => 'sqlite:some_sqlite_file.db'
|
752 |
+
]);
|
753 |
+
$injector->share('PDO');
|
754 |
+
$service = $injector->make('SomeService');
|
755 |
+
```
|
756 |
+
|
757 |
+
In the above code, the injector will pass the string definition as the `$dsn` argument in the
|
758 |
+
`PDO::__construct` method and generate the shared PDO instance automatically only if one of the
|
759 |
+
classes it instantiates requires a `PDO` instance!
|
760 |
+
|
761 |
+
|
762 |
+
|
763 |
+
### App-Bootstrapping
|
764 |
+
|
765 |
+
DICs should be used to wire together the disparate objects of your application into a cohesive
|
766 |
+
functional unit (generally at the bootstrap or front-controller stage of the application). One such
|
767 |
+
usage provides an elegant solution for one of the thorny problems in object-oriented (OO) web
|
768 |
+
applications: how to instantiate classes in a routed environment where the dependencies are not
|
769 |
+
known ahead of time.
|
770 |
+
|
771 |
+
Consider the following front controller code whose job is to:
|
772 |
+
|
773 |
+
1. Load a list of application routes and pass them to the router
|
774 |
+
2. Generate a model of the client's HTTP request
|
775 |
+
3. Route the request instance given the application's route list
|
776 |
+
4. Instantiate the routed controller and invoke a method appropriate to the HTTP request
|
777 |
+
|
778 |
+
```php
|
779 |
+
<?php
|
780 |
+
|
781 |
+
define('CONTROLLER_ROUTES', '/hard/path/to/routes.xml');
|
782 |
+
|
783 |
+
$routeLoader = new RouteLoader();
|
784 |
+
$routes = $routeLoader->loadFromXml(CONTROLLER_ROUTES);
|
785 |
+
$router = new Router($routes);
|
786 |
+
|
787 |
+
$requestDetector = new RequestDetector();
|
788 |
+
$request = $requestDetector->detectFromSuperglobal($_SERVER);
|
789 |
+
|
790 |
+
$requestUri = $request->getUri();
|
791 |
+
$requestMethod = strtolower($request->getMethod());
|
792 |
+
|
793 |
+
$injector = new Auryn\Injector;
|
794 |
+
$injector->share($request);
|
795 |
+
|
796 |
+
try {
|
797 |
+
if (!$controllerClass = $router->route($requestUri, $requestMethod)) {
|
798 |
+
throw new NoRouteMatchException();
|
799 |
+
}
|
800 |
+
|
801 |
+
$controller = $injector->make($controllerClass);
|
802 |
+
$callableController = array($controller, $requestMethod);
|
803 |
+
|
804 |
+
if (!is_callable($callableController)) {
|
805 |
+
throw new MethodNotAllowedException();
|
806 |
+
} else {
|
807 |
+
$callableController();
|
808 |
+
}
|
809 |
+
|
810 |
+
} catch (NoRouteMatchException $e) {
|
811 |
+
// send 404 response
|
812 |
+
} catch (MethodNotAllowedException $e) {
|
813 |
+
// send 405 response
|
814 |
+
} catch (Exception $e) {
|
815 |
+
// send 500 response
|
816 |
+
}
|
817 |
+
```
|
818 |
+
|
819 |
+
And elsewhere we have various controller classes, each of which ask for their own individual
|
820 |
+
dependencies:
|
821 |
+
|
822 |
+
```php
|
823 |
+
<?php
|
824 |
+
|
825 |
+
class WidgetController {
|
826 |
+
private $request;
|
827 |
+
private $mapper;
|
828 |
+
public function __construct(Request $request, WidgetDataMapper $mapper) {
|
829 |
+
$this->request = $request;
|
830 |
+
$this->mapper = $mapper;
|
831 |
+
}
|
832 |
+
public function get() {
|
833 |
+
// do something for HTTP GET requests
|
834 |
+
}
|
835 |
+
public function post() {
|
836 |
+
// do something for HTTP POST requests
|
837 |
+
}
|
838 |
+
}
|
839 |
+
```
|
840 |
+
|
841 |
+
In the above example the auryn DIC allows us to write fully testable, fully OO controllers that ask
|
842 |
+
for their dependencies. Because the DIC recursively instantiates the dependencies of objects it
|
843 |
+
creates we have no need to pass around a Service Locator. Additionally, this example shows how we can
|
844 |
+
eliminate evil Singletons using the sharing capabilities of the auryn DIC. In the front controller
|
845 |
+
code, we share the request object so that any classes instantiated by the `Auryn\Injector` that ask
|
846 |
+
for a `Request` will receive the same instance. This feature not only helps eliminate Singletons,
|
847 |
+
but also the need for hard-to-test `static` properties.
|
addons/vendor/otgs/auryn/lib/CachingReflector.php
ADDED
@@ -0,0 +1,108 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace WPML\Auryn;
|
4 |
+
|
5 |
+
class CachingReflector implements Reflector
|
6 |
+
{
|
7 |
+
const CACHE_KEY_CLASSES = 'auryn.refls.classes.';
|
8 |
+
const CACHE_KEY_CTORS = 'auryn.refls.ctors.';
|
9 |
+
const CACHE_KEY_CTOR_PARAMS = 'auryn.refls.ctor-params.';
|
10 |
+
const CACHE_KEY_FUNCS = 'auryn.refls.funcs.';
|
11 |
+
const CACHE_KEY_METHODS = 'auryn.refls.methods.';
|
12 |
+
|
13 |
+
private $reflector;
|
14 |
+
private $cache;
|
15 |
+
|
16 |
+
public function __construct(Reflector $reflector = null, ReflectionCache $cache = null)
|
17 |
+
{
|
18 |
+
$this->reflector = $reflector ?: new StandardReflector;
|
19 |
+
$this->cache = $cache ?: new ReflectionCacheArray;
|
20 |
+
}
|
21 |
+
|
22 |
+
public function getClass($class)
|
23 |
+
{
|
24 |
+
$cacheKey = self::CACHE_KEY_CLASSES . strtolower($class);
|
25 |
+
|
26 |
+
if (($reflectionClass = $this->cache->fetch($cacheKey)) === false) {
|
27 |
+
$this->cache->store($cacheKey, $reflectionClass = $this->reflector->getClass($class));
|
28 |
+
}
|
29 |
+
|
30 |
+
return $reflectionClass;
|
31 |
+
}
|
32 |
+
|
33 |
+
public function getCtor($class)
|
34 |
+
{
|
35 |
+
$cacheKey = self::CACHE_KEY_CTORS . strtolower($class);
|
36 |
+
|
37 |
+
if (($reflectedCtor = $this->cache->fetch($cacheKey)) === false) {
|
38 |
+
$this->cache->store($cacheKey, $reflectedCtor = $this->reflector->getCtor($class));
|
39 |
+
}
|
40 |
+
|
41 |
+
return $reflectedCtor;
|
42 |
+
}
|
43 |
+
|
44 |
+
public function getCtorParams($class)
|
45 |
+
{
|
46 |
+
$cacheKey = self::CACHE_KEY_CTOR_PARAMS . strtolower($class);
|
47 |
+
|
48 |
+
if (($reflectedCtorParams = $this->cache->fetch($cacheKey)) === false) {
|
49 |
+
$this->cache->store($cacheKey, $reflectedCtorParams = $this->reflector->getCtorParams($class));
|
50 |
+
}
|
51 |
+
|
52 |
+
return $reflectedCtorParams;
|
53 |
+
}
|
54 |
+
|
55 |
+
public function getParamTypeHint(\ReflectionFunctionAbstract $function, \ReflectionParameter $param)
|
56 |
+
{
|
57 |
+
$lowParam = strtolower($param->name);
|
58 |
+
|
59 |
+
if ($function instanceof \ReflectionMethod) {
|
60 |
+
$lowClass = strtolower($function->class);
|
61 |
+
$lowMethod = strtolower($function->name);
|
62 |
+
$paramCacheKey = self::CACHE_KEY_CLASSES . "{$lowClass}.{$lowMethod}.param-{$lowParam}";
|
63 |
+
} else {
|
64 |
+
$lowFunc = strtolower($function->name);
|
65 |
+
$paramCacheKey = (strpos($lowFunc, '{closure}') === false)
|
66 |
+
? self::CACHE_KEY_FUNCS . ".{$lowFunc}.param-{$lowParam}"
|
67 |
+
: null;
|
68 |
+
}
|
69 |
+
|
70 |
+
$typeHint = ($paramCacheKey === null) ? false : $this->cache->fetch($paramCacheKey);
|
71 |
+
|
72 |
+
if (false === $typeHint) {
|
73 |
+
$typeHint = $this->reflector->getParamTypeHint($function, $param);
|
74 |
+
if ($paramCacheKey !== null) {
|
75 |
+
$this->cache->store($paramCacheKey, $typeHint);
|
76 |
+
}
|
77 |
+
}
|
78 |
+
|
79 |
+
return $typeHint;
|
80 |
+
}
|
81 |
+
|
82 |
+
public function getFunction($functionName)
|
83 |
+
{
|
84 |
+
$lowFunc = strtolower($functionName);
|
85 |
+
$cacheKey = self::CACHE_KEY_FUNCS . $lowFunc;
|
86 |
+
|
87 |
+
if (($reflectedFunc = $this->cache->fetch($cacheKey)) === false) {
|
88 |
+
$this->cache->store($cacheKey, $reflectedFunc = $this->reflector->getFunction($functionName));
|
89 |
+
}
|
90 |
+
|
91 |
+
return $reflectedFunc;
|
92 |
+
}
|
93 |
+
|
94 |
+
public function getMethod($classNameOrInstance, $methodName)
|
95 |
+
{
|
96 |
+
$className = is_string($classNameOrInstance)
|
97 |
+
? $classNameOrInstance
|
98 |
+
: get_class($classNameOrInstance);
|
99 |
+
|
100 |
+
$cacheKey = self::CACHE_KEY_METHODS . strtolower($className) . '.' . strtolower($methodName);
|
101 |
+
|
102 |
+
if (($reflectedMethod = $this->cache->fetch($cacheKey)) === false) {
|
103 |
+
$this->cache->store($cacheKey, $reflectedMethod = $this->reflector->getMethod($classNameOrInstance, $methodName));
|
104 |
+
}
|
105 |
+
|
106 |
+
return $reflectedMethod;
|
107 |
+
}
|
108 |
+
}
|
addons/vendor/otgs/auryn/lib/ConfigException.php
ADDED
@@ -0,0 +1,7 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace WPML\Auryn;
|
4 |
+
|
5 |
+
class ConfigException extends InjectorException
|
6 |
+
{
|
7 |
+
}
|
addons/vendor/otgs/auryn/lib/Executable.php
ADDED
@@ -0,0 +1,82 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace WPML\Auryn;
|
4 |
+
|
5 |
+
class Executable
|
6 |
+
{
|
7 |
+
private $callableReflection;
|
8 |
+
private $invocationObject;
|
9 |
+
private $isInstanceMethod;
|
10 |
+
|
11 |
+
public function __construct(\ReflectionFunctionAbstract $reflFunc, $invocationObject = null)
|
12 |
+
{
|
13 |
+
if ($reflFunc instanceof \ReflectionMethod) {
|
14 |
+
$this->isInstanceMethod = true;
|
15 |
+
$this->setMethodCallable($reflFunc, $invocationObject);
|
16 |
+
} else {
|
17 |
+
$this->isInstanceMethod = false;
|
18 |
+
$this->callableReflection = $reflFunc;
|
19 |
+
}
|
20 |
+
}
|
21 |
+
|
22 |
+
private function setMethodCallable(\ReflectionMethod $reflection, $invocationObject)
|
23 |
+
{
|
24 |
+
if (is_object($invocationObject)) {
|
25 |
+
$this->callableReflection = $reflection;
|
26 |
+
$this->invocationObject = $invocationObject;
|
27 |
+
} elseif ($reflection->isStatic()) {
|
28 |
+
$this->callableReflection = $reflection;
|
29 |
+
} else {
|
30 |
+
throw new \InvalidArgumentException(
|
31 |
+
'ReflectionMethod callables must specify an invocation object'
|
32 |
+
);
|
33 |
+
}
|
34 |
+
}
|
35 |
+
|
36 |
+
public function __invoke()
|
37 |
+
{
|
38 |
+
$args = func_get_args();
|
39 |
+
$reflection = $this->callableReflection;
|
40 |
+
|
41 |
+
if ($this->isInstanceMethod) {
|
42 |
+
return $reflection->invokeArgs($this->invocationObject, $args);
|
43 |
+
}
|
44 |
+
|
45 |
+
return $this->callableReflection->isClosure()
|
46 |
+
? $this->invokeClosureCompat($reflection, $args)
|
47 |
+
: $reflection->invokeArgs($args);
|
48 |
+
}
|
49 |
+
|
50 |
+
/**
|
51 |
+
* @TODO Remove this extra indirection when 5.3 support is dropped
|
52 |
+
*/
|
53 |
+
private function invokeClosureCompat($reflection, $args)
|
54 |
+
{
|
55 |
+
if (version_compare(PHP_VERSION, '5.4.0') >= 0) {
|
56 |
+
$scope = $reflection->getClosureScopeClass();
|
57 |
+
$closure = \Closure::bind(
|
58 |
+
$reflection->getClosure(),
|
59 |
+
$reflection->getClosureThis(),
|
60 |
+
$scope ? $scope->name : null
|
61 |
+
);
|
62 |
+
return call_user_func_array($closure, $args);
|
63 |
+
} else {
|
64 |
+
return $reflection->invokeArgs($args);
|
65 |
+
}
|
66 |
+
}
|
67 |
+
|
68 |
+
public function getCallableReflection()
|
69 |
+
{
|
70 |
+
return $this->callableReflection;
|
71 |
+
}
|
72 |
+
|
73 |
+
public function getInvocationObject()
|
74 |
+
{
|
75 |
+
return $this->invocationObject;
|
76 |
+
}
|
77 |
+
|
78 |
+
public function isInstanceMethod()
|
79 |
+
{
|
80 |
+
return $this->isInstanceMethod;
|
81 |
+
}
|
82 |
+
}
|
addons/vendor/otgs/auryn/lib/InjectionException.php
ADDED
@@ -0,0 +1,67 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace WPML\Auryn;
|
4 |
+
|
5 |
+
class InjectionException extends InjectorException
|
6 |
+
{
|
7 |
+
public $dependencyChain;
|
8 |
+
|
9 |
+
public function __construct(array $inProgressMakes, $message = "", $code = 0, \Exception $previous = null)
|
10 |
+
{
|
11 |
+
$this->dependencyChain = array_flip($inProgressMakes);
|
12 |
+
ksort($this->dependencyChain);
|
13 |
+
|
14 |
+
parent::__construct($message, $code, $previous);
|
15 |
+
}
|
16 |
+
|
17 |
+
/**
|
18 |
+
* Add a human readable version of the invalid callable to the standard 'invalid invokable' message.
|
19 |
+
*/
|
20 |
+
public static function fromInvalidCallable(
|
21 |
+
array $inProgressMakes,
|
22 |
+
$callableOrMethodStr,
|
23 |
+
\Exception $previous = null
|
24 |
+
) {
|
25 |
+
$callableString = null;
|
26 |
+
|
27 |
+
if (is_string($callableOrMethodStr)) {
|
28 |
+
$callableString .= $callableOrMethodStr;
|
29 |
+
} else if (is_array($callableOrMethodStr) &&
|
30 |
+
array_key_exists(0, $callableOrMethodStr) &&
|
31 |
+
array_key_exists(0, $callableOrMethodStr)) {
|
32 |
+
if (is_string($callableOrMethodStr[0]) && is_string($callableOrMethodStr[1])) {
|
33 |
+
$callableString .= $callableOrMethodStr[0].'::'.$callableOrMethodStr[1];
|
34 |
+
} else if (is_object($callableOrMethodStr[0]) && is_string($callableOrMethodStr[1])) {
|
35 |
+
$callableString .= sprintf(
|
36 |
+
"[object(%s), '%s']",
|
37 |
+
get_class($callableOrMethodStr[0]),
|
38 |
+
$callableOrMethodStr[1]
|
39 |
+
);
|
40 |
+
}
|
41 |
+
}
|
42 |
+
|
43 |
+
if ($callableString) {
|
44 |
+
// Prevent accidental usage of long strings from filling logs.
|
45 |
+
$callableString = substr($callableString, 0, 250);
|
46 |
+
$message = sprintf(
|
47 |
+
"%s. Invalid callable was '%s'",
|
48 |
+
Injector::M_INVOKABLE,
|
49 |
+
$callableString
|
50 |
+
);
|
51 |
+
} else {
|
52 |
+
$message = Injector::M_INVOKABLE;
|
53 |
+
}
|
54 |
+
|
55 |
+
return new self($inProgressMakes, $message, Injector::E_INVOKABLE, $previous);
|
56 |
+
}
|
57 |
+
|
58 |
+
/**
|
59 |
+
* Returns the hierarchy of dependencies that were being created when
|
60 |
+
* the exception occurred.
|
61 |
+
* @return array
|
62 |
+
*/
|
63 |
+
public function getDependencyChain()
|
64 |
+
{
|
65 |
+
return $this->dependencyChain;
|
66 |
+
}
|
67 |
+
}
|
addons/vendor/otgs/auryn/lib/Injector.php
ADDED
@@ -0,0 +1,757 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace WPML\Auryn;
|
4 |
+
|
5 |
+
class Injector
|
6 |
+
{
|
7 |
+
const A_RAW = ':';
|
8 |
+
const A_DELEGATE = '+';
|
9 |
+
const A_DEFINE = '@';
|
10 |
+
const I_BINDINGS = 1;
|
11 |
+
const I_DELEGATES = 2;
|
12 |
+
const I_PREPARES = 4;
|
13 |
+
const I_ALIASES = 8;
|
14 |
+
const I_SHARES = 16;
|
15 |
+
const I_ALL = 31;
|
16 |
+
|
17 |
+
const E_NON_EMPTY_STRING_ALIAS = 1;
|
18 |
+
const M_NON_EMPTY_STRING_ALIAS = "Invalid alias: non-empty string required at arguments 1 and 2";
|
19 |
+
const E_SHARED_CANNOT_ALIAS = 2;
|
20 |
+
const M_SHARED_CANNOT_ALIAS = "Cannot alias class %s to %s because it is currently shared";
|
21 |
+
const E_SHARE_ARGUMENT = 3;
|
22 |
+
const M_SHARE_ARGUMENT = "%s::share() requires a string class name or object instance at Argument 1; %s specified";
|
23 |
+
const E_ALIASED_CANNOT_SHARE = 4;
|
24 |
+
const M_ALIASED_CANNOT_SHARE = "Cannot share class %s because it is currently aliased to %s";
|
25 |
+
const E_INVOKABLE = 5;
|
26 |
+
const M_INVOKABLE = "Invalid invokable: callable or provisional string required";
|
27 |
+
const E_NON_PUBLIC_CONSTRUCTOR = 6;
|
28 |
+
const M_NON_PUBLIC_CONSTRUCTOR = "Cannot instantiate protected/private constructor in class %s";
|
29 |
+
const E_NEEDS_DEFINITION = 7;
|
30 |
+
const M_NEEDS_DEFINITION = "Injection definition required for %s %s";
|
31 |
+
const E_MAKE_FAILURE = 8;
|
32 |
+
const M_MAKE_FAILURE = "Could not make %s: %s";
|
33 |
+
const E_UNDEFINED_PARAM = 9;
|
34 |
+
const M_UNDEFINED_PARAM = "No definition available to provision typeless parameter \$%s at position %d in %s()%s";
|
35 |
+
const E_DELEGATE_ARGUMENT = 10;
|
36 |
+
const M_DELEGATE_ARGUMENT = "%s::delegate expects a valid callable or executable class::method string at Argument 2%s";
|
37 |
+
const E_CYCLIC_DEPENDENCY = 11;
|
38 |
+
const M_CYCLIC_DEPENDENCY = "Detected a cyclic dependency while provisioning %s";
|
39 |
+
const E_MAKING_FAILED = 12;
|
40 |
+
const M_MAKING_FAILED = "Making %s did not result in an object, instead result is of type '%s'";
|
41 |
+
|
42 |
+
private $reflector;
|
43 |
+
private $classDefinitions = array();
|
44 |
+
private $paramDefinitions = array();
|
45 |
+
private $aliases = array();
|
46 |
+
private $shares = array();
|
47 |
+
private $prepares = array();
|
48 |
+
private $delegates = array();
|
49 |
+
private $inProgressMakes = array();
|
50 |
+
|
51 |
+
public function __construct(Reflector $reflector = null)
|
52 |
+
{
|
53 |
+
$this->reflector = $reflector ?: new CachingReflector;
|
54 |
+
}
|
55 |
+
|
56 |
+
public function __clone()
|
57 |
+
{
|
58 |
+
$this->inProgressMakes = array();
|
59 |
+
}
|
60 |
+
|
61 |
+
/**
|
62 |
+
* Define instantiation directives for the specified class
|
63 |
+
*
|
64 |
+
* @param string $name The class (or alias) whose constructor arguments we wish to define
|
65 |
+
* @param array $args An array mapping parameter names to values/instructions
|
66 |
+
* @return self
|
67 |
+
*/
|
68 |
+
public function define($name, array $args)
|
69 |
+
{
|
70 |
+
list(, $normalizedName) = $this->resolveAlias($name);
|
71 |
+
$this->classDefinitions[$normalizedName] = $args;
|
72 |
+
|
73 |
+
return $this;
|
74 |
+
}
|
75 |
+
|
76 |
+
/**
|
77 |
+
* Assign a global default value for all parameters named $paramName
|
78 |
+
*
|
79 |
+
* Global parameter definitions are only used for parameters with no typehint, pre-defined or
|
80 |
+
* call-time definition.
|
81 |
+
*
|
82 |
+
* @param string $paramName The parameter name for which this value applies
|
83 |
+
* @param mixed $value The value to inject for this parameter name
|
84 |
+
* @return self
|
85 |
+
*/
|
86 |
+
public function defineParam($paramName, $value)
|
87 |
+
{
|
88 |
+
$this->paramDefinitions[$paramName] = $value;
|
89 |
+
|
90 |
+
return $this;
|
91 |
+
}
|
92 |
+
|
93 |
+
/**
|
94 |
+
* Define an alias for all occurrences of a given typehint
|
95 |
+
*
|
96 |
+
* Use this method to specify implementation classes for interface and abstract class typehints.
|
97 |
+
*
|
98 |
+
* @param string $original The typehint to replace
|
99 |
+
* @param string $alias The implementation name
|
100 |
+
* @throws ConfigException if any argument is empty or not a string
|
101 |
+
* @return self
|
102 |
+
*/
|
103 |
+
public function alias($original, $alias)
|
104 |
+
{
|
105 |
+
if (empty($original) || !is_string($original)) {
|
106 |
+
throw new ConfigException(
|
107 |
+
self::M_NON_EMPTY_STRING_ALIAS,
|
108 |
+
self::E_NON_EMPTY_STRING_ALIAS
|
109 |
+
);
|
110 |
+
}
|
111 |
+
if (empty($alias) || !is_string($alias)) {
|
112 |
+
throw new ConfigException(
|
113 |
+
self::M_NON_EMPTY_STRING_ALIAS,
|
114 |
+
self::E_NON_EMPTY_STRING_ALIAS
|
115 |
+
);
|
116 |
+
}
|
117 |
+
|
118 |
+
$originalNormalized = $this->normalizeName($original);
|
119 |
+
|
120 |
+
if (isset($this->shares[$originalNormalized])) {
|
121 |
+
throw new ConfigException(
|
122 |
+
sprintf(
|
123 |
+
self::M_SHARED_CANNOT_ALIAS,
|
124 |
+
$this->normalizeName(get_class($this->shares[$originalNormalized])),
|
125 |
+
$alias
|
126 |
+
),
|
127 |
+
self::E_SHARED_CANNOT_ALIAS
|
128 |
+
);
|
129 |
+
}
|
130 |
+
|
131 |
+
if (array_key_exists($originalNormalized, $this->shares)) {
|
132 |
+
$aliasNormalized = $this->normalizeName($alias);
|
133 |
+
$this->shares[$aliasNormalized] = null;
|
134 |
+
unset($this->shares[$originalNormalized]);
|
135 |
+
}
|
136 |
+
|
137 |
+
$this->aliases[$originalNormalized] = $alias;
|
138 |
+
|
139 |
+
return $this;
|
140 |
+
}
|
141 |
+
|
142 |
+
private function normalizeName($className)
|
143 |
+
{
|
144 |
+
return ltrim(strtolower($className), '\\');
|
145 |
+
}
|
146 |
+
|
147 |
+
/**
|
148 |
+
* Share the specified class/instance across the Injector context
|
149 |
+
*
|
150 |
+
* @param mixed $nameOrInstance The class or object to share
|
151 |
+
* @throws ConfigException if $nameOrInstance is not a string or an object
|
152 |
+
* @return self
|
153 |
+
*/
|
154 |
+
public function share($nameOrInstance)
|
155 |
+
{
|
156 |
+
if (is_string($nameOrInstance)) {
|
157 |
+
$this->shareClass($nameOrInstance);
|
158 |
+
} elseif (is_object($nameOrInstance)) {
|
159 |
+
$this->shareInstance($nameOrInstance);
|
160 |
+
} else {
|
161 |
+
throw new ConfigException(
|
162 |
+
sprintf(
|
163 |
+
self::M_SHARE_ARGUMENT,
|
164 |
+
__CLASS__,
|
165 |
+
gettype($nameOrInstance)
|
166 |
+
),
|
167 |
+
self::E_SHARE_ARGUMENT
|
168 |
+
);
|
169 |
+
}
|
170 |
+
|
171 |
+
return $this;
|
172 |
+
}
|
173 |
+
|
174 |
+
private function shareClass($nameOrInstance)
|
175 |
+
{
|
176 |
+
list(, $normalizedName) = $this->resolveAlias($nameOrInstance);
|
177 |
+
$this->shares[$normalizedName] = isset($this->shares[$normalizedName])
|
178 |
+
? $this->shares[$normalizedName]
|
179 |
+
: null;
|
180 |
+
}
|
181 |
+
|
182 |
+
private function resolveAlias($name)
|
183 |
+
{
|
184 |
+
$normalizedName = $this->normalizeName($name);
|
185 |
+
if (isset($this->aliases[$normalizedName])) {
|
186 |
+
$name = $this->aliases[$normalizedName];
|
187 |
+
$normalizedName = $this->normalizeName($name);
|
188 |
+
}
|
189 |
+
|
190 |
+
return array($name, $normalizedName);
|
191 |
+
}
|
192 |
+
|
193 |
+
private function shareInstance($obj)
|
194 |
+
{
|
195 |
+
$normalizedName = $this->normalizeName(get_class($obj));
|
196 |
+
if (isset($this->aliases[$normalizedName])) {
|
197 |
+
// You cannot share an instance of a class name that is already aliased
|
198 |
+
throw new ConfigException(
|
199 |
+
sprintf(
|
200 |
+
self::M_ALIASED_CANNOT_SHARE,
|
201 |
+
$normalizedName,
|
202 |
+
$this->aliases[$normalizedName]
|
203 |
+
),
|
204 |
+
self::E_ALIASED_CANNOT_SHARE
|
205 |
+
);
|
206 |
+
}
|
207 |
+
$this->shares[$normalizedName] = $obj;
|
208 |
+
}
|
209 |
+
|
210 |
+
/**
|
211 |
+
* Register a prepare callable to modify/prepare objects of type $name after instantiation
|
212 |
+
*
|
213 |
+
* Any callable or provisionable invokable may be specified. Preparers are passed two
|
214 |
+
* arguments: the instantiated object to be mutated and the current Injector instance.
|
215 |
+
*
|
216 |
+
* @param string $name
|
217 |
+
* @param mixed $callableOrMethodStr Any callable or provisionable invokable method
|
218 |
+
* @throws InjectionException if $callableOrMethodStr is not a callable.
|
219 |
+
* See https://github.com/rdlowrey/auryn#injecting-for-execution
|
220 |
+
* @return self
|
221 |
+
*/
|
222 |
+
public function prepare($name, $callableOrMethodStr)
|
223 |
+
{
|
224 |
+
if ($this->isExecutable($callableOrMethodStr) === false) {
|
225 |
+
throw InjectionException::fromInvalidCallable(
|
226 |
+
$this->inProgressMakes,
|
227 |
+
$callableOrMethodStr
|
228 |
+
);
|
229 |
+
}
|
230 |
+
|
231 |
+
list(, $normalizedName) = $this->resolveAlias($name);
|
232 |
+
$this->prepares[$normalizedName] = $callableOrMethodStr;
|
233 |
+
|
234 |
+
return $this;
|
235 |
+
}
|
236 |
+
|
237 |
+
private function isExecutable($exe)
|
238 |
+
{
|
239 |
+
if (is_callable($exe)) {
|
240 |
+
return true;
|
241 |
+
}
|
242 |
+
if (is_string($exe) && method_exists($exe, '__invoke')) {
|
243 |
+
return true;
|
244 |
+
}
|
245 |
+
if (is_array($exe) && isset($exe[0], $exe[1]) && method_exists($exe[0], $exe[1])) {
|
246 |
+
return true;
|
247 |
+
}
|
248 |
+
|
249 |
+
return false;
|
250 |
+
}
|
251 |
+
|
252 |
+
/**
|
253 |
+
* Delegate the creation of $name instances to the specified callable
|
254 |
+
*
|
255 |
+
* @param string $name
|
256 |
+
* @param mixed $callableOrMethodStr Any callable or provisionable invokable method
|
257 |
+
* @throws ConfigException if $callableOrMethodStr is not a callable.
|
258 |
+
* @return self
|
259 |
+
*/
|
260 |
+
public function delegate($name, $callableOrMethodStr)
|
261 |
+
{
|
262 |
+
if ($this->isExecutable($callableOrMethodStr) === false) {
|
263 |
+
$errorDetail = '';
|
264 |
+
if (is_string($callableOrMethodStr)) {
|
265 |
+
$errorDetail = " but received '$callableOrMethodStr'";
|
266 |
+
} elseif (is_array($callableOrMethodStr) &&
|
267 |
+
count($callableOrMethodStr) === 2 &&
|
268 |
+
array_key_exists(0, $callableOrMethodStr) &&
|
269 |
+
array_key_exists(1, $callableOrMethodStr)
|
270 |
+
) {
|
271 |
+
if (is_string($callableOrMethodStr[0]) && is_string($callableOrMethodStr[1])) {
|
272 |
+
$errorDetail = " but received ['".$callableOrMethodStr[0]."', '".$callableOrMethodStr[1]."']";
|
273 |
+
}
|
274 |
+
}
|
275 |
+
throw new ConfigException(
|
276 |
+
sprintf(self::M_DELEGATE_ARGUMENT, __CLASS__, $errorDetail),
|
277 |
+
self::E_DELEGATE_ARGUMENT
|
278 |
+
);
|
279 |
+
}
|
280 |
+
$normalizedName = $this->normalizeName($name);
|
281 |
+
$this->delegates[$normalizedName] = $callableOrMethodStr;
|
282 |
+
|
283 |
+
return $this;
|
284 |
+
}
|
285 |
+
|
286 |
+
/**
|
287 |
+
* Retrieve stored data for the specified definition type
|
288 |
+
*
|
289 |
+
* Exposes introspection of existing binds/delegates/shares/etc for decoration and composition.
|
290 |
+
*
|
291 |
+
* @param string $nameFilter An optional class name filter
|
292 |
+
* @param int $typeFilter A bitmask of Injector::* type constant flags
|
293 |
+
* @return array
|
294 |
+
*/
|
295 |
+
public function inspect($nameFilter = null, $typeFilter = null)
|
296 |
+
{
|
297 |
+
$result = array();
|
298 |
+
$name = $nameFilter ? $this->normalizeName($nameFilter) : null;
|
299 |
+
|
300 |
+
if (empty($typeFilter)) {
|
301 |
+
$typeFilter = self::I_ALL;
|
302 |
+
}
|
303 |
+
|
304 |
+
$types = array(
|
305 |
+
self::I_BINDINGS => "classDefinitions",
|
306 |
+
self::I_DELEGATES => "delegates",
|
307 |
+
self::I_PREPARES => "prepares",
|
308 |
+
self::I_ALIASES => "aliases",
|
309 |
+
self::I_SHARES => "shares"
|
310 |
+
);
|
311 |
+
|
312 |
+
foreach ($types as $type => $source) {
|
313 |
+
if ($typeFilter & $type) {
|
314 |
+
$result[$type] = $this->filter($this->{$source}, $name);
|
315 |
+
}
|
316 |
+
}
|
317 |
+
|
318 |
+
return $result;
|
319 |
+
}
|
320 |
+
|
321 |
+
private function filter($source, $name)
|
322 |
+
{
|
323 |
+
if (empty($name)) {
|
324 |
+
return $source;
|
325 |
+
} elseif (array_key_exists($name, $source)) {
|
326 |
+
return array($name => $source[$name]);
|
327 |
+
} else {
|
328 |
+
return array();
|
329 |
+
}
|
330 |
+
}
|
331 |
+
|
332 |
+
/**
|
333 |
+
* Instantiate/provision a class instance
|
334 |
+
*
|
335 |
+
* @param string $name
|
336 |
+
* @param array $args
|
337 |
+
* @throws InjectionException if a cyclic gets detected when provisioning
|
338 |
+
* @return mixed
|
339 |
+
*/
|
340 |
+
public function make($name, array $args = array())
|
341 |
+
{
|
342 |
+
list($className, $normalizedClass) = $this->resolveAlias($name);
|
343 |
+
|
344 |
+
if (isset($this->inProgressMakes[$normalizedClass])) {
|
345 |
+
throw new InjectionException(
|
346 |
+
$this->inProgressMakes,
|
347 |
+
sprintf(
|
348 |
+
self::M_CYCLIC_DEPENDENCY,
|
349 |
+
$className
|
350 |
+
),
|
351 |
+
self::E_CYCLIC_DEPENDENCY
|
352 |
+
);
|
353 |
+
}
|
354 |
+
|
355 |
+
$this->inProgressMakes[$normalizedClass] = count($this->inProgressMakes);
|
356 |
+
|
357 |
+
// isset() is used specifically here because classes may be marked as "shared" before an
|
358 |
+
// instance is stored. In these cases the class is "shared," but it has a null value and
|
359 |
+
// instantiation is needed.
|
360 |
+
if (isset($this->shares[$normalizedClass])) {
|
361 |
+
unset($this->inProgressMakes[$normalizedClass]);
|
362 |
+
|
363 |
+
return $this->shares[$normalizedClass];
|
364 |
+
}
|
365 |
+
|
366 |
+
try {
|
367 |
+
if (isset($this->delegates[$normalizedClass])) {
|
368 |
+
$executable = $this->buildExecutable($this->delegates[$normalizedClass]);
|
369 |
+
$reflectionFunction = $executable->getCallableReflection();
|
370 |
+
$args = $this->provisionFuncArgs($reflectionFunction, $args, null, $className);
|
371 |
+
$obj = call_user_func_array(array($executable, '__invoke'), $args);
|
372 |
+
} else {
|
373 |
+
$obj = $this->provisionInstance($className, $normalizedClass, $args);
|
374 |
+
}
|
375 |
+
|
376 |
+
$obj = $this->prepareInstance($obj, $normalizedClass);
|
377 |
+
|
378 |
+
if (array_key_exists($normalizedClass, $this->shares)) {
|
379 |
+
$this->shares[$normalizedClass] = $obj;
|
380 |
+
}
|
381 |
+
|
382 |
+
unset($this->inProgressMakes[$normalizedClass]);
|
383 |
+
}
|
384 |
+
catch (\Throwable $exception) {
|
385 |
+
unset($this->inProgressMakes[$normalizedClass]);
|
386 |
+
throw $exception;
|
387 |
+
}
|
388 |
+
catch (\Exception $exception) {
|
389 |
+
unset($this->inProgressMakes[$normalizedClass]);
|
390 |
+
throw $exception;
|
391 |
+
}
|
392 |
+
|
393 |
+
return $obj;
|
394 |
+
}
|
395 |
+
|
396 |
+
private function provisionInstance($className, $normalizedClass, array $definition)
|
397 |
+
{
|
398 |
+
try {
|
399 |
+
$ctor = $this->reflector->getCtor($className);
|
400 |
+
|
401 |
+
if (!$ctor) {
|
402 |
+
$obj = $this->instantiateWithoutCtorParams($className);
|
403 |
+
} elseif (!$ctor->isPublic()) {
|
404 |
+
throw new InjectionException(
|
405 |
+
$this->inProgressMakes,
|
406 |
+
sprintf(self::M_NON_PUBLIC_CONSTRUCTOR, $className),
|
407 |
+
self::E_NON_PUBLIC_CONSTRUCTOR
|
408 |
+
);
|
409 |
+
} elseif ($ctorParams = $this->reflector->getCtorParams($className)) {
|
410 |
+
$reflClass = $this->reflector->getClass($className);
|
411 |
+
$definition = isset($this->classDefinitions[$normalizedClass])
|
412 |
+
? array_replace($this->classDefinitions[$normalizedClass], $definition)
|
413 |
+
: $definition;
|
414 |
+
$args = $this->provisionFuncArgs($ctor, $definition, $ctorParams, $className);
|
415 |
+
$obj = $reflClass->newInstanceArgs($args);
|
416 |
+
} else {
|
417 |
+
$obj = $this->instantiateWithoutCtorParams($className);
|
418 |
+
}
|
419 |
+
|
420 |
+
return $obj;
|
421 |
+
} catch (\ReflectionException $e) {
|
422 |
+
throw new InjectionException(
|
423 |
+
$this->inProgressMakes,
|
424 |
+
sprintf(self::M_MAKE_FAILURE, $className, $e->getMessage()),
|
425 |
+
self::E_MAKE_FAILURE,
|
426 |
+
$e
|
427 |
+
);
|
428 |
+
}
|
429 |
+
}
|
430 |
+
|
431 |
+
private function instantiateWithoutCtorParams($className)
|
432 |
+
{
|
433 |
+
$reflClass = $this->reflector->getClass($className);
|
434 |
+
|
435 |
+
if (!$reflClass->isInstantiable()) {
|
436 |
+
$type = $reflClass->isInterface() ? 'interface' : 'abstract class';
|
437 |
+
throw new InjectionException(
|
438 |
+
$this->inProgressMakes,
|
439 |
+
sprintf(self::M_NEEDS_DEFINITION, $type, $className),
|
440 |
+
self::E_NEEDS_DEFINITION
|
441 |
+
);
|
442 |
+
}
|
443 |
+
|
444 |
+
return new $className;
|
445 |
+
}
|
446 |
+
|
447 |
+
private function provisionFuncArgs(\ReflectionFunctionAbstract $reflFunc, array $definition, array $reflParams = null, $className = null)
|
448 |
+
{
|
449 |
+
$args = array();
|
450 |
+
|
451 |
+
// @TODO store this in ReflectionStorage
|
452 |
+
if (!isset($reflParams)) {
|
453 |
+
$reflParams = $reflFunc->getParameters();
|
454 |
+
}
|
455 |
+
|
456 |
+
foreach ($reflParams as $i => $reflParam) {
|
457 |
+
$name = $reflParam->name;
|
458 |
+
|
459 |
+
if (isset($definition[$i]) || array_key_exists($i, $definition)) {
|
460 |
+
// indexed arguments take precedence over named parameters
|
461 |
+
$arg = $definition[$i];
|
462 |
+
} elseif (isset($definition[$name]) || array_key_exists($name, $definition)) {
|
463 |
+
// interpret the param as a class name to be instantiated
|
464 |
+
$arg = $this->make($definition[$name]);
|
465 |
+
} elseif (($prefix = self::A_RAW . $name) && (isset($definition[$prefix]) || array_key_exists($prefix, $definition))) {
|
466 |
+
// interpret the param as a raw value to be injected
|
467 |
+
$arg = $definition[$prefix];
|
468 |
+
} elseif (($prefix = self::A_DELEGATE . $name) && isset($definition[$prefix])) {
|
469 |
+
// interpret the param as an invokable delegate
|
470 |
+
$arg = $this->buildArgFromDelegate($name, $definition[$prefix]);
|
471 |
+
} elseif (($prefix = self::A_DEFINE . $name) && isset($definition[$prefix])) {
|
472 |
+
// interpret the param as a class definition
|
473 |
+
$arg = $this->buildArgFromParamDefineArr($definition[$prefix]);
|
474 |
+
} elseif (!$arg = $this->buildArgFromTypeHint($reflFunc, $reflParam)) {
|
475 |
+
$arg = $this->buildArgFromReflParam($reflParam, $className);
|
476 |
+
|
477 |
+
if ($arg === null && PHP_VERSION_ID >= 50600 && $reflParam->isVariadic()) {
|
478 |
+
// buildArgFromReflParam might return null in case the parameter is optional
|
479 |
+
// in case of variadics, the parameter is optional, but null might not be allowed
|
480 |
+
continue;
|
481 |
+
}
|
482 |
+
}
|
483 |
+
|
484 |
+
$args[] = $arg;
|
485 |
+
}
|
486 |
+
|
487 |
+
return $args;
|
488 |
+
}
|
489 |
+
|
490 |
+
private function buildArgFromParamDefineArr($definition)
|
491 |
+
{
|
492 |
+
if (!is_array($definition)) {
|
493 |
+
throw new InjectionException(
|
494 |
+
$this->inProgressMakes
|
495 |
+
// @TODO Add message
|
496 |
+
);
|
497 |
+
}
|
498 |
+
|
499 |
+
if (!isset($definition[0], $definition[1])) {
|
500 |
+
throw new InjectionException(
|
501 |
+
$this->inProgressMakes
|
502 |
+
// @TODO Add message
|
503 |
+
);
|
504 |
+
}
|
505 |
+
|
506 |
+
list($class, $definition) = $definition;
|
507 |
+
|
508 |
+
return $this->make($class, $definition);
|
509 |
+
}
|
510 |
+
|
511 |
+
private function buildArgFromDelegate($paramName, $callableOrMethodStr)
|
512 |
+
{
|
513 |
+
if ($this->isExecutable($callableOrMethodStr) === false) {
|
514 |
+
throw InjectionException::fromInvalidCallable(
|
515 |
+
$this->inProgressMakes,
|
516 |
+
$callableOrMethodStr
|
517 |
+
);
|
518 |
+
}
|
519 |
+
|
520 |
+
$executable = $this->buildExecutable($callableOrMethodStr);
|
521 |
+
|
522 |
+
return $executable($paramName, $this);
|
523 |
+
}
|
524 |
+
|
525 |
+
private function buildArgFromTypeHint(\ReflectionFunctionAbstract $reflFunc, \ReflectionParameter $reflParam)
|
526 |
+
{
|
527 |
+
$typeHint = $this->reflector->getParamTypeHint($reflFunc, $reflParam);
|
528 |
+
|
529 |
+
if (!$typeHint) {
|
530 |
+
$obj = null;
|
531 |
+
} elseif ($reflParam->isDefaultValueAvailable()) {
|
532 |
+
$normalizedName = $this->normalizeName($typeHint);
|
533 |
+
// Injector has been told explicitly how to make this type
|
534 |
+
if (isset($this->aliases[$normalizedName]) ||
|
535 |
+
isset($this->delegates[$normalizedName]) ||
|
536 |
+
isset($this->shares[$normalizedName])) {
|
537 |
+
$obj = $this->make($typeHint);
|
538 |
+
} else {
|
539 |
+
$obj = $reflParam->getDefaultValue();
|
540 |
+
}
|
541 |
+
} else {
|
542 |
+
$obj = $this->make($typeHint);
|
543 |
+
}
|
544 |
+
|
545 |
+
return $obj;
|
546 |
+
}
|
547 |
+
|
548 |
+
private function buildArgFromReflParam(\ReflectionParameter $reflParam, $className = null)
|
549 |
+
{
|
550 |
+
if (array_key_exists($reflParam->name, $this->paramDefinitions)) {
|
551 |
+
$arg = $this->paramDefinitions[$reflParam->name];
|
552 |
+
} elseif ($reflParam->isDefaultValueAvailable()) {
|
553 |
+
$arg = $reflParam->getDefaultValue();
|
554 |
+
} elseif ($reflParam->isOptional()) {
|
555 |
+
// This branch is required to work around PHP bugs where a parameter is optional
|
556 |
+
// but has no default value available through reflection. Specifically, PDO exhibits
|
557 |
+
// this behavior.
|
558 |
+
$arg = null;
|
559 |
+
} else {
|
560 |
+
$reflFunc = $reflParam->getDeclaringFunction();
|
561 |
+
$classDeclare = ($reflFunc instanceof \ReflectionMethod)
|
562 |
+
? " declared in " . $reflFunc->getDeclaringClass()->name . "::"
|
563 |
+
: "";
|
564 |
+
$classWord = ($reflFunc instanceof \ReflectionMethod)
|
565 |
+
? $className . '::'
|
566 |
+
: '';
|
567 |
+
$funcWord = $classWord . $reflFunc->name;
|
568 |
+
|
569 |
+
throw new InjectionException(
|
570 |
+
$this->inProgressMakes,
|
571 |
+
sprintf(
|
572 |
+
self::M_UNDEFINED_PARAM,
|
573 |
+
$reflParam->name,
|
574 |
+
$reflParam->getPosition(),
|
575 |
+
$funcWord,
|
576 |
+
$classDeclare
|
577 |
+
),
|
578 |
+
self::E_UNDEFINED_PARAM
|
579 |
+
);
|
580 |
+
}
|
581 |
+
|
582 |
+
return $arg;
|
583 |
+
}
|
584 |
+
|
585 |
+
private function prepareInstance($obj, $normalizedClass)
|
586 |
+
{
|
587 |
+
if (isset($this->prepares[$normalizedClass])) {
|
588 |
+
$prepare = $this->prepares[$normalizedClass];
|
589 |
+
$executable = $this->buildExecutable($prepare);
|
590 |
+
$result = $executable($obj, $this);
|
591 |
+
if ($result instanceof $normalizedClass) {
|
592 |
+
$obj = $result;
|
593 |
+
}
|
594 |
+
}
|
595 |
+
|
596 |
+
$interfaces = @class_implements($obj);
|
597 |
+
|
598 |
+
if ($interfaces === false) {
|
599 |
+
throw new InjectionException(
|
600 |
+
$this->inProgressMakes,
|
601 |
+
sprintf(
|
602 |
+
self::M_MAKING_FAILED,
|
603 |
+
$normalizedClass,
|
604 |
+
gettype($obj)
|
605 |
+
),
|
606 |
+
self::E_MAKING_FAILED
|
607 |
+
);
|
608 |
+
}
|
609 |
+
|
610 |
+
if (empty($interfaces)) {
|
611 |
+
return $obj;
|
612 |
+
}
|
613 |
+
|
614 |
+
$interfaces = array_flip(array_map(array($this, 'normalizeName'), $interfaces));
|
615 |
+
$prepares = array_intersect_key($this->prepares, $interfaces);
|
616 |
+
foreach ($prepares as $interfaceName => $prepare) {
|
617 |
+
$executable = $this->buildExecutable($prepare);
|
618 |
+
$result = $executable($obj, $this);
|
619 |
+
if ($result instanceof $normalizedClass) {
|
620 |
+
$obj = $result;
|
621 |
+
}
|
622 |
+
}
|
623 |
+
|
624 |
+
return $obj;
|
625 |
+
}
|
626 |
+
|
627 |
+
/**
|
628 |
+
* Invoke the specified callable or class::method string, provisioning dependencies along the way
|
629 |
+
*
|
630 |
+
* @param mixed $callableOrMethodStr A valid PHP callable or a provisionable ClassName::methodName string
|
631 |
+
* @param array $args Optional array specifying params with which to invoke the provisioned callable
|
632 |
+
* @throws \Auryn\InjectionException
|
633 |
+
* @return mixed Returns the invocation result returned from calling the generated executable
|
634 |
+
*/
|
635 |
+
public function execute($callableOrMethodStr, array $args = array())
|
636 |
+
{
|
637 |
+
list($reflFunc, $invocationObj) = $this->buildExecutableStruct($callableOrMethodStr);
|
638 |
+
$executable = new Executable($reflFunc, $invocationObj);
|
639 |
+
$args = $this->provisionFuncArgs($reflFunc, $args, null, $invocationObj === null ? null : get_class($invocationObj));
|
640 |
+
|
641 |
+
return call_user_func_array(array($executable, '__invoke'), $args);
|
642 |
+
}
|
643 |
+
|
644 |
+
/**
|
645 |
+
* Provision an Executable instance from any valid callable or class::method string
|
646 |
+
*
|
647 |
+
* @param mixed $callableOrMethodStr A valid PHP callable or a provisionable ClassName::methodName string
|
648 |
+
* @return \Auryn\Executable
|
649 |
+
*/
|
650 |
+
public function buildExecutable($callableOrMethodStr)
|
651 |
+
{
|
652 |
+
try {
|
653 |
+
list($reflFunc, $invocationObj) = $this->buildExecutableStruct($callableOrMethodStr);
|
654 |
+
} catch (\ReflectionException $e) {
|
655 |
+
throw InjectionException::fromInvalidCallable(
|
656 |
+
$this->inProgressMakes,
|
657 |
+
$callableOrMethodStr,
|
658 |
+
$e
|
659 |
+
);
|
660 |
+
}
|
661 |
+
|
662 |
+
return new Executable($reflFunc, $invocationObj);
|
663 |
+
}
|
664 |
+
|
665 |
+
private function buildExecutableStruct($callableOrMethodStr)
|
666 |
+
{
|
667 |
+
if (is_string($callableOrMethodStr)) {
|
668 |
+
$executableStruct = $this->buildExecutableStructFromString($callableOrMethodStr);
|
669 |
+
} elseif ($callableOrMethodStr instanceof \Closure) {
|
670 |
+
$callableRefl = new \ReflectionFunction($callableOrMethodStr);
|
671 |
+
$executableStruct = array($callableRefl, null);
|
672 |
+
} elseif (is_object($callableOrMethodStr) && is_callable($callableOrMethodStr)) {
|
673 |
+
$invocationObj = $callableOrMethodStr;
|
674 |
+
$callableRefl = $this->reflector->getMethod($invocationObj, '__invoke');
|
675 |
+
$executableStruct = array($callableRefl, $invocationObj);
|
676 |
+
} elseif (is_array($callableOrMethodStr)
|
677 |
+
&& isset($callableOrMethodStr[0], $callableOrMethodStr[1])
|
678 |
+
&& count($callableOrMethodStr) === 2
|
679 |
+
) {
|
680 |
+
$executableStruct = $this->buildExecutableStructFromArray($callableOrMethodStr);
|
681 |
+
} else {
|
682 |
+
throw InjectionException::fromInvalidCallable(
|
683 |
+
$this->inProgressMakes,
|
684 |
+
$callableOrMethodStr
|
685 |
+
);
|
686 |
+
}
|
687 |
+
|
688 |
+
return $executableStruct;
|
689 |
+
}
|
690 |
+
|
691 |
+
private function buildExecutableStructFromString($stringExecutable)
|
692 |
+
{
|
693 |
+
if (function_exists($stringExecutable)) {
|
694 |
+
$callableRefl = $this->reflector->getFunction($stringExecutable);
|
695 |
+
$executableStruct = array($callableRefl, null);
|
696 |
+
} elseif (method_exists($stringExecutable, '__invoke')) {
|
697 |
+
$invocationObj = $this->make($stringExecutable);
|
698 |
+
$callableRefl = $this->reflector->getMethod($invocationObj, '__invoke');
|
699 |
+
$executableStruct = array($callableRefl, $invocationObj);
|
700 |
+
} elseif (strpos($stringExecutable, '::') !== false) {
|
701 |
+
list($class, $method) = explode('::', $stringExecutable, 2);
|
702 |
+
$executableStruct = $this->buildStringClassMethodCallable($class, $method);
|
703 |
+
} else {
|
704 |
+
throw InjectionException::fromInvalidCallable(
|
705 |
+
$this->inProgressMakes,
|
706 |
+
$stringExecutable
|
707 |
+
);
|
708 |
+
}
|
709 |
+
|
710 |
+
return $executableStruct;
|
711 |
+
}
|
712 |
+
|
713 |
+
private function buildStringClassMethodCallable($class, $method)
|
714 |
+
{
|
715 |
+
$relativeStaticMethodStartPos = strpos($method, 'parent::');
|
716 |
+
|
717 |
+
if ($relativeStaticMethodStartPos === 0) {
|
718 |
+
$childReflection = $this->reflector->getClass($class);
|
719 |
+
$class = $childReflection->getParentClass()->name;
|
720 |
+
$method = substr($method, $relativeStaticMethodStartPos + 8);
|
721 |
+
}
|
722 |
+
|
723 |
+
list($className, $normalizedClass) = $this->resolveAlias($class);
|
724 |
+
$reflectionMethod = $this->reflector->getMethod($className, $method);
|
725 |
+
|
726 |
+
if ($reflectionMethod->isStatic()) {
|
727 |
+
return array($reflectionMethod, null);
|
728 |
+
}
|
729 |
+
|
730 |
+
$instance = $this->make($className);
|
731 |
+
// If the class was delegated, the instance may not be of the type
|
732 |
+
// $class but some other type. We need to get the reflection on the
|
733 |
+
// actual class to be able to call the method correctly.
|
734 |
+
$reflectionMethod = $this->reflector->getMethod($instance, $method);
|
735 |
+
|
736 |
+
return array($reflectionMethod, $instance);
|
737 |
+
}
|
738 |
+
|
739 |
+
private function buildExecutableStructFromArray($arrayExecutable)
|
740 |
+
{
|
741 |
+
list($classOrObj, $method) = $arrayExecutable;
|
742 |
+
|
743 |
+
if (is_object($classOrObj) && method_exists($classOrObj, $method)) {
|
744 |
+
$callableRefl = $this->reflector->getMethod($classOrObj, $method);
|
745 |
+
$executableStruct = array($callableRefl, $classOrObj);
|
746 |
+
} elseif (is_string($classOrObj)) {
|
747 |
+
$executableStruct = $this->buildStringClassMethodCallable($classOrObj, $method);
|
748 |
+
} else {
|
749 |
+
throw InjectionException::fromInvalidCallable(
|
750 |
+
$this->inProgressMakes,
|
751 |
+
$arrayExecutable
|
752 |
+
);
|
753 |
+
}
|
754 |
+
|
755 |
+
return $executableStruct;
|
756 |
+
}
|
757 |
+
}
|
addons/vendor/otgs/auryn/lib/InjectorException.php
ADDED
@@ -0,0 +1,7 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace WPML\Auryn;
|
4 |
+
|
5 |
+
class InjectorException extends \Exception
|
6 |
+
{
|
7 |
+
}
|
addons/vendor/otgs/auryn/lib/ReflectionCache.php
ADDED
@@ -0,0 +1,9 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace WPML\Auryn;
|
4 |
+
|
5 |
+
interface ReflectionCache
|
6 |
+
{
|
7 |
+
public function fetch($key);
|
8 |
+
public function store($key, $data);
|
9 |
+
}
|
addons/vendor/otgs/auryn/lib/ReflectionCacheApc.php
ADDED
@@ -0,0 +1,41 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace WPML\Auryn;
|
4 |
+
|
5 |
+
class ReflectionCacheApc implements ReflectionCache
|
6 |
+
{
|
7 |
+
private $localCache;
|
8 |
+
private $timeToLive = 5;
|
9 |
+
|
10 |
+
public function __construct(ReflectionCache $localCache = null)
|
11 |
+
{
|
12 |
+
$this->localCache = $localCache ?: new ReflectionCacheArray;
|
13 |
+
}
|
14 |
+
|
15 |
+
public function setTimeToLive($seconds)
|
16 |
+
{
|
17 |
+
$seconds = (int) $seconds;
|
18 |
+
$this->timeToLive = ($seconds > 0) ? $seconds : $this->timeToLive;
|
19 |
+
|
20 |
+
return $this;
|
21 |
+
}
|
22 |
+
|
23 |
+
public function fetch($key)
|
24 |
+
{
|
25 |
+
$localData = $this->localCache->fetch($key);
|
26 |
+
|
27 |
+
if ($localData != false) {
|
28 |
+
return $localData;
|
29 |
+
} else {
|
30 |
+
$success = null; // stupid by-ref parameter that scrutinizer complains about
|
31 |
+
$data = apc_fetch($key, $success);
|
32 |
+
return $success ? $data : false;
|
33 |
+
}
|
34 |
+
}
|
35 |
+
|
36 |
+
public function store($key, $data)
|
37 |
+
{
|
38 |
+
$this->localCache->store($key, $data);
|
39 |
+
apc_store($key, $data, $this->timeToLive);
|
40 |
+
}
|
41 |
+
}
|
addons/vendor/otgs/auryn/lib/ReflectionCacheArray.php
ADDED
@@ -0,0 +1,22 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace WPML\Auryn;
|
4 |
+
|
5 |
+
class ReflectionCacheArray implements ReflectionCache
|
6 |
+
{
|
7 |
+
private $cache = array();
|
8 |
+
|
9 |
+
public function fetch($key)
|
10 |
+
{
|
11 |
+
// The additional isset() check here improves performance but we also
|
12 |
+
// need array_key_exists() because some cached values === NULL.
|
13 |
+
return (isset($this->cache[$key]) || array_key_exists($key, $this->cache))
|
14 |
+
? $this->cache[$key]
|
15 |
+
: false;
|
16 |
+
}
|
17 |
+
|
18 |
+
public function store($key, $data)
|
19 |
+
{
|
20 |
+
$this->cache[$key] = $data;
|
21 |
+
}
|
22 |
+
}
|
addons/vendor/otgs/auryn/lib/Reflector.php
ADDED
@@ -0,0 +1,61 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace WPML\Auryn;
|
4 |
+
|
5 |
+
interface Reflector
|
6 |
+
{
|
7 |
+
/**
|
8 |
+
* Retrieves ReflectionClass instances, caching them for future retrieval
|
9 |
+
*
|
10 |
+
* @param string $class
|
11 |
+
* @return \ReflectionClass
|
12 |
+
*/
|
13 |
+
public function getClass($class);
|
14 |
+
|
15 |
+
/**
|
16 |
+
* Retrieves and caches the constructor (ReflectionMethod) for the specified class
|
17 |
+
*
|
18 |
+
* @param string $class
|
19 |
+
* @return \ReflectionMethod
|
20 |
+
*/
|
21 |
+
public function getCtor($class);
|
22 |
+
|
23 |
+
/**
|
24 |
+
* Retrieves and caches an array of constructor parameters for the given class
|
25 |
+
*
|
26 |
+
* @param string $class
|
27 |
+
* @return \ReflectionParameter[]
|
28 |
+
*/
|
29 |
+
public function getCtorParams($class);
|
30 |
+
|
31 |
+
/**
|
32 |
+
* Retrieves the class type-hint from a given ReflectionParameter
|
33 |
+
*
|
34 |
+
* There is no way to directly access a parameter's type-hint without
|
35 |
+
* instantiating a new ReflectionClass instance and calling its getName()
|
36 |
+
* method. This method stores the results of this approach so that if
|
37 |
+
* the same parameter type-hint or ReflectionClass is needed again we
|
38 |
+
* already have it cached.
|
39 |
+
*
|
40 |
+
* @param \ReflectionFunctionAbstract $function
|
41 |
+
* @param \ReflectionParameter $param
|
42 |
+
*/
|
43 |
+
public function getParamTypeHint(\ReflectionFunctionAbstract $function, \ReflectionParameter $param);
|
44 |
+
|
45 |
+
/**
|
46 |
+
* Retrieves and caches a reflection for the specified function
|
47 |
+
*
|
48 |
+
* @param string $functionName
|
49 |
+
* @return \ReflectionFunction
|
50 |
+
*/
|
51 |
+
public function getFunction($functionName);
|
52 |
+
|
53 |
+
/**
|
54 |
+
* Retrieves and caches a reflection for the specified class method
|
55 |
+
*
|
56 |
+
* @param mixed $classNameOrInstance
|
57 |
+
* @param string $methodName
|
58 |
+
* @return \ReflectionMethod
|
59 |
+
*/
|
60 |
+
public function getMethod($classNameOrInstance, $methodName);
|
61 |
+
}
|
addons/vendor/otgs/auryn/lib/StandardReflector.php
ADDED
@@ -0,0 +1,53 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace WPML\Auryn;
|
4 |
+
|
5 |
+
class StandardReflector implements Reflector
|
6 |
+
{
|
7 |
+
public function getClass($class)
|
8 |
+
{
|
9 |
+
return new \ReflectionClass($class);
|
10 |
+
}
|
11 |
+
|
12 |
+
public function getCtor($class)
|
13 |
+
{
|
14 |
+
$reflectionClass = new \ReflectionClass($class);
|
15 |
+
|
16 |
+
return $reflectionClass->getConstructor();
|
17 |
+
}
|
18 |
+
|
19 |
+
public function getCtorParams($class)
|
20 |
+
{
|
21 |
+
return ($reflectedCtor = $this->getCtor($class))
|
22 |
+
? $reflectedCtor->getParameters()
|
23 |
+
: null;
|
24 |
+
}
|
25 |
+
|
26 |
+
public function getParamTypeHint( \ReflectionFunctionAbstract $function, \ReflectionParameter $param ) {
|
27 |
+
if ( version_compare( '7.1.0', phpversion(), '<' ) ) {
|
28 |
+
$reflectionClass = $param->getType() && ! $param->getType()->isBuiltin()
|
29 |
+
? new \ReflectionClass( $param->getType()->getName() )
|
30 |
+
: null;
|
31 |
+
} else {
|
32 |
+
$reflectionClass = $param->getClass();
|
33 |
+
}
|
34 |
+
|
35 |
+
return ( $reflectionClass )
|
36 |
+
? $reflectionClass->getName()
|
37 |
+
: null;
|
38 |
+
}
|
39 |
+
|
40 |
+
public function getFunction($functionName)
|
41 |
+
{
|
42 |
+
return new \ReflectionFunction($functionName);
|
43 |
+
}
|
44 |
+
|
45 |
+
public function getMethod($classNameOrInstance, $methodName)
|
46 |
+
{
|
47 |
+
$className = is_string($classNameOrInstance)
|
48 |
+
? $classNameOrInstance
|
49 |
+
: get_class($classNameOrInstance);
|
50 |
+
|
51 |
+
return new \ReflectionMethod($className, $methodName);
|
52 |
+
}
|
53 |
+
}
|
addons/vendor/otgs/auryn/phpunit.xml
ADDED
@@ -0,0 +1,43 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<phpunit backupGlobals="false"
|
2 |
+
backupStaticAttributes="false"
|
3 |
+
colors="true"
|
4 |
+
convertErrorsToExceptions="true"
|
5 |
+
convertNoticesToExceptions="true"
|
6 |
+
convertWarningsToExceptions="true"
|
7 |
+
processIsolation="false"
|
8 |
+
stopOnFailure="false"
|
9 |
+
syntaxCheck="false"
|
10 |
+
bootstrap="vendor/autoload.php"
|
11 |
+
>
|
12 |
+
<testsuites>
|
13 |
+
<testsuite name="Unit-Tests">
|
14 |
+
<directory>./test</directory>
|
15 |
+
</testsuite>
|
16 |
+
</testsuites>
|
17 |
+
<filter>
|
18 |
+
<whitelist addUncoveredFilesFromWhitelist="true">
|
19 |
+
<directory>./lib</directory>
|
20 |
+
</whitelist>
|
21 |
+
</filter>
|
22 |
+
|
23 |
+
<logging>
|
24 |
+
<log
|
25 |
+
type="coverage-text"
|
26 |
+
target="php://stdout"
|
27 |
+
lowUpperBound="35"
|
28 |
+
highLowerBound="75"
|
29 |
+
/>
|
30 |
+
<!-- uncomment below to generate HTML code coverage reports in ./test/coverage -->
|
31 |
+
<!--
|
32 |
+
<log
|
33 |
+
type="coverage-html"
|
34 |
+
target="./test/coverage"
|
35 |
+
charset="UTF-8"
|
36 |
+
yui="true"
|
37 |
+
lowUpperBound="35"
|
38 |
+
highLowerBound="70"
|
39 |
+
showUncoveredFiles="true"
|
40 |
+
/>
|
41 |
+
-->
|
42 |
+
</logging>
|
43 |
+
</phpunit>
|
addons/vendor/otgs/icons
ADDED
@@ -0,0 +1 @@
|
|
|
1 |
+
Subproject commit 4dbce75c1ba493c7d4d2c86f318d2ad10fa4f24b
|
addons/vendor/otgs/ui
ADDED
@@ -0,0 +1 @@
|
|
|
1 |
+
Subproject commit d8b11b073ba3247f25108b0dd88742ca3b0d4628
|
addons/vendor/wpml/collect/collect-logo.png
ADDED
Binary file
|
addons/vendor/wpml/collect/phpunit.xml
ADDED
@@ -0,0 +1,20 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?xml version="1.0" encoding="UTF-8"?>
|
2 |
+
<phpunit backupGlobals="false"
|
3 |
+
backupStaticAttributes="false"
|
4 |
+
bootstrap="tests/bootstrap.php"
|
5 |
+
colors="true"
|
6 |
+
convertErrorsToExceptions="true"
|
7 |
+
convertNoticesToExceptions="true"
|
8 |
+
convertWarningsToExceptions="true"
|
9 |
+
processIsolation="false"
|
10 |
+
stopOnError="false"
|
11 |
+
stopOnFailure="false"
|
12 |
+
syntaxCheck="true"
|
13 |
+
verbose="true"
|
14 |
+
>
|
15 |
+
<testsuites>
|
16 |
+
<testsuite name="Laravel Test Suite">
|
17 |
+
<directory suffix="Test.php">./tests</directory>
|
18 |
+
</testsuite>
|
19 |
+
</testsuites>
|
20 |
+
</phpunit>
|
addons/vendor/wpml/collect/readme.md
ADDED
@@ -0,0 +1,19 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
[![Codeship Status for tightenco/collect](https://codeship.com/projects/7a88b780-04ee-0134-0d48-3e31f9e0f6b8/status?branch=master)](https://codeship.com/projects/154325)
|
2 |
+
|
3 |
+
![](https://raw.githubusercontent.com/tightenco/collect/master/collect-logo.png)
|
4 |
+
|
5 |
+
# Collect - Illuminate Collections
|
6 |
+
|
7 |
+
Import [Laravel's Collections](https://laravel.com/docs/collections) into non-Laravel packages easily, without needing to require the entire `Illuminate\Support` package. ([Why not pull `Illuminate\Support` in framework-agnostic packages](https://yuloh.github.io/2016/dont-use-illuminate-support/))
|
8 |
+
|
9 |
+
Written by Taylor Otwell as a part of Laravel's [Illuminate/Support](https://github.com/illuminate/support) package, Collect is just the code from Support needed in order to use Collections on their own.
|
10 |
+
|
11 |
+
Lovingly split by Matt Stauffer for [Tighten Co.](http://tighten.co/), with a kick in the butt to finally do it from [@assertchris](https://github.com/assertchris).
|
12 |
+
|
13 |
+
## FAQ
|
14 |
+
- **Will this develop independently from Illuminate's Collections?**
|
15 |
+
No. Right now it's split manually, but the goal is for it shortly to be split automatically to keep it in sync with Laravel's Collections, even mirroring the release numbers.
|
16 |
+
- **Why isn't this just under the Illuminate namespace?**
|
17 |
+
Because that would require adding a lot of complexity and duplication to Illuminate\Support's internal structure. One day Taylor may choose to do that, but right now he hasn't and doesn't have any immediate plans to do so. If he does, we'll deprecate this package and point to the core version.
|
18 |
+
- **Why not just use an array?**
|
19 |
+
What a great question. [Tightenite Adam Wathan has a book about that.](http://adamwathan.me/refactoring-to-collections/)
|
addons/vendor/wpml/collect/src/Illuminate/Contracts/Support/Arrayable.php
ADDED
@@ -0,0 +1,13 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace WPML\Collect\Contracts\Support;
|
4 |
+
|
5 |
+
interface Arrayable
|
6 |
+
{
|
7 |
+
/**
|
8 |
+
* Get the instance as an array.
|
9 |
+
*
|
10 |
+
* @return array
|
11 |
+
*/
|
12 |
+
public function toArray();
|
13 |
+
}
|
addons/vendor/wpml/collect/src/Illuminate/Contracts/Support/Jsonable.php
ADDED
@@ -0,0 +1,14 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace WPML\Collect\Contracts\Support;
|
4 |
+
|
5 |
+
interface Jsonable
|
6 |
+
{
|
7 |
+
/**
|
8 |
+
* Convert the object to its JSON representation.
|
9 |
+
*
|
10 |
+
* @param int $options
|
11 |
+
* @return string
|
12 |
+
*/
|
13 |
+
public function toJson($options = 0);
|
14 |
+
}
|
addons/vendor/wpml/collect/src/Illuminate/Support/Arr.php
ADDED
@@ -0,0 +1,533 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace WPML\Collect\Support;
|
4 |
+
|
5 |
+
use ArrayAccess;
|
6 |
+
use WPML\Collect\Support\Traits\Macroable;
|
7 |
+
|
8 |
+
class Arr
|
9 |
+
{
|
10 |
+
use Macroable;
|
11 |
+
|
12 |
+
/**
|
13 |
+
* Determine whether the given value is array accessible.
|
14 |
+
*
|
15 |
+
* @param mixed $value
|
16 |
+
* @return bool
|
17 |
+
*/
|
18 |
+
public static function accessible($value)
|
19 |
+
{
|
20 |
+
return is_array($value) || $value instanceof ArrayAccess;
|
21 |
+
}
|
22 |
+
|
23 |
+
/**
|
24 |
+
* Add an element to an array using "dot" notation if it doesn't exist.
|
25 |
+
*
|
26 |
+
* @param mixed[] $array
|
27 |
+
* @param string $key
|
28 |
+
* @param mixed $value
|
29 |
+
* @return mixed[]
|
30 |
+
*/
|
31 |
+
public static function add($array, $key, $value)
|
32 |
+
{
|
33 |
+
if (is_null(static::get($array, $key))) {
|
34 |
+
static::set($array, $key, $value);
|
35 |
+
}
|
36 |
+
|
37 |
+
return $array;
|
38 |
+
}
|
39 |
+
|
40 |
+
/**
|
41 |
+
* Collapse an array of arrays into a single array.
|
42 |
+
*
|
43 |
+
* @param mixed[] $array
|
44 |
+
* @return mixed[]
|
45 |
+
*/
|
46 |
+
public static function collapse($array)
|
47 |
+
{
|
48 |
+
$results = [];
|
49 |
+
|
50 |
+
foreach ($array as $values) {
|
51 |
+
if ($values instanceof Collection) {
|
52 |
+
$values = $values->all();
|
53 |
+
} elseif (! is_array($values)) {
|
54 |
+
continue;
|
55 |
+
}
|
56 |
+
|
57 |
+
$results = array_merge($results, $values);
|
58 |
+
}
|
59 |
+
|
60 |
+
return $results;
|
61 |
+
}
|
62 |
+
|
63 |
+
/**
|
64 |
+
* Divide an array into two arrays. One with keys and the other with values.
|
65 |
+
*
|
66 |
+
* @param mixed[] $array
|
67 |
+
* @return mixed[]
|
68 |
+
*/
|
69 |
+
public static function divide($array)
|
70 |
+
{
|
71 |
+
return [array_keys($array), array_values($array)];
|
72 |
+
}
|
73 |
+
|
74 |
+
/**
|
75 |
+
* Flatten a multi-dimensional associative array with dots.
|
76 |
+
*
|
77 |
+
* @param mixed[] $array
|
78 |
+
* @param string $prepend
|
79 |
+
* @return mixed[]
|
80 |
+
*/
|
81 |
+
public static function dot($array, $prepend = '')
|
82 |
+
{
|
83 |
+
$results = [];
|
84 |
+
|
85 |
+
foreach ($array as $key => $value) {
|
86 |
+
if (is_array($value) && ! empty($value)) {
|
87 |
+
$results = array_merge($results, static::dot($value, $prepend.$key.'.'));
|
88 |
+
} else {
|
89 |
+
$results[$prepend.$key] = $value;
|
90 |
+
}
|
91 |
+
}
|
92 |
+
|
93 |
+
return $results;
|
94 |
+
}
|
95 |
+
|
96 |
+
/**
|
97 |
+
* Get all of the given array except for a specified array of items.
|
98 |
+
*
|
99 |
+
* @param mixed[] $array
|
100 |
+
* @param mixed[]|string $keys
|
101 |
+
* @return mixed[]
|
102 |
+
*/
|
103 |
+
public static function except($array, $keys)
|
104 |
+
{
|
105 |
+
static::forget($array, $keys);
|
106 |
+
|
107 |
+
return $array;
|
108 |
+
}
|
109 |
+
|
110 |
+
/**
|
111 |
+
* Determine if the given key exists in the provided array.
|
112 |
+
*
|
113 |
+
* @param \ArrayAccess<mixed>|mixed[] $array
|
114 |
+
* @param string|int $key
|
115 |
+
* @return bool
|
116 |
+
*/
|
117 |
+
public static function exists($array, $key)
|
118 |
+
{
|
119 |
+
if ($array instanceof ArrayAccess) {
|
120 |
+
return $array->offsetExists($key);
|
121 |
+
}
|
122 |
+
|
123 |
+
return array_key_exists($key, $array);
|
124 |
+
}
|
125 |
+
|
126 |
+
/**
|
127 |
+
* Return the first element in an array passing a given truth test.
|
128 |
+
*
|
129 |
+
* @param mixed[] $array
|
130 |
+
* @param callable|null $callback
|
131 |
+
* @param mixed $default
|
132 |
+
* @return mixed
|
133 |
+
*/
|
134 |
+
public static function first($array, callable $callback = null, $default = null)
|
135 |
+
{
|
136 |
+
if (is_null($callback)) {
|
137 |
+
if (empty($array)) {
|
138 |
+
return value($default);
|
139 |
+
}
|
140 |
+
|
141 |
+
foreach ($array as $item) {
|
142 |
+
return $item;
|
143 |
+
}
|
144 |
+
}
|
145 |
+
|
146 |
+
foreach ($array as $key => $value) {
|
147 |
+
if (call_user_func($callback, $value, $key)) {
|
148 |
+
return $value;
|
149 |
+
}
|
150 |
+
}
|
151 |
+
|
152 |
+
return value($default);
|
153 |
+
}
|
154 |
+
|
155 |
+
/**
|
156 |
+
* Return the last element in an array passing a given truth test.
|
157 |
+
*
|
158 |
+
* @param mixed[] $array
|
159 |
+
* @param callable|null $callback
|
160 |
+
* @param mixed $default
|
161 |
+
* @return mixed
|
162 |
+
*/
|
163 |
+
public static function last($array, callable $callback = null, $default = null)
|
164 |
+
{
|
165 |
+
if (is_null($callback)) {
|
166 |
+
return empty($array) ? value($default) : end($array);
|
167 |
+
}
|
168 |
+
|
169 |
+
return static::first(array_reverse($array, true), $callback, $default);
|
170 |
+
}
|
171 |
+
|
172 |
+
/**
|
173 |
+
* Flatten a multi-dimensional array into a single level.
|
174 |
+
*
|
175 |
+
* @param mixed[] $array
|
176 |
+
* @param int $depth
|
177 |
+
* @return array
|
178 |
+
*/
|
179 |
+
public static function flatten($array, $depth = INF)
|
180 |
+
{
|
181 |
+
return array_reduce($array, function ($result, $item) use ($depth) {
|
182 |
+
$item = $item instanceof Collection ? $item->all() : $item;
|
183 |
+
|
184 |
+
if (! is_array($item)) {
|
185 |
+
return array_merge($result, [$item]);
|
186 |
+
} elseif ($depth === 1) {
|
187 |
+
return array_merge($result, array_values($item));
|
188 |
+
} else {
|
189 |
+
return array_merge($result, static::flatten($item, $depth - 1));
|
190 |
+
}
|
191 |
+
}, []);
|
192 |
+
}
|
193 |
+
|
194 |
+
/**
|
195 |
+
* Remove one or many array items from a given array using "dot" notation.
|
196 |
+
*
|
197 |
+
* @param mixed[] $array
|
198 |
+
* @param mixed[]|string $keys
|
199 |
+
* @return void
|
200 |
+
*/
|
201 |
+
public static function forget(&$array, $keys)
|
202 |
+
{
|
203 |
+
$original = &$array;
|
204 |
+
|
205 |
+
$keys = (array) $keys;
|
206 |
+
|
207 |
+
if (count($keys) === 0) {
|
208 |
+
return;
|
209 |
+
}
|
210 |
+
|
211 |
+
foreach ($keys as $key) {
|
212 |
+
// if the exact key exists in the top-level, remove it
|
213 |
+
if (static::exists($array, $key)) {
|
214 |
+
unset($array[$key]);
|
215 |
+
|
216 |
+
continue;
|
217 |
+
}
|
218 |
+
|
219 |
+
$parts = explode('.', $key);
|
220 |
+
|
221 |
+
// clean up before each pass
|
222 |
+
$array = &$original;
|
223 |
+
|
224 |
+
while (count($parts) > 1) {
|
225 |
+
$part = array_shift($parts);
|
226 |
+
|
227 |
+
if (isset($array[$part]) && is_array($array[$part])) {
|
228 |
+
$array = &$array[$part];
|
229 |
+
} else {
|
230 |
+
continue 2;
|
231 |
+
}
|
232 |
+
}
|
233 |
+
|
234 |
+
unset($array[array_shift($parts)]);
|
235 |
+
}
|
236 |
+
}
|
237 |
+
|
238 |
+
/**
|
239 |
+
* Get an item from an array using "dot" notation.
|
240 |
+
*
|
241 |
+
* @param \ArrayAccess<mixed>|mixed[] $array
|
242 |
+
* @param string $key
|
243 |
+
* @param mixed $default
|
244 |
+
* @return mixed
|
245 |
+
*/
|
246 |
+
public static function get($array, $key, $default = null)
|
247 |
+
{
|
248 |
+
if (! static::accessible($array)) {
|
249 |
+
return value($default);
|
250 |
+
}
|
251 |
+
|
252 |
+
if (is_null($key)) {
|
253 |
+
return $array;
|
254 |
+
}
|
255 |
+
|
256 |
+
if (static::exists($array, $key)) {
|
257 |
+
return $array[$key];
|
258 |
+
}
|
259 |
+
|
260 |
+
foreach (explode('.', $key) as $segment) {
|
261 |
+
if (static::accessible($array) && static::exists($array, $segment)) {
|
262 |
+
$array = $array[$segment];
|
263 |
+
} else {
|
264 |
+
return value($default);
|
265 |
+
}
|
266 |
+
}
|
267 |
+
|
268 |
+
return $array;
|
269 |
+
}
|
270 |
+
|
271 |
+
/**
|
272 |
+
* Check if an item or items exist in an array using "dot" notation.
|
273 |
+
*
|
274 |
+
* @param \ArrayAccess<mixed>|mixed[] $array
|
275 |
+
* @param string|mixed[] $keys
|
276 |
+
* @return bool
|
277 |
+
*/
|
278 |
+
public static function has($array, $keys)
|
279 |
+
{
|
280 |
+
if (is_null($keys)) {
|
281 |
+
return false;
|
282 |
+
}
|
283 |
+
|
284 |
+
$keys = (array) $keys;
|
285 |
+
|
286 |
+
if (! $array) {
|
287 |
+
return false;
|
288 |
+
}
|
289 |
+
|
290 |
+
if ($keys === []) {
|
291 |
+
return false;
|
292 |
+
}
|
293 |
+
|
294 |
+
foreach ($keys as $key) {
|
295 |
+
$subKeyArray = $array;
|
296 |
+
|
297 |
+
if (static::exists($array, $key)) {
|
298 |
+
continue;
|
299 |
+
}
|
300 |
+
|
301 |
+
foreach (explode('.', $key) as $segment) {
|
302 |
+
if (static::accessible($subKeyArray) && static::exists($subKeyArray, $segment)) {
|
303 |
+
$subKeyArray = $subKeyArray[$segment];
|
304 |
+
} else {
|
305 |
+
return false;
|
306 |
+
}
|
307 |
+
}
|
308 |
+
}
|
309 |
+
|
310 |
+
return true;
|
311 |
+
}
|
312 |
+
|
313 |
+
/**
|
314 |
+
* Determines if an array is associative.
|
315 |
+
*
|
316 |
+
* An array is "associative" if it doesn't have sequential numerical keys beginning with zero.
|
317 |
+
*
|
318 |
+
* @param mixed[] $array
|
319 |
+
* @return bool
|
320 |
+
*/
|
321 |
+
public static function isAssoc(array $array)
|
322 |
+
{
|
323 |
+
$keys = array_keys($array);
|
324 |
+
|
325 |
+
return array_keys($keys) !== $keys;
|
326 |
+
}
|
327 |
+
|
328 |
+
/**
|
329 |
+
* Get a subset of the items from the given array.
|
330 |
+
*
|
331 |
+
* @param mixed[] $array
|
332 |
+
* @param mixed[]|string $keys
|
333 |
+
* @return array
|
334 |
+
*/
|
335 |
+
public static function only($array, $keys)
|
336 |
+
{
|
337 |
+
return array_intersect_key($array, array_flip((array) $keys));
|
338 |
+
}
|
339 |
+
|
340 |
+
/**
|
341 |
+
* Pluck an array of values from an array.
|
342 |
+
*
|
343 |
+
* @param mixed[] $array
|
344 |
+
* @param string|mixed[] $value
|
345 |
+
* @param string|mixed[]|null $key
|
346 |
+
* @return mixed[]
|
347 |
+
*/
|
348 |
+
public static function pluck($array, $value, $key = null)
|
349 |
+
{
|
350 |
+
$results = [];
|
351 |
+
|
352 |
+
list($value, $key) = static::explodePluckParameters($value, $key);
|
353 |
+
|
354 |
+
foreach ($array as $item) {
|
355 |
+
$itemValue = data_get($item, $value);
|
356 |
+
|
357 |
+
// If the key is "null", we will just append the value to the array and keep
|
358 |
+
// looping. Otherwise we will key the array using the value of the key we
|
359 |
+
// received from the developer. Then we'll return the final array form.
|
360 |
+
if (is_null($key)) {
|
361 |
+
$results[] = $itemValue;
|
362 |
+
} else {
|
363 |
+
$itemKey = data_get($item, $key);
|
364 |
+
|
365 |
+
$results[$itemKey] = $itemValue;
|
366 |
+
}
|
367 |
+
}
|
368 |
+
|
369 |
+
return $results;
|
370 |
+
}
|
371 |
+
|
372 |
+
/**
|
373 |
+
* Explode the "value" and "key" arguments passed to "pluck".
|
374 |
+
*
|
375 |
+
* @param string|mixed[] $value
|
376 |
+
* @param string|mixed[]|null $key
|
377 |
+
* @return mixed[]
|
378 |
+
*/
|
379 |
+
protected static function explodePluckParameters($value, $key)
|
380 |
+
{
|
381 |
+
$value = is_string($value) ? explode('.', $value) : $value;
|
382 |
+
|
383 |
+
$key = is_null($key) || is_array($key) ? $key : explode('.', $key);
|
384 |
+
|
385 |
+
return [$value, $key];
|
386 |
+
}
|
387 |
+
|
388 |
+
/**
|
389 |
+
* Push an item onto the beginning of an array.
|
390 |
+
*
|
391 |
+
* @param mixed[] $array
|
392 |
+
* @param mixed $value
|
393 |
+
* @param mixed $key
|
394 |
+
* @return mixed[]
|
395 |
+
*/
|
396 |
+
public static function prepend($array, $value, $key = null)
|
397 |
+
{
|
398 |
+
if (is_null($key)) {
|
399 |
+
array_unshift($array, $value);
|
400 |
+
} else {
|
401 |
+
$array = [$key => $value] + $array;
|
402 |
+
}
|
403 |
+
|
404 |
+
return $array;
|
405 |
+
}
|
406 |
+
|
407 |
+
/**
|
408 |
+
* Get a value from the array, and remove it.
|
409 |
+
*
|
410 |
+
* @param mixed[] $array
|
411 |
+
* @param string $key
|
412 |
+
* @param mixed $default
|
413 |
+
* @return mixed
|
414 |
+
*/
|
415 |
+
public static function pull(&$array, $key, $default = null)
|
416 |
+
{
|
417 |
+
$value = static::get($array, $key, $default);
|
418 |
+
|
419 |
+
static::forget($array, $key);
|
420 |
+
|
421 |
+
return $value;
|
422 |
+
}
|
423 |
+
|
424 |
+
/**
|
425 |
+
* Set an array item to a given value using "dot" notation.
|
426 |
+
*
|
427 |
+
* If no key is given to the method, the entire array will be replaced.
|
428 |
+
*
|
429 |
+
* @param mixed[] $array
|
430 |
+
* @param string $key
|
431 |
+
* @param mixed $value
|
432 |
+
* @return mixed[]
|
433 |
+
*/
|
434 |
+
public static function set(&$array, $key, $value)
|
435 |
+
{
|
436 |
+
if (is_null($key)) {
|
437 |
+
return $array = $value;
|
438 |
+
}
|
439 |
+
|
440 |
+
$keys = explode('.', $key);
|
441 |
+
|
442 |
+
while (count($keys) > 1) {
|
443 |
+
$key = array_shift($keys);
|
444 |
+
|
445 |
+
// If the key doesn't exist at this depth, we will just create an empty array
|
446 |
+
// to hold the next value, allowing us to create the arrays to hold final
|
447 |
+
// values at the correct depth. Then we'll keep digging into the array.
|
448 |
+
if (! isset($array[$key]) || ! is_array($array[$key])) {
|
449 |
+
$array[$key] = [];
|
450 |
+
}
|
451 |
+
|
452 |
+
$array = &$array[$key];
|
453 |
+
}
|
454 |
+
|
455 |
+
$array[array_shift($keys)] = $value;
|
456 |
+
|
457 |
+
return $array;
|
458 |
+
}
|
459 |
+
|
460 |
+
/**
|
461 |
+
* Sort the array using the given callback or "dot" notation.
|
462 |
+
*
|
463 |
+
* @param mixed[] $array
|
464 |
+
* @param callable|string $callback
|
465 |
+
* @return mixed[]
|
466 |
+
*/
|
467 |
+
public static function sort($array, $callback)
|
468 |
+
{
|
469 |
+
return Collection::make($array)->sortBy($callback)->all();
|
470 |
+
}
|
471 |
+
|
472 |
+
/**
|
473 |
+
* Recursively sort an array by keys and values.
|
474 |
+
*
|
475 |
+
* @param mixed[] $array
|
476 |
+
* @return mixed[]
|
477 |
+
*/
|
478 |
+
public static function sortRecursive($array)
|
479 |
+
{
|
480 |
+
foreach ($array as &$value) {
|
481 |
+
if (is_array($value)) {
|
482 |
+
$value = static::sortRecursive($value);
|
483 |
+
}
|
484 |
+
}
|
485 |
+
|
486 |
+
if (static::isAssoc($array)) {
|
487 |
+
ksort($array);
|
488 |
+
} else {
|
489 |
+
sort($array);
|
490 |
+
}
|
491 |
+
|
492 |
+
return $array;
|
493 |
+
}
|
494 |
+
|
495 |
+
/**
|
496 |
+
* Filter the array using the given callback.
|
497 |
+
*
|
498 |
+
* @param mixed[] $array
|
499 |
+
* @param callable $callback
|
500 |
+
* @return mixed[]
|
501 |
+
*/
|
502 |
+
public static function where($array, callable $callback)
|
503 |
+
{
|
504 |
+
return array_filter($array, $callback, ARRAY_FILTER_USE_BOTH);
|
505 |
+
}
|
506 |
+
|
507 |
+
|
508 |
+
/**
|
509 |
+
* @param mixed ...$arrays
|
510 |
+
*
|
511 |
+
* @return mixed[]|mixed[mixed]
|
512 |
+
*/
|
513 |
+
public static function crossJoin(...$arrays)
|
514 |
+
{
|
515 |
+
$results = [[]];
|
516 |
+
|
517 |
+
foreach ($arrays as $index => $array) {
|
518 |
+
$append = [];
|
519 |
+
|
520 |
+
foreach ($results as $product) {
|
521 |
+
foreach ($array as $item) {
|
522 |
+
$product[$index] = $item;
|
523 |
+
|
524 |
+
$append[] = $product;
|
525 |
+
}
|
526 |
+
}
|
527 |
+
|
528 |
+
$results = $append;
|
529 |
+
}
|
530 |
+
|
531 |
+
return $results;
|
532 |
+
}
|
533 |
+
}
|
addons/vendor/wpml/collect/src/Illuminate/Support/Collection.php
ADDED
@@ -0,0 +1,1500 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace WPML\Collect\Support;
|
4 |
+
|
5 |
+
use Countable;
|
6 |
+
use ArrayAccess;
|
7 |
+
use Traversable;
|
8 |
+
use ArrayIterator;
|
9 |
+
use CachingIterator;
|
10 |
+
use JsonSerializable;
|
11 |
+
use IteratorAggregate;
|
12 |
+
use InvalidArgumentException;
|
13 |
+
use WPML\Collect\Support\Traits\Macroable;
|
14 |
+
use WPML\Collect\Contracts\Support\Jsonable;
|
15 |
+
use WPML\Collect\Contracts\Support\Arrayable;
|
16 |
+
|
17 |
+
class Collection implements ArrayAccess, Arrayable, Countable, IteratorAggregate, Jsonable, JsonSerializable
|
18 |
+
{
|
19 |
+
use Macroable;
|
20 |
+
|
21 |
+
/**
|
22 |
+
* The items contained in the collection.
|
23 |
+
*
|
24 |
+
* @var mixed[]
|
25 |
+
*/
|
26 |
+
protected $items = [];
|
27 |
+
|
28 |
+
/**
|
29 |
+
* Create a new collection.
|
30 |
+
*
|
31 |
+
* @param mixed $items
|
32 |
+
* @return void
|
33 |
+
*/
|
34 |
+
public function __construct($items = [])
|
35 |
+
{
|
36 |
+
$this->items = $this->getArrayableItems($items);
|
37 |
+
}
|
38 |
+
|
39 |
+
/**
|
40 |
+
* Create a new collection instance if the value isn't one already.
|
41 |
+
*
|
42 |
+
* @param mixed[] $items
|
43 |
+
* @return static
|
44 |
+
*/
|
45 |
+
public static function make($items = [])
|
46 |
+
{
|
47 |
+
return new static($items);
|
48 |
+
}
|
49 |
+
|
50 |
+
/**
|
51 |
+
* Get all of the items in the collection.
|
52 |
+
*
|
53 |
+
* @return mixed[]
|
54 |
+
*/
|
55 |
+
public function all()
|
56 |
+
{
|
57 |
+
return $this->items;
|
58 |
+
}
|
59 |
+
|
60 |
+
/**
|
61 |
+
* Get the average value of a given key.
|
62 |
+
*
|
63 |
+
* @param callable|string|null $callback
|
64 |
+
* @return float|void
|
65 |
+
*/
|
66 |
+
public function avg($callback = null)
|
67 |
+
{
|
68 |
+
if ($count = $this->count()) {
|
69 |
+
return $this->sum($callback) / $count;
|
70 |
+
}
|
71 |
+
}
|
72 |
+
|
73 |
+
/**
|
74 |
+
* Alias for the "avg" method.
|
75 |
+
*
|
76 |
+
* @param callable|string|null $callback
|
77 |
+
* @return float|void
|
78 |
+
*/
|
79 |
+
public function average($callback = null)
|
80 |
+
{
|
81 |
+
return $this->avg($callback);
|
82 |
+
}
|
83 |
+
|
84 |
+
/**
|
85 |
+
* Get the median of a given key.
|
86 |
+
*
|
87 |
+
* @param null $key
|
88 |
+
* @return float|void
|
89 |
+
*/
|
90 |
+
public function median($key = null)
|
91 |
+
{
|
92 |
+
$count = $this->count();
|
93 |
+
|
94 |
+
if ($count == 0) {
|
95 |
+
return;
|
96 |
+
}
|
97 |
+
|
98 |
+
$values = with(isset($key) ? $this->pluck($key) : $this)
|
99 |
+
->sort()->values();
|
100 |
+
|
101 |
+
$middle = (int) ($count / 2);
|
102 |
+
|
103 |
+
if ($count % 2) {
|
104 |
+
return $values->get($middle);
|
105 |
+
}
|
106 |
+
|
107 |
+
return (new static([
|
108 |
+
$values->get($middle - 1), $values->get($middle),
|
109 |
+
]))->average();
|
110 |
+
}
|
111 |
+
|
112 |
+
/**
|
113 |
+
* Get the mode of a given key.
|
114 |
+
*
|
115 |
+
* @param null $key
|
116 |
+
* @return mixed[]|void
|
117 |
+
*/
|
118 |
+
public function mode($key = null)
|
119 |
+
{
|
120 |
+
$count = $this->count();
|
121 |
+
|
122 |
+
if ($count == 0) {
|
123 |
+
return;
|
124 |
+
}
|
125 |
+
|
126 |
+
$collection = isset($key) ? $this->pluck($key) : $this;
|
127 |
+
|
128 |
+
$counts = new self;
|
129 |
+
|
130 |
+
$collection->each(function ($value) use ($counts) {
|
131 |
+
$counts[$value] = isset($counts[$value]) ? $counts[$value] + 1 : 1;
|
132 |
+
});
|
133 |
+
|
134 |
+
$sorted = $counts->sort();
|
135 |
+
|
136 |
+
$highestValue = $sorted->last();
|
137 |
+
|
138 |
+
return $sorted->filter(function ($value) use ($highestValue) {
|
139 |
+
return $value == $highestValue;
|
140 |
+
})->sort()->keys()->all();
|
141 |
+
}
|
142 |
+
|
143 |
+
/**
|
144 |
+
* Collapse the collection of items into a single array.
|
145 |
+
*
|
146 |
+
* @return static
|
147 |
+
*/
|
148 |
+
public function collapse()
|
149 |
+
{
|
150 |
+
return new static(Arr::collapse($this->items));
|
151 |
+
}
|
152 |
+
|
153 |
+
/**
|
154 |
+
* Determine if an item exists in the collection.
|
155 |
+
*
|
156 |
+
* @param mixed $key
|
157 |
+
* @param mixed $value
|
158 |
+
* @return bool
|
159 |
+
*/
|
160 |
+
public function contains($key, $value = null)
|
161 |
+
{
|
162 |
+
if (func_num_args() == 2) {
|
163 |
+
return $this->contains(function ($item) use ($key, $value) {
|
164 |
+
return data_get($item, $key) == $value;
|
165 |
+
});
|
166 |
+
}
|
167 |
+
|
168 |
+
if ($this->useAsCallable($key)) {
|
169 |
+
return ! is_null($this->first($key));
|
170 |
+
}
|
171 |
+
|
172 |
+
return in_array($key, $this->items);
|
173 |
+
}
|
174 |
+
|
175 |
+
/**
|
176 |
+
* Determine if an item exists in the collection using strict comparison.
|
177 |
+
*
|
178 |
+
* @param mixed $key
|
179 |
+
* @param mixed $value
|
180 |
+
* @return bool
|
181 |
+
*/
|
182 |
+
public function containsStrict($key, $value = null)
|
183 |
+
{
|
184 |
+
if (func_num_args() == 2) {
|
185 |
+
return $this->contains(function ($item) use ($key, $value) {
|
186 |
+
return data_get($item, $key) === $value;
|
187 |
+
});
|
188 |
+
}
|
189 |
+
|
190 |
+
if ($this->useAsCallable($key)) {
|
191 |
+
return ! is_null($this->first($key));
|
192 |
+
}
|
193 |
+
|
194 |
+
return in_array($key, $this->items, true);
|
195 |
+
}
|
196 |
+
|
197 |
+
/**
|
198 |
+
* Get the items in the collection that are not present in the given items.
|
199 |
+
*
|
200 |
+
* @param mixed $items
|
201 |
+
* @return static
|
202 |
+
*/
|
203 |
+
public function diff($items)
|
204 |
+
{
|
205 |
+
return new static(array_diff($this->items, $this->getArrayableItems($items)));
|
206 |
+
}
|
207 |
+
|
208 |
+
/**
|
209 |
+
* Get the items in the collection whose keys are not present in the given items.
|
210 |
+
*
|
211 |
+
* @param mixed $items
|
212 |
+
* @return static
|
213 |
+
*/
|
214 |
+
public function diffKeys($items)
|
215 |
+
{
|
216 |
+
return new static(array_diff_key($this->items, $this->getArrayableItems($items)));
|
217 |
+
}
|
218 |
+
|
219 |
+
/**
|
220 |
+
* Execute a callback over each item.
|
221 |
+
*
|
222 |
+
* @param callable $callback
|
223 |
+
* @return $this
|
224 |
+
*/
|
225 |
+
public function each(callable $callback)
|
226 |
+
{
|
227 |
+
foreach ($this->items as $key => $item) {
|
228 |
+
if ($callback($item, $key) === false) {
|
229 |
+
break;
|
230 |
+
}
|
231 |
+
}
|
232 |
+
|
233 |
+
return $this;
|
234 |
+
}
|
235 |
+
|
236 |
+
/**
|
237 |
+
* Create a new collection consisting of every n-th element.
|
238 |
+
*
|
239 |
+
* @param int $step
|
240 |
+
* @param int $offset
|
241 |
+
* @return static
|
242 |
+
*/
|
243 |
+
public function every($step, $offset = 0)
|
244 |
+
{
|
245 |
+
$new = [];
|
246 |
+
|
247 |
+
$position = 0;
|
248 |
+
|
249 |
+
foreach ($this->items as $item) {
|
250 |
+
if ($position % $step === $offset) {
|
251 |
+
$new[] = $item;
|
252 |
+
}
|
253 |
+
|
254 |
+
$position++;
|
255 |
+
}
|
256 |
+
|
257 |
+
return new static($new);
|
258 |
+
}
|
259 |
+
|
260 |
+
/**
|
261 |
+
* Get all items except for those with the specified keys.
|
262 |
+
*
|
263 |
+
* @param mixed $keys
|
264 |
+
* @return static
|
265 |
+
*/
|
266 |
+
public function except($keys)
|
267 |
+
{
|
268 |
+
$keys = is_array($keys) ? $keys : func_get_args();
|
269 |
+
|
270 |
+
return new static(Arr::except($this->items, $keys));
|
271 |
+
}
|
272 |
+
|
273 |
+
/**
|
274 |
+
* Run a filter over each of the items.
|
275 |
+
*
|
276 |
+
* @param callable|null $callback
|
277 |
+
* @return static
|
278 |
+
*/
|
279 |
+
public function filter(callable $callback = null)
|
280 |
+
{
|
281 |
+
if ($callback) {
|
282 |
+
return new static(Arr::where($this->items, $callback));
|
283 |
+
}
|
284 |
+
|
285 |
+
return new static(array_filter($this->items));
|
286 |
+
}
|
287 |
+
|
288 |
+
/**
|
289 |
+
* Filter items by the given key value pair.
|
290 |
+
*
|
291 |
+
* @param string $key
|
292 |
+
* @param mixed $operator
|
293 |
+
* @param mixed $value
|
294 |
+
* @return static
|
295 |
+
*/
|
296 |
+
public function where($key, $operator, $value = null)
|
297 |
+
{
|
298 |
+
if (func_num_args() == 2) {
|
299 |
+
$value = $operator;
|
300 |
+
|
301 |
+
$operator = '=';
|
302 |
+
}
|
303 |
+
|
304 |
+
return $this->filter($this->operatorForWhere($key, $operator, $value));
|
305 |
+
}
|
306 |
+
|
307 |
+
/**
|
308 |
+
* Get an operator checker callback.
|
309 |
+
*
|
310 |
+
* @param string $key
|
311 |
+
* @param string $operator
|
312 |
+
* @param mixed $value
|
313 |
+
* @return \Closure
|
314 |
+
*/
|
315 |
+
protected function operatorForWhere($key, $operator, $value)
|
316 |
+
{
|
317 |
+
return function ($item) use ($key, $operator, $value) {
|
318 |
+
$retrieved = data_get($item, $key);
|
319 |
+
|
320 |
+
switch ($operator) {
|
321 |
+
default:
|
322 |
+
case '=':
|
323 |
+
case '==': return $retrieved == $value;
|
324 |
+
case '!=':
|
325 |
+
case '<>': return $retrieved != $value;
|
326 |
+
case '<': return $retrieved < $value;
|
327 |
+
case '>': return $retrieved > $value;
|
328 |
+
case '<=': return $retrieved <= $value;
|
329 |
+
case '>=': return $retrieved >= $value;
|
330 |
+
case '===': return $retrieved === $value;
|
331 |
+
case '!==': return $retrieved !== $value;
|
332 |
+
}
|
333 |
+
};
|
334 |
+
}
|
335 |
+
|
336 |
+
/**
|
337 |
+
* Filter items by the given key value pair using strict comparison.
|
338 |
+
*
|
339 |
+
* @param string $key
|
340 |
+
* @param mixed $value
|
341 |
+
* @return static
|
342 |
+
*/
|
343 |
+
public function whereStrict($key, $value)
|
344 |
+
{
|
345 |
+
return $this->where($key, '===', $value);
|
346 |
+
}
|
347 |
+
|
348 |
+
/**
|
349 |
+
* Filter items by the given key value pair.
|
350 |
+
*
|
351 |
+
* @param string $key
|
352 |
+
* @param mixed $values
|
353 |
+
* @param bool $strict
|
354 |
+
* @return static
|
355 |
+
*/
|
356 |
+
public function whereIn($key, $values, $strict = false)
|
357 |
+
{
|
358 |
+
$values = $this->getArrayableItems($values);
|
359 |
+
|
360 |
+
return $this->filter(function ($item) use ($key, $values, $strict) {
|
361 |
+
return in_array(data_get($item, $key), $values, $strict);
|
362 |
+
});
|
363 |
+
}
|
364 |
+
|
365 |
+
/**
|
366 |
+
* Filter items by the given key value pair using strict comparison.
|
367 |
+
*
|
368 |
+
* @param string $key
|
369 |
+
* @param mixed $values
|
370 |
+
* @return static
|
371 |
+
*/
|
372 |
+
public function whereInStrict($key, $values)
|
373 |
+
{
|
374 |
+
return $this->whereIn($key, $values, true);
|
375 |
+
}
|
376 |
+
|
377 |
+
/**
|
378 |
+
* Get the first item from the collection.
|
379 |
+
*
|
380 |
+
* @param callable|null $callback
|
381 |
+
* @param mixed $default
|
382 |
+
* @return mixed
|
383 |
+
*/
|
384 |
+
public function first(callable $callback = null, $default = null)
|
385 |
+
{
|
386 |
+
return Arr::first($this->items, $callback, $default);
|
387 |
+
}
|
388 |
+
|
389 |
+
/**
|
390 |
+
* Get a flattened array of the items in the collection.
|
391 |
+
*
|
392 |
+
* @param int $depth
|
393 |
+
* @return static
|
394 |
+
*/
|
395 |
+
public function flatten($depth = INF)
|
396 |
+
{
|
397 |
+
return new static(Arr::flatten($this->items, $depth));
|
398 |
+
}
|
399 |
+
|
400 |
+
/**
|
401 |
+
* Flip the items in the collection.
|
402 |
+
*
|
403 |
+
* @return static
|
404 |
+
*/
|
405 |
+
public function flip()
|
406 |
+
{
|
407 |
+
return new static(array_flip($this->items));
|
408 |
+
}
|
409 |
+
|
410 |
+
/**
|
411 |
+
* Remove an item from the collection by key.
|
412 |
+
*
|
413 |
+
* @param string|array $keys
|
414 |
+
* @return $this
|
415 |
+
*/
|
416 |
+
public function forget($keys)
|
417 |
+
{
|
418 |
+
foreach ((array) $keys as $key) {
|
419 |
+
$this->offsetUnset($key);
|
420 |
+
}
|
421 |
+
|
422 |
+
return $this;
|
423 |
+
}
|
424 |
+
|
425 |
+
/**
|
426 |
+
* Get an item from the collection by key.
|
427 |
+
*
|
428 |
+
* @param mixed $key
|
429 |
+
* @param mixed $default
|
430 |
+
* @return mixed
|
431 |
+
*/
|
432 |
+
public function get($key, $default = null)
|
433 |
+
{
|
434 |
+
if ($this->offsetExists($key)) {
|
435 |
+
return $this->items[$key];
|
436 |
+
}
|
437 |
+
|
438 |
+
return value($default);
|
439 |
+
}
|
440 |
+
|
441 |
+
/**
|
442 |
+
* Group an associative array by a field or using a callback.
|
443 |
+
*
|
444 |
+
* @param callable|string $groupBy
|
445 |
+
* @param bool $preserveKeys
|
446 |
+
* @return static
|
447 |
+
*/
|
448 |
+
public function groupBy($groupBy, $preserveKeys = false)
|
449 |
+
{
|
450 |
+
$groupBy = $this->valueRetriever($groupBy);
|
451 |
+
|
452 |
+
$results = [];
|
453 |
+
|
454 |
+
foreach ($this->items as $key => $value) {
|
455 |
+
$groupKeys = $groupBy($value, $key);
|
456 |
+
|
457 |
+
if (! is_array($groupKeys)) {
|
458 |
+
$groupKeys = [$groupKeys];
|
459 |
+
}
|
460 |
+
|
461 |
+
foreach ($groupKeys as $groupKey) {
|
462 |
+
if (! array_key_exists($groupKey, $results)) {
|
463 |
+
$results[$groupKey] = new static;
|
464 |
+
}
|
465 |
+
|
466 |
+
$results[$groupKey]->offsetSet($preserveKeys ? $key : null, $value);
|
467 |
+
}
|
468 |
+
}
|
469 |
+
|
470 |
+
return new static($results);
|
471 |
+
}
|
472 |
+
|
473 |
+
/**
|
474 |
+
* Key an associative array by a field or using a callback.
|
475 |
+
*
|
476 |
+
* @param callable|string $keyBy
|
477 |
+
* @return static
|
478 |
+
*/
|
479 |
+
public function keyBy($keyBy)
|
480 |
+
{
|
481 |
+
$keyBy = $this->valueRetriever($keyBy);
|
482 |
+
|
483 |
+
$results = [];
|
484 |
+
|
485 |
+
foreach ($this->items as $key => $item) {
|
486 |
+
$resolvedKey = $keyBy($item, $key);
|
487 |
+
|
488 |
+
if (is_object($resolvedKey)) {
|
489 |
+
$resolvedKey = (string) $resolvedKey;
|
490 |
+
}
|
491 |
+
|
492 |
+
$results[$resolvedKey] = $item;
|
493 |
+
}
|
494 |
+
|
495 |
+
return new static($results);
|
496 |
+
}
|
497 |
+
|
498 |
+
/**
|
499 |
+
* Determine if an item exists in the collection by key.
|
500 |
+
*
|
501 |
+
* @param mixed $key
|
502 |
+
* @return bool
|
503 |
+
*/
|
504 |
+
public function has($key)
|
505 |
+
{
|
506 |
+
return $this->offsetExists($key);
|
507 |
+
}
|
508 |
+
|
509 |
+
/**
|
510 |
+
* Concatenate values of a given key as a string.
|
511 |
+
*
|
512 |
+
* @param string $value
|
513 |
+
* @param string $glue
|
514 |
+
* @return string
|
515 |
+
*/
|
516 |
+
public function implode($value, $glue = null)
|
517 |
+
{
|
518 |
+
$first = $this->first();
|
519 |
+
|
520 |
+
if (is_array($first) || is_object($first)) {
|
521 |
+
return implode($glue, $this->pluck($value)->all());
|
522 |
+
}
|
523 |
+
|
524 |
+
return implode($value, $this->items);
|
525 |
+
}
|
526 |
+
|
527 |
+
/**
|
528 |
+
* Intersect the collection with the given items.
|
529 |
+
*
|
530 |
+
* @param mixed $items
|
531 |
+
* @return static
|
532 |
+
*/
|
533 |
+
public function intersect($items)
|
534 |
+
{
|
535 |
+
return new static(array_intersect($this->items, $this->getArrayableItems($items)));
|
536 |
+
}
|
537 |
+
|
538 |
+
/**
|
539 |
+
* Determine if the collection is empty or not.
|
540 |
+
*
|
541 |
+
* @return bool
|
542 |
+
*/
|
543 |
+
public function isEmpty()
|
544 |
+
{
|
545 |
+
return empty($this->items);
|
546 |
+
}
|
547 |
+
|
548 |
+
/**
|
549 |
+
* Determine if the given value is callable, but not a string.
|
550 |
+
*
|
551 |
+
* @param mixed $value
|
552 |
+
* @return bool
|
553 |
+
*/
|
554 |
+
protected function useAsCallable($value)
|
555 |
+
{
|
556 |
+
return ! is_string($value) && is_callable($value);
|
557 |
+
}
|
558 |
+
|
559 |
+
/**
|
560 |
+
* Get the keys of the collection items.
|
561 |
+
*
|
562 |
+
* @return static
|
563 |
+
*/
|
564 |
+
public function keys()
|
565 |
+
{
|
566 |
+
return new static(array_keys($this->items));
|
567 |
+
}
|
568 |
+
|
569 |
+
/**
|
570 |
+
* Get the last item from the collection.
|
571 |
+
*
|
572 |
+
* @param callable|null $callback
|
573 |
+
* @param mixed $default
|
574 |
+
* @return mixed
|
575 |
+
*/
|
576 |
+
public function last(callable $callback = null, $default = null)
|
577 |
+
{
|
578 |
+
return Arr::last($this->items, $callback, $default);
|
579 |
+
}
|
580 |
+
|
581 |
+
/**
|
582 |
+
* Get the values of a given key.
|
583 |
+
*
|
584 |
+
* @param string $value
|
585 |
+
* @param string|null $key
|
586 |
+
* @return static
|
587 |
+
*/
|
588 |
+
public function pluck($value, $key = null)
|
589 |
+
{
|
590 |
+
return new static(Arr::pluck($this->items, $value, $key));
|
591 |
+
}
|
592 |
+
|
593 |
+
/**
|
594 |
+
* Run a map over each of the items.
|
595 |
+
*
|
596 |
+
* @param callable $callback
|
597 |
+
* @return static
|
598 |
+
*/
|
599 |
+
public function map(callable $callback)
|
600 |
+
{
|
601 |
+
$keys = array_keys($this->items);
|
602 |
+
|
603 |
+
$items = array_map($callback, $this->items, $keys);
|
604 |
+
|
605 |
+
return new static(array_combine($keys, $items));
|
606 |
+
}
|
607 |
+
|
608 |
+
/**
|
609 |
+
* Run an associative map over each of the items.
|
610 |
+
*
|
611 |
+
* The callback should return an associative array with a single key/value pair.
|
612 |
+
*
|
613 |
+
* @param callable $callback
|
614 |
+
* @return static
|
615 |
+
*/
|
616 |
+
public function mapWithKeys(callable $callback)
|
617 |
+
{
|
618 |
+
return $this->flatMap($callback);
|
619 |
+
}
|
620 |
+
|
621 |
+
/**
|
622 |
+
* Map a collection and flatten the result by a single level.
|
623 |
+
*
|
624 |
+
* @param callable $callback
|
625 |
+
* @return static
|
626 |
+
*/
|
627 |
+
public function flatMap(callable $callback)
|
628 |
+
{
|
629 |
+
return $this->map($callback)->collapse();
|
630 |
+
}
|
631 |
+
|
632 |
+
/**
|
633 |
+
* Get the max value of a given key.
|
634 |
+
*
|
635 |
+
* @param callable|string|null $callback
|
636 |
+
* @return mixed
|
637 |
+
*/
|
638 |
+
public function max($callback = null)
|
639 |
+
{
|
640 |
+
$callback = $this->valueRetriever($callback);
|
641 |
+
|
642 |
+
return $this->reduce(function ($result, $item) use ($callback) {
|
643 |
+
$value = $callback($item);
|
644 |
+
|
645 |
+
return is_null($result) || $value > $result ? $value : $result;
|
646 |
+
});
|
647 |
+
}
|
648 |
+
|
649 |
+
/**
|
650 |
+
* Merge the collection with the given items.
|
651 |
+
*
|
652 |
+
* @param mixed $items
|
653 |
+
* @return static
|
654 |
+
*/
|
655 |
+
public function merge($items)
|
656 |
+
{
|
657 |
+
return new static(array_merge($this->items, $this->getArrayableItems($items)));
|
658 |
+
}
|
659 |
+
|
660 |
+
/**
|
661 |
+
* Create a collection by using this collection for keys and another for its values.
|
662 |
+
*
|
663 |
+
* @param mixed $values
|
664 |
+
* @return static
|
665 |
+
*/
|
666 |
+
public function combine($values)
|
667 |
+
{
|
668 |
+
return new static(array_combine($this->all(), $this->getArrayableItems($values)));
|
669 |
+
}
|
670 |
+
|
671 |
+
/**
|
672 |
+
* Union the collection with the given items.
|
673 |
+
*
|
674 |
+
* @param mixed $items
|
675 |
+
* @return static
|
676 |
+
*/
|
677 |
+
public function union($items)
|
678 |
+
{
|
679 |
+
return new static($this->items + $this->getArrayableItems($items));
|
680 |
+
}
|
681 |
+
|
682 |
+
/**
|
683 |
+
* Get the min value of a given key.
|
684 |
+
*
|
685 |
+
* @param callable|string|null $callback
|
686 |
+
* @return mixed
|
687 |
+
*/
|
688 |
+
public function min($callback = null)
|
689 |
+
{
|
690 |
+
$callback = $this->valueRetriever($callback);
|
691 |
+
|
692 |
+
return $this->reduce(function ($result, $item) use ($callback) {
|
693 |
+
$value = $callback($item);
|
694 |
+
|
695 |
+
return is_null($result) || $value < $result ? $value : $result;
|
696 |
+
});
|
697 |
+
}
|
698 |
+
|
699 |
+
/**
|
700 |
+
* Get the items with the specified keys.
|
701 |
+
*
|
702 |
+
* @param mixed $keys
|
703 |
+
* @return static
|
704 |
+
*/
|
705 |
+
public function only($keys)
|
706 |
+
{
|
707 |
+
if (is_null($keys)) {
|
708 |
+
return new static($this->items);
|
709 |
+
}
|
710 |
+
|
711 |
+
$keys = is_array($keys) ? $keys : func_get_args();
|
712 |
+
|
713 |
+
return new static(Arr::only($this->items, $keys));
|
714 |
+
}
|
715 |
+
|
716 |
+
/**
|
717 |
+
* "Paginate" the collection by slicing it into a smaller collection.
|
718 |
+
*
|
719 |
+
* @param int $page
|
720 |
+
* @param int $perPage
|
721 |
+
* @return static
|
722 |
+
*/
|
723 |
+
public function forPage($page, $perPage)
|
724 |
+
{
|
725 |
+
return $this->slice(($page - 1) * $perPage, $perPage);
|
726 |
+
}
|
727 |
+
|
728 |
+
/**
|
729 |
+
* Partition the collection into two arrays using the given callback or key.
|
730 |
+
*
|
731 |
+
* @param callable|string $key
|
732 |
+
* @param mixed $operator
|
733 |
+
* @param mixed $value
|
734 |
+
* @return static
|
735 |
+
*/
|
736 |
+
public function partition($key, $operator = null, $value = null)
|
737 |
+
{
|
738 |
+
$partitions = [new static, new static];
|
739 |
+
|
740 |
+
$callback = func_num_args() === 1
|
741 |
+
? $this->valueRetriever($key)
|
742 |
+
: $this->operatorForWhere(...func_get_args());
|
743 |
+
|
744 |
+
foreach ($this->items as $key => $item) {
|
745 |
+
$partitions[(int) ! $callback($item, $key)][$key] = $item;
|
746 |
+
}
|
747 |
+
|
748 |
+
return new static($partitions);
|
749 |
+
}
|
750 |
+
/**
|
751 |
+
* Pass the collection to the given callback and return the result.
|
752 |
+
*
|
753 |
+
* @param callable $callback
|
754 |
+
* @return mixed
|
755 |
+
*/
|
756 |
+
public function pipe(callable $callback)
|
757 |
+
{
|
758 |
+
return $callback($this);
|
759 |
+
}
|
760 |
+
|
761 |
+
/**
|
762 |
+
* Get and remove the last item from the collection.
|
763 |
+
*
|
764 |
+
* @return mixed
|
765 |
+
*/
|
766 |
+
public function pop()
|
767 |
+
{
|
768 |
+
return array_pop($this->items);
|
769 |
+
}
|
770 |
+
|
771 |
+
/**
|
772 |
+
* Push an item onto the beginning of the collection.
|
773 |
+
*
|
774 |
+
* @param mixed $value
|
775 |
+
* @param mixed $key
|
776 |
+
* @return $this
|
777 |
+
*/
|
778 |
+
public function prepend($value, $key = null)
|
779 |
+
{
|
780 |
+
$this->items = Arr::prepend($this->items, $value, $key);
|
781 |
+
|
782 |
+
return $this;
|
783 |
+
}
|
784 |
+
|
785 |
+
/**
|
786 |
+
* Push an item onto the end of the collection.
|
787 |
+
*
|
788 |
+
* @param mixed $value
|
789 |
+
* @return $this
|
790 |
+
*/
|
791 |
+
public function push($value)
|
792 |
+
{
|
793 |
+
$this->offsetSet(null, $value);
|
794 |
+
|
795 |
+
return $this;
|
796 |
+
}
|
797 |
+
|
798 |
+
/**
|
799 |
+
* Get and remove an item from the collection.
|
800 |
+
*
|
801 |
+
* @param mixed $key
|
802 |
+
* @param mixed $default
|
803 |
+
* @return mixed
|
804 |
+
*/
|
805 |
+
public function pull($key, $default = null)
|
806 |
+
{
|
807 |
+
return Arr::pull($this->items, $key, $default);
|
808 |
+
}
|
809 |
+
|
810 |
+
/**
|
811 |
+
* Put an item in the collection by key.
|
812 |
+
*
|
813 |
+
* @param mixed $key
|
814 |
+
* @param mixed $value
|
815 |
+
* @return $this
|
816 |
+
*/
|
817 |
+
public function put($key, $value)
|
818 |
+
{
|
819 |
+
$this->offsetSet($key, $value);
|
820 |
+
|
821 |
+
return $this;
|
822 |
+
}
|
823 |
+
|
824 |
+
/**
|
825 |
+
* Get one or more items randomly from the collection.
|
826 |
+
*
|
827 |
+
* @param int $amount
|
828 |
+
* @return mixed
|
829 |
+
*
|
830 |
+
* @throws \InvalidArgumentException
|
831 |
+
*/
|
832 |
+
public function random($amount = 1)
|
833 |
+
{
|
834 |
+
if ($amount > ($count = $this->count())) {
|
835 |
+
throw new InvalidArgumentException("You requested {$amount} items, but there are only {$count} items in the collection");
|
836 |
+
}
|
837 |
+
|
838 |
+
$keys = array_rand($this->items, $amount);
|
839 |
+
|
840 |
+
if ($amount == 1) {
|
841 |
+
return $this->items[$keys];
|
842 |
+
}
|
843 |
+
|
844 |
+
return new static(array_intersect_key($this->items, array_flip($keys)));
|
845 |
+
}
|
846 |
+
|
847 |
+
/**
|
848 |
+
* Reduce the collection to a single value.
|
849 |
+
*
|
850 |
+
* @param callable $callback
|
851 |
+
* @param mixed $initial
|
852 |
+
* @return mixed
|
853 |
+
*/
|
854 |
+
public function reduce(callable $callback, $initial = null)
|
855 |
+
{
|
856 |
+
return array_reduce($this->items, $callback, $initial);
|
857 |
+
}
|
858 |
+
|
859 |
+
/**
|
860 |
+
* Create a collection of all elements that do not pass a given truth test.
|
861 |
+
*
|
862 |
+
* @param callable|mixed $callback
|
863 |
+
* @return static
|
864 |
+
*/
|
865 |
+
public function reject($callback)
|
866 |
+
{
|
867 |
+
if ($this->useAsCallable($callback)) {
|
868 |
+
return $this->filter(function ($value, $key) use ($callback) {
|
869 |
+
return ! $callback($value, $key);
|
870 |
+
});
|
871 |
+
}
|
872 |
+
|
873 |
+
return $this->filter(function ($item) use ($callback) {
|
874 |
+
return $item != $callback;
|
875 |
+
});
|
876 |
+
}
|
877 |
+
|
878 |
+
/**
|
879 |
+
* Reverse items order.
|
880 |
+
*
|
881 |
+
* @return static
|
882 |
+
*/
|
883 |
+
public function reverse()
|
884 |
+
{
|
885 |
+
return new static(array_reverse($this->items, true));
|
886 |
+
}
|
887 |
+
|
888 |
+
/**
|
889 |
+
* Search the collection for a given value and return the corresponding key if successful.
|
890 |
+
*
|
891 |
+
* @param mixed $value
|
892 |
+
* @param bool $strict
|
893 |
+
* @return mixed
|
894 |
+
*/
|
895 |
+
public function search($value, $strict = false)
|
896 |
+
{
|
897 |
+
if (! $this->useAsCallable($value)) {
|
898 |
+
return array_search($value, $this->items, $strict);
|
899 |
+
}
|
900 |
+
|
901 |
+
foreach ($this->items as $key => $item) {
|
902 |
+
if (call_user_func($value, $item, $key)) {
|
903 |
+
return $key;
|
904 |
+
}
|
905 |
+
}
|
906 |
+
|
907 |
+
return false;
|
908 |
+
}
|
909 |
+
|
910 |
+
/**
|
911 |
+
* Get and remove the first item from the collection.
|
912 |
+
*
|
913 |
+
* @return mixed
|
914 |
+
*/
|
915 |
+
public function shift()
|
916 |
+
{
|
917 |
+
return array_shift($this->items);
|
918 |
+
}
|
919 |
+
|
920 |
+
/**
|
921 |
+
* Shuffle the items in the collection.
|
922 |
+
*
|
923 |
+
* @param int $seed
|
924 |
+
* @return static
|
925 |
+
*/
|
926 |
+
public function shuffle($seed = null)
|
927 |
+
{
|
928 |
+
$items = $this->items;
|
929 |
+
|
930 |
+
if (is_null($seed)) {
|
931 |
+
shuffle($items);
|
932 |
+
} else {
|
933 |
+
srand($seed);
|
934 |
+
|
935 |
+
usort($items, function () {
|
936 |
+
return rand(-1, 1);
|
937 |
+
});
|
938 |
+
}
|
939 |
+
|
940 |
+
return new static($items);
|
941 |
+
}
|
942 |
+
|
943 |
+
/**
|
944 |
+
* Slice the underlying collection array.
|
945 |
+
*
|
946 |
+
* @param int $offset
|
947 |
+
* @param int $length
|
948 |
+
* @return static
|
949 |
+
*/
|
950 |
+
public function slice($offset, $length = null)
|
951 |
+
{
|
952 |
+
return new static(array_slice($this->items, $offset, $length, true));
|
953 |
+
}
|
954 |
+
|
955 |
+
/**
|
956 |
+
* Split a collection into a certain number of groups.
|
957 |
+
*
|
958 |
+
* @param int $numberOfGroups
|
959 |
+
* @return static
|
960 |
+
*/
|
961 |
+
public function split($numberOfGroups)
|
962 |
+
{
|
963 |
+
if ($this->isEmpty()) {
|
964 |
+
return new static;
|
965 |
+
}
|
966 |
+
|
967 |
+
$groupSize = ceil($this->count() / $numberOfGroups);
|
968 |
+
|
969 |
+
return $this->chunk($groupSize);
|
970 |
+
}
|
971 |
+
|
972 |
+
/**
|
973 |
+
* Chunk the underlying collection array.
|
974 |
+
*
|
975 |
+
* @param int $size
|
976 |
+
* @return static
|
977 |
+
*/
|
978 |
+
public function chunk($size)
|
979 |
+
{
|
980 |
+
$chunks = [];
|
981 |
+
|
982 |
+
foreach (array_chunk($this->items, $size, true) as $chunk) {
|
983 |
+
$chunks[] = new static($chunk);
|
984 |
+
}
|
985 |
+
|
986 |
+
return new static($chunks);
|
987 |
+
}
|
988 |
+
|
989 |
+
/**
|
990 |
+
* Sort through each item with a callback.
|
991 |
+
*
|
992 |
+
* @param callable|null $callback
|
993 |
+
* @return static
|
994 |
+
*/
|
995 |
+
public function sort(callable $callback = null)
|
996 |
+
{
|
997 |
+
$items = $this->items;
|
998 |
+
|
999 |
+
$callback
|
1000 |
+
? uasort($items, $callback)
|
1001 |
+
: asort($items);
|
1002 |
+
|
1003 |
+
return new static($items);
|
1004 |
+
}
|
1005 |
+
|
1006 |
+
/**
|
1007 |
+
* Sort the collection using the given callback.
|
1008 |
+
*
|
1009 |
+
* @param callable|string $callback
|
1010 |
+
* @param int $options
|
1011 |
+
* @param bool $descending
|
1012 |
+
* @return static
|
1013 |
+
*/
|
1014 |
+
public function sortBy($callback, $options = SORT_REGULAR, $descending = false)
|
1015 |
+
{
|
1016 |
+
$results = [];
|
1017 |
+
|
1018 |
+
$callback = $this->valueRetriever($callback);
|
1019 |
+
|
1020 |
+
// First we will loop through the items and get the comparator from a callback
|
1021 |
+
// function which we were given. Then, we will sort the returned values and
|
1022 |
+
// and grab the corresponding values for the sorted keys from this array.
|
1023 |
+
foreach ($this->items as $key => $value) {
|
1024 |
+
$results[$key] = $callback($value, $key);
|
1025 |
+
}
|
1026 |
+
|
1027 |
+
$descending ? arsort($results, $options)
|
1028 |
+
: asort($results, $options);
|
1029 |
+
|
1030 |
+
// Once we have sorted all of the keys in the array, we will loop through them
|
1031 |
+
// and grab the corresponding model so we can set the underlying items list
|
1032 |
+
// to the sorted version. Then we'll just return the collection instance.
|
1033 |
+
foreach (array_keys($results) as $key) {
|
1034 |
+
$results[$key] = $this->items[$key];
|
1035 |
+
}
|
1036 |
+
|
1037 |
+
return new static($results);
|
1038 |
+
}
|
1039 |
+
|
1040 |
+
/**
|
1041 |
+
* Sort the collection in descending order using the given callback.
|
1042 |
+
*
|
1043 |
+
* @param callable|string $callback
|
1044 |
+
* @param int $options
|
1045 |
+
* @return static
|
1046 |
+
*/
|
1047 |
+
public function sortByDesc($callback, $options = SORT_REGULAR)
|
1048 |
+
{
|
1049 |
+
return $this->sortBy($callback, $options, true);
|
1050 |
+
}
|
1051 |
+
|
1052 |
+
/**
|
1053 |
+
* Splice a portion of the underlying collection array.
|
1054 |
+
*
|
1055 |
+
* @param int $offset
|
1056 |
+
* @param int|null $length
|
1057 |
+
* @param mixed $replacement
|
1058 |
+
* @return static
|
1059 |
+
*/
|
1060 |
+
public function splice($offset, $length = null, $replacement = [])
|
1061 |
+
{
|
1062 |
+
if (func_num_args() == 1) {
|
1063 |
+
return new static(array_splice($this->items, $offset));
|
1064 |
+
}
|
1065 |
+
|
1066 |
+
return new static(array_splice($this->items, $offset, $length, $replacement));
|
1067 |
+
}
|
1068 |
+
|
1069 |
+
/**
|
1070 |
+
* Get the sum of the given values.
|
1071 |
+
*
|
1072 |
+
* @param callable|string|null $callback
|
1073 |
+
* @return mixed
|
1074 |
+
*/
|
1075 |
+
public function sum($callback = null)
|
1076 |
+
{
|
1077 |
+
if (is_null($callback)) {
|
1078 |
+
return array_sum($this->items);
|
1079 |
+
}
|
1080 |
+
|
1081 |
+
$callback = $this->valueRetriever($callback);
|
1082 |
+
|
1083 |
+
return $this->reduce(function ($result, $item) use ($callback) {
|
1084 |
+
return $result + $callback($item);
|
1085 |
+
}, 0);
|
1086 |
+
}
|
1087 |
+
|
1088 |
+
/**
|
1089 |
+
* Take the first or last {$limit} items.
|
1090 |
+
*
|
1091 |
+
* @param int $limit
|
1092 |
+
* @return static
|
1093 |
+
*/
|
1094 |
+
public function take($limit)
|
1095 |
+
{
|
1096 |
+
if ($limit < 0) {
|
1097 |
+
return $this->slice($limit, abs($limit));
|
1098 |
+
}
|
1099 |
+
|
1100 |
+
return $this->slice(0, $limit);
|
1101 |
+
}
|
1102 |
+
|
1103 |
+
/**
|
1104 |
+
* Transform each item in the collection using a callback.
|
1105 |
+
*
|
1106 |
+
* @param callable $callback
|
1107 |
+
* @return $this
|
1108 |
+
*/
|
1109 |
+
public function transform(callable $callback)
|
1110 |
+
{
|
1111 |
+
$this->items = $this->map($callback)->all();
|
1112 |
+
|
1113 |
+
return $this;
|
1114 |
+
}
|
1115 |
+
|
1116 |
+
/**
|
1117 |
+
* Return only unique items from the collection array.
|
1118 |
+
*
|
1119 |
+
* @param string|callable|null $key
|
1120 |
+
* @param bool $strict
|
1121 |
+
*
|
1122 |
+
* @return static
|
1123 |
+
*/
|
1124 |
+
public function unique($key = null, $strict = false)
|
1125 |
+
{
|
1126 |
+
if (is_null($key)) {
|
1127 |
+
return new static(array_unique($this->items, SORT_REGULAR));
|
1128 |
+
}
|
1129 |
+
|
1130 |
+
$key = $this->valueRetriever($key);
|
1131 |
+
|
1132 |
+
$exists = [];
|
1133 |
+
|
1134 |
+
return $this->reject(function ($item) use ($key, $strict, &$exists) {
|
1135 |
+
if (in_array($id = $key($item), $exists, $strict)) {
|
1136 |
+
return true;
|
1137 |
+
}
|
1138 |
+
|
1139 |
+
$exists[] = $id;
|
1140 |
+
});
|
1141 |
+
}
|
1142 |
+
|
1143 |
+
/**
|
1144 |
+
* Return only unique items from the collection array using strict comparison.
|
1145 |
+
*
|
1146 |
+
* @param string|callable|null $key
|
1147 |
+
* @return static
|
1148 |
+
*/
|
1149 |
+
public function uniqueStrict($key = null)
|
1150 |
+
{
|
1151 |
+
return $this->unique($key, true);
|
1152 |
+
}
|
1153 |
+
|
1154 |
+
/**
|
1155 |
+
* Reset the keys on the underlying array.
|
1156 |
+
*
|
1157 |
+
* @return static
|
1158 |
+
*/
|
1159 |
+
public function values()
|
1160 |
+
{
|
1161 |
+
return new static(array_values($this->items));
|
1162 |
+
}
|
1163 |
+
|
1164 |
+
/**
|
1165 |
+
* Get a value retrieving callback.
|
1166 |
+
*
|
1167 |
+
* @param string $value
|
1168 |
+
* @return callable
|
1169 |
+
*/
|
1170 |
+
protected function valueRetriever($value)
|
1171 |
+
{
|
1172 |
+
if ($this->useAsCallable($value)) {
|
1173 |
+
return $value;
|
1174 |
+
}
|
1175 |
+
|
1176 |
+
return function ($item) use ($value) {
|
1177 |
+
return data_get($item, $value);
|
1178 |
+
};
|
1179 |
+
}
|
1180 |
+
|
1181 |
+
/**
|
1182 |
+
* Zip the collection together with one or more arrays.
|
1183 |
+
*
|
1184 |
+
* e.g. new Collection([1, 2, 3])->zip([4, 5, 6]);
|
1185 |
+
* => [[1, 4], [2, 5], [3, 6]]
|
1186 |
+
*
|
1187 |
+
* @param mixed ...$items
|
1188 |
+
* @return static
|
1189 |
+
*/
|
1190 |
+
public function zip($items)
|
1191 |
+
{
|
1192 |
+
$arrayableItems = array_map(function ($items) {
|
1193 |
+
return $this->getArrayableItems($items);
|
1194 |
+
}, func_get_args());
|
1195 |
+
|
1196 |
+
$params = array_merge([function () {
|
1197 |
+
return new static(func_get_args());
|
1198 |
+
}, $this->items], $arrayableItems);
|
1199 |
+
|
1200 |
+
return new static(call_user_func_array('array_map', $params));
|
1201 |
+
}
|
1202 |
+
|
1203 |
+
/**
|
1204 |
+
* Get the collection of items as a plain array.
|
1205 |
+
*
|
1206 |
+
* @return array
|
1207 |
+
*/
|
1208 |
+
public function toArray()
|
1209 |
+
{
|
1210 |
+
return array_map(function ($value) {
|
1211 |
+
return $value instanceof Arrayable ? $value->toArray() : $value;
|
1212 |
+
}, $this->items);
|
1213 |
+
}
|
1214 |
+
|
1215 |
+
/**
|
1216 |
+
* Convert the object into something JSON serializable.
|
1217 |
+
*
|
1218 |
+
* @return array
|
1219 |
+
*/
|
1220 |
+
public function jsonSerialize()
|
1221 |
+
{
|
1222 |
+
return array_map(function ($value) {
|
1223 |
+
if ($value instanceof JsonSerializable) {
|
1224 |
+
return $value->jsonSerialize();
|
1225 |
+
} elseif ($value instanceof Jsonable) {
|
1226 |
+
return json_decode($value->toJson(), true);
|
1227 |
+
} elseif ($value instanceof Arrayable) {
|
1228 |
+
return $value->toArray();
|
1229 |
+
} else {
|
1230 |
+
return $value;
|
1231 |
+
}
|
1232 |
+
}, $this->items);
|
1233 |
+
}
|
1234 |
+
|
1235 |
+
/**
|
1236 |
+
* Get the collection of items as JSON.
|
1237 |
+
*
|
1238 |
+
* @param int $options
|
1239 |
+
* @return string
|
1240 |
+
*/
|
1241 |
+
public function toJson($options = 0)
|
1242 |
+
{
|
1243 |
+
return json_encode($this->jsonSerialize(), $options);
|
1244 |
+
}
|
1245 |
+
|
1246 |
+
/**
|
1247 |
+
* Get an iterator for the items.
|
1248 |
+
*
|
1249 |
+
* @return \ArrayIterator
|
1250 |
+
*/
|
1251 |
+
public function getIterator()
|
1252 |
+
{
|
1253 |
+
return new ArrayIterator($this->items);
|
1254 |
+
}
|
1255 |
+
|
1256 |
+
/**
|
1257 |
+
* Get a CachingIterator instance.
|
1258 |
+
*
|
1259 |
+
* @param int $flags
|
1260 |
+
* @return \CachingIterator
|
1261 |
+
*/
|
1262 |
+
public function getCachingIterator($flags = CachingIterator::CALL_TOSTRING)
|
1263 |
+
{
|
1264 |
+
return new CachingIterator($this->getIterator(), $flags);
|
1265 |
+
}
|
1266 |
+
|
1267 |
+
/**
|
1268 |
+
* Count the number of items in the collection.
|
1269 |
+
*
|
1270 |
+
* @return int
|
1271 |
+
*/
|
1272 |
+
public function count()
|
1273 |
+
{
|
1274 |
+
return count($this->items);
|
1275 |
+
}
|
1276 |
+
|
1277 |
+
/**
|
1278 |
+
* Get a base Support collection instance from this collection.
|
1279 |
+
*
|
1280 |
+
* @return \WPML\Collect\Support\Collection
|
1281 |
+
*/
|
1282 |
+
public function toBase()
|
1283 |
+
{
|
1284 |
+
return new self($this);
|
1285 |
+
}
|
1286 |
+
|
1287 |
+
/**
|
1288 |
+
* Determine if an item exists at an offset.
|
1289 |
+
*
|
1290 |
+
* @param mixed $key
|
1291 |
+
* @return bool
|
1292 |
+
*/
|
1293 |
+
public function offsetExists($key)
|
1294 |
+
{
|
1295 |
+
return array_key_exists($key, $this->items);
|
1296 |
+
}
|
1297 |
+
|
1298 |
+
/**
|
1299 |
+
* Get an item at a given offset.
|
1300 |
+
*
|
1301 |
+
* @param mixed $key
|
1302 |
+
* @return mixed
|
1303 |
+
*/
|
1304 |
+
public function offsetGet($key)
|
1305 |
+
{
|
1306 |
+
return $this->items[$key];
|
1307 |
+
}
|
1308 |
+
|
1309 |
+
/**
|
1310 |
+
* Set the item at a given offset.
|
1311 |
+
*
|
1312 |
+
* @param mixed $key
|
1313 |
+
* @param mixed $value
|
1314 |
+
* @return void
|
1315 |
+
*/
|
1316 |
+
public function offsetSet($key, $value)
|
1317 |
+
{
|
1318 |
+
if (is_null($key)) {
|
1319 |
+
$this->items[] = $value;
|
1320 |
+
} else {
|
1321 |
+
$this->items[$key] = $value;
|
1322 |
+
}
|
1323 |
+
}
|
1324 |
+
|
1325 |
+
/**
|
1326 |
+
* Unset the item at a given offset.
|
1327 |
+
*
|
1328 |
+
* @param string $key
|
1329 |
+
* @return void
|
1330 |
+
*/
|
1331 |
+
public function offsetUnset($key)
|
1332 |
+
{
|
1333 |
+
unset($this->items[$key]);
|
1334 |
+
}
|
1335 |
+
|
1336 |
+
/**
|
1337 |
+
* Convert the collection to its string representation.
|
1338 |
+
*
|
1339 |
+
* @return string
|
1340 |
+
*/
|
1341 |
+
public function __toString()
|
1342 |
+
{
|
1343 |
+
return $this->toJson();
|
1344 |
+
}
|
1345 |
+
|
1346 |
+
/**
|
1347 |
+
* Results array of items from Collection or Arrayable.
|
1348 |
+
*
|
1349 |
+
* @param mixed $items
|
1350 |
+
* @return array
|
1351 |
+
*/
|
1352 |
+
protected function getArrayableItems($items)
|
1353 |
+
{
|
1354 |
+
if (is_array($items)) {
|
1355 |
+
return $items;
|
1356 |
+
} elseif ($items instanceof self) {
|
1357 |
+
return $items->all();
|
1358 |
+
} elseif ($items instanceof Arrayable) {
|
1359 |
+
return $items->toArray();
|
1360 |
+
} elseif ($items instanceof Jsonable) {
|
1361 |
+
return json_decode($items->toJson(), true);
|
1362 |
+
} elseif ($items instanceof JsonSerializable) {
|
1363 |
+
return $items->jsonSerialize();
|
1364 |
+
} elseif ($items instanceof Traversable) {
|
1365 |
+
return iterator_to_array($items);
|
1366 |
+
}
|
1367 |
+
|
1368 |
+
return (array) $items;
|
1369 |
+
}
|
1370 |
+
|
1371 |
+
/** Those methods exist in the latest version of the library and have been copied here */
|
1372 |
+
|
1373 |
+
/**
|
1374 |
+
* Run a dictionary map over the items.
|
1375 |
+
*
|
1376 |
+
* The callback should return an associative array with a single key/value pair.
|
1377 |
+
*
|
1378 |
+
* @param callable $callback
|
1379 |
+
* @return $this
|
1380 |
+
*/
|
1381 |
+
public function mapToDictionary(callable $callback)
|
1382 |
+
{
|
1383 |
+
$dictionary = [];
|
1384 |
+
|
1385 |
+
foreach ($this->items as $key => $item) {
|
1386 |
+
$pair = $callback($item, $key);
|
1387 |
+
|
1388 |
+
$key = key($pair);
|
1389 |
+
|
1390 |
+
$value = reset($pair);
|
1391 |
+
|
1392 |
+
if (! isset($dictionary[$key])) {
|
1393 |
+
$dictionary[$key] = [];
|
1394 |
+
}
|
1395 |
+
|
1396 |
+
$dictionary[$key][] = $value;
|
1397 |
+
}
|
1398 |
+
|
1399 |
+
return new static($dictionary);
|
1400 |
+
}
|
1401 |
+
|
1402 |
+
/**
|
1403 |
+
* Run a grouping map over the items.
|
1404 |
+
*
|
1405 |
+
* The callback should return an associative array with a single key/value pair.
|
1406 |
+
*
|
1407 |
+
* @param callable $callback
|
1408 |
+
* @return static
|
1409 |
+
*/
|
1410 |
+
public function mapToGroups(callable $callback)
|
1411 |
+
{
|
1412 |
+
$groups = $this->mapToDictionary($callback);
|
1413 |
+
|
1414 |
+
return $groups->map([$this, 'make']);
|
1415 |
+
}
|
1416 |
+
|
1417 |
+
/**
|
1418 |
+
* Move the items meeting the condition to the front of the collection
|
1419 |
+
*
|
1420 |
+
* @param callable $condition
|
1421 |
+
*
|
1422 |
+
* @return Collection - A new collection
|
1423 |
+
*/
|
1424 |
+
public function prioritize( callable $condition ) {
|
1425 |
+
$nonPrioritized = $this->reject( $condition );
|
1426 |
+
|
1427 |
+
return $this
|
1428 |
+
->filter( $condition )
|
1429 |
+
->toBase()
|
1430 |
+
->merge( $nonPrioritized );
|
1431 |
+
}
|
1432 |
+
|
1433 |
+
/**
|
1434 |
+
* Convert an associative array of key => value to array of pairs [ key, value ].
|
1435 |
+
*
|
1436 |
+
* @return Collection
|
1437 |
+
*/
|
1438 |
+
public function assocToPair() {
|
1439 |
+
return $this->map( function ( $item, $key ) {
|
1440 |
+
return [ $key, $item ];
|
1441 |
+
} )->values();
|
1442 |
+
}
|
1443 |
+
|
1444 |
+
/**
|
1445 |
+
* Convert an array of pairs [ key, value ] to an associative array of key => value.
|
1446 |
+
*
|
1447 |
+
* @return Collection
|
1448 |
+
*/
|
1449 |
+
public function pairToAssoc() {
|
1450 |
+
return $this->mapWithKeys( function ( $pair ) {
|
1451 |
+
return [ $pair[0] => $pair[1] ];
|
1452 |
+
} );
|
1453 |
+
}
|
1454 |
+
|
1455 |
+
/**
|
1456 |
+
* Executes the given function for each item while the total execution time is less than the time out.
|
1457 |
+
* Returns the unprocessed items if a timeout occurred.
|
1458 |
+
*
|
1459 |
+
* @param callable $fn Function to all for each item.
|
1460 |
+
* @param int $timeout Timeout in seconds.
|
1461 |
+
*
|
1462 |
+
* @return Collection
|
1463 |
+
*/
|
1464 |
+
public function eachWithTimeout( callable $fn, $timeout ) {
|
1465 |
+
$endTime = time() + $timeout;
|
1466 |
+
|
1467 |
+
return $this->reduce( function ( Collection $unProcessed, $item ) use ( $endTime, $fn ) {
|
1468 |
+
if ( time() > $endTime ) {
|
1469 |
+
$unProcessed->push( $item );
|
1470 |
+
} else {
|
1471 |
+
$fn( $item );
|
1472 |
+
}
|
1473 |
+
|
1474 |
+
return $unProcessed;
|
1475 |
+
}, wpml_collect() );
|
1476 |
+
}
|
1477 |
+
|
1478 |
+
/**
|
1479 |
+
* Determine if the collection is not empty.
|
1480 |
+
*
|
1481 |
+
* @return bool
|
1482 |
+
*/
|
1483 |
+
public function isNotEmpty()
|
1484 |
+
{
|
1485 |
+
return ! empty($this->items);
|
1486 |
+
}
|
1487 |
+
|
1488 |
+
/**
|
1489 |
+
* Cross join with the given lists, returning all possible permutations.
|
1490 |
+
*
|
1491 |
+
* @param mixed ...$lists
|
1492 |
+
* @return static
|
1493 |
+
*/
|
1494 |
+
public function crossJoin(...$lists)
|
1495 |
+
{
|
1496 |
+
return new static(Arr::crossJoin(
|
1497 |
+
$this->items, ...array_map([$this, 'getArrayableItems'], $lists)
|
1498 |
+
));
|
1499 |
+
}
|
1500 |
+
}
|
addons/vendor/wpml/collect/src/Illuminate/Support/Traits/Macroable.php
ADDED
@@ -0,0 +1,83 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace WPML\Collect\Support\Traits;
|
4 |
+
|
5 |
+
use Closure;
|
6 |
+
use BadMethodCallException;
|
7 |
+
|
8 |
+
trait Macroable
|
9 |
+
{
|
10 |
+
/**
|
11 |
+
* The registered string macros.
|
12 |
+
*
|
13 |
+
* @var callable[]
|
14 |
+
*/
|
15 |
+
protected static $macros = [];
|
16 |
+
|
17 |
+
/**
|
18 |
+
* Register a custom macro.
|
19 |
+
*
|
20 |
+
* @param string $name
|
21 |
+
* @param callable $macro
|
22 |
+
* @return void
|
23 |
+
*/
|
24 |
+
public static function macro($name, callable $macro)
|
25 |
+
{
|
26 |
+
static::$macros[$name] = $macro;
|
27 |
+
}
|
28 |
+
|
29 |
+
/**
|
30 |
+
* Checks if macro is registered.
|
31 |
+
*
|
32 |
+
* @param string $name
|
33 |
+
* @return bool
|
34 |
+
*/
|
35 |
+
public static function hasMacro($name)
|
36 |
+
{
|
37 |
+
return isset(static::$macros[$name]);
|
38 |
+
}
|
39 |
+
|
40 |
+
/**
|
41 |
+
* Dynamically handle calls to the class.
|
42 |
+
*
|
43 |
+
* @param string $method
|
44 |
+
* @param mixed[] $parameters
|
45 |
+
* @return mixed
|
46 |
+
*
|
47 |
+
* @throws \BadMethodCallException
|
48 |
+
*/
|
49 |
+
public static function __callStatic($method, $parameters)
|
50 |
+
{
|
51 |
+
if (! static::hasMacro($method)) {
|
52 |
+
throw new BadMethodCallException("Method {$method} does not exist.");
|
53 |
+
}
|
54 |
+
|
55 |
+
if (static::$macros[$method] instanceof Closure) {
|
56 |
+
return call_user_func_array(Closure::bind(static::$macros[$method], null, static::class), $parameters);
|
57 |
+
}
|
58 |
+
|
59 |
+
return call_user_func_array(static::$macros[$method], $parameters);
|
60 |
+
}
|
61 |
+
|
62 |
+
/**
|
63 |
+
* Dynamically handle calls to the class.
|
64 |
+
*
|
65 |
+
* @param string $method
|
66 |
+
* @param mixed[] $parameters
|
67 |
+
* @return mixed
|
68 |
+
*
|
69 |
+
* @throws \BadMethodCallException
|
70 |
+
*/
|
71 |
+
public function __call($method, $parameters)
|
72 |
+
{
|
73 |
+
if (! static::hasMacro($method)) {
|
74 |
+
throw new BadMethodCallException("Method {$method} does not exist.");
|
75 |
+
}
|
76 |
+
|
77 |
+
if (static::$macros[$method] instanceof Closure) {
|
78 |
+
return call_user_func_array(static::$macros[$method]->bindTo($this, static::class), $parameters);
|
79 |
+
}
|
80 |
+
|
81 |
+
return call_user_func_array(static::$macros[$method], $parameters);
|
82 |
+
}
|
83 |
+
}
|
addons/vendor/wpml/collect/src/Illuminate/Support/helpers.php
ADDED
@@ -0,0 +1,84 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
use WPML\Collect\Support\Arr;
|
4 |
+
use WPML\Collect\Support\Collection;
|
5 |
+
|
6 |
+
if (! function_exists('wpml_collect')) {
|
7 |
+
/**
|
8 |
+
* @param mixed|null $value
|
9 |
+
*
|
10 |
+
* @return \WPML\Collect\Support\Collection<mixed>
|
11 |
+
*/
|
12 |
+
function wpml_collect( $value = null ) {
|
13 |
+
return new Collection( $value );
|
14 |
+
}
|
15 |
+
}
|
16 |
+
|
17 |
+
if (! function_exists('value')) {
|
18 |
+
/**
|
19 |
+
* Return the default value of the given value.
|
20 |
+
*
|
21 |
+
* @param mixed $value
|
22 |
+
*
|
23 |
+
* @return mixed
|
24 |
+
*/
|
25 |
+
function value( $value ) {
|
26 |
+
return $value instanceof Closure ? $value() : $value;
|
27 |
+
}
|
28 |
+
}
|
29 |
+
|
30 |
+
if (! function_exists('data_get')) {
|
31 |
+
/**
|
32 |
+
* Get an item from an array or object using "dot" notation.
|
33 |
+
*
|
34 |
+
* @param mixed $target
|
35 |
+
* @param string|string[] $key
|
36 |
+
* @param mixed $default
|
37 |
+
* @return mixed
|
38 |
+
*/
|
39 |
+
function data_get($target, $key, $default = null)
|
40 |
+
{
|
41 |
+
if (is_null($key)) {
|
42 |
+
return $target;
|
43 |
+
}
|
44 |
+
|
45 |
+
$key = is_array($key) ? $key : explode('.', $key);
|
46 |
+
|
47 |
+
while (($segment = array_shift($key)) !== null) {
|
48 |
+
if ($segment === '*') {
|
49 |
+
if ($target instanceof Collection) {
|
50 |
+
$target = $target->all();
|
51 |
+
} elseif (! is_array($target)) {
|
52 |
+
return value($default);
|
53 |
+
}
|
54 |
+
|
55 |
+
$result = Arr::pluck($target, $key);
|
56 |
+
|
57 |
+
return in_array('*', $key) ? Arr::collapse($result) : $result;
|
58 |
+
}
|
59 |
+
|
60 |
+
if (Arr::accessible($target) && Arr::exists($target, $segment)) {
|
61 |
+
$target = $target[$segment];
|
62 |
+
} elseif (is_object($target) && isset($target->{$segment})) {
|
63 |
+
$target = $target->{$segment};
|
64 |
+
} else {
|
65 |
+
return value($default);
|
66 |
+
}
|
67 |
+
}
|
68 |
+
|
69 |
+
return $target;
|
70 |
+
}
|
71 |
+
}
|
72 |
+
|
73 |
+
if (! function_exists('with')) {
|
74 |
+
/**
|
75 |
+
* Return the given object. Useful for chaining.
|
76 |
+
*
|
77 |
+
* @param mixed $object
|
78 |
+
* @return mixed
|
79 |
+
*/
|
80 |
+
function with($object)
|
81 |
+
{
|
82 |
+
return $object;
|
83 |
+
}
|
84 |
+
}
|
addons/vendor/wpml/collect/tests/Support/SupportCollectionTest.php
ADDED
@@ -0,0 +1,1763 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
use Mockery as m;
|
4 |
+
use WPML\Collect\Support\Collection;
|
5 |
+
use WPML\Collect\Contracts\Support\Jsonable;
|
6 |
+
use WPML\Collect\Contracts\Support\Arrayable;
|
7 |
+
|
8 |
+
class SupportCollectionTest extends PHPUnit_Framework_TestCase
|
9 |
+
{
|
10 |
+
public function testFirstReturnsFirstItemInCollection()
|
11 |
+
{
|
12 |
+
$c = new Collection(['foo', 'bar']);
|
13 |
+
$this->assertEquals('foo', $c->first());
|
14 |
+
}
|
15 |
+
|
16 |
+
public function testLastReturnsLastItemInCollection()
|
17 |
+
{
|
18 |
+
$c = new Collection(['foo', 'bar']);
|
19 |
+
|
20 |
+
$this->assertEquals('bar', $c->last());
|
21 |
+
}
|
22 |
+
|
23 |
+
public function testLastWithCallback()
|
24 |
+
{
|
25 |
+
$data = new Collection([100, 200, 300]);
|
26 |
+
$result = $data->last(function ($value) {
|
27 |
+
return $value < 250;
|
28 |
+
});
|
29 |
+
$this->assertEquals(200, $result);
|
30 |
+
$result = $data->last(function ($value, $key) {
|
31 |
+
return $key < 2;
|
32 |
+
});
|
33 |
+
$this->assertEquals(200, $result);
|
34 |
+
}
|
35 |
+
|
36 |
+
public function testLastWithCallbackAndDefault()
|
37 |
+
{
|
38 |
+
$data = new Collection(['foo', 'bar']);
|
39 |
+
$result = $data->last(function ($value) {
|
40 |
+
return $value === 'baz';
|
41 |
+
}, 'default');
|
42 |
+
$this->assertEquals('default', $result);
|
43 |
+
}
|
44 |
+
|
45 |
+
public function testLastWithDefaultAndWithoutCallback()
|
46 |
+
{
|
47 |
+
$data = new Collection;
|
48 |
+
$result = $data->last(null, 'default');
|
49 |
+
$this->assertEquals('default', $result);
|
50 |
+
}
|
51 |
+
|
52 |
+
public function testPopReturnsAndRemovesLastItemInCollection()
|
53 |
+
{
|
54 |
+
$c = new Collection(['foo', 'bar']);
|
55 |
+
|
56 |
+
$this->assertEquals('bar', $c->pop());
|
57 |
+
$this->assertEquals('foo', $c->first());
|
58 |
+
}
|
59 |
+
|
60 |
+
public function testShiftReturnsAndRemovesFirstItemInCollection()
|
61 |
+
{
|
62 |
+
$c = new Collection(['foo', 'bar']);
|
63 |
+
|
64 |
+
$this->assertEquals('foo', $c->shift());
|
65 |
+
$this->assertEquals('bar', $c->first());
|
66 |
+
}
|
67 |
+
|
68 |
+
public function testEmptyCollectionIsEmpty()
|
69 |
+
{
|
70 |
+
$c = new Collection();
|
71 |
+
|
72 |
+
$this->assertTrue($c->isEmpty());
|
73 |
+
}
|
74 |
+
|
75 |
+
public function testNotEmptyCollectionIsNotEmpty()
|
76 |
+
{
|
77 |
+
$c = new Collection( [ 1, 2, 3 ]);
|
78 |
+
|
79 |
+
$this->assertTrue($c->isNotEmpty());
|
80 |
+
}
|
81 |
+
|
82 |
+
public function testCollectionIsConstructed()
|
83 |
+
{
|
84 |
+
$collection = new Collection('foo');
|
85 |
+
$this->assertSame(['foo'], $collection->all());
|
86 |
+
|
87 |
+
$collection = new Collection(2);
|
88 |
+
$this->assertSame([2], $collection->all());
|
89 |
+
|
90 |
+
$collection = new Collection(false);
|
91 |
+
$this->assertSame([false], $collection->all());
|
92 |
+
|
93 |
+
$collection = new Collection(null);
|
94 |
+
$this->assertSame([], $collection->all());
|
95 |
+
|
96 |
+
$collection = new Collection;
|
97 |
+
$this->assertSame([], $collection->all());
|
98 |
+
}
|
99 |
+
|
100 |
+
public function testGetArrayableItems()
|
101 |
+
{
|
102 |
+
$collection = new Collection;
|
103 |
+
|
104 |
+
$class = new ReflectionClass($collection);
|
105 |
+
$method = $class->getMethod('getArrayableItems');
|
106 |
+
$method->setAccessible(true);
|
107 |
+
|
108 |
+
$items = new TestArrayableObject;
|
109 |
+
$array = $method->invokeArgs($collection, [$items]);
|
110 |
+
$this->assertSame(['foo' => 'bar'], $array);
|
111 |
+
|
112 |
+
$items = new TestJsonableObject;
|
113 |
+
$array = $method->invokeArgs($collection, [$items]);
|
114 |
+
$this->assertSame(['foo' => 'bar'], $array);
|
115 |
+
|
116 |
+
$items = new TestJsonSerializeObject;
|
117 |
+
$array = $method->invokeArgs($collection, [$items]);
|
118 |
+
$this->assertSame(['foo' => 'bar'], $array);
|
119 |
+
|
120 |
+
$items = new Collection(['foo' => 'bar']);
|
121 |
+
$array = $method->invokeArgs($collection, [$items]);
|
122 |
+
$this->assertSame(['foo' => 'bar'], $array);
|
123 |
+
|
124 |
+
$items = ['foo' => 'bar'];
|
125 |
+
$array = $method->invokeArgs($collection, [$items]);
|
126 |
+
$this->assertSame(['foo' => 'bar'], $array);
|
127 |
+
}
|
128 |
+
|
129 |
+
public function testToArrayCallsToArrayOnEachItemInCollection()
|
130 |
+
{
|
131 |
+
$item1 = m::mock('WPML\Collect\Contracts\Support\Arrayable');
|
132 |
+
$item1->shouldReceive('toArray')->once()->andReturn('foo.array');
|
133 |
+
$item2 = m::mock('WPML\Collect\Contracts\Support\Arrayable');
|
134 |
+
$item2->shouldReceive('toArray')->once()->andReturn('bar.array');
|
135 |
+
$c = new Collection([$item1, $item2]);
|
136 |
+
$results = $c->toArray();
|
137 |
+
|
138 |
+
$this->assertEquals(['foo.array', 'bar.array'], $results);
|
139 |
+
}
|
140 |
+
|
141 |
+
public function testJsonSerializeCallsToArrayOrJsonSerializeOnEachItemInCollection()
|
142 |
+
{
|
143 |
+
$item1 = m::mock('JsonSerializable');
|
144 |
+
$item1->shouldReceive('jsonSerialize')->once()->andReturn('foo.json');
|
145 |
+
$item2 = m::mock('WPML\Collect\Contracts\Support\Arrayable');
|
146 |
+
$item2->shouldReceive('toArray')->once()->andReturn('bar.array');
|
147 |
+
$c = new Collection([$item1, $item2]);
|
148 |
+
$results = $c->jsonSerialize();
|
149 |
+
|
150 |
+
$this->assertEquals(['foo.json', 'bar.array'], $results);
|
151 |
+
}
|
152 |
+
|
153 |
+
public function testToJsonEncodesTheJsonSerializeResult()
|
154 |
+
{
|
155 |
+
$c = $this->getMockBuilder(Collection::class)->setMethods(['jsonSerialize'])->getMock();
|
156 |
+
$c->expects($this->once())->method('jsonSerialize')->will($this->returnValue('foo'));
|
157 |
+
$results = $c->toJson();
|
158 |
+
|
159 |
+
$this->assertJsonStringEqualsJsonString(json_encode('foo'), $results);
|
160 |
+
}
|
161 |
+
|
162 |
+
public function testCastingToStringJsonEncodesTheToArrayResult()
|
163 |
+
{
|
164 |
+
$c = $this->getMockBuilder(Collection::class)->setMethods(['jsonSerialize'])->getMock();
|
165 |
+
$c->expects($this->once())->method('jsonSerialize')->will($this->returnValue('foo'));
|
166 |
+
|
167 |
+
$this->assertJsonStringEqualsJsonString(json_encode('foo'), (string) $c);
|
168 |
+
}
|
169 |
+
|
170 |
+
public function testOffsetAccess()
|
171 |
+
{
|
172 |
+
$c = new Collection(['name' => 'taylor']);
|
173 |
+
$this->assertEquals('taylor', $c['name']);
|
174 |
+
$c['name'] = 'dayle';
|
175 |
+
$this->assertEquals('dayle', $c['name']);
|
176 |
+
$this->assertTrue(isset($c['name']));
|
177 |
+
unset($c['name']);
|
178 |
+
$this->assertFalse(isset($c['name']));
|
179 |
+
$c[] = 'jason';
|
180 |
+
$this->assertEquals('jason', $c[0]);
|
181 |
+
}
|
182 |
+
|
183 |
+
public function testArrayAccessOffsetExists()
|
184 |
+
{
|
185 |
+
$c = new Collection(['foo', 'bar']);
|
186 |
+
$this->assertTrue($c->offsetExists(0));
|
187 |
+
$this->assertTrue($c->offsetExists(1));
|
188 |
+
$this->assertFalse($c->offsetExists(1000));
|
189 |
+
}
|
190 |
+
|
191 |
+
public function testArrayAccessOffsetGet()
|
192 |
+
{
|
193 |
+
$c = new Collection(['foo', 'bar']);
|
194 |
+
$this->assertEquals('foo', $c->offsetGet(0));
|
195 |
+
$this->assertEquals('bar', $c->offsetGet(1));
|
196 |
+
}
|
197 |
+
|
198 |
+
/**
|
199 |
+
* @expectedException PHPUnit_Framework_Error_Notice
|
200 |
+
*/
|
201 |
+
public function testArrayAccessOffsetGetOnNonExist()
|
202 |
+
{
|
203 |
+
$c = new Collection(['foo', 'bar']);
|
204 |
+
$c->offsetGet(1000);
|
205 |
+
}
|
206 |
+
|
207 |
+
public function testArrayAccessOffsetSet()
|
208 |
+
{
|
209 |
+
$c = new Collection(['foo', 'foo']);
|
210 |
+
|
211 |
+
$c->offsetSet(1, 'bar');
|
212 |
+
$this->assertEquals('bar', $c[1]);
|
213 |
+
|
214 |
+
$c->offsetSet(null, 'qux');
|
215 |
+
$this->assertEquals('qux', $c[2]);
|
216 |
+
}
|
217 |
+
|
218 |
+
/**
|
219 |
+
* @expectedException PHPUnit_Framework_Error_Notice
|
220 |
+
*/
|
221 |
+
public function testArrayAccessOffsetUnset()
|
222 |
+
{
|
223 |
+
$c = new Collection(['foo', 'bar']);
|
224 |
+
|
225 |
+
$c->offsetUnset(1);
|
226 |
+
$c[1];
|
227 |
+
}
|
228 |
+
|
229 |
+
public function testForgetSingleKey()
|
230 |
+
{
|
231 |
+
$c = new Collection(['foo', 'bar']);
|
232 |
+
$c->forget(0);
|
233 |
+
$this->assertFalse(isset($c['foo']));
|
234 |
+
|
235 |
+
$c = new Collection(['foo' => 'bar', 'baz' => 'qux']);
|
236 |
+
$c->forget('foo');
|
237 |
+
$this->assertFalse(isset($c['foo']));
|
238 |
+
}
|
239 |
+
|
240 |
+
public function testForgetArrayOfKeys()
|
241 |
+
{
|
242 |
+
$c = new Collection(['foo', 'bar', 'baz']);
|
243 |
+
$c->forget([0, 2]);
|
244 |
+
$this->assertFalse(isset($c[0]));
|
245 |
+
$this->assertFalse(isset($c[2]));
|
246 |
+
$this->assertTrue(isset($c[1]));
|
247 |
+
|
248 |
+
$c = new Collection(['name' => 'taylor', 'foo' => 'bar', 'baz' => 'qux']);
|
249 |
+
$c->forget(['foo', 'baz']);
|
250 |
+
$this->assertFalse(isset($c['foo']));
|
251 |
+
$this->assertFalse(isset($c['baz']));
|
252 |
+
$this->assertTrue(isset($c['name']));
|
253 |
+
}
|
254 |
+
|
255 |
+
public function testCountable()
|
256 |
+
{
|
257 |
+
$c = new Collection(['foo', 'bar']);
|
258 |
+
$this->assertCount(2, $c);
|
259 |
+
}
|
260 |
+
|
261 |
+
public function testIterable()
|
262 |
+
{
|
263 |
+
$c = new Collection(['foo']);
|
264 |
+
$this->assertInstanceOf('ArrayIterator', $c->getIterator());
|
265 |
+
$this->assertEquals(['foo'], $c->getIterator()->getArrayCopy());
|
266 |
+
}
|
267 |
+
|
268 |
+
public function testCachingIterator()
|
269 |
+
{
|
270 |
+
$c = new Collection(['foo']);
|
271 |
+
$this->assertInstanceOf('CachingIterator', $c->getCachingIterator());
|
272 |
+
}
|
273 |
+
|
274 |
+
public function testFilter()
|
275 |
+
{
|
276 |
+
$c = new Collection([['id' => 1, 'name' => 'Hello'], ['id' => 2, 'name' => 'World']]);
|
277 |
+
$this->assertEquals([1 => ['id' => 2, 'name' => 'World']], $c->filter(function ($item) {
|
278 |
+
return $item['id'] == 2;
|
279 |
+
})->all());
|
280 |
+
|
281 |
+
$c = new Collection(['', 'Hello', '', 'World']);
|
282 |
+
$this->assertEquals(['Hello', 'World'], $c->filter()->values()->toArray());
|
283 |
+
|
284 |
+
$c = new Collection(['id' => 1, 'first' => 'Hello', 'second' => 'World']);
|
285 |
+
$this->assertEquals(['first' => 'Hello', 'second' => 'World'], $c->filter(function ($item, $key) {
|
286 |
+
return $key != 'id';
|
287 |
+
})->all());
|
288 |
+
}
|
289 |
+
|
290 |
+
public function testWhere()
|
291 |
+
{
|
292 |
+
$c = new Collection([['v' => 1], ['v' => 2], ['v' => 3], ['v' => '3'], ['v' => 4]]);
|
293 |
+
|
294 |
+
$this->assertEquals(
|
295 |
+
[['v' => 3], ['v' => '3']],
|
296 |
+
$c->where('v', 3)->values()->all()
|
297 |
+
);
|
298 |
+
$this->assertEquals(
|
299 |
+
[['v' => 3], ['v' => '3']],
|
300 |
+
$c->where('v', '=', 3)->values()->all()
|
301 |
+
);
|
302 |
+
$this->assertEquals(
|
303 |
+
[['v' => 3], ['v' => '3']],
|
304 |
+
$c->where('v', '==', 3)->values()->all()
|
305 |
+
);
|
306 |
+
$this->assertEquals(
|
307 |
+
[['v' => 3], ['v' => '3']],
|
308 |
+
$c->where('v', 'garbage', 3)->values()->all()
|
309 |
+
);
|
310 |
+
$this->assertEquals(
|
311 |
+
[['v' => 3]],
|
312 |
+
$c->where('v', '===', 3)->values()->all()
|
313 |
+
);
|
314 |
+
|
315 |
+
$this->assertEquals(
|
316 |
+
[['v' => 1], ['v' => 2], ['v' => 4]],
|
317 |
+
$c->where('v', '<>', 3)->values()->all()
|
318 |
+
);
|
319 |
+
$this->assertEquals(
|
320 |
+
[['v' => 1], ['v' => 2], ['v' => 4]],
|
321 |
+
$c->where('v', '!=', 3)->values()->all()
|
322 |
+
);
|
323 |
+
$this->assertEquals(
|
324 |
+
[['v' => 1], ['v' => 2], ['v' => '3'], ['v' => 4]],
|
325 |
+
$c->where('v', '!==', 3)->values()->all()
|
326 |
+
);
|
327 |
+
$this->assertEquals(
|
328 |
+
[['v' => 1], ['v' => 2], ['v' => 3], ['v' => '3']],
|
329 |
+
$c->where('v', '<=', 3)->values()->all()
|
330 |
+
);
|
331 |
+
$this->assertEquals(
|
332 |
+
[['v' => 3], ['v' => '3'], ['v' => 4]],
|
333 |
+
$c->where('v', '>=', 3)->values()->all()
|
334 |
+
);
|
335 |
+
$this->assertEquals(
|
336 |
+
[['v' => 1], ['v' => 2]],
|
337 |
+
$c->where('v', '<', 3)->values()->all()
|
338 |
+
);
|
339 |
+
$this->assertEquals(
|
340 |
+
[['v' => 4]],
|
341 |
+
$c->where('v', '>', 3)->values()->all()
|
342 |
+
);
|
343 |
+
}
|
344 |
+
|
345 |
+
public function testWhereStrict()
|
346 |
+
{
|
347 |
+
$c = new Collection([['v' => 3], ['v' => '3']]);
|
348 |
+
|
349 |
+
$this->assertEquals(
|
350 |
+
[['v' => 3]],
|
351 |
+
$c->whereStrict('v', 3)->values()->all()
|
352 |
+
);
|
353 |
+
}
|
354 |
+
|
355 |
+
public function testWhereIn()
|
356 |
+
{
|
357 |
+
$c = new Collection([['v' => 1], ['v' => 2], ['v' => 3], ['v' => '3'], ['v' => 4]]);
|
358 |
+
$this->assertEquals([['v' => 1], ['v' => 3], ['v' => '3']], $c->whereIn('v', [1, 3])->values()->all());
|
359 |
+
}
|
360 |
+
|
361 |
+
public function testWhereInStrict()
|
362 |
+
{
|
363 |
+
$c = new Collection([['v' => 1], ['v' => 2], ['v' => 3], ['v' => '3'], ['v' => 4]]);
|
364 |
+
$this->assertEquals([['v' => 1], ['v' => 3]], $c->whereInStrict('v', [1, 3])->values()->all());
|
365 |
+
}
|
366 |
+
|
367 |
+
public function testValues()
|
368 |
+
{
|
369 |
+
$c = new Collection([['id' => 1, 'name' => 'Hello'], ['id' => 2, 'name' => 'World']]);
|
370 |
+
$this->assertEquals([['id' => 2, 'name' => 'World']], $c->filter(function ($item) {
|
371 |
+
return $item['id'] == 2;
|
372 |
+
})->values()->all());
|
373 |
+
}
|
374 |
+
|
375 |
+
public function testFlatten()
|
376 |
+
{
|
377 |
+
// Flat arrays are unaffected
|
378 |
+
$c = new Collection(['#foo', '#bar', '#baz']);
|
379 |
+
$this->assertEquals(['#foo', '#bar', '#baz'], $c->flatten()->all());
|
380 |
+
|
381 |
+
// Nested arrays are flattened with existing flat items
|
382 |
+
$c = new Collection([['#foo', '#bar'], '#baz']);
|
383 |
+
$this->assertEquals(['#foo', '#bar', '#baz'], $c->flatten()->all());
|
384 |
+
|
385 |
+
// Sets of nested arrays are flattened
|
386 |
+
$c = new Collection([['#foo', '#bar'], ['#baz']]);
|
387 |
+
$this->assertEquals(['#foo', '#bar', '#baz'], $c->flatten()->all());
|
388 |
+
|
389 |
+
// Deeply nested arrays are flattened
|
390 |
+
$c = new Collection([['#foo', ['#bar']], ['#baz']]);
|
391 |
+
$this->assertEquals(['#foo', '#bar', '#baz'], $c->flatten()->all());
|
392 |
+
|
393 |
+
// Nested collections are flattened alongside arrays
|
394 |
+
$c = new Collection([new Collection(['#foo', '#bar']), ['#baz']]);
|
395 |
+
$this->assertEquals(['#foo', '#bar', '#baz'], $c->flatten()->all());
|
396 |
+
|
397 |
+
// Nested collections containing plain arrays are flattened
|
398 |
+
$c = new Collection([new Collection(['#foo', ['#bar']]), ['#baz']]);
|
399 |
+
$this->assertEquals(['#foo', '#bar', '#baz'], $c->flatten()->all());
|
400 |
+
|
401 |
+
// Nested arrays containing collections are flattened
|
402 |
+
$c = new Collection([['#foo', new Collection(['#bar'])], ['#baz']]);
|
403 |
+
$this->assertEquals(['#foo', '#bar', '#baz'], $c->flatten()->all());
|
404 |
+
|
405 |
+
// Nested arrays containing collections containing arrays are flattened
|
406 |
+
$c = new Collection([['#foo', new Collection(['#bar', ['#zap']])], ['#baz']]);
|
407 |
+
$this->assertEquals(['#foo', '#bar', '#zap', '#baz'], $c->flatten()->all());
|
408 |
+
}
|
409 |
+
|
410 |
+
public function testFlattenWithDepth()
|
411 |
+
{
|
412 |
+
// No depth flattens recursively
|
413 |
+
$c = new Collection([['#foo', ['#bar', ['#baz']]], '#zap']);
|
414 |
+
$this->assertEquals(['#foo', '#bar', '#baz', '#zap'], $c->flatten()->all());
|
415 |
+
|
416 |
+
// Specifying a depth only flattens to that depth
|
417 |
+
$c = new Collection([['#foo', ['#bar', ['#baz']]], '#zap']);
|
418 |
+
$this->assertEquals(['#foo', ['#bar', ['#baz']], '#zap'], $c->flatten(1)->all());
|
419 |
+
|
420 |
+
$c = new Collection([['#foo', ['#bar', ['#baz']]], '#zap']);
|
421 |
+
$this->assertEquals(['#foo', '#bar', ['#baz'], '#zap'], $c->flatten(2)->all());
|
422 |
+
}
|
423 |
+
|
424 |
+
public function testFlattenIgnoresKeys()
|
425 |
+
{
|
426 |
+
// No depth ignores keys
|
427 |
+
$c = new Collection(['#foo', ['key' => '#bar'], ['key' => '#baz'], 'key' => '#zap']);
|
428 |
+
$this->assertEquals(['#foo', '#bar', '#baz', '#zap'], $c->flatten()->all());
|
429 |
+
|
430 |
+
// Depth of 1 ignores keys
|
431 |
+
$c = new Collection(['#foo', ['key' => '#bar'], ['key' => '#baz'], 'key' => '#zap']);
|
432 |
+
$this->assertEquals(['#foo', '#bar', '#baz', '#zap'], $c->flatten(1)->all());
|
433 |
+
}
|
434 |
+
|
435 |
+
public function testMergeNull()
|
436 |
+
{
|
437 |
+
$c = new Collection(['name' => 'Hello']);
|
438 |
+
$this->assertEquals(['name' => 'Hello'], $c->merge(null)->all());
|
439 |
+
}
|
440 |
+
|
441 |
+
public function testMergeArray()
|
442 |
+
{
|
443 |
+
$c = new Collection(['name' => 'Hello']);
|
444 |
+
$this->assertEquals(['name' => 'Hello', 'id' => 1], $c->merge(['id' => 1])->all());
|
445 |
+
}
|
446 |
+
|
447 |
+
public function testMergeCollection()
|
448 |
+
{
|
449 |
+
$c = new Collection(['name' => 'Hello']);
|
450 |
+
$this->assertEquals(['name' => 'World', 'id' => 1], $c->merge(new Collection(['name' => 'World', 'id' => 1]))->all());
|
451 |
+
}
|
452 |
+
|
453 |
+
public function testUnionNull()
|
454 |
+
{
|
455 |
+
$c = new Collection(['name' => 'Hello']);
|
456 |
+
$this->assertEquals(['name' => 'Hello'], $c->union(null)->all());
|
457 |
+
}
|
458 |
+
|
459 |
+
public function testUnionArray()
|
460 |
+
{
|
461 |
+
$c = new Collection(['name' => 'Hello']);
|
462 |
+
$this->assertEquals(['name' => 'Hello', 'id' => 1], $c->union(['id' => 1])->all());
|
463 |
+
}
|
464 |
+
|
465 |
+
public function testUnionCollection()
|
466 |
+
{
|
467 |
+
$c = new Collection(['name' => 'Hello']);
|
468 |
+
$this->assertEquals(['name' => 'Hello', 'id' => 1], $c->union(new Collection(['name' => 'World', 'id' => 1]))->all());
|
469 |
+
}
|
470 |
+
|
471 |
+
public function testDiffCollection()
|
472 |
+
{
|
473 |
+
$c = new Collection(['id' => 1, 'first_word' => 'Hello']);
|
474 |
+
$this->assertEquals(['id' => 1], $c->diff(new Collection(['first_word' => 'Hello', 'last_word' => 'World']))->all());
|
475 |
+
}
|
476 |
+
|
477 |
+
public function testDiffNull()
|
478 |
+
{
|
479 |
+
$c = new Collection(['id' => 1, 'first_word' => 'Hello']);
|
480 |
+
$this->assertEquals(['id' => 1, 'first_word' => 'Hello'], $c->diff(null)->all());
|
481 |
+
}
|
482 |
+
|
483 |
+
public function testDiffKeys()
|
484 |
+
{
|
485 |
+
$c1 = new Collection(['id' => 1, 'first_word' => 'Hello']);
|
486 |
+
$c2 = new Collection(['id' => 123, 'foo_bar' => 'Hello']);
|
487 |
+
$this->assertEquals(['first_word' => 'Hello'], $c1->diffKeys($c2)->all());
|
488 |
+
}
|
489 |
+
|
490 |
+
public function testEach()
|
491 |
+
{
|
492 |
+
$c = new Collection($original = [1, 2, 'foo' => 'bar', 'bam' => 'baz']);
|
493 |
+
|
494 |
+
$result = [];
|
495 |
+
$c->each(function ($item, $key) use (&$result) {
|
496 |
+
$result[$key] = $item;
|
497 |
+
});
|
498 |
+
$this->assertEquals($original, $result);
|
499 |
+
|
500 |
+
$result = [];
|
501 |
+
$c->each(function ($item, $key) use (&$result) {
|
502 |
+
$result[$key] = $item;
|
503 |
+
if (is_string($key)) {
|
504 |
+
return false;
|
505 |
+
}
|
506 |
+
});
|
507 |
+
$this->assertEquals([1, 2, 'foo' => 'bar'], $result);
|
508 |
+
}
|
509 |
+
|
510 |
+
public function testIntersectNull()
|
511 |
+
{
|
512 |
+
$c = new Collection(['id' => 1, 'first_word' => 'Hello']);
|
513 |
+
$this->assertEquals([], $c->intersect(null)->all());
|
514 |
+
}
|
515 |
+
|
516 |
+
public function testIntersectCollection()
|
517 |
+
{
|
518 |
+
$c = new Collection(['id' => 1, 'first_word' => 'Hello']);
|
519 |
+
$this->assertEquals(['first_word' => 'Hello'], $c->intersect(new Collection(['first_world' => 'Hello', 'last_word' => 'World']))->all());
|
520 |
+
}
|
521 |
+
|
522 |
+
public function testUnique()
|
523 |
+
{
|
524 |
+
$c = new Collection(['Hello', 'World', 'World']);
|
525 |
+
$this->assertEquals(['Hello', 'World'], $c->unique()->all());
|
526 |
+
|
527 |
+
$c = new Collection([[1, 2], [1, 2], [2, 3], [3, 4], [2, 3]]);
|
528 |
+
$this->assertEquals([[1, 2], [2, 3], [3, 4]], $c->unique()->values()->all());
|
529 |
+
}
|
530 |
+
|
531 |
+
public function testUniqueWithCallback()
|
532 |
+
{
|
533 |
+
$c = new Collection([
|
534 |
+
1 => ['id' => 1, 'first' => 'Taylor', 'last' => 'Otwell'], 2 => ['id' => 2, 'first' => 'Taylor', 'last' => 'Otwell'],
|
535 |
+
3 => ['id' => 3, 'first' => 'Abigail', 'last' => 'Otwell'], 4 => ['id' => 4, 'first' => 'Abigail', 'last' => 'Otwell'],
|
536 |
+
5 => ['id' => 5, 'first' => 'Taylor', 'last' => 'Swift'], 6 => ['id' => 6, 'first' => 'Taylor', 'last' => 'Swift'],
|
537 |
+
]);
|
538 |
+
|
539 |
+
$this->assertEquals([
|
540 |
+
1 => ['id' => 1, 'first' => 'Taylor', 'last' => 'Otwell'],
|
541 |
+
3 => ['id' => 3, 'first' => 'Abigail', 'last' => 'Otwell'],
|
542 |
+
], $c->unique('first')->all());
|
543 |
+
|
544 |
+
$this->assertEquals([
|
545 |
+
1 => ['id' => 1, 'first' => 'Taylor', 'last' => 'Otwell'],
|
546 |
+
3 => ['id' => 3, 'first' => 'Abigail', 'last' => 'Otwell'],
|
547 |
+
5 => ['id' => 5, 'first' => 'Taylor', 'last' => 'Swift'],
|
548 |
+
], $c->unique(function ($item) {
|
549 |
+
return $item['first'].$item['last'];
|
550 |
+
})->all());
|
551 |
+
}
|
552 |
+
|
553 |
+
public function testUniqueStrict()
|
554 |
+
{
|
555 |
+
$c = new Collection([
|
556 |
+
[
|
557 |
+
'id' => '0',
|
558 |
+
'name' => 'zero',
|
559 |
+
],
|
560 |
+
[
|
561 |
+
'id' => '00',
|
562 |
+
'name' => 'double zero',
|
563 |
+
],
|
564 |
+
[
|
565 |
+
'id' => '0',
|
566 |
+
'name' => 'again zero',
|
567 |
+
],
|
568 |
+
]);
|
569 |
+
|
570 |
+
$this->assertEquals([
|
571 |
+
[
|
572 |
+
'id' => '0',
|
573 |
+
'name' => 'zero',
|
574 |
+
],
|
575 |
+
[
|
576 |
+
'id' => '00',
|
577 |
+
'name' => 'double zero',
|
578 |
+
],
|
579 |
+
], $c->uniqueStrict('id')->all());
|
580 |
+
}
|
581 |
+
|
582 |
+
public function testCollapse()
|
583 |
+
{
|
584 |
+
$data = new Collection([[$object1 = new StdClass], [$object2 = new StdClass]]);
|
585 |
+
$this->assertEquals([$object1, $object2], $data->collapse()->all());
|
586 |
+
}
|
587 |
+
|
588 |
+
public function testCollapseWithNestedCollactions()
|
589 |
+
{
|
590 |
+
$data = new Collection([new Collection([1, 2, 3]), new Collection([4, 5, 6])]);
|
591 |
+
$this->assertEquals([1, 2, 3, 4, 5, 6], $data->collapse()->all());
|
592 |
+
}
|
593 |
+
|
594 |
+
public function testSort()
|
595 |
+
{
|
596 |
+
$data = (new Collection([5, 3, 1, 2, 4]))->sort();
|
597 |
+
$this->assertEquals([1, 2, 3, 4, 5], $data->values()->all());
|
598 |
+
|
599 |
+
$data = (new Collection([-1, -3, -2, -4, -5, 0, 5, 3, 1, 2, 4]))->sort();
|
600 |
+
$this->assertEquals([-5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5], $data->values()->all());
|
601 |
+
|
602 |
+
$data = (new Collection(['foo', 'bar-10', 'bar-1']))->sort();
|
603 |
+
$this->assertEquals(['bar-1', 'bar-10', 'foo'], $data->values()->all());
|
604 |
+
}
|
605 |
+
|
606 |
+
public function testSortWithCallback()
|
607 |
+
{
|
608 |
+
$data = (new Collection([5, 3, 1, 2, 4]))->sort(function ($a, $b) {
|
609 |
+
if ($a === $b) {
|
610 |
+
return 0;
|
611 |
+
}
|
612 |
+
|
613 |
+
return ($a < $b) ? -1 : 1;
|
614 |
+
});
|
615 |
+
|
616 |
+
$this->assertEquals(range(1, 5), array_values($data->all()));
|
617 |
+
}
|
618 |
+
|
619 |
+
public function testSortBy()
|
620 |
+
{
|
621 |
+
$data = new Collection(['taylor', 'dayle']);
|
622 |
+
$data = $data->sortBy(function ($x) {
|
623 |
+
return $x;
|
624 |
+
});
|
625 |
+
|
626 |
+
$this->assertEquals(['dayle', 'taylor'], array_values($data->all()));
|
627 |
+
|
628 |
+
$data = new Collection(['dayle', 'taylor']);
|
629 |
+
$data = $data->sortByDesc(function ($x) {
|
630 |
+
return $x;
|
631 |
+
});
|
632 |
+
|
633 |
+
$this->assertEquals(['taylor', 'dayle'], array_values($data->all()));
|
634 |
+
}
|
635 |
+
|
636 |
+
public function testSortByString()
|
637 |
+
{
|
638 |
+
$data = new Collection([['name' => 'taylor'], ['name' => 'dayle']]);
|
639 |
+
$data = $data->sortBy('name');
|
640 |
+
|
641 |
+
$this->assertEquals([['name' => 'dayle'], ['name' => 'taylor']], array_values($data->all()));
|
642 |
+
}
|
643 |
+
|
644 |
+
public function testReverse()
|
645 |
+
{
|
646 |
+
$data = new Collection(['zaeed', 'alan']);
|
647 |
+
$reversed = $data->reverse();
|
648 |
+
|
649 |
+
$this->assertSame([1 => 'alan', 0 => 'zaeed'], $reversed->all());
|
650 |
+
|
651 |
+
$data = new Collection(['name' => 'taylor', 'framework' => 'laravel']);
|
652 |
+
$reversed = $data->reverse();
|
653 |
+
|
654 |
+
$this->assertSame(['framework' => 'laravel', 'name' => 'taylor'], $reversed->all());
|
655 |
+
}
|
656 |
+
|
657 |
+
public function testFlip()
|
658 |
+
{
|
659 |
+
$data = new Collection(['name' => 'taylor', 'framework' => 'laravel']);
|
660 |
+
$this->assertEquals(['taylor' => 'name', 'laravel' => 'framework'], $data->flip()->toArray());
|
661 |
+
}
|
662 |
+
|
663 |
+
public function testChunk()
|
664 |
+
{
|
665 |
+
$data = new Collection([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
|
666 |
+
$data = $data->chunk(3);
|
667 |
+
|
668 |
+
$this->assertInstanceOf(Collection::class, $data);
|
669 |
+
$this->assertInstanceOf(Collection::class, $data[0]);
|
670 |
+
$this->assertCount(4, $data);
|
671 |
+
$this->assertEquals([1, 2, 3], $data[0]->toArray());
|
672 |
+
$this->assertEquals([9 => 10], $data[3]->toArray());
|
673 |
+
}
|
674 |
+
|
675 |
+
public function testEvery()
|
676 |
+
{
|
677 |
+
$data = new Collection([
|
678 |
+
6 => 'a',
|
679 |
+
4 => 'b',
|
680 |
+
7 => 'c',
|
681 |
+
1 => 'd',
|
682 |
+
5 => 'e',
|
683 |
+
3 => 'f',
|
684 |
+
]);
|
685 |
+
|
686 |
+
$this->assertEquals(['a', 'e'], $data->every(4)->all());
|
687 |
+
$this->assertEquals(['b', 'f'], $data->every(4, 1)->all());
|
688 |
+
$this->assertEquals(['c'], $data->every(4, 2)->all());
|
689 |
+
$this->assertEquals(['d'], $data->every(4, 3)->all());
|
690 |
+
}
|
691 |
+
|
692 |
+
public function testExcept()
|
693 |
+
{
|
694 |
+
$data = new Collection(['first' => 'Taylor', 'last' => 'Otwell', 'email' => 'taylorotwell@gmail.com']);
|
695 |
+
|
696 |
+
$this->assertEquals(['first' => 'Taylor'], $data->except(['last', 'email', 'missing'])->all());
|
697 |
+
$this->assertEquals(['first' => 'Taylor'], $data->except('last', 'email', 'missing')->all());
|
698 |
+
|
699 |
+
$this->assertEquals(['first' => 'Taylor', 'email' => 'taylorotwell@gmail.com'], $data->except(['last'])->all());
|
700 |
+
$this->assertEquals(['first' => 'Taylor', 'email' => 'taylorotwell@gmail.com'], $data->except('last')->all());
|
701 |
+
}
|
702 |
+
|
703 |
+
public function testPluckWithArrayAndObjectValues()
|
704 |
+
{
|
705 |
+
$data = new Collection([(object) ['name' => 'taylor', 'email' => 'foo'], ['name' => 'dayle', 'email' => 'bar']]);
|
706 |
+
$this->assertEquals(['taylor' => 'foo', 'dayle' => 'bar'], $data->pluck('email', 'name')->all());
|
707 |
+
$this->assertEquals(['foo', 'bar'], $data->pluck('email')->all());
|
708 |
+
}
|
709 |
+
|
710 |
+
public function testPluckWithArrayAccessValues()
|
711 |
+
{
|
712 |
+
$data = new Collection([
|
713 |
+
new TestArrayAccessImplementation(['name' => 'taylor', 'email' => 'foo']),
|
714 |
+
new TestArrayAccessImplementation(['name' => 'dayle', 'email' => 'bar']),
|
715 |
+
]);
|
716 |
+
|
717 |
+
$this->assertEquals(['taylor' => 'foo', 'dayle' => 'bar'], $data->pluck('email', 'name')->all());
|
718 |
+
$this->assertEquals(['foo', 'bar'], $data->pluck('email')->all());
|
719 |
+
}
|
720 |
+
|
721 |
+
public function testImplode()
|
722 |
+
{
|
723 |
+
$data = new Collection([['name' => 'taylor', 'email' => 'foo'], ['name' => 'dayle', 'email' => 'bar']]);
|
724 |
+
$this->assertEquals('foobar', $data->implode('email'));
|
725 |
+
$this->assertEquals('foo,bar', $data->implode('email', ','));
|
726 |
+
|
727 |
+
$data = new Collection(['taylor', 'dayle']);
|
728 |
+
$this->assertEquals('taylordayle', $data->implode(''));
|
729 |
+
$this->assertEquals('taylor,dayle', $data->implode(','));
|
730 |
+
}
|
731 |
+
|
732 |
+
public function testTake()
|
733 |
+
{
|
734 |
+
$data = new Collection(['taylor', 'dayle', 'shawn']);
|
735 |
+
$data = $data->take(2);
|
736 |
+
$this->assertEquals(['taylor', 'dayle'], $data->all());
|
737 |
+
}
|
738 |
+
|
739 |
+
public function testRandom()
|
740 |
+
{
|
741 |
+
$data = new Collection([1, 2, 3, 4, 5, 6]);
|
742 |
+
|
743 |
+
$random = $data->random();
|
744 |
+
$this->assertInternalType('integer', $random);
|
745 |
+
$this->assertContains($random, $data->all());
|
746 |
+
|
747 |
+
$random = $data->random(3);
|
748 |
+
$this->assertInstanceOf(Collection::class, $random);
|
749 |
+
$this->assertCount(3, $random);
|
750 |
+
}
|
751 |
+
|
752 |
+
/**
|
753 |
+
* @expectedException InvalidArgumentException
|
754 |
+
*/
|
755 |
+
public function testRandomThrowsAnErrorWhenRequestingMoreItemsThanAreAvailable()
|
756 |
+
{
|
757 |
+
(new Collection)->random();
|
758 |
+
}
|
759 |
+
|
760 |
+
public function testTakeLast()
|
761 |
+
{
|
762 |
+
$data = new Collection(['taylor', 'dayle', 'shawn']);
|
763 |
+
$data = $data->take(-2);
|
764 |
+
$this->assertEquals([1 => 'dayle', 2 => 'shawn'], $data->all());
|
765 |
+
}
|
766 |
+
|
767 |
+
public function testMacroable()
|
768 |
+
{
|
769 |
+
// Foo() macro : unique values starting with A
|
770 |
+
Collection::macro('foo', function () {
|
771 |
+
return $this->filter(function ($item) {
|
772 |
+
return strpos($item, 'a') === 0;
|
773 |
+
})
|
774 |
+
->unique()
|
775 |
+
->values();
|
776 |
+
});
|
777 |
+
|
778 |
+
$c = new Collection(['a', 'a', 'aa', 'aaa', 'bar']);
|
779 |
+
|
780 |
+
$this->assertSame(['a', 'aa', 'aaa'], $c->foo()->all());
|
781 |
+
}
|
782 |
+
|
783 |
+
public function testMakeMethod()
|
784 |
+
{
|
785 |
+
$collection = Collection::make('foo');
|
786 |
+
$this->assertEquals(['foo'], $collection->all());
|
787 |
+
}
|
788 |
+
|
789 |
+
public function testMakeMethodFromNull()
|
790 |
+
{
|
791 |
+
$collection = Collection::make(null);
|
792 |
+
$this->assertEquals([], $collection->all());
|
793 |
+
|
794 |
+
$collection = Collection::make();
|
795 |
+
$this->assertEquals([], $collection->all());
|
796 |
+
}
|
797 |
+
|
798 |
+
public function testMakeMethodFromCollection()
|
799 |
+
{
|
800 |
+
$firstCollection = Collection::make(['foo' => 'bar']);
|
801 |
+
$secondCollection = Collection::make($firstCollection);
|
802 |
+
$this->assertEquals(['foo' => 'bar'], $secondCollection->all());
|
803 |
+
}
|
804 |
+
|
805 |
+
public function testMakeMethodFromArray()
|
806 |
+
{
|
807 |
+
$collection = Collection::make(['foo' => 'bar']);
|
808 |
+
$this->assertEquals(['foo' => 'bar'], $collection->all());
|
809 |
+
}
|
810 |
+
|
811 |
+
public function testConstructMakeFromObject()
|
812 |
+
{
|
813 |
+
$object = new stdClass();
|
814 |
+
$object->foo = 'bar';
|
815 |
+
$collection = Collection::make($object);
|
816 |
+
$this->assertEquals(['foo' => 'bar'], $collection->all());
|
817 |
+
}
|
818 |
+
|
819 |
+
public function testConstructMethod()
|
820 |
+
{
|
821 |
+
$collection = new Collection('foo');
|
822 |
+
$this->assertEquals(['foo'], $collection->all());
|
823 |
+
}
|
824 |
+
|
825 |
+
public function testConstructMethodFromNull()
|
826 |
+
{
|
827 |
+
$collection = new Collection(null);
|
828 |
+
$this->assertEquals([], $collection->all());
|
829 |
+
|
830 |
+
$collection = new Collection();
|
831 |
+
$this->assertEquals([], $collection->all());
|
832 |
+
}
|
833 |
+
|
834 |
+
public function testConstructMethodFromCollection()
|
835 |
+
{
|
836 |
+
$firstCollection = new Collection(['foo' => 'bar']);
|
837 |
+
$secondCollection = new Collection($firstCollection);
|
838 |
+
$this->assertEquals(['foo' => 'bar'], $secondCollection->all());
|
839 |
+
}
|
840 |
+
|
841 |
+
public function testConstructMethodFromArray()
|
842 |
+
{
|
843 |
+
$collection = new Collection(['foo' => 'bar']);
|
844 |
+
$this->assertEquals(['foo' => 'bar'], $collection->all());
|
845 |
+
}
|
846 |
+
|
847 |
+
public function testConstructMethodFromObject()
|
848 |
+
{
|
849 |
+
$object = new stdClass();
|
850 |
+
$object->foo = 'bar';
|
851 |
+
$collection = new Collection($object);
|
852 |
+
$this->assertEquals(['foo' => 'bar'], $collection->all());
|
853 |
+
}
|
854 |
+
|
855 |
+
public function testSplice()
|
856 |
+
{
|
857 |
+
$data = new Collection(['foo', 'baz']);
|
858 |
+
$data->splice(1);
|
859 |
+
$this->assertEquals(['foo'], $data->all());
|
860 |
+
|
861 |
+
$data = new Collection(['foo', 'baz']);
|
862 |
+
$data->splice(1, 0, 'bar');
|
863 |
+
$this->assertEquals(['foo', 'bar', 'baz'], $data->all());
|
864 |
+
|
865 |
+
$data = new Collection(['foo', 'baz']);
|
866 |
+
$data->splice(1, 1);
|
867 |
+
$this->assertEquals(['foo'], $data->all());
|
868 |
+
|
869 |
+
$data = new Collection(['foo', 'baz']);
|
870 |
+
$cut = $data->splice(1, 1, 'bar');
|
871 |
+
$this->assertEquals(['foo', 'bar'], $data->all());
|
872 |
+
$this->assertEquals(['baz'], $cut->all());
|
873 |
+
}
|
874 |
+
|
875 |
+
public function testGetPluckValueWithAccessors()
|
876 |
+
{
|
877 |
+
$model = new TestAccessorEloquentTestStub(['some' => 'foo']);
|
878 |
+
$modelTwo = new TestAccessorEloquentTestStub(['some' => 'bar']);
|
879 |
+
$data = new Collection([$model, $modelTwo]);
|
880 |
+
|
881 |
+
$this->assertEquals(['foo', 'bar'], $data->pluck('some')->all());
|
882 |
+
}
|
883 |
+
|
884 |
+
public function testMap()
|
885 |
+
{
|
886 |
+
$data = new Collection(['first' => 'taylor', 'last' => 'otwell']);
|
887 |
+
$data = $data->map(function ($item, $key) {
|
888 |
+
return $key.'-'.strrev($item);
|
889 |
+
});
|
890 |
+
$this->assertEquals(['first' => 'first-rolyat', 'last' => 'last-llewto'], $data->all());
|
891 |
+
}
|
892 |
+
|
893 |
+
public function testFlatMap()
|
894 |
+
{
|
895 |
+
$data = new Collection([
|
896 |
+
['name' => 'taylor', 'hobbies' => ['programming', 'basketball']],
|
897 |
+
['name' => 'adam', 'hobbies' => ['music', 'powerlifting']],
|
898 |
+
]);
|
899 |
+
$data = $data->flatMap(function ($person) {
|
900 |
+
return $person['hobbies'];
|
901 |
+
});
|
902 |
+
$this->assertEquals(['programming', 'basketball', 'music', 'powerlifting'], $data->all());
|
903 |
+
}
|
904 |
+
|
905 |
+
public function testMapWithKeys()
|
906 |
+
{
|
907 |
+
$data = new Collection([
|
908 |
+
['name' => 'Blastoise', 'type' => 'Water', 'idx' => 9],
|
909 |
+
['name' => 'Charmander', 'type' => 'Fire', 'idx' => 4],
|
910 |
+
['name' => 'Dragonair', 'type' => 'Dragon', 'idx' => 148],
|
911 |
+
]);
|
912 |
+
$data = $data->mapWithKeys(function ($pokemon) {
|
913 |
+
return [$pokemon['name'] => $pokemon['type']];
|
914 |
+
});
|
915 |
+
$this->assertEquals(
|
916 |
+
['Blastoise' => 'Water', 'Charmander' => 'Fire', 'Dragonair' => 'Dragon'],
|
917 |
+
$data->all()
|
918 |
+
);
|
919 |
+
}
|
920 |
+
|
921 |
+
public function testTransform()
|
922 |
+
{
|
923 |
+
$data = new Collection(['first' => 'taylor', 'last' => 'otwell']);
|
924 |
+
$data->transform(function ($item, $key) {
|
925 |
+
return $key.'-'.strrev($item);
|
926 |
+
});
|
927 |
+
$this->assertEquals(['first' => 'first-rolyat', 'last' => 'last-llewto'], $data->all());
|
928 |
+
}
|
929 |
+
|
930 |
+
public function testFirstWithCallback()
|
931 |
+
{
|
932 |
+
$data = new Collection(['foo', 'bar', 'baz']);
|
933 |
+
$result = $data->first(function ($value) {
|
934 |
+
return $value === 'bar';
|
935 |
+
});
|
936 |
+
$this->assertEquals('bar', $result);
|
937 |
+
}
|
938 |
+
|
939 |
+
public function testFirstWithCallbackAndDefault()
|
940 |
+
{
|
941 |
+
$data = new Collection(['foo', 'bar']);
|
942 |
+
$result = $data->first(function ($value) {
|
943 |
+
return $value === 'baz';
|
944 |
+
}, 'default');
|
945 |
+
$this->assertEquals('default', $result);
|
946 |
+
}
|
947 |
+
|
948 |
+
public function testFirstWithDefaultAndWithoutCallback()
|
949 |
+
{
|
950 |
+
$data = new Collection;
|
951 |
+
$result = $data->first(null, 'default');
|
952 |
+
$this->assertEquals('default', $result);
|
953 |
+
}
|
954 |
+
|
955 |
+
public function testGroupByAttribute()
|
956 |
+
{
|
957 |
+
$data = new Collection([['rating' => 1, 'url' => '1'], ['rating' => 1, 'url' => '1'], ['rating' => 2, 'url' => '2']]);
|
958 |
+
|
959 |
+
$result = $data->groupBy('rating');
|
960 |
+
$this->assertEquals([1 => [['rating' => 1, 'url' => '1'], ['rating' => 1, 'url' => '1']], 2 => [['rating' => 2, 'url' => '2']]], $result->toArray());
|
961 |
+
|
962 |
+
$result = $data->groupBy('url');
|
963 |
+
$this->assertEquals([1 => [['rating' => 1, 'url' => '1'], ['rating' => 1, 'url' => '1']], 2 => [['rating' => 2, 'url' => '2']]], $result->toArray());
|
964 |
+
}
|
965 |
+
|
966 |
+
public function testGroupByAttributePreservingKeys()
|
967 |
+
{
|
968 |
+
$data = new Collection([10 => ['rating' => 1, 'url' => '1'], 20 => ['rating' => 1, 'url' => '1'], 30 => ['rating' => 2, 'url' => '2']]);
|
969 |
+
|
970 |
+
$result = $data->groupBy('rating', true);
|
971 |
+
|
972 |
+
$expected_result = [
|
973 |
+
1 => [10 => ['rating' => 1, 'url' => '1'], 20 => ['rating' => 1, 'url' => '1']],
|
974 |
+
2 => [30 => ['rating' => 2, 'url' => '2']],
|
975 |
+
];
|
976 |
+
|
977 |
+
$this->assertEquals($expected_result, $result->toArray());
|
978 |
+
}
|
979 |
+
|
980 |
+
public function testGroupByClosureWhereItemsHaveSingleGroup()
|
981 |
+
{
|
982 |
+
$data = new Collection([['rating' => 1, 'url' => '1'], ['rating' => 1, 'url' => '1'], ['rating' => 2, 'url' => '2']]);
|
983 |
+
|
984 |
+
$result = $data->groupBy(function ($item) {
|
985 |
+
return $item['rating'];
|
986 |
+
});
|
987 |
+
|
988 |
+
$this->assertEquals([1 => [['rating' => 1, 'url' => '1'], ['rating' => 1, 'url' => '1']], 2 => [['rating' => 2, 'url' => '2']]], $result->toArray());
|
989 |
+
}
|
990 |
+
|
991 |
+
public function testGroupByClosureWhereItemsHaveSingleGroupPreservingKeys()
|
992 |
+
{
|
993 |
+
$data = new Collection([10 => ['rating' => 1, 'url' => '1'], 20 => ['rating' => 1, 'url' => '1'], 30 => ['rating' => 2, 'url' => '2']]);
|
994 |
+
|
995 |
+
$result = $data->groupBy(function ($item) {
|
996 |
+
return $item['rating'];
|
997 |
+
}, true);
|
998 |
+
|
999 |
+
$expected_result = [
|
1000 |
+
1 => [10 => ['rating' => 1, 'url' => '1'], 20 => ['rating' => 1, 'url' => '1']],
|
1001 |
+
2 => [30 => ['rating' => 2, 'url' => '2']],
|
1002 |
+
];
|
1003 |
+
|
1004 |
+
$this->assertEquals($expected_result, $result->toArray());
|
1005 |
+
}
|
1006 |
+
|
1007 |
+
public function testGroupByClosureWhereItemsHaveMultipleGroups()
|
1008 |
+
{
|
1009 |
+
$data = new Collection([
|
1010 |
+
['user' => 1, 'roles' => ['Role_1', 'Role_3']],
|
1011 |
+
['user' => 2, 'roles' => ['Role_1', 'Role_2']],
|
1012 |
+
['user' => 3, 'roles' => ['Role_1']],
|
1013 |
+
]);
|
1014 |
+
|
1015 |
+
$result = $data->groupBy(function ($item) {
|
1016 |
+
return $item['roles'];
|
1017 |
+
});
|
1018 |
+
|
1019 |
+
$expected_result = [
|
1020 |
+
'Role_1' => [
|
1021 |
+
['user' => 1, 'roles' => ['Role_1', 'Role_3']],
|
1022 |
+
['user' => 2, 'roles' => ['Role_1', 'Role_2']],
|
1023 |
+
['user' => 3, 'roles' => ['Role_1']],
|
1024 |
+
],
|
1025 |
+
'Role_2' => [
|
1026 |
+
['user' => 2, 'roles' => ['Role_1', 'Role_2']],
|
1027 |
+
],
|
1028 |
+
'Role_3' => [
|
1029 |
+
['user' => 1, 'roles' => ['Role_1', 'Role_3']],
|
1030 |
+
],
|
1031 |
+
];
|
1032 |
+
|
1033 |
+
$this->assertEquals($expected_result, $result->toArray());
|
1034 |
+
}
|
1035 |
+
|
1036 |
+
public function testGroupByClosureWhereItemsHaveMultipleGroupsPreservingKeys()
|
1037 |
+
{
|
1038 |
+
$data = new Collection([
|
1039 |
+
10 => ['user' => 1, 'roles' => ['Role_1', 'Role_3']],
|
1040 |
+
20 => ['user' => 2, 'roles' => ['Role_1', 'Role_2']],
|
1041 |
+
30 => ['user' => 3, 'roles' => ['Role_1']],
|
1042 |
+
]);
|
1043 |
+
|
1044 |
+
$result = $data->groupBy(function ($item) {
|
1045 |
+
return $item['roles'];
|
1046 |
+
}, true);
|
1047 |
+
|
1048 |
+
$expected_result = [
|
1049 |
+
'Role_1' => [
|
1050 |
+
10 => ['user' => 1, 'roles' => ['Role_1', 'Role_3']],
|
1051 |
+
20 => ['user' => 2, 'roles' => ['Role_1', 'Role_2']],
|
1052 |
+
30 => ['user' => 3, 'roles' => ['Role_1']],
|
1053 |
+
],
|
1054 |
+
'Role_2' => [
|
1055 |
+
20 => ['user' => 2, 'roles' => ['Role_1', 'Role_2']],
|
1056 |
+
],
|
1057 |
+
'Role_3' => [
|
1058 |
+
10 => ['user' => 1, 'roles' => ['Role_1', 'Role_3']],
|
1059 |
+
],
|
1060 |
+
];
|
1061 |
+
|
1062 |
+
$this->assertEquals($expected_result, $result->toArray());
|
1063 |
+
}
|
1064 |
+
|
1065 |
+
public function testKeyByAttribute()
|
1066 |
+
{
|
1067 |
+
$data = new Collection([['rating' => 1, 'name' => '1'], ['rating' => 2, 'name' => '2'], ['rating' => 3, 'name' => '3']]);
|
1068 |
+
|
1069 |
+
$result = $data->keyBy('rating');
|
1070 |
+
$this->assertEquals([1 => ['rating' => 1, 'name' => '1'], 2 => ['rating' => 2, 'name' => '2'], 3 => ['rating' => 3, 'name' => '3']], $result->all());
|
1071 |
+
|
1072 |
+
$result = $data->keyBy(function ($item) {
|
1073 |
+
return $item['rating'] * 2;
|
1074 |
+
});
|
1075 |
+
$this->assertEquals([2 => ['rating' => 1, 'name' => '1'], 4 => ['rating' => 2, 'name' => '2'], 6 => ['rating' => 3, 'name' => '3']], $result->all());
|
1076 |
+
}
|
1077 |
+
|
1078 |
+
public function testKeyByClosure()
|
1079 |
+
{
|
1080 |
+
$data = new Collection([
|
1081 |
+
['firstname' => 'Taylor', 'lastname' => 'Otwell', 'locale' => 'US'],
|
1082 |
+
['firstname' => 'Lucas', 'lastname' => 'Michot', 'locale' => 'FR'],
|
1083 |
+
]);
|
1084 |
+
$result = $data->keyBy(function ($item, $key) {
|
1085 |
+
return strtolower($key.'-'.$item['firstname'].$item['lastname']);
|
1086 |
+
});
|
1087 |
+
$this->assertEquals([
|
1088 |
+
'0-taylorotwell' => ['firstname' => 'Taylor', 'lastname' => 'Otwell', 'locale' => 'US'],
|
1089 |
+
'1-lucasmichot' => ['firstname' => 'Lucas', 'lastname' => 'Michot', 'locale' => 'FR'],
|
1090 |
+
], $result->all());
|
1091 |
+
}
|
1092 |
+
|
1093 |
+
public function testContains()
|
1094 |
+
{
|
1095 |
+
$c = new Collection([1, 3, 5]);
|
1096 |
+
|
1097 |
+
$this->assertTrue($c->contains(1));
|
1098 |
+
$this->assertFalse($c->contains(2));
|
1099 |
+
$this->assertTrue($c->contains(function ($value) {
|
1100 |
+
return $value < 5;
|
1101 |
+
}));
|
1102 |
+
$this->assertFalse($c->contains(function ($value) {
|
1103 |
+
return $value > 5;
|
1104 |
+
}));
|
1105 |
+
|
1106 |
+
$c = new Collection([['v' => 1], ['v' => 3], ['v' => 5]]);
|
1107 |
+
|
1108 |
+
$this->assertTrue($c->contains('v', 1));
|
1109 |
+
$this->assertFalse($c->contains('v', 2));
|
1110 |
+
|
1111 |
+
$c = new Collection(['date', 'class', (object) ['foo' => 50]]);
|
1112 |
+
|
1113 |
+
$this->assertTrue($c->contains('date'));
|
1114 |
+
$this->assertTrue($c->contains('class'));
|
1115 |
+
$this->assertFalse($c->contains('foo'));
|
1116 |
+
}
|
1117 |
+
|
1118 |
+
public function testContainsStrict()
|
1119 |
+
{
|
1120 |
+
$c = new Collection([1, 3, 5, '02']);
|
1121 |
+
|
1122 |
+
$this->assertTrue($c->containsStrict(1));
|
1123 |
+
$this->assertFalse($c->containsStrict(2));
|
1124 |
+
$this->assertTrue($c->containsStrict('02'));
|
1125 |
+
$this->assertTrue($c->containsStrict(function ($value) {
|
1126 |
+
return $value < 5;
|
1127 |
+
}));
|
1128 |
+
$this->assertFalse($c->containsStrict(function ($value) {
|
1129 |
+
return $value > 5;
|
1130 |
+
}));
|
1131 |
+
|
1132 |
+
$c = new Collection([['v' => 1], ['v' => 3], ['v' => '04'], ['v' => 5]]);
|
1133 |
+
|
1134 |
+
$this->assertTrue($c->containsStrict('v', 1));
|
1135 |
+
$this->assertFalse($c->containsStrict('v', 2));
|
1136 |
+
$this->assertFalse($c->containsStrict('v', 4));
|
1137 |
+
$this->assertTrue($c->containsStrict('v', '04'));
|
1138 |
+
|
1139 |
+
$c = new Collection(['date', 'class', (object) ['foo' => 50], '']);
|
1140 |
+
|
1141 |
+
$this->assertTrue($c->containsStrict('date'));
|
1142 |
+
$this->assertTrue($c->containsStrict('class'));
|
1143 |
+
$this->assertFalse($c->containsStrict('foo'));
|
1144 |
+
$this->assertFalse($c->containsStrict(null));
|
1145 |
+
$this->assertTrue($c->containsStrict(''));
|
1146 |
+
}
|
1147 |
+
|
1148 |
+
public function testGettingSumFromCollection()
|
1149 |
+
{
|
1150 |
+
$c = new Collection([(object) ['foo' => 50], (object) ['foo' => 50]]);
|
1151 |
+
$this->assertEquals(100, $c->sum('foo'));
|
1152 |
+
|
1153 |
+
$c = new Collection([(object) ['foo' => 50], (object) ['foo' => 50]]);
|
1154 |
+
$this->assertEquals(100, $c->sum(function ($i) {
|
1155 |
+
return $i->foo;
|
1156 |
+
}));
|
1157 |
+
}
|
1158 |
+
|
1159 |
+
public function testCanSumValuesWithoutACallback()
|
1160 |
+
{
|
1161 |
+
$c = new Collection([1, 2, 3, 4, 5]);
|
1162 |
+
$this->assertEquals(15, $c->sum());
|
1163 |
+
}
|
1164 |
+
|
1165 |
+
public function testGettingSumFromEmptyCollection()
|
1166 |
+
{
|
1167 |
+
$c = new Collection();
|
1168 |
+
$this->assertEquals(0, $c->sum('foo'));
|
1169 |
+
}
|
1170 |
+
|
1171 |
+
public function testValueRetrieverAcceptsDotNotation()
|
1172 |
+
{
|
1173 |
+
$c = new Collection([
|
1174 |
+
(object) ['id' => 1, 'foo' => ['bar' => 'B']], (object) ['id' => 2, 'foo' => ['bar' => 'A']],
|
1175 |
+
]);
|
1176 |
+
|
1177 |
+
$c = $c->sortBy('foo.bar');
|
1178 |
+
$this->assertEquals([2, 1], $c->pluck('id')->all());
|
1179 |
+
}
|
1180 |
+
|
1181 |
+
public function testPullRetrievesItemFromCollection()
|
1182 |
+
{
|
1183 |
+
$c = new Collection(['foo', 'bar']);
|
1184 |
+
|
1185 |
+
$this->assertEquals('foo', $c->pull(0));
|
1186 |
+
}
|
1187 |
+
|
1188 |
+
public function testPullRemovesItemFromCollection()
|
1189 |
+
{
|
1190 |
+
$c = new Collection(['foo', 'bar']);
|
1191 |
+
$c->pull(0);
|
1192 |
+
$this->assertEquals([1 => 'bar'], $c->all());
|
1193 |
+
}
|
1194 |
+
|
1195 |
+
public function testPullReturnsDefault()
|
1196 |
+
{
|
1197 |
+
$c = new Collection([]);
|
1198 |
+
$value = $c->pull(0, 'foo');
|
1199 |
+
$this->assertEquals('foo', $value);
|
1200 |
+
}
|
1201 |
+
|
1202 |
+
public function testRejectRemovesElementsPassingTruthTest()
|
1203 |
+
{
|
1204 |
+
$c = new Collection(['foo', 'bar']);
|
1205 |
+
$this->assertEquals(['foo'], $c->reject('bar')->values()->all());
|
1206 |
+
|
1207 |
+
$c = new Collection(['foo', 'bar']);
|
1208 |
+
$this->assertEquals(['foo'], $c->reject(function ($v) {
|
1209 |
+
return $v == 'bar';
|
1210 |
+
})->values()->all());
|
1211 |
+
|
1212 |
+
$c = new Collection(['foo', null]);
|
1213 |
+
$this->assertEquals(['foo'], $c->reject(null)->values()->all());
|
1214 |
+
|
1215 |
+
$c = new Collection(['foo', 'bar']);
|
1216 |
+
$this->assertEquals(['foo', 'bar'], $c->reject('baz')->values()->all());
|
1217 |
+
|
1218 |
+
$c = new Collection(['foo', 'bar']);
|
1219 |
+
$this->assertEquals(['foo', 'bar'], $c->reject(function ($v) {
|
1220 |
+
return $v == 'baz';
|
1221 |
+
})->values()->all());
|
1222 |
+
|
1223 |
+
$c = new Collection(['id' => 1, 'primary' => 'foo', 'secondary' => 'bar']);
|
1224 |
+
$this->assertEquals(['primary' => 'foo', 'secondary' => 'bar'], $c->reject(function ($item, $key) {
|
1225 |
+
return $key == 'id';
|
1226 |
+
})->all());
|
1227 |
+
}
|
1228 |
+
|
1229 |
+
public function testSearchReturnsIndexOfFirstFoundItem()
|
1230 |
+
{
|
1231 |
+
$c = new Collection([1, 2, 3, 4, 5, 2, 5, 'foo' => 'bar']);
|
1232 |
+
|
1233 |
+
$this->assertEquals(1, $c->search(2));
|
1234 |
+
$this->assertEquals('foo', $c->search('bar'));
|
1235 |
+
$this->assertEquals(4, $c->search(function ($value) {
|
1236 |
+
return $value > 4;
|
1237 |
+
}));
|
1238 |
+
$this->assertEquals('foo', $c->search(function ($value) {
|
1239 |
+
return ! is_numeric($value);
|
1240 |
+
}));
|
1241 |
+
}
|
1242 |
+
|
1243 |
+
public function testSearchReturnsFalseWhenItemIsNotFound()
|
1244 |
+
{
|
1245 |
+
$c = new Collection([1, 2, 3, 4, 5, 'foo' => 'bar']);
|
1246 |
+
|
1247 |
+
$this->assertFalse($c->search(6));
|
1248 |
+
$this->assertFalse($c->search('foo'));
|
1249 |
+
$this->assertFalse($c->search(function ($value) {
|
1250 |
+
return $value < 1 && is_numeric($value);
|
1251 |
+
}));
|
1252 |
+
$this->assertFalse($c->search(function ($value) {
|
1253 |
+
return $value == 'nope';
|
1254 |
+
}));
|
1255 |
+
}
|
1256 |
+
|
1257 |
+
public function testKeys()
|
1258 |
+
{
|
1259 |
+
$c = new Collection(['name' => 'taylor', 'framework' => 'laravel']);
|
1260 |
+
$this->assertEquals(['name', 'framework'], $c->keys()->all());
|
1261 |
+
}
|
1262 |
+
|
1263 |
+
public function testPaginate()
|
1264 |
+
{
|
1265 |
+
$c = new Collection(['one', 'two', 'three', 'four']);
|
1266 |
+
$this->assertEquals(['one', 'two'], $c->forPage(1, 2)->all());
|
1267 |
+
$this->assertEquals([2 => 'three', 3 => 'four'], $c->forPage(2, 2)->all());
|
1268 |
+
$this->assertEquals([], $c->forPage(3, 2)->all());
|
1269 |
+
}
|
1270 |
+
|
1271 |
+
public function testPrepend()
|
1272 |
+
{
|
1273 |
+
$c = new Collection(['one', 'two', 'three', 'four']);
|
1274 |
+
$this->assertEquals(['zero', 'one', 'two', 'three', 'four'], $c->prepend('zero')->all());
|
1275 |
+
|
1276 |
+
$c = new Collection(['one' => 1, 'two' => 2]);
|
1277 |
+
$this->assertEquals(['zero' => 0, 'one' => 1, 'two' => 2], $c->prepend(0, 'zero')->all());
|
1278 |
+
}
|
1279 |
+
|
1280 |
+
public function testZip()
|
1281 |
+
{
|
1282 |
+
$c = new Collection([1, 2, 3]);
|
1283 |
+
$c = $c->zip(new Collection([4, 5, 6]));
|
1284 |
+
$this->assertInstanceOf(Collection::class, $c);
|
1285 |
+
$this->assertInstanceOf(Collection::class, $c[0]);
|
1286 |
+
$this->assertInstanceOf(Collection::class, $c[1]);
|
1287 |
+
$this->assertInstanceOf(Collection::class, $c[2]);
|
1288 |
+
$this->assertCount(3, $c);
|
1289 |
+
$this->assertEquals([1, 4], $c[0]->all());
|
1290 |
+
$this->assertEquals([2, 5], $c[1]->all());
|
1291 |
+
$this->assertEquals([3, 6], $c[2]->all());
|
1292 |
+
|
1293 |
+
$c = new Collection([1, 2, 3]);
|
1294 |
+
$c = $c->zip([4, 5, 6], [7, 8, 9]);
|
1295 |
+
$this->assertCount(3, $c);
|
1296 |
+
$this->assertEquals([1, 4, 7], $c[0]->all());
|
1297 |
+
$this->assertEquals([2, 5, 8], $c[1]->all());
|
1298 |
+
$this->assertEquals([3, 6, 9], $c[2]->all());
|
1299 |
+
|
1300 |
+
$c = new Collection([1, 2, 3]);
|
1301 |
+
$c = $c->zip([4, 5, 6], [7]);
|
1302 |
+
$this->assertCount(3, $c);
|
1303 |
+
$this->assertEquals([1, 4, 7], $c[0]->all());
|
1304 |
+
$this->assertEquals([2, 5, null], $c[1]->all());
|
1305 |
+
$this->assertEquals([3, 6, null], $c[2]->all());
|
1306 |
+
}
|
1307 |
+
|
1308 |
+
public function testGettingMaxItemsFromCollection()
|
1309 |
+
{
|
1310 |
+
$c = new Collection([(object) ['foo' => 10], (object) ['foo' => 20]]);
|
1311 |
+
$this->assertEquals(20, $c->max(function ($item) {
|
1312 |
+
return $item->foo;
|
1313 |
+
}));
|
1314 |
+
$this->assertEquals(20, $c->max('foo'));
|
1315 |
+
|
1316 |
+
$c = new Collection([['foo' => 10], ['foo' => 20]]);
|
1317 |
+
$this->assertEquals(20, $c->max('foo'));
|
1318 |
+
|
1319 |
+
$c = new Collection([1, 2, 3, 4, 5]);
|
1320 |
+
$this->assertEquals(5, $c->max());
|
1321 |
+
|
1322 |
+
$c = new Collection();
|
1323 |
+
$this->assertNull($c->max());
|
1324 |
+
}
|
1325 |
+
|
1326 |
+
public function testGettingMinItemsFromCollection()
|
1327 |
+
{
|
1328 |
+
$c = new Collection([(object) ['foo' => 10], (object) ['foo' => 20]]);
|
1329 |
+
$this->assertEquals(10, $c->min(function ($item) {
|
1330 |
+
return $item->foo;
|
1331 |
+
}));
|
1332 |
+
$this->assertEquals(10, $c->min('foo'));
|
1333 |
+
|
1334 |
+
$c = new Collection([['foo' => 10], ['foo' => 20]]);
|
1335 |
+
$this->assertEquals(10, $c->min('foo'));
|
1336 |
+
|
1337 |
+
$c = new Collection([1, 2, 3, 4, 5]);
|
1338 |
+
$this->assertEquals(1, $c->min());
|
1339 |
+
|
1340 |
+
$c = new Collection();
|
1341 |
+
$this->assertNull($c->min());
|
1342 |
+
}
|
1343 |
+
|
1344 |
+
public function testOnly()
|
1345 |
+
{
|
1346 |
+
$data = new Collection(['first' => 'Taylor', 'last' => 'Otwell', 'email' => 'taylorotwell@gmail.com']);
|
1347 |
+
|
1348 |
+
$this->assertEquals($data->all(), $data->only(null)->all());
|
1349 |
+
$this->assertEquals(['first' => 'Taylor'], $data->only(['first', 'missing'])->all());
|
1350 |
+
$this->assertEquals(['first' => 'Taylor'], $data->only('first', 'missing')->all());
|
1351 |
+
|
1352 |
+
$this->assertEquals(['first' => 'Taylor', 'email' => 'taylorotwell@gmail.com'], $data->only(['first', 'email'])->all());
|
1353 |
+
$this->assertEquals(['first' => 'Taylor', 'email' => 'taylorotwell@gmail.com'], $data->only('first', 'email')->all());
|
1354 |
+
}
|
1355 |
+
|
1356 |
+
public function testGettingAvgItemsFromCollection()
|
1357 |
+
{
|
1358 |
+
$c = new Collection([(object) ['foo' => 10], (object) ['foo' => 20]]);
|
1359 |
+
$this->assertEquals(15, $c->avg(function ($item) {
|
1360 |
+
return $item->foo;
|
1361 |
+
}));
|
1362 |
+
$this->assertEquals(15, $c->avg('foo'));
|
1363 |
+
|
1364 |
+
$c = new Collection([['foo' => 10], ['foo' => 20]]);
|
1365 |
+
$this->assertEquals(15, $c->avg('foo'));
|
1366 |
+
|
1367 |
+
$c = new Collection([1, 2, 3, 4, 5]);
|
1368 |
+
$this->assertEquals(3, $c->avg());
|
1369 |
+
|
1370 |
+
$c = new Collection();
|
1371 |
+
$this->assertNull($c->avg());
|
1372 |
+
}
|
1373 |
+
|
1374 |
+
public function testJsonSerialize()
|
1375 |
+
{
|
1376 |
+
$c = new Collection([
|
1377 |
+
new TestArrayableObject(),
|
1378 |
+
new TestJsonableObject(),
|
1379 |
+
new TestJsonSerializeObject(),
|
1380 |
+
'baz',
|
1381 |
+
]);
|
1382 |
+
|
1383 |
+
$this->assertSame([
|
1384 |
+
['foo' => 'bar'],
|
1385 |
+
['foo' => 'bar'],
|
1386 |
+
['foo' => 'bar'],
|
1387 |
+
'baz',
|
1388 |
+
], $c->jsonSerialize());
|
1389 |
+
}
|
1390 |
+
|
1391 |
+
public function testCombineWithArray()
|
1392 |
+
{
|
1393 |
+
$expected = [
|
1394 |
+
1 => 4,
|
1395 |
+
2 => 5,
|
1396 |
+
3 => 6,
|
1397 |
+
];
|
1398 |
+
|
1399 |
+
$c = new Collection(array_keys($expected));
|
1400 |
+
$actual = $c->combine(array_values($expected))->toArray();
|
1401 |
+
|
1402 |
+
$this->assertSame($expected, $actual);
|
1403 |
+
}
|
1404 |
+
|
1405 |
+
public function testCombineWithCollection()
|
1406 |
+
{
|
1407 |
+
$expected = [
|
1408 |
+
1 => 4,
|
1409 |
+
2 => 5,
|
1410 |
+
3 => 6,
|
1411 |
+
];
|
1412 |
+
|
1413 |
+
$keyCollection = new Collection(array_keys($expected));
|
1414 |
+
$valueCollection = new Collection(array_values($expected));
|
1415 |
+
$actual = $keyCollection->combine($valueCollection)->toArray();
|
1416 |
+
|
1417 |
+
$this->assertSame($expected, $actual);
|
1418 |
+
}
|
1419 |
+
|
1420 |
+
public function testReduce()
|
1421 |
+
{
|
1422 |
+
$data = new Collection([1, 2, 3]);
|
1423 |
+
$this->assertEquals(6, $data->reduce(function ($carry, $element) {
|
1424 |
+
return $carry += $element;
|
1425 |
+
}));
|
1426 |
+
}
|
1427 |
+
|
1428 |
+
/**
|
1429 |
+
* @expectedException InvalidArgumentException
|
1430 |
+
*/
|
1431 |
+
public function testRandomThrowsAnExceptionUsingAmountBiggerThanCollectionSize()
|
1432 |
+
{
|
1433 |
+
$data = new Collection([1, 2, 3]);
|
1434 |
+
$data->random(4);
|
1435 |
+
}
|
1436 |
+
|
1437 |
+
public function testPipe()
|
1438 |
+
{
|
1439 |
+
$collection = new Collection([1, 2, 3]);
|
1440 |
+
|
1441 |
+
$this->assertEquals(6, $collection->pipe(function ($collection) {
|
1442 |
+
return $collection->sum();
|
1443 |
+
}));
|
1444 |
+
}
|
1445 |
+
|
1446 |
+
public function testMedianValueWithArrayCollection()
|
1447 |
+
{
|
1448 |
+
$collection = new Collection([1, 2, 2, 4]);
|
1449 |
+
|
1450 |
+
$this->assertEquals(2, $collection->median());
|
1451 |
+
}
|
1452 |
+
|
1453 |
+
public function testMedianValueByKey()
|
1454 |
+
{
|
1455 |
+
$collection = new Collection([
|
1456 |
+
(object) ['foo' => 1],
|
1457 |
+
(object) ['foo' => 2],
|
1458 |
+
(object) ['foo' => 2],
|
1459 |
+
(object) ['foo' => 4],
|
1460 |
+
]);
|
1461 |
+
$this->assertEquals(2, $collection->median('foo'));
|
1462 |
+
}
|
1463 |
+
|
1464 |
+
public function testEvenMedianCollection()
|
1465 |
+
{
|
1466 |
+
$collection = new Collection([
|
1467 |
+
(object) ['foo' => 0],
|
1468 |
+
(object) ['foo' => 3],
|
1469 |
+
]);
|
1470 |
+
$this->assertEquals(1.5, $collection->median('foo'));
|
1471 |
+
}
|
1472 |
+
|
1473 |
+
public function testMedianOutOfOrderCollection()
|
1474 |
+
{
|
1475 |
+
$collection = new Collection([
|
1476 |
+
(object) ['foo' => 0],
|
1477 |
+
(object) ['foo' => 5],
|
1478 |
+
(object) ['foo' => 3],
|
1479 |
+
]);
|
1480 |
+
$this->assertEquals(3, $collection->median('foo'));
|
1481 |
+
}
|
1482 |
+
|
1483 |
+
public function testMedianOnEmptyCollectionReturnsNull()
|
1484 |
+
{
|
1485 |
+
$collection = new Collection();
|
1486 |
+
$this->assertNull($collection->median());
|
1487 |
+
}
|
1488 |
+
|
1489 |
+
public function testModeOnNullCollection()
|
1490 |
+
{
|
1491 |
+
$collection = new Collection();
|
1492 |
+
$this->assertNull($collection->mode());
|
1493 |
+
}
|
1494 |
+
|
1495 |
+
public function testMode()
|
1496 |
+
{
|
1497 |
+
$collection = new Collection([1, 2, 3, 4, 4, 5]);
|
1498 |
+
$this->assertEquals([4], $collection->mode());
|
1499 |
+
}
|
1500 |
+
|
1501 |
+
public function testModeValueByKey()
|
1502 |
+
{
|
1503 |
+
$collection = new Collection([
|
1504 |
+
(object) ['foo' => 1],
|
1505 |
+
(object) ['foo' => 1],
|
1506 |
+
(object) ['foo' => 2],
|
1507 |
+
(object) ['foo' => 4],
|
1508 |
+
]);
|
1509 |
+
$this->assertEquals([1], $collection->mode('foo'));
|
1510 |
+
}
|
1511 |
+
|
1512 |
+
public function testWithMultipleModeValues()
|
1513 |
+
{
|
1514 |
+
$collection = new Collection([1, 2, 2, 1]);
|
1515 |
+
$this->assertEquals([1, 2], $collection->mode());
|
1516 |
+
}
|
1517 |
+
|
1518 |
+
public function testSliceOffset()
|
1519 |
+
{
|
1520 |
+
$collection = new Collection([1, 2, 3, 4, 5, 6, 7, 8]);
|
1521 |
+
$this->assertEquals([4, 5, 6, 7, 8], $collection->slice(3)->values()->toArray());
|
1522 |
+
}
|
1523 |
+
|
1524 |
+
public function testSliceNegativeOffset()
|
1525 |
+
{
|
1526 |
+
$collection = new Collection([1, 2, 3, 4, 5, 6, 7, 8]);
|
1527 |
+
$this->assertEquals([6, 7, 8], $collection->slice(-3)->values()->toArray());
|
1528 |
+
}
|
1529 |
+
|
1530 |
+
public function testSliceOffsetAndLength()
|
1531 |
+
{
|
1532 |
+
$collection = new Collection([1, 2, 3, 4, 5, 6, 7, 8]);
|
1533 |
+
$this->assertEquals([4, 5, 6], $collection->slice(3, 3)->values()->toArray());
|
1534 |
+
}
|
1535 |
+
|
1536 |
+
public function testSliceOffsetAndNegativeLength()
|
1537 |
+
{
|
1538 |
+
$collection = new Collection([1, 2, 3, 4, 5, 6, 7, 8]);
|
1539 |
+
$this->assertEquals([4, 5, 6, 7], $collection->slice(3, -1)->values()->toArray());
|
1540 |
+
}
|
1541 |
+
|
1542 |
+
public function testSliceNegativeOffsetAndLength()
|
1543 |
+
{
|
1544 |
+
$collection = new Collection([1, 2, 3, 4, 5, 6, 7, 8]);
|
1545 |
+
$this->assertEquals([4, 5, 6], $collection->slice(-5, 3)->values()->toArray());
|
1546 |
+
}
|
1547 |
+
|
1548 |
+
public function testSliceNegativeOffsetAndNegativeLength()
|
1549 |
+
{
|
1550 |
+
$collection = new Collection([1, 2, 3, 4, 5, 6, 7, 8]);
|
1551 |
+
$this->assertEquals([3, 4, 5, 6], $collection->slice(-6, -2)->values()->toArray());
|
1552 |
+
}
|
1553 |
+
|
1554 |
+
public function testCollectonFromTraversable()
|
1555 |
+
{
|
1556 |
+
$collection = new Collection(new \ArrayObject([1, 2, 3]));
|
1557 |
+
$this->assertEquals([1, 2, 3], $collection->toArray());
|
1558 |
+
}
|
1559 |
+
|
1560 |
+
public function testCollectonFromTraversableWithKeys()
|
1561 |
+
{
|
1562 |
+
$collection = new Collection(new \ArrayObject(['foo' => 1, 'bar' => 2, 'baz' => 3]));
|
1563 |
+
$this->assertEquals(['foo' => 1, 'bar' => 2, 'baz' => 3], $collection->toArray());
|
1564 |
+
}
|
1565 |
+
|
1566 |
+
public function testSplitCollectionWithADivisableCount()
|
1567 |
+
{
|
1568 |
+
$collection = new Collection(['a', 'b', 'c', 'd']);
|
1569 |
+
|
1570 |
+
$this->assertEquals(
|
1571 |
+
[['a', 'b'], ['c', 'd']],
|
1572 |
+
$collection->split(2)->map(function (Collection $chunk) {
|
1573 |
+
return $chunk->values()->toArray();
|
1574 |
+
})->toArray()
|
1575 |
+
);
|
1576 |
+
}
|
1577 |
+
|
1578 |
+
public function testSplitCollectionWithAnUndivisableCount()
|
1579 |
+
{
|
1580 |
+
$collection = new Collection(['a', 'b', 'c']);
|
1581 |
+
|
1582 |
+
$this->assertEquals(
|
1583 |
+
[['a', 'b'], ['c']],
|
1584 |
+
$collection->split(2)->map(function (Collection $chunk) {
|
1585 |
+
return $chunk->values()->toArray();
|
1586 |
+
})->toArray()
|
1587 |
+
);
|
1588 |
+
}
|
1589 |
+
|
1590 |
+
public function testSplitCollectionWithCountLessThenDivisor()
|
1591 |
+
{
|
1592 |
+
$collection = new Collection(['a']);
|
1593 |
+
|
1594 |
+
$this->assertEquals(
|
1595 |
+
[['a']],
|
1596 |
+
$collection->split(2)->map(function (Collection $chunk) {
|
1597 |
+
return $chunk->values()->toArray();
|
1598 |
+
})->toArray()
|
1599 |
+
);
|
1600 |
+
}
|
1601 |
+
|
1602 |
+
public function testSplitEmptyCollection()
|
1603 |
+
{
|
1604 |
+
$collection = new Collection();
|
1605 |
+
|
1606 |
+
$this->assertEquals(
|
1607 |
+
[],
|
1608 |
+
$collection->split(2)->map(function (Collection $chunk) {
|
1609 |
+
return $chunk->values()->toArray();
|
1610 |
+
})->toArray()
|
1611 |
+
);
|
1612 |
+
}
|
1613 |
+
|
1614 |
+
public function testPrioritize() {
|
1615 |
+
$collection = new Collection( [ 1, 2, 3, 4, 5 ] );
|
1616 |
+
|
1617 |
+
$filter = function( $item ) { return $item > 3; };
|
1618 |
+
|
1619 |
+
$this->assertEquals(
|
1620 |
+
[ 4, 5, 1, 2, 3 ],
|
1621 |
+
$collection->prioritize( $filter )->toArray()
|
1622 |
+
);
|
1623 |
+
|
1624 |
+
$collection = new Collection( [ 'first', 'second', 'third' ] );
|
1625 |
+
|
1626 |
+
$filter = function( $item ) { return $item === 'second'; };
|
1627 |
+
|
1628 |
+
$this->assertEquals(
|
1629 |
+
[ 'second', 'first', 'third' ],
|
1630 |
+
$collection->prioritize( $filter )->toArray()
|
1631 |
+
);
|
1632 |
+
}
|
1633 |
+
|
1634 |
+
public function testAssocToPair() {
|
1635 |
+
$collection = new Collection ( [ 'name' => 'wpml', 'type' => 'plugin' ] );
|
1636 |
+
|
1637 |
+
$this->assertEquals(
|
1638 |
+
[ [ 'name', 'wpml' ], [ 'type', 'plugin' ] ],
|
1639 |
+
$collection->assocToPair()->toArray()
|
1640 |
+
);
|
1641 |
+
}
|
1642 |
+
|
1643 |
+
public function testPairToAssoc() {
|
1644 |
+
$collection = new Collection ( [ [ 'name', 'wpml' ], [ 'type', 'plugin' ] ] );
|
1645 |
+
|
1646 |
+
$this->assertEquals(
|
1647 |
+
[ 'name' => 'wpml', 'type' => 'plugin' ],
|
1648 |
+
$collection->pairToAssoc()->toArray()
|
1649 |
+
);
|
1650 |
+
}
|
1651 |
+
|
1652 |
+
public function testEachWithTimeout() {
|
1653 |
+
$timeout = 10;
|
1654 |
+
|
1655 |
+
$c = new Collection( $original = [ 1, 2, 'bar', 'baz' ] );
|
1656 |
+
|
1657 |
+
$result = [];
|
1658 |
+
$unProcessed = $c->eachWithTimeout( function ( $item ) use ( &$result ) {
|
1659 |
+
$result[] = $item;
|
1660 |
+
}, $timeout );
|
1661 |
+
$this->assertEquals( $original, $result );
|
1662 |
+
$this->assertTrue( $unProcessed->isEmpty() );
|
1663 |
+
|
1664 |
+
$timeout = - 1; // force a timeout
|
1665 |
+
$result = [];
|
1666 |
+
$unProcessed = $c->eachWithTimeout( function ( $item ) use ( &$result ) {
|
1667 |
+
$result[] = $item;
|
1668 |
+
}, $timeout );
|
1669 |
+
$this->assertCount( 0, $result );
|
1670 |
+
$this->assertEquals( $original, $unProcessed->toArray() );
|
1671 |
+
}
|
1672 |
+
|
1673 |
+
}
|
1674 |
+
|
1675 |
+
class TestAccessorEloquentTestStub
|
1676 |
+
{
|
1677 |
+
protected $attributes = [];
|
1678 |
+
|
1679 |
+
public function __construct($attributes)
|
1680 |
+
{
|
1681 |
+
$this->attributes = $attributes;
|
1682 |
+
}
|
1683 |
+
|
1684 |
+
public function __get($attribute)
|
1685 |
+
{
|
1686 |
+
$accessor = 'get'.lcfirst($attribute).'Attribute';
|
1687 |
+
if (method_exists($this, $accessor)) {
|
1688 |
+
return $this->$accessor();
|
1689 |
+
}
|
1690 |
+
|
1691 |
+
return $this->$attribute;
|
1692 |
+
}
|
1693 |
+
|
1694 |
+
public function __isset($attribute)
|
1695 |
+
{
|
1696 |
+
$accessor = 'get'.lcfirst($attribute).'Attribute';
|
1697 |
+
|
1698 |
+
if (method_exists($this, $accessor)) {
|
1699 |
+
return ! is_null($this->$accessor());
|
1700 |
+
}
|
1701 |
+
|
1702 |
+
return isset($this->$attribute);
|
1703 |
+
}
|
1704 |
+
|
1705 |
+
public function getSomeAttribute()
|
1706 |
+
{
|
1707 |
+
return $this->attributes['some'];
|
1708 |
+
}
|
1709 |
+
}
|
1710 |
+
|
1711 |
+
class TestArrayAccessImplementation implements ArrayAccess
|
1712 |
+
{
|
1713 |
+
private $arr;
|
1714 |
+
|
1715 |
+
public function __construct($arr)
|
1716 |
+
{
|
1717 |
+
$this->arr = $arr;
|
1718 |
+
}
|
1719 |
+
|
1720 |
+
public function offsetExists($offset)
|
1721 |
+
{
|
1722 |
+
return isset($this->arr[$offset]);
|
1723 |
+
}
|
1724 |
+
|
1725 |
+
public function offsetGet($offset)
|
1726 |
+
{
|
1727 |
+
return $this->arr[$offset];
|
1728 |
+
}
|
1729 |
+
|
1730 |
+
public function offsetSet($offset, $value)
|
1731 |
+
{
|
1732 |
+
$this->arr[$offset] = $value;
|
1733 |
+
}
|
1734 |
+
|
1735 |
+
public function offsetUnset($offset)
|
1736 |
+
{
|
1737 |
+
unset($this->arr[$offset]);
|
1738 |
+
}
|
1739 |
+
}
|
1740 |
+
|
1741 |
+
class TestArrayableObject implements Arrayable
|
1742 |
+
{
|
1743 |
+
public function toArray()
|
1744 |
+
{
|
1745 |
+
return ['foo' => 'bar'];
|
1746 |
+
}
|
1747 |
+
}
|
1748 |
+
|
1749 |
+
class TestJsonableObject implements Jsonable
|
1750 |
+
{
|
1751 |
+
public function toJson($options = 0)
|
1752 |
+
{
|
1753 |
+
return '{"foo":"bar"}';
|
1754 |
+
}
|
1755 |
+
}
|
1756 |
+
|
1757 |
+
class TestJsonSerializeObject implements JsonSerializable
|
1758 |
+
{
|
1759 |
+
public function jsonSerialize()
|
1760 |
+
{
|
1761 |
+
return ['foo' => 'bar'];
|
1762 |
+
}
|
1763 |
+
}
|
addons/vendor/wpml/collect/tests/bootstrap.php
ADDED
@@ -0,0 +1,5 @@
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
require __DIR__.'/../vendor/autoload.php';
|
4 |
+
|
5 |
+
date_default_timezone_set('UTC');
|
addons/vendor/wpml/core-api
ADDED
@@ -0,0 +1 @@
|
|
|
1 |
+
Subproject commit 369cfd53dba15e4dceb55e0e0458c16a5a142eab
|
addons/vendor/wpml/fp
ADDED
@@ -0,0 +1 @@
|
|
|
1 |
+
Subproject commit 5f233620422988ca47f3180d2fc1c2aa18191bee
|
addons/vendor/wpml/wp
ADDED
@@ -0,0 +1 @@
|
|
|
1 |
+
Subproject commit dc2fbeb965133f5e569f51009b919a585a5fc1a9
|
addons/vendor/wpml/wpml-dependencies
ADDED
@@ -0,0 +1 @@
|
|
|
1 |
+
Subproject commit bd11271851a380365a6d97c5920c4cd089a07427
|
classes/AdminDashboard/Hooks.php
CHANGED
@@ -2,7 +2,7 @@
|
|
2 |
|
3 |
namespace WCML\AdminDashboard;
|
4 |
|
5 |
-
use
|
6 |
use wpdb;
|
7 |
use IWPML_DIC_Action;
|
8 |
use IWPML_Backend_Action;
|
@@ -15,7 +15,7 @@ class Hooks implements IWPML_Backend_Action, IWPML_DIC_Action {
|
|
15 |
/** @var wpdb $wpdb */
|
16 |
private $wpdb;
|
17 |
|
18 |
-
public function __construct(
|
19 |
$this->sitepress = $sitepress;
|
20 |
$this->wpdb = $wpdb;
|
21 |
}
|
2 |
|
3 |
namespace WCML\AdminDashboard;
|
4 |
|
5 |
+
use WPML\Core\ISitePress;
|
6 |
use wpdb;
|
7 |
use IWPML_DIC_Action;
|
8 |
use IWPML_Backend_Action;
|
15 |
/** @var wpdb $wpdb */
|
16 |
private $wpdb;
|
17 |
|
18 |
+
public function __construct( ISitePress $sitepress, wpdb $wpdb ) {
|
19 |
$this->sitepress = $sitepress;
|
20 |
$this->wpdb = $wpdb;
|
21 |
}
|
classes/AdminNotices/CachePlugins.php
CHANGED
@@ -30,8 +30,8 @@ class CachePlugins implements \IWPML_Backend_Action, \IWPML_DIC_Action {
|
|
30 |
}
|
31 |
|
32 |
public function addNotice() {
|
33 |
-
$text = '<h2>' . __( 'WooCommerce Multilingual detected an active cache plugin on your site.', 'woocommerce-multilingual' ) . '</h2>';
|
34 |
-
$text .= '<p>' . __( 'Caching may cause currency display issues for your customers if you are using the
|
35 |
$text .= '<p>' . __( 'To avoid this, set your cache plugin to not cache pages for visitors that have a cookie set in their browser.', 'woocommerce-multilingual' ) . '</p>';
|
36 |
|
37 |
$notice = $this->notices->create_notice( self::NOTICE_ID, $text );
|
@@ -46,6 +46,10 @@ class CachePlugins implements \IWPML_Backend_Action, \IWPML_DIC_Action {
|
|
46 |
* @return bool
|
47 |
*/
|
48 |
private static function hasActiveCachePlugin() {
|
|
|
|
|
|
|
|
|
49 |
// $isActive :: ( array, string ) -> bool
|
50 |
$isActive = pipe(
|
51 |
Fns::nthArg( 1 ), // array index
|
30 |
}
|
31 |
|
32 |
public function addNotice() {
|
33 |
+
$text = '<h2>' . __( 'WooCommerce Multilingual & Multicurrency detected an active cache plugin on your site.', 'woocommerce-multilingual' ) . '</h2>';
|
34 |
+
$text .= '<p>' . __( 'Caching may cause currency display issues for your customers if you are using the multicurrency feature.', 'woocommerce-multilingual' ) . '</p>';
|
35 |
$text .= '<p>' . __( 'To avoid this, set your cache plugin to not cache pages for visitors that have a cookie set in their browser.', 'woocommerce-multilingual' ) . '</p>';
|
36 |
|
37 |
$notice = $this->notices->create_notice( self::NOTICE_ID, $text );
|
46 |
* @return bool
|
47 |
*/
|
48 |
private static function hasActiveCachePlugin() {
|
49 |
+
if ( ! function_exists( 'is_plugin_active' ) ) {
|
50 |
+
include_once( ABSPATH . 'wp-admin/includes/plugin.php' );
|
51 |
+
}
|
52 |
+
|
53 |
// $isActive :: ( array, string ) -> bool
|
54 |
$isActive = pipe(
|
55 |
Fns::nthArg( 1 ), // array index
|
classes/AdminNotices/MultiCurrencyMissing.php
CHANGED
@@ -43,8 +43,8 @@ class MultiCurrencyMissing implements \IWPML_Backend_Action, \IWPML_DIC_Action {
|
|
43 |
*/
|
44 |
public function addNotice() {
|
45 |
$text = '<h2>' . __( "You haven't added any secondary currencies", 'woocommerce-multilingual' ) . '</h2>';
|
46 |
-
$text .= '<p>' . __( "Please add another currency to fully utilize
|
47 |
-
$text .= '<a href="' . admin_url( 'admin.php?page=wpml-wcml&tab=multi-currency' ) . '">' . __( 'Configure
|
48 |
|
49 |
$notice = $this->notices->create_notice( self::NOTICE_ID, $text );
|
50 |
$notice->set_css_class_types( 'notice-warning' );
|
43 |
*/
|
44 |
public function addNotice() {
|
45 |
$text = '<h2>' . __( "You haven't added any secondary currencies", 'woocommerce-multilingual' ) . '</h2>';
|
46 |
+
$text .= '<p>' . __( "Please add another currency to fully utilize multicurrency mode. If you do not need multiple currencies, you can disable this setting to improve your site's performance.", 'woocommerce-multilingual' ) . '</p>';
|
47 |
+
$text .= '<a href="' . admin_url( 'admin.php?page=wpml-wcml&tab=multi-currency' ) . '">' . __( 'Configure multicurrency mode', 'woocommerce-multilingual' ) . '</a>';
|
48 |
|
49 |
$notice = $this->notices->create_notice( self::NOTICE_ID, $text );
|
50 |
$notice->set_css_class_types( 'notice-warning' );
|
classes/AdminNotices/Review.php
CHANGED
@@ -2,14 +2,15 @@
|
|
2 |
|
3 |
namespace WCML\AdminNotices;
|
4 |
|
|
|
5 |
use WPML_Notices;
|
6 |
use IWPML_Backend_Action;
|
7 |
use IWPML_Frontend_Action;
|
8 |
use IWPML_DIC_Action;
|
9 |
use wpdb;
|
10 |
-
use
|
11 |
|
12 |
-
class Review implements IWPML_Backend_Action, IWPML_Frontend_Action, IWPML_DIC_Action {
|
13 |
|
14 |
const OPTION_NAME = 'wcml-rate-notice';
|
15 |
|
@@ -29,7 +30,7 @@ class Review implements IWPML_Backend_Action, IWPML_Frontend_Action, IWPML_DIC_A
|
|
29 |
* @param wpdb $wpdb
|
30 |
* @param SitePress $sitepress
|
31 |
*/
|
32 |
-
public function __construct( WPML_Notices $wpmlNotices, wpdb $wpdb,
|
33 |
$this->wpmlNotices = $wpmlNotices;
|
34 |
$this->wpdb = $wpdb;
|
35 |
$this->sitepress = $sitepress;
|
@@ -60,7 +61,7 @@ class Review implements IWPML_Backend_Action, IWPML_Frontend_Action, IWPML_DIC_A
|
|
60 |
$notice->set_dismissible( true );
|
61 |
|
62 |
$reviewLink = 'https://wordpress.org/support/plugin/woocommerce-multilingual/reviews/?filter=5#new-post';
|
63 |
-
$reviewButton = $this->wpmlNotices->get_new_notice_action( __( 'Review WooCommerce Multilingual', 'woocommerce-multilingual' ), $reviewLink, false, false, true );
|
64 |
$notice->add_action( $reviewButton );
|
65 |
|
66 |
$notice->set_restrict_to_screen_ids( RestrictedScreens::get() );
|
@@ -76,7 +77,7 @@ class Review implements IWPML_Backend_Action, IWPML_Frontend_Action, IWPML_DIC_A
|
|
76 |
*/
|
77 |
private function getNoticeText() {
|
78 |
$text = '<h2>';
|
79 |
-
$text .= __( 'Congrats! You\'ve just earned some money using WooCommerce Multilingual.', 'woocommerce-multilingual' );
|
80 |
$text .= '</h2>';
|
81 |
|
82 |
$text .= '<p>';
|
2 |
|
3 |
namespace WCML\AdminNotices;
|
4 |
|
5 |
+
use WCML\StandAlone\IStandAloneAction;
|
6 |
use WPML_Notices;
|
7 |
use IWPML_Backend_Action;
|
8 |
use IWPML_Frontend_Action;
|
9 |
use IWPML_DIC_Action;
|
10 |
use wpdb;
|
11 |
+
use WPML\Core\ISitePress;
|
12 |
|
13 |
+
class Review implements IWPML_Backend_Action, IWPML_Frontend_Action, IWPML_DIC_Action, IStandAloneAction {
|
14 |
|
15 |
const OPTION_NAME = 'wcml-rate-notice';
|
16 |
|
30 |
* @param wpdb $wpdb
|
31 |
* @param SitePress $sitepress
|
32 |
*/
|
33 |
+
public function __construct( WPML_Notices $wpmlNotices, wpdb $wpdb, ISitePress $sitepress ) {
|
34 |
$this->wpmlNotices = $wpmlNotices;
|
35 |
$this->wpdb = $wpdb;
|
36 |
$this->sitepress = $sitepress;
|
61 |
$notice->set_dismissible( true );
|
62 |
|
63 |
$reviewLink = 'https://wordpress.org/support/plugin/woocommerce-multilingual/reviews/?filter=5#new-post';
|
64 |
+
$reviewButton = $this->wpmlNotices->get_new_notice_action( __( 'Review WooCommerce Multilingual & Multicurrency', 'woocommerce-multilingual' ), $reviewLink, false, false, true );
|
65 |
$notice->add_action( $reviewButton );
|
66 |
|
67 |
$notice->set_restrict_to_screen_ids( RestrictedScreens::get() );
|
77 |
*/
|
78 |
private function getNoticeText() {
|
79 |
$text = '<h2>';
|
80 |
+
$text .= __( 'Congrats! You\'ve just earned some money using WooCommerce Multilingual & Multicurrency.', 'woocommerce-multilingual' );
|
81 |
$text .= '</h2>';
|
82 |
|
83 |
$text .= '<p>';
|
classes/Attributes/LookupFilters.php
ADDED
@@ -0,0 +1,36 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace WCML\Attributes;
|
4 |
+
|
5 |
+
class LookupFilters implements \IWPML_Action {
|
6 |
+
|
7 |
+
/** @var \SitePress $sitepress */
|
8 |
+
private $sitepress;
|
9 |
+
|
10 |
+
/** @var \wpdb $wpdb */
|
11 |
+
private $wpdb;
|
12 |
+
|
13 |
+
public function __construct( \SitePress $sitepress, \wpdb $wpdb ) {
|
14 |
+
$this->sitepress = $sitepress;
|
15 |
+
$this->wpdb = $wpdb;
|
16 |
+
}
|
17 |
+
|
18 |
+
public function add_hooks() {
|
19 |
+
add_filter( 'woocommerce_get_filtered_term_product_counts_query', [ $this, 'adjustAttributeWidgetCount' ] );
|
20 |
+
}
|
21 |
+
|
22 |
+
/**
|
23 |
+
* @param array $query
|
24 |
+
*
|
25 |
+
* @return array
|
26 |
+
*/
|
27 |
+
public function adjustAttributeWidgetCount( $query ) {
|
28 |
+
|
29 |
+
$query['join'] .= " INNER JOIN {$this->wpdb->prefix}icl_translations AS icl_t ON {$this->wpdb->posts}.ID = icl_t.element_id
|
30 |
+
AND icl_t.element_type = 'post_product'";
|
31 |
+
|
32 |
+
$query['where'] .= $this->wpdb->prepare(" AND icl_t.language_code = %s", $this->sitepress->get_current_language() );
|
33 |
+
|
34 |
+
return $query;
|
35 |
+
}
|
36 |
+
}
|
classes/Attributes/LookupFiltersFactory.php
ADDED
@@ -0,0 +1,31 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace WCML\Attributes;
|
4 |
+
|
5 |
+
class LookupFiltersFactory implements \IWPML_Frontend_Action_Loader {
|
6 |
+
|
7 |
+
/**
|
8 |
+
* @return \IWPML_Action|null
|
9 |
+
*/
|
10 |
+
public function create() {
|
11 |
+
/**
|
12 |
+
* @var \SitePress $sitepress
|
13 |
+
* @var \wpdb $wpdb
|
14 |
+
*/
|
15 |
+
global $sitepress, $wpdb;
|
16 |
+
|
17 |
+
if ( self::isEnabled() ) {
|
18 |
+
return new LookupFilters( $sitepress, $wpdb );
|
19 |
+
}
|
20 |
+
|
21 |
+
return null;
|
22 |
+
}
|
23 |
+
|
24 |
+
/**
|
25 |
+
* @return bool
|
26 |
+
*/
|
27 |
+
public static function isEnabled() {
|
28 |
+
return 'yes' === get_option( 'woocommerce_attribute_lookup_enabled' );
|
29 |
+
}
|
30 |
+
|
31 |
+
}
|
classes/Attributes/LookupTable.php
ADDED
@@ -0,0 +1,108 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace WCML\Attributes;
|
4 |
+
|
5 |
+
use Automattic\WooCommerce\Internal\ProductAttributesLookup\LookupDataStore as ProductAttributesLookupDataStore;
|
6 |
+
use WPML\FP\Obj;
|
7 |
+
use WPML\LIB\WP\Hooks;
|
8 |
+
use function WPML\FP\spreadArgs;
|
9 |
+
use WPML\FP\Fns;
|
10 |
+
|
11 |
+
class LookupTable implements \IWPML_Action {
|
12 |
+
|
13 |
+
/** @var \SitePress $sitepress */
|
14 |
+
private $sitepress;
|
15 |
+
|
16 |
+
/**
|
17 |
+
* @param \SitePress $sitepress
|
18 |
+
*/
|
19 |
+
public function __construct( \SitePress $sitepress ) {
|
20 |
+
$this->sitepress = $sitepress;
|
21 |
+
}
|
22 |
+
|
23 |
+
public function add_hooks() {
|
24 |
+
Hooks::onAction( 'save_post' )
|
25 |
+
->then( spreadArgs( [ $this, 'triggerUpdateForTranslations' ] ) );
|
26 |
+
|
27 |
+
// For defered updates, we adjust terms filter just before the action scheduler.
|
28 |
+
Hooks::onAction( 'woocommerce_run_product_attribute_lookup_update_callback', 5 )
|
29 |
+
->then( [ $this, 'adjustTermsFilters' ] );
|
30 |
+
|
31 |
+
// When regenerating the table we need all products and all terms.
|
32 |
+
Hooks::onFilter( 'woocommerce_attribute_lookup_regeneration_step_size' )
|
33 |
+
->then( spreadArgs( Fns::tap( [ $this, 'regenerateTable' ] ) ) );
|
34 |
+
}
|
35 |
+
|
36 |
+
/**
|
37 |
+
* @param int $productId
|
38 |
+
*/
|
39 |
+
public function triggerUpdateForTranslations( $productId ) {
|
40 |
+
if (
|
41 |
+
'product' === get_post_type( $productId )
|
42 |
+
&& 'publish' === get_post_status( $productId )
|
43 |
+
&& ! $this->sitepress->is_original_content_filter( false, $productId, 'post_product' )
|
44 |
+
) {
|
45 |
+
Hooks::onAction( 'shutdown' )
|
46 |
+
->then( function() use ( $productId ) {
|
47 |
+
// For direct updates, we adjust terms filters just before triggering the update.
|
48 |
+
$hasTermsClausesFilter = $this->adjustTermsFilters();
|
49 |
+
|
50 |
+
wc_get_container()->get( ProductAttributesLookupDataStore::class )->on_product_changed( $productId );
|
51 |
+
|
52 |
+
$this->restoreTermsFilters( $hasTermsClausesFilter );
|
53 |
+
} );
|
54 |
+
}
|
55 |
+
}
|
56 |
+
|
57 |
+
/**
|
58 |
+
* @return bool
|
59 |
+
*/
|
60 |
+
public function adjustTermsFilters() {
|
61 |
+
add_filter( 'woocommerce_product_get_attributes', [ $this, 'translateAttributeOptions' ], 10, 2 );
|
62 |
+
|
63 |
+
return remove_filter( 'terms_clauses', [ $this->sitepress, 'terms_clauses' ] );
|
64 |
+
}
|
65 |
+
|
66 |
+
/**
|
67 |
+
* @param bool $hasTermsClausesFilter
|
68 |
+
*/
|
69 |
+
private function restoreTermsFilters( $hasTermsClausesFilter ) {
|
70 |
+
if ( $hasTermsClausesFilter ) {
|
71 |
+
add_filter( 'terms_clauses', [ $this->sitepress, 'terms_clauses' ], 10, 3 );
|
72 |
+
}
|
73 |
+
|
74 |
+
remove_filter( 'woocommerce_product_get_attributes', [ $this, 'translateAttributeOptions' ] );
|
75 |
+
}
|
76 |
+
|
77 |
+
/**
|
78 |
+
* @param WC_Product_Attribute[] $attrs
|
79 |
+
* @param WC_Product $product
|
80 |
+
*
|
81 |
+
* @return WC_Product_Attribute[]
|
82 |
+
*/
|
83 |
+
public function translateAttributeOptions( $attrs, $product ) {
|
84 |
+
$language = $this->sitepress->get_language_for_element(
|
85 |
+
$product->get_id(),
|
86 |
+
'post_product'
|
87 |
+
);
|
88 |
+
|
89 |
+
if ( $language && is_array( $attrs ) ) {
|
90 |
+
foreach ( $attrs as $taxonomy => $attr ) {
|
91 |
+
$options = $attr->get_options();
|
92 |
+
foreach ( $options as $index => $option ) {
|
93 |
+
$options[ $index ] = $this->sitepress->get_object_id( $option, $taxonomy, false, $language );
|
94 |
+
}
|
95 |
+
$attr->set_options( $options );
|
96 |
+
}
|
97 |
+
}
|
98 |
+
|
99 |
+
return $attrs;
|
100 |
+
}
|
101 |
+
|
102 |
+
public function regenerateTable() {
|
103 |
+
$this->adjustTermsFilters();
|
104 |
+
|
105 |
+
add_filter( 'woocommerce_product_object_query_args', Obj::assoc( 'suppress_filters', true ) );
|
106 |
+
}
|
107 |
+
|
108 |
+
}
|
classes/Attributes/LookupTableFactory.php
ADDED
@@ -0,0 +1,30 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace WCML\Attributes;
|
4 |
+
|
5 |
+
class LookupTableFactory implements \IWPML_Backend_Action_Loader, \IWPML_Frontend_Action_Loader {
|
6 |
+
|
7 |
+
const MIN_WC_VERSION = '6.3';
|
8 |
+
|
9 |
+
/**
|
10 |
+
* @return \IWPML_Action|null
|
11 |
+
*/
|
12 |
+
public function create() {
|
13 |
+
/** @var \SitePress $sitepress */
|
14 |
+
global $sitepress;
|
15 |
+
|
16 |
+
if ( self::hasFeature() ) {
|
17 |
+
return new LookupTable( $sitepress );
|
18 |
+
}
|
19 |
+
|
20 |
+
return null;
|
21 |
+
}
|
22 |
+
|
23 |
+
/**
|
24 |
+
* @return bool
|
25 |
+
*/
|
26 |
+
public static function hasFeature() {
|
27 |
+
return defined( 'WC_VERSION' ) && version_compare( WC_VERSION, self::MIN_WC_VERSION, '>=' );
|
28 |
+
}
|
29 |
+
|
30 |
+
}
|
classes/Block/Convert/Hooks.php
CHANGED
@@ -4,7 +4,7 @@ namespace WCML\Block\Convert;
|
|
4 |
|
5 |
use IWPML_DIC_Action;
|
6 |
use IWPML_Frontend_Action;
|
7 |
-
use
|
8 |
use WCML\Rest\Frontend\Language;
|
9 |
use WPML\FP\Just;
|
10 |
use WPML\FP\Str;
|
@@ -17,7 +17,7 @@ class Hooks implements IWPML_Frontend_Action, IWPML_DIC_Action {
|
|
17 |
/** @var Language $frontendRestLang */
|
18 |
private $frontendRestLang;
|
19 |
|
20 |
-
public function __construct(
|
21 |
$this->sitepress = $sitepress;
|
22 |
$this->frontendRestLang = $frontendRestLang;
|
23 |
}
|
4 |
|
5 |
use IWPML_DIC_Action;
|
6 |
use IWPML_Frontend_Action;
|
7 |
+
use WPML\Core\ISitePress;
|
8 |
use WCML\Rest\Frontend\Language;
|
9 |
use WPML\FP\Just;
|
10 |
use WPML\FP\Str;
|
17 |
/** @var Language $frontendRestLang */
|
18 |
private $frontendRestLang;
|
19 |
|
20 |
+
public function __construct( ISitePress $sitepress, Language $frontendRestLang ) {
|
21 |
$this->sitepress = $sitepress;
|
22 |
$this->frontendRestLang = $frontendRestLang;
|
23 |
}
|
classes/Container/Config.php
CHANGED
@@ -14,8 +14,32 @@ class Config {
|
|
14 |
|
15 |
public static function getSharedClasses() {
|
16 |
return [
|
17 |
-
\WCML_Multi_Currency::class,
|
18 |
\WCML_Currencies_Payment_Gateways::class,
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
19 |
];
|
20 |
}
|
21 |
}
|
14 |
|
15 |
public static function getSharedClasses() {
|
16 |
return [
|
|
|
17 |
\WCML_Currencies_Payment_Gateways::class,
|
18 |
+
\WCML_Dependencies::class,
|
19 |
+
\WCML_Exchange_Rates::class,
|
20 |
+
\WCML_Multi_Currency::class,
|
21 |
+
];
|
22 |
+
}
|
23 |
+
|
24 |
+
/**
|
25 |
+
* Replaces global $sitepress with null object.
|
26 |
+
*
|
27 |
+
* @return array
|
28 |
+
*/
|
29 |
+
public static function getAliases() {
|
30 |
+
return [
|
31 |
+
\WPML\Core\ISitePress::class => \WCML\functions\isStandAlone()
|
32 |
+
? \WCML\StandAlone\NullSitePress::class
|
33 |
+
: \SitePress::class,
|
34 |
+
];
|
35 |
+
}
|
36 |
+
|
37 |
+
/**
|
38 |
+
* @return array
|
39 |
+
*/
|
40 |
+
public static function getDelegated() {
|
41 |
+
return [
|
42 |
+
\WCML_Exchange_Rates::class => [ \WCML_Exchange_Rates::class, 'create' ],
|
43 |
];
|
44 |
}
|
45 |
}
|
classes/Email/Settings/Hooks.php
CHANGED
@@ -4,7 +4,7 @@ namespace WCML\Email\Settings;
|
|
4 |
|
5 |
use IWPML_Backend_Action;
|
6 |
use IWPML_DIC_Action;
|
7 |
-
use
|
8 |
use WCML_WC_Strings;
|
9 |
use WPML_Simple_Language_Selector;
|
10 |
|
@@ -18,7 +18,7 @@ class Hooks implements IWPML_Backend_Action, IWPML_DIC_Action {
|
|
18 |
/** @var WCML_WC_Strings */
|
19 |
private $wcmlStrings;
|
20 |
|
21 |
-
public function __construct(
|
22 |
$this->sitepress = $sitepress;
|
23 |
$this->wcmlStrings = $wcmlStrings;
|
24 |
}
|
4 |
|
5 |
use IWPML_Backend_Action;
|
6 |
use IWPML_DIC_Action;
|
7 |
+
use WPML\Core\ISitePress;
|
8 |
use WCML_WC_Strings;
|
9 |
use WPML_Simple_Language_Selector;
|
10 |
|
18 |
/** @var WCML_WC_Strings */
|
19 |
private $wcmlStrings;
|
20 |
|
21 |
+
public function __construct( ISitePress $sitepress, WCML_WC_Strings $wcmlStrings ) {
|
22 |
$this->sitepress = $sitepress;
|
23 |
$this->wcmlStrings = $wcmlStrings;
|
24 |
}
|
classes/HomeScreen/Factory.php
ADDED
@@ -0,0 +1,18 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace WCML\HomeScreen;
|
4 |
+
|
5 |
+
use WCML\StandAlone\IStandAloneAction;
|
6 |
+
|
7 |
+
class Factory implements \IWPML_Backend_Action_Loader, IStandAloneAction {
|
8 |
+
|
9 |
+
/**
|
10 |
+
* @return \IWPML_Action|null
|
11 |
+
*/
|
12 |
+
public function create() {
|
13 |
+
if ( wcml_is_multi_currency_on() ) {
|
14 |
+
return new Hooks();
|
15 |
+
}
|
16 |
+
}
|
17 |
+
|
18 |
+
}
|
classes/HomeScreen/Hooks.php
ADDED
@@ -0,0 +1,26 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace WCML\HomeScreen;
|
4 |
+
|
5 |
+
use WCML\Utilities\Resources;
|
6 |
+
use WCML\Utilities\WcAdminPages;
|
7 |
+
use WCML\StandAlone\IStandAloneAction;
|
8 |
+
|
9 |
+
class Hooks implements \IWPML_Action, IStandAloneAction {
|
10 |
+
|
11 |
+
public function add_hooks() {
|
12 |
+
if ( WcAdminPages::isHomeScreen() ) {
|
13 |
+
add_action( 'admin_enqueue_scripts', [ $this, 'enqueueAssets' ] );
|
14 |
+
}
|
15 |
+
}
|
16 |
+
|
17 |
+
public function enqueueAssets() {
|
18 |
+
$enqueue = Resources::enqueueApp( 'homeScreen' );
|
19 |
+
$enqueue( [
|
20 |
+
'name' => 'wcmlHomeScreen',
|
21 |
+
'data' => [],
|
22 |
+
] );
|
23 |
+
|
24 |
+
}
|
25 |
+
|
26 |
+
}
|
classes/Multicurrency/Analytics/Factory.php
CHANGED
@@ -2,7 +2,9 @@
|
|
2 |
|
3 |
namespace WCML\Multicurrency\Analytics;
|
4 |
|
5 |
-
|
|
|
|
|
6 |
|
7 |
/**
|
8 |
* @return string
|
2 |
|
3 |
namespace WCML\Multicurrency\Analytics;
|
4 |
|
5 |
+
use WCML\StandAlone\IStandAloneAction;
|
6 |
+
|
7 |
+
class Factory implements \IWPML_Backend_Action_Loader, \IWPML_REST_Action_Loader, \IWPML_Deferred_Action_Loader, IStandAloneAction {
|
8 |
|
9 |
/**
|
10 |
* @return string
|
classes/Multicurrency/Analytics/Hooks.php
CHANGED
@@ -4,10 +4,12 @@ namespace WCML\Multicurrency\Analytics;
|
|
4 |
|
5 |
use WCML\Utilities\Resources;
|
6 |
use WCML\Rest\Functions;
|
|
|
7 |
use WPML\FP\Obj;
|
8 |
use WPML\FP\Fns;
|
|
|
9 |
|
10 |
-
class Hooks implements \IWPML_Action {
|
11 |
|
12 |
/** @var \woocommerce_wpml $woocommerce_wpml */
|
13 |
private $woocommerce_wpml;
|
@@ -181,11 +183,13 @@ class Hooks implements \IWPML_Action {
|
|
181 |
}
|
182 |
|
183 |
private function getCurrency() {
|
184 |
-
|
185 |
-
|
186 |
-
|
|
|
|
|
|
|
187 |
: wcml_get_woocommerce_currency_option();
|
188 |
-
// phpcs:enable WordPress.Security.NonceVerification.Recommended
|
189 |
}
|
190 |
|
191 |
}
|
4 |
|
5 |
use WCML\Utilities\Resources;
|
6 |
use WCML\Rest\Functions;
|
7 |
+
use WCML\StandAlone\IStandAloneAction;
|
8 |
use WPML\FP\Obj;
|
9 |
use WPML\FP\Fns;
|
10 |
+
use WCML\Utilities\WpAdminPages;
|
11 |
|
12 |
+
class Hooks implements \IWPML_Action, IStandAloneAction {
|
13 |
|
14 |
/** @var \woocommerce_wpml $woocommerce_wpml */
|
15 |
private $woocommerce_wpml;
|
183 |
}
|
184 |
|
185 |
private function getCurrency() {
|
186 |
+
$rawCurrency = WpAdminPages::isDashboard()
|
187 |
+
? Obj::prop( '_wcml_dashboard_currency', $_COOKIE )
|
188 |
+
: Obj::prop( 'currency', $_GET );
|
189 |
+
|
190 |
+
return $rawCurrency
|
191 |
+
? sanitize_text_field( wp_unslash( $rawCurrency ) )
|
192 |
: wcml_get_woocommerce_currency_option();
|
|
|
193 |
}
|
194 |
|
195 |
}
|
classes/Multicurrency/Resolver/ComposedResolver.php
ADDED
@@ -0,0 +1,32 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace WCML\MultiCurrency\Resolver;
|
4 |
+
|
5 |
+
use WPML\FP\Fns;
|
6 |
+
use WPML\FP\Logic;
|
7 |
+
use WPML\FP\Lst;
|
8 |
+
|
9 |
+
class ComposedResolver implements Resolver {
|
10 |
+
|
11 |
+
/**
|
12 |
+
* @var callable
|
13 |
+
*/
|
14 |
+
private $get;
|
15 |
+
|
16 |
+
/**
|
17 |
+
* @param Resolver[] $resolvers
|
18 |
+
*/
|
19 |
+
public function __construct( array $resolvers ) {
|
20 |
+
$this->get = Logic::firstSatisfying(
|
21 |
+
Logic::isNotNull(),
|
22 |
+
Fns::map( Lst::makePair( Fns::__, 'getClientCurrency' ), $resolvers )
|
23 |
+
);
|
24 |
+
}
|
25 |
+
|
26 |
+
/**
|
27 |
+
* @return string
|
28 |
+
*/
|
29 |
+
public function getClientCurrency() {
|
30 |
+
return call_user_func( $this->get, null );
|
31 |
+
}
|
32 |
+
}
|
classes/Multicurrency/Resolver/Factory.php
ADDED
@@ -0,0 +1,27 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace WCML\MultiCurrency\Resolver;
|
4 |
+
|
5 |
+
use WCML\MultiCurrency\Settings;
|
6 |
+
|
7 |
+
class Factory {
|
8 |
+
|
9 |
+
/**
|
10 |
+
* @return Resolver
|
11 |
+
*/
|
12 |
+
public static function create() {
|
13 |
+
// $getOriginalProductLang :: int|string -> string|null
|
14 |
+
$getOriginalProductLang = function( $productId ) {
|
15 |
+
/** @var \woocommerce_wpml $woocommerce_wpml */
|
16 |
+
global $woocommerce_wpml;
|
17 |
+
|
18 |
+
return $woocommerce_wpml->products->get_original_product_language( $productId );
|
19 |
+
};
|
20 |
+
|
21 |
+
return new ComposedResolver( [
|
22 |
+
new ResolverForContext( $getOriginalProductLang ),
|
23 |
+
Settings::isModeByLocation() ? new ResolverForModeLocation() : new ResolverForModeLanguage(),
|
24 |
+
new ResolverForDefault(),
|
25 |
+
] );
|
26 |
+
}
|
27 |
+
}
|
classes/Multicurrency/Resolver/HelperByLanguage.php
ADDED
@@ -0,0 +1,49 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace WCML\MultiCurrency\Resolver;
|
4 |
+
|
5 |
+
use WCML\MultiCurrency\Geolocation;
|
6 |
+
use WCML\MultiCurrency\Settings;
|
7 |
+
use WPML\FP\Fns;
|
8 |
+
use function WCML\functions\getSitePress;
|
9 |
+
|
10 |
+
class HelperByLanguage {
|
11 |
+
|
12 |
+
/** @var null|callable $getCurrency */
|
13 |
+
private static $getCurrency;
|
14 |
+
|
15 |
+
/**
|
16 |
+
* @param string $currentLang
|
17 |
+
*
|
18 |
+
* @return string|null
|
19 |
+
*/
|
20 |
+
public static function getCurrencyByUserCountry( $currentLang ) {
|
21 |
+
if ( ! self::$getCurrency ) {
|
22 |
+
self::$getCurrency = Fns::memorize( function() use ( $currentLang ) {
|
23 |
+
$clientCountry = Geolocation::getUserCountry();
|
24 |
+
$currency = Geolocation::getOfficialCurrencyCodeByCountry( $clientCountry );
|
25 |
+
|
26 |
+
if ( ! Settings::isValidCurrencyForLang( $currency, $currentLang ) ) {
|
27 |
+
$currency = Settings::getFirstAvailableCurrencyForLang( $currentLang );
|
28 |
+
}
|
29 |
+
|
30 |
+
return $currency ?: null;
|
31 |
+
} );
|
32 |
+
}
|
33 |
+
|
34 |
+
return call_user_func( self::$getCurrency );
|
35 |
+
}
|
36 |
+
|
37 |
+
|
38 |
+
/**
|
39 |
+
* @return string|null
|
40 |
+
*/
|
41 |
+
public static function getCurrentLanguage() {
|
42 |
+
/** @var string|null $currentLang */
|
43 |
+
$currentLang = getSitePress()->get_current_language();
|
44 |
+
|
45 |
+
return in_array( $currentLang, [ 'all', null ], true )
|
46 |
+
? getSitePress()->get_default_language()
|
47 |
+
: $currentLang;
|
48 |
+
}
|
49 |
+
}
|
classes/Multicurrency/Resolver/HelperByLocation.php
ADDED
@@ -0,0 +1,33 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace WCML\MultiCurrency\Resolver;
|
4 |
+
|
5 |
+
use WCML\MultiCurrency\Geolocation;
|
6 |
+
use WCML\MultiCurrency\Settings;
|
7 |
+
use WPML\FP\Fns;
|
8 |
+
|
9 |
+
class HelperByLocation {
|
10 |
+
|
11 |
+
/** @var null|callable $getCurrency */
|
12 |
+
private static $getCurrency;
|
13 |
+
|
14 |
+
/**
|
15 |
+
* @return string|null
|
16 |
+
*/
|
17 |
+
public static function getCurrencyByUserCountry() {
|
18 |
+
if ( ! self::$getCurrency ) {
|
19 |
+
self::$getCurrency = Fns::memorize( function() {
|
20 |
+
$clientCountry = Geolocation::getUserCountry();
|
21 |
+
$currency = Geolocation::getOfficialCurrencyCodeByCountry( $clientCountry );
|
22 |
+
|
23 |
+
if ( ! Settings::isValidCurrencyByCountry( $currency, $clientCountry ) ) {
|
24 |
+
$currency = Settings::getFirstAvailableCurrencyByCountry( $clientCountry );
|
25 |
+
}
|
26 |
+
|
27 |
+
return $currency ?: null;
|
28 |
+
} );
|
29 |
+
}
|
30 |
+
|
31 |
+
return call_user_func( self::$getCurrency );
|
32 |
+
}
|
33 |
+
}
|
classes/Multicurrency/Resolver/Resolver.php
ADDED
@@ -0,0 +1,11 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace WCML\MultiCurrency\Resolver;
|
4 |
+
|
5 |
+
interface Resolver {
|
6 |
+
|
7 |
+
/**
|
8 |
+
* @return string|null
|
9 |
+
*/
|
10 |
+
public function getClientCurrency();
|
11 |
+
}
|
classes/Multicurrency/Resolver/ResolverForContext.php
ADDED
@@ -0,0 +1,123 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace WCML\MultiCurrency\Resolver;
|
4 |
+
|
5 |
+
use WCML\MultiCurrency\Settings;
|
6 |
+
use WPML\FP\Logic;
|
7 |
+
use WPML\FP\Obj;
|
8 |
+
use WPML\FP\Relation;
|
9 |
+
|
10 |
+
class ResolverForContext implements Resolver {
|
11 |
+
|
12 |
+
/** @var callable $getOriginalProductLanguage */
|
13 |
+
private $getOriginalProductLanguage;
|
14 |
+
|
15 |
+
public function __construct( callable $getOriginalProductLanguage ) {
|
16 |
+
$this->getOriginalProductLanguage = $getOriginalProductLanguage;
|
17 |
+
}
|
18 |
+
|
19 |
+
/**
|
20 |
+
* @inheritDoc
|
21 |
+
*/
|
22 |
+
public function getClientCurrency() {
|
23 |
+
$getOnWoocommerceQuickEdit = function() {
|
24 |
+
if ( ! empty( $_REQUEST['woocommerce_quick_edit'] ) ) {
|
25 |
+
return wcml_get_woocommerce_currency_option();
|
26 |
+
}
|
27 |
+
|
28 |
+
return null;
|
29 |
+
};
|
30 |
+
|
31 |
+
$getIfMissingCustomPrice = function() {
|
32 |
+
if ( Settings::isDisplayOnlyCustomPrices() && is_product() ) {
|
33 |
+
$product = wc_get_product();
|
34 |
+
$originalProductLanguage = call_user_func( $this->getOriginalProductLanguage, $product->get_id() );
|
35 |
+
|
36 |
+
// $isMissingCustomPrice :: int -> bool
|
37 |
+
$isMissingCustomPrice = function( $productOrVariationId ) use ( $originalProductLanguage ) {
|
38 |
+
return ! get_post_meta(
|
39 |
+
apply_filters( 'wpml_object_id', $productOrVariationId, get_post_type( $productOrVariationId ), true, $originalProductLanguage ),
|
40 |
+
'_wcml_custom_prices_status',
|
41 |
+
true
|
42 |
+
);
|
43 |
+
};
|
44 |
+
|
45 |
+
if ( $product->get_type() === 'variable' ) {
|
46 |
+
foreach ( $product->get_children() as $child ) {
|
47 |
+
if ( $isMissingCustomPrice( $child ) ) {
|
48 |
+
return wcml_get_woocommerce_currency_option();
|
49 |
+
}
|
50 |
+
}
|
51 |
+
} elseif ( $isMissingCustomPrice( $product->get_id() ) ) {
|
52 |
+
return wcml_get_woocommerce_currency_option();
|
53 |
+
}
|
54 |
+
}
|
55 |
+
|
56 |
+
return null;
|
57 |
+
};
|
58 |
+
|
59 |
+
$getOnPayForOrder = function() {
|
60 |
+
// phpcs:ignore WordPress.Security.ValidatedSanitizedInput
|
61 |
+
if ( isset( $_GET['pay_for_order'], $_GET['key'] ) && $_GET['pay_for_order'] ) {
|
62 |
+
$cacheGroup = 'wcml_client_currency';
|
63 |
+
// phpcs:ignore WordPress.Security.ValidatedSanitizedInput.MissingUnslash
|
64 |
+
$cacheKey = 'order' . sanitize_text_field( $_GET['key'] );
|
65 |
+
$orderCurrency = wp_cache_get( $cacheKey, $cacheGroup );
|
66 |
+
|
67 |
+
if ( $orderCurrency ) {
|
68 |
+
return $orderCurrency;
|
69 |
+
} else {
|
70 |
+
// phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
|
71 |
+
$orderId = wc_get_order_id_by_order_key( wc_clean( wp_unslash( $_GET['key'] ) ) );
|
72 |
+
if ( $orderId ) {
|
73 |
+
$clientCurrency = get_post_meta( $orderId, '_order_currency', true );
|
74 |
+
wp_cache_set( $cacheKey, $clientCurrency, $cacheGroup );
|
75 |
+
return $clientCurrency;
|
76 |
+
}
|
77 |
+
}
|
78 |
+
}
|
79 |
+
|
80 |
+
return null;
|
81 |
+
};
|
82 |
+
|
83 |
+
$getOnSearchProductsFromOrderCurrencyCookie = function() {
|
84 |
+
if ( Relation::propEq( 'action', 'woocommerce_json_search_products_and_variations', $_GET ) ) {
|
85 |
+
return Obj::prop( '_wcml_order_currency', $_COOKIE );
|
86 |
+
}
|
87 |
+
|
88 |
+
return null;
|
89 |
+
};
|
90 |
+
|
91 |
+
$getFromHttpRefererShopOrderCurrency = function() {
|
92 |
+
$refererUrl = Obj::prop( 'HTTP_REFERER', $_SERVER );
|
93 |
+
|
94 |
+
if ( $refererUrl ) {
|
95 |
+
$query = parse_url( $refererUrl, PHP_URL_QUERY );
|
96 |
+
|
97 |
+
if ( $query ) {
|
98 |
+
parse_str( $query, $queryArgs );
|
99 |
+
$postId = Obj::prop( 'post', $queryArgs );
|
100 |
+
|
101 |
+
if ( $postId && get_post_type( $postId ) === 'shop_order' ) {
|
102 |
+
return get_post_meta( $postId, '_order_currency', true );
|
103 |
+
}
|
104 |
+
}
|
105 |
+
}
|
106 |
+
|
107 |
+
return null;
|
108 |
+
};
|
109 |
+
|
110 |
+
$resolve = Logic::firstSatisfying(
|
111 |
+
Logic::isTruthy(),
|
112 |
+
[
|
113 |
+
$getOnWoocommerceQuickEdit,
|
114 |
+
$getIfMissingCustomPrice,
|
115 |
+
$getOnPayForOrder,
|
116 |
+
$getOnSearchProductsFromOrderCurrencyCookie,
|
117 |
+
$getFromHttpRefererShopOrderCurrency,
|
118 |
+
]
|
119 |
+
);
|
120 |
+
|
121 |
+
return $resolve( null );
|
122 |
+
}
|
123 |
+
}
|
classes/Multicurrency/Resolver/ResolverForDefault.php
ADDED
@@ -0,0 +1,19 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace WCML\MultiCurrency\Resolver;
|
4 |
+
|
5 |
+
class ResolverForDefault implements Resolver {
|
6 |
+
|
7 |
+
/**
|
8 |
+
* We consider that we should always be able to resolve a currency
|
9 |
+
* for any customer.
|
10 |
+
*
|
11 |
+
* If no currency could be found in the previous steps, we'll
|
12 |
+
* fall back to the default WC currency.
|
13 |
+
*
|
14 |
+
* @inheritDoc
|
15 |
+
*/
|
16 |
+
public function getClientCurrency() {
|
17 |
+
return wcml_get_woocommerce_currency_option();
|
18 |
+
}
|
19 |
+
}
|
classes/Multicurrency/Resolver/ResolverForModeLanguage.php
ADDED
@@ -0,0 +1,77 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace WCML\MultiCurrency\Resolver;
|
4 |
+
|
5 |
+
use WCML\MultiCurrency\Settings;
|
6 |
+
use WCML_Multi_Currency;
|
7 |
+
use WPML\FP\Logic;
|
8 |
+
|
9 |
+
class ResolverForModeLanguage implements Resolver {
|
10 |
+
|
11 |
+
/**
|
12 |
+
* @inheritDoc
|
13 |
+
*/
|
14 |
+
public function getClientCurrency() {
|
15 |
+
/** @var string $currentLang */
|
16 |
+
$currentLang = HelperByLanguage::getCurrentLanguage();
|
17 |
+
$storedLang = wcml_user_store_get( WCML_Multi_Currency::CURRENCY_LANGUAGE_STORAGE_KEY );
|
18 |
+
$storedCurrency = wcml_user_store_get( WCML_Multi_Currency::CURRENCY_STORAGE_KEY );
|
19 |
+
|
20 |
+
$getInitialCurrencyForLang = function() use ( $currentLang ) {
|
21 |
+
return Settings::isDefaultCurrencyByLocationForLang( $currentLang )
|
22 |
+
? HelperByLanguage::getCurrencyByUserCountry( $currentLang )
|
23 |
+
: Settings::getDefaultCurrencyForLang( $currentLang );
|
24 |
+
};
|
25 |
+
|
26 |
+
$reInitCurrencyIfLangHasChanged = function() use ( $currentLang, $storedLang, $storedCurrency, $getInitialCurrencyForLang ) {
|
27 |
+
$hasChangedLang = $storedLang && $currentLang !== $storedLang;
|
28 |
+
|
29 |
+
if ( $hasChangedLang ) {
|
30 |
+
$initialCurrencyForLang = $getInitialCurrencyForLang();
|
31 |
+
|
32 |
+
if ( $initialCurrencyForLang ) {
|
33 |
+
$preventSwitching = apply_filters( 'wcml_switch_currency_exception', false, $storedCurrency, $initialCurrencyForLang, true );
|
34 |
+
|
35 |
+
if ( ! array_key_exists( 'force_switch', $_POST ) && $preventSwitching ) {
|
36 |
+
do_action( 'wcml_multi_currency_set_switching_currency_html', $preventSwitching['prevent_switching'] );
|
37 |
+
}
|
38 |
+
|
39 |
+
return $initialCurrencyForLang;
|
40 |
+
}
|
41 |
+
}
|
42 |
+
|
43 |
+
return null;
|
44 |
+
};
|
45 |
+
|
46 |
+
$getStoredCurrencyIfValid = function() use ( $currentLang, $storedCurrency ) {
|
47 |
+
return Settings::isValidCurrencyForLang( $storedCurrency, $currentLang )
|
48 |
+
? $storedCurrency
|
49 |
+
: null;
|
50 |
+
};
|
51 |
+
|
52 |
+
$getDefaultCurrencyIfValid = function() use ( $currentLang ) {
|
53 |
+
$defaultCurrency = wcml_get_woocommerce_currency_option();
|
54 |
+
|
55 |
+
return Settings::isValidCurrencyForLang( $defaultCurrency, $currentLang )
|
56 |
+
? $defaultCurrency
|
57 |
+
: null;
|
58 |
+
};
|
59 |
+
|
60 |
+
$getFirstAvailableCurrencyForLang = function() use ( $currentLang ) {
|
61 |
+
return Settings::getFirstAvailableCurrencyForLang( $currentLang );
|
62 |
+
};
|
63 |
+
|
64 |
+
$resolve = Logic::firstSatisfying(
|
65 |
+
Logic::isTruthy(),
|
66 |
+
[
|
67 |
+
$reInitCurrencyIfLangHasChanged,
|
68 |
+
$getStoredCurrencyIfValid,
|
69 |
+
$getInitialCurrencyForLang,
|
70 |
+
$getDefaultCurrencyIfValid,
|
71 |
+
$getFirstAvailableCurrencyForLang,
|
72 |
+
]
|
73 |
+
);
|
74 |
+
|
75 |
+
return $resolve( null );
|
76 |
+
}
|
77 |
+
}
|
classes/Multicurrency/Resolver/ResolverForModeLocation.php
ADDED
@@ -0,0 +1,30 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace WCML\MultiCurrency\Resolver;
|
4 |
+
|
5 |
+
use WCML\MultiCurrency\Geolocation;
|
6 |
+
use WCML\MultiCurrency\Settings;
|
7 |
+
use WCML_Multi_Currency;
|
8 |
+
|
9 |
+
class ResolverForModeLocation implements Resolver {
|
10 |
+
|
11 |
+
/**
|
12 |
+
* @inheritDoc
|
13 |
+
*/
|
14 |
+
public function getClientCurrency() {
|
15 |
+
$storedCurrency = wcml_user_store_get( WCML_Multi_Currency::CURRENCY_STORAGE_KEY );
|
16 |
+
|
17 |
+
// $isCurrencyInvalidInCountry :: string -> bool
|
18 |
+
$isCurrencyInvalidInCountry = function( $currency ) {
|
19 |
+
return ! Settings::isValidCurrencyByCountry( $currency, Geolocation::getUserCountry() );
|
20 |
+
};
|
21 |
+
|
22 |
+
if ( ! $storedCurrency ) {
|
23 |
+
return HelperByLocation::getCurrencyByUserCountry();
|
24 |
+
} elseif ( $isCurrencyInvalidInCountry( $storedCurrency ) ) {
|
25 |
+
return HelperByLocation::getCurrencyByUserCountry();
|
26 |
+
}
|
27 |
+
|
28 |
+
return $storedCurrency;
|
29 |
+
}
|
30 |
+
}
|
classes/Multicurrency/Settings.php
ADDED
@@ -0,0 +1,203 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace WCML\MultiCurrency;
|
4 |
+
|
5 |
+
use WPML\FP\Fns;
|
6 |
+
use WPML\FP\Lst;
|
7 |
+
use WPML\FP\Obj;
|
8 |
+
use WPML\FP\Relation;
|
9 |
+
use function WCML\functions\getSetting;
|
10 |
+
use function WCML\functions\isStandAlone;
|
11 |
+
use function WCML\functions\updateSetting;
|
12 |
+
|
13 |
+
class Settings {
|
14 |
+
|
15 |
+
const MODE_BY_LANGUAGE = 'by_language';
|
16 |
+
const MODE_BY_LOCATION = 'by_location';
|
17 |
+
|
18 |
+
/**
|
19 |
+
* @return string|null
|
20 |
+
*/
|
21 |
+
public static function getMode() {
|
22 |
+
$persistedMode = getSetting( 'currency_mode' );
|
23 |
+
|
24 |
+
// Force location mode at runtime in standalone
|
25 |
+
// to preserve settings in case of temporary change.
|
26 |
+
if ( self::MODE_BY_LANGUAGE === $persistedMode && isStandAlone() ) {
|
27 |
+
return self::MODE_BY_LOCATION;
|
28 |
+
}
|
29 |
+
|
30 |
+
return $persistedMode;
|
31 |
+
}
|
32 |
+
|
33 |
+
/**
|
34 |
+
* @return bool
|
35 |
+
*/
|
36 |
+
public static function isModeByLanguage() {
|
37 |
+
return self::getMode() === self::MODE_BY_LANGUAGE;
|
38 |
+
}
|
39 |
+
|
40 |
+
/**
|
41 |
+
* @return bool
|
42 |
+
*/
|
43 |
+
public static function isModeByLocation() {
|
44 |
+
return self::getMode() === self::MODE_BY_LOCATION;
|
45 |
+
}
|
46 |
+
|
47 |
+
/**
|
48 |
+
* @param string $mode
|
49 |
+
*
|
50 |
+
* @return void
|
51 |
+
*/
|
52 |
+
public static function setMode( $mode ) {
|
53 |
+
updateSetting( 'currency_mode', $mode );
|
54 |
+
}
|
55 |
+
|
56 |
+
/**
|
57 |
+
* @return bool
|
58 |
+
*/
|
59 |
+
public static function isDisplayOnlyCustomPrices() {
|
60 |
+
return (bool) getSetting( 'display_custom_prices' );
|
61 |
+
}
|
62 |
+
|
63 |
+
/**
|
64 |
+
* @param string $code
|
65 |
+
*
|
66 |
+
* @return bool
|
67 |
+
*/
|
68 |
+
public static function isActiveCurrency( $code ) {
|
69 |
+
return Lst::includes( $code, self::getActiveCurrencyCodes() );
|
70 |
+
}
|
71 |
+
|
72 |
+
/**
|
73 |
+
* @return array
|
74 |
+
*/
|
75 |
+
public static function getActiveCurrencyCodes() {
|
76 |
+
return Obj::keys( self::getCurrenciesOptions() );
|
77 |
+
}
|
78 |
+
|
79 |
+
/**
|
80 |
+
* @return array
|
81 |
+
*/
|
82 |
+
public static function getCurrenciesOptions() {
|
83 |
+
return (array) getSetting( 'currency_options' );
|
84 |
+
}
|
85 |
+
|
86 |
+
/**
|
87 |
+
* @param string|array $keyOrPath
|
88 |
+
* @param mixed|null $default
|
89 |
+
*
|
90 |
+
* @return mixed
|
91 |
+
*/
|
92 |
+
public static function getCurrenciesOption( $keyOrPath, $default = null ) {
|
93 |
+
return Obj::pathOr( $default, (array) $keyOrPath, self::getCurrenciesOptions() );
|
94 |
+
}
|
95 |
+
|
96 |
+
/**
|
97 |
+
* @param string $currency
|
98 |
+
* @param string $clientCountry
|
99 |
+
*
|
100 |
+
* @return bool
|
101 |
+
*/
|
102 |
+
public static function isValidCurrencyByCountry( $currency, $clientCountry ) {
|
103 |
+
$currencySettings = self::getCurrenciesOption( $currency );
|
104 |
+
|
105 |
+
// $isLocationMode :: string -> bool
|
106 |
+
$isLocationMode = Relation::propEq( 'location_mode', Fns::__, $currencySettings );
|
107 |
+
|
108 |
+
// $containsCountry :: string -> bool
|
109 |
+
$containsCountry = Lst::includes( Fns::__, (array) Obj::prop( 'countries', $currencySettings ) );
|
110 |
+
|
111 |
+
if ( $isLocationMode( 'all' ) ) {
|
112 |
+
return true;
|
113 |
+
} elseif ( $isLocationMode( 'include' ) && $containsCountry( $clientCountry ) ) {
|
114 |
+
return true;
|
115 |
+
} elseif ( $isLocationMode( 'exclude' ) && ! $containsCountry( $clientCountry ) ) {
|
116 |
+
return true;
|
117 |
+
}
|
118 |
+
|
119 |
+
return false;
|
120 |
+
}
|
121 |
+
|
122 |
+
/**
|
123 |
+
* @param string $country
|
124 |
+
*
|
125 |
+
* @return string|null
|
126 |
+
*/
|
127 |
+
public static function getFirstAvailableCurrencyByCountry( $country ) {
|
128 |
+
// $isValidCurrency :: string -> bool
|
129 |
+
$isValidCurrency = function( $currency ) use ( $country ) {
|
130 |
+
return self::isValidCurrencyByCountry( $currency, $country );
|
131 |
+
};
|
132 |
+
|
133 |
+
return wpml_collect( self::getActiveCurrencyCodes() )->first( $isValidCurrency );
|
134 |
+
}
|
135 |
+
|
136 |
+
/**
|
137 |
+
* @return array
|
138 |
+
*/
|
139 |
+
public static function getDefaultCurrencies() {
|
140 |
+
return (array) getSetting( 'default_currencies' );
|
141 |
+
}
|
142 |
+
|
143 |
+
/**
|
144 |
+
* @return array
|
145 |
+
*/
|
146 |
+
public static function getOrderedCurrencyCodes() {
|
147 |
+
return (array) getSetting( 'currencies_order' ) ?: self::getActiveCurrencyCodes();
|
148 |
+
}
|
149 |
+
|
150 |
+
/**
|
151 |
+
* @param string $lang
|
152 |
+
*
|
153 |
+
* @return bool
|
154 |
+
*/
|
155 |
+
public static function isDefaultCurrencyByLocationForLang( $lang ) {
|
156 |
+
return 'location' === self::getDefaultCurrencyForLang( $lang );
|
157 |
+
}
|
158 |
+
|
159 |
+
/**
|
160 |
+
* @param string $lang
|
161 |
+
*
|
162 |
+
* @return string A real currency (e.g. "USD") or "location" or a falsy string for "keep" (default).
|
163 |
+
*/
|
164 |
+
public static function getDefaultCurrencyForLang( $lang ) {
|
165 |
+
return (string) Obj::propOr( '', $lang, self::getDefaultCurrencies() );
|
166 |
+
}
|
167 |
+
|
168 |
+
/**
|
169 |
+
* @param string $currency
|
170 |
+
* @param string $lang
|
171 |
+
*
|
172 |
+
* @return bool
|
173 |
+
*/
|
174 |
+
public static function isValidCurrencyForLang( $currency, $lang ) {
|
175 |
+
return (bool) self::getCurrenciesOption( [ $currency, 'languages', $lang ] );
|
176 |
+
}
|
177 |
+
|
178 |
+
/**
|
179 |
+
* @param string $lang
|
180 |
+
*
|
181 |
+
* @return string|null
|
182 |
+
*/
|
183 |
+
public static function getFirstAvailableCurrencyForLang( $lang ) {
|
184 |
+
return (string) wpml_collect( self::getCurrenciesOptions() )
|
185 |
+
->filter( Obj::path( [ 'languages', $lang ] ) )
|
186 |
+
->keys()
|
187 |
+
->first();
|
188 |
+
}
|
189 |
+
|
190 |
+
/**
|
191 |
+
* @return bool
|
192 |
+
*/
|
193 |
+
public static function isAutomaticRateEnabled() {
|
194 |
+
return (bool) Obj::prop( 'automatic', self::getAutomaticRateSettings() );
|
195 |
+
}
|
196 |
+
|
197 |
+
/**
|
198 |
+
* @return array
|
199 |
+
*/
|
200 |
+
private static function getAutomaticRateSettings() {
|
201 |
+
return Obj::propOr( [], 'exchange_rates', getSetting( 'multi_currency', [] ) );
|
202 |
+
}
|
203 |
+
}
|
classes/Multicurrency/Shipping/AdminHooks.php
CHANGED
@@ -3,9 +3,10 @@
|
|
3 |
namespace WCML\Multicurrency\Shipping;
|
4 |
|
5 |
use IWPML_Action;
|
|
|
6 |
use WCML_Multi_Currency;
|
7 |
|
8 |
-
class AdminHooks implements IWPML_Action {
|
9 |
const WCML_SHIPPING_COSTS = 'wcml_shipping_costs';
|
10 |
|
11 |
/** @var WCML_Multi_Currency */
|
@@ -70,7 +71,7 @@ class AdminHooks implements IWPML_Action {
|
|
70 |
'title' => __( 'Costs and values in custom currencies', 'woocommerce-multilingual' ),
|
71 |
'type' => 'title',
|
72 |
'default' => '',
|
73 |
-
'description' => __( '
|
74 |
];
|
75 |
return $field;
|
76 |
}
|
3 |
namespace WCML\Multicurrency\Shipping;
|
4 |
|
5 |
use IWPML_Action;
|
6 |
+
use WCML\StandAlone\IStandAloneAction;
|
7 |
use WCML_Multi_Currency;
|
8 |
|
9 |
+
class AdminHooks implements IWPML_Action, IStandAloneAction {
|
10 |
const WCML_SHIPPING_COSTS = 'wcml_shipping_costs';
|
11 |
|
12 |
/** @var WCML_Multi_Currency */
|
71 |
'title' => __( 'Costs and values in custom currencies', 'woocommerce-multilingual' ),
|
72 |
'type' => 'title',
|
73 |
'default' => '',
|
74 |
+
'description' => __( 'WooCommerce Multilingual & Multicurrency by default will multiply all your costs and values defined above by currency exchange rates. If you don\'t want this and you prefer static values instead, you can define them here.', 'woocommerce-multilingual' ),
|
75 |
];
|
76 |
return $field;
|
77 |
}
|
classes/Multicurrency/Shipping/FreeShipping.php
CHANGED
@@ -10,6 +10,8 @@ class FreeShipping implements ShippingMode {
|
|
10 |
if ( ! is_string( $currencyCode ) ) {
|
11 |
$currencyCode = '';
|
12 |
}
|
|
|
|
|
13 |
return sprintf( esc_html_x( 'Minimal order amount in %s',
|
14 |
'The label for the field with minimal order amount in additional currency. The currency symbol will be added in place of %s specifier.',
|
15 |
'woocommerce-multilingual' ), $currencyCode );
|
@@ -19,6 +21,8 @@ class FreeShipping implements ShippingMode {
|
|
19 |
if ( ! is_string( $currencyCode ) ) {
|
20 |
$currencyCode = '';
|
21 |
}
|
|
|
|
|
22 |
return sprintf( esc_html_x( 'The minimal order amount if customer choose %s as a purchase currency.',
|
23 |
'The description for the field with minimal order amount in additional currency. The currency symbol will be added in place of %s specifier.',
|
24 |
'woocommerce-multilingual' ), $currencyCode );
|
10 |
if ( ! is_string( $currencyCode ) ) {
|
11 |
$currencyCode = '';
|
12 |
}
|
13 |
+
|
14 |
+
/* translators: %s is the currency code */
|
15 |
return sprintf( esc_html_x( 'Minimal order amount in %s',
|
16 |
'The label for the field with minimal order amount in additional currency. The currency symbol will be added in place of %s specifier.',
|
17 |
'woocommerce-multilingual' ), $currencyCode );
|
21 |
if ( ! is_string( $currencyCode ) ) {
|
22 |
$currencyCode = '';
|
23 |
}
|
24 |
+
|
25 |
+
/* translators: %s is the currency code */
|
26 |
return sprintf( esc_html_x( 'The minimal order amount if customer choose %s as a purchase currency.',
|
27 |
'The description for the field with minimal order amount in additional currency. The currency symbol will be added in place of %s specifier.',
|
28 |
'woocommerce-multilingual' ), $currencyCode );
|
classes/Multicurrency/Shipping/FrontEndHooks.php
CHANGED
@@ -3,8 +3,9 @@
|
|
3 |
namespace WCML\Multicurrency\Shipping;
|
4 |
|
5 |
use IWPML_Action;
|
|
|
6 |
|
7 |
-
class FrontEndHooks implements IWPML_Action {
|
8 |
|
9 |
private $multiCurrency;
|
10 |
|
3 |
namespace WCML\Multicurrency\Shipping;
|
4 |
|
5 |
use IWPML_Action;
|
6 |
+
use WCML\StandAlone\IStandAloneAction;
|
7 |
|
8 |
+
class FrontEndHooks implements IWPML_Action, IStandAloneAction {
|
9 |
|
10 |
private $multiCurrency;
|
11 |
|
classes/Multicurrency/Shipping/ShippingClasses.php
CHANGED
@@ -59,7 +59,8 @@ class ShippingClasses {
|
|
59 |
protected static function askToSwitchLanguage( $field, $shippingClass, $classSourceLanguageCode ) {
|
60 |
$field[ 'wcml_ask_to_switch_language_' . $shippingClass->term_id ] = [
|
61 |
'title' => '',
|
62 |
-
|
|
|
63 |
$shippingClass->name,
|
64 |
$classSourceLanguageCode),
|
65 |
'type' => 'title'
|
@@ -69,7 +70,8 @@ class ShippingClasses {
|
|
69 |
|
70 |
protected static function addShippingClassField( $field, $shippingClass, $currencyCode ) {
|
71 |
$field[ 'class_cost_' . $shippingClass->term_id . '_' . $currencyCode ] = [
|
72 |
-
|
|
|
73 |
'type' => 'text',
|
74 |
'placeholder' => __( 'N/A', 'woocommerce-multilingual' ),
|
75 |
'class' => 'wcml-shipping-cost-currency'
|
@@ -79,6 +81,7 @@ class ShippingClasses {
|
|
79 |
|
80 |
protected static function addNoShippingClassField( $field, $currencyCode ) {
|
81 |
$field[ 'no_class_cost_' . $currencyCode ] = [
|
|
|
82 |
'title' => sprintf( __( 'No shipping class cost in %s', 'woocommerce-multilingual' ), esc_html( $currencyCode ) ),
|
83 |
'type' => 'text',
|
84 |
'placeholder' => __( 'N/A', 'woocommerce-multilingual' ),
|
59 |
protected static function askToSwitchLanguage( $field, $shippingClass, $classSourceLanguageCode ) {
|
60 |
$field[ 'wcml_ask_to_switch_language_' . $shippingClass->term_id ] = [
|
61 |
'title' => '',
|
62 |
+
/* translators: %1$s is a shipping class name and %2$s is a language code */
|
63 |
+
'description' => sprintf( __( 'Your shipping class %1$s has been created in %2$s language. Please switch your language if you want to provide shipping costs in different currencies for this class.', 'woocommerce-multilingual' ),
|
64 |
$shippingClass->name,
|
65 |
$classSourceLanguageCode),
|
66 |
'type' => 'title'
|
70 |
|
71 |
protected static function addShippingClassField( $field, $shippingClass, $currencyCode ) {
|
72 |
$field[ 'class_cost_' . $shippingClass->term_id . '_' . $currencyCode ] = [
|
73 |
+
/* translators: %1$s is a shipping class name and %2$s is a currency code */
|
74 |
+
'title' => sprintf( __( '"%1$s" shipping class cost in %2$s', 'woocommerce-multilingual' ), esc_html( $shippingClass->name ), esc_html( $currencyCode ) ),
|
75 |
'type' => 'text',
|
76 |
'placeholder' => __( 'N/A', 'woocommerce-multilingual' ),
|
77 |
'class' => 'wcml-shipping-cost-currency'
|
81 |
|
82 |
protected static function addNoShippingClassField( $field, $currencyCode ) {
|
83 |
$field[ 'no_class_cost_' . $currencyCode ] = [
|
84 |
+
/* translators: %s is a currency code */
|
85 |
'title' => sprintf( __( 'No shipping class cost in %s', 'woocommerce-multilingual' ), esc_html( $currencyCode ) ),
|
86 |
'type' => 'text',
|
87 |
'placeholder' => __( 'N/A', 'woocommerce-multilingual' ),
|
classes/Multicurrency/Shipping/ShippingHooksFactory.php
CHANGED
@@ -2,7 +2,9 @@
|
|
2 |
|
3 |
namespace WCML\Multicurrency\Shipping;
|
4 |
|
5 |
-
|
|
|
|
|
6 |
|
7 |
public function get_load_action() {
|
8 |
return 'init';
|
2 |
|
3 |
namespace WCML\Multicurrency\Shipping;
|
4 |
|
5 |
+
use WCML\StandAlone\IStandAloneAction;
|
6 |
+
|
7 |
+
class ShippingHooksFactory implements \IWPML_Deferred_Action_Loader, \IWPML_Backend_Action_Loader, \IWPML_Frontend_Action_Loader, IStandAloneAction {
|
8 |
|
9 |
public function get_load_action() {
|
10 |
return 'init';
|
classes/Multicurrency/Shipping/VariableCost.php
CHANGED
@@ -13,6 +13,7 @@ trait VariableCost {
|
|
13 |
* return string
|
14 |
*/
|
15 |
public function getFieldTitle( $currencyCode ) {
|
|
|
16 |
return sprintf( esc_html_x( 'Cost in %s',
|
17 |
'The label for the field with shipping cost in additional currency. The currency symbol will be added in place of %s specifier.',
|
18 |
'woocommerce-multilingual' ), $currencyCode );
|
@@ -26,6 +27,7 @@ trait VariableCost {
|
|
26 |
* @return string
|
27 |
*/
|
28 |
public function getFieldDescription( $currencyCode ) {
|
|
|
29 |
return sprintf( esc_html_x( 'The shipping cost if customer choose %s as a purchase currency.',
|
30 |
'The description for the field with shipping cost in additional currency. The currency symbol will be added in place of %s specifier.',
|
31 |
'woocommerce-multilingual' ), $currencyCode );
|
13 |
* return string
|
14 |
*/
|
15 |
public function getFieldTitle( $currencyCode ) {
|
16 |
+
/* translators: %s is a currency code */
|
17 |
return sprintf( esc_html_x( 'Cost in %s',
|
18 |
'The label for the field with shipping cost in additional currency. The currency symbol will be added in place of %s specifier.',
|
19 |
'woocommerce-multilingual' ), $currencyCode );
|
27 |
* @return string
|
28 |
*/
|
29 |
public function getFieldDescription( $currencyCode ) {
|
30 |
+
/* translators: %s is a currency code */
|
31 |
return sprintf( esc_html_x( 'The shipping cost if customer choose %s as a purchase currency.',
|
32 |
'The description for the field with shipping cost in additional currency. The currency symbol will be added in place of %s specifier.',
|
33 |
'woocommerce-multilingual' ), $currencyCode );
|
classes/Multicurrency/Transient/Hooks.php
ADDED
@@ -0,0 +1,50 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace WCML\Multicurrency\Transient;
|
4 |
+
|
5 |
+
use WCML\MultiCurrency\Settings as McSettings;
|
6 |
+
use WPML\FP\Fns;
|
7 |
+
use WPML\FP\Str;
|
8 |
+
use WPML\LIB\WP\Hooks as WpHooks;
|
9 |
+
use function WCML\functions\getClientCurrency;
|
10 |
+
use function WPML\FP\spreadArgs;
|
11 |
+
|
12 |
+
class Hooks {
|
13 |
+
|
14 |
+
/**
|
15 |
+
* @param string $key
|
16 |
+
*/
|
17 |
+
public static function addHooks( $key ) {
|
18 |
+
$getKeyWithCurrency = Str::concat( $key . '_' );
|
19 |
+
$getKeyWithClientCurrency = function() use ( $getKeyWithCurrency ) {
|
20 |
+
return $getKeyWithCurrency( getClientCurrency() );
|
21 |
+
};
|
22 |
+
|
23 |
+
$getTransient = function() use ( $getKeyWithClientCurrency ) {
|
24 |
+
return get_transient( $getKeyWithClientCurrency() );
|
25 |
+
};
|
26 |
+
|
27 |
+
$setTransient = function( $value ) use ( $key, $getKeyWithClientCurrency ) {
|
28 |
+
delete_transient( $key );
|
29 |
+
return set_transient( $getKeyWithClientCurrency(), $value );
|
30 |
+
};
|
31 |
+
|
32 |
+
$deleteTransient = function() use ( $getKeyWithCurrency ) {
|
33 |
+
foreach ( McSettings::getActiveCurrencyCodes() as $code ) {
|
34 |
+
delete_transient( $getKeyWithCurrency( $code ) );
|
35 |
+
}
|
36 |
+
};
|
37 |
+
|
38 |
+
$withLock = Fns::withNamedLock( __CLASS__ . "_$key", Fns::identity() );
|
39 |
+
|
40 |
+
WpHooks::onFilter( 'pre_transient_' . $key )
|
41 |
+
->then( $getTransient );
|
42 |
+
|
43 |
+
WpHooks::onAction( 'set_transient_' . $key )
|
44 |
+
->then( spreadArgs( $withLock( $setTransient ) ) );
|
45 |
+
|
46 |
+
WpHooks::onAction( 'delete_transient_' . $key )
|
47 |
+
->then( $withLock( $deleteTransient ) );
|
48 |
+
}
|
49 |
+
|
50 |
+
}
|
classes/Multicurrency/UI/Factory.php
CHANGED
@@ -2,9 +2,12 @@
|
|
2 |
|
3 |
namespace WCML\Multicurrency\UI;
|
4 |
|
|
|
|
|
|
|
5 |
use function WPML\Container\make;
|
6 |
|
7 |
-
class Factory implements \IWPML_Backend_Action_Loader, \IWPML_Deferred_Action_Loader {
|
8 |
|
9 |
public function get_load_action() {
|
10 |
return 'init';
|
@@ -17,7 +20,7 @@ class Factory implements \IWPML_Backend_Action_Loader, \IWPML_Deferred_Action_Lo
|
|
17 |
/** @var \woocommerce_wpml $woocommerce_wpml */
|
18 |
global $woocommerce_wpml;
|
19 |
|
20 |
-
if (
|
21 |
return make(
|
22 |
Hooks::class,
|
23 |
[
|
@@ -28,13 +31,4 @@ class Factory implements \IWPML_Backend_Action_Loader, \IWPML_Deferred_Action_Lo
|
|
28 |
|
29 |
return null;
|
30 |
}
|
31 |
-
|
32 |
-
/**
|
33 |
-
* @return bool
|
34 |
-
*/
|
35 |
-
public static function isMultiCurrencySettings() {
|
36 |
-
return isset( $_GET['page'], $_GET['tab'] )
|
37 |
-
&& 'wpml-wcml' === $_GET['page']
|
38 |
-
&& 'multi-currency' === $_GET['tab'];
|
39 |
-
}
|
40 |
-
}
|
2 |
|
3 |
namespace WCML\Multicurrency\UI;
|
4 |
|
5 |
+
use WCML\StandAlone\IStandAloneAction;
|
6 |
+
|
7 |
+
use WCML\Utilities\AdminPages;
|
8 |
use function WPML\Container\make;
|
9 |
|
10 |
+
class Factory implements \IWPML_Backend_Action_Loader, \IWPML_Deferred_Action_Loader, IStandAloneAction {
|
11 |
|
12 |
public function get_load_action() {
|
13 |
return 'init';
|
20 |
/** @var \woocommerce_wpml $woocommerce_wpml */
|
21 |
global $woocommerce_wpml;
|
22 |
|
23 |
+
if ( AdminPages::isMultiCurrency() && make( \WCML_Dependencies::class )->check() ) {
|
24 |
return make(
|
25 |
Hooks::class,
|
26 |
[
|
31 |
|
32 |
return null;
|
33 |
}
|
34 |
+
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
classes/Multicurrency/UI/Hooks.php
CHANGED
@@ -2,14 +2,16 @@
|
|
2 |
|
3 |
namespace WCML\Multicurrency\UI;
|
4 |
|
5 |
-
use WCML\MultiCurrency\
|
|
|
6 |
use WCML\Utilities\Resources;
|
7 |
use WPML\Collect\Support\Collection;
|
8 |
use WPML\FP\Fns;
|
9 |
use WPML\FP\Obj;
|
|
|
10 |
use function WPML\FP\curryN;
|
11 |
|
12 |
-
class Hooks implements \IWPML_Action {
|
13 |
|
14 |
const HANDLE = 'wcml-multicurrency-options';
|
15 |
|
@@ -28,7 +30,7 @@ class Hooks implements \IWPML_Action {
|
|
28 |
public function __construct(
|
29 |
\WCML_Multi_Currency $multiCurrency,
|
30 |
\WCML_Currencies_Payment_Gateways $currenciesPaymentGateways,
|
31 |
-
\
|
32 |
array $wcmlSettings
|
33 |
) {
|
34 |
$this->multiCurrency = $multiCurrency;
|
@@ -48,15 +50,17 @@ class Hooks implements \IWPML_Action {
|
|
48 |
$enqueue( [
|
49 |
'name' => 'wcmlMultiCurrency',
|
50 |
'data' => [
|
51 |
-
'endpoint'
|
52 |
-
'activeCurrencies'
|
53 |
-
'allCurrencies'
|
54 |
-
'allCountries'
|
55 |
-
'languages'
|
56 |
-
'gateways'
|
57 |
-
'strings'
|
58 |
-
'mode'
|
59 |
-
'maxMindKeyExist'
|
|
|
|
|
60 |
],
|
61 |
] );
|
62 |
}
|
@@ -181,14 +185,18 @@ class Hooks implements \IWPML_Action {
|
|
181 |
'labelKeep' => __( 'Keep', 'woocommerce-multilingual' ),
|
182 |
'labelDelete' => __( 'Delete', 'woocommerce-multilingual' ),
|
183 |
'labelCurrenciesToDisplay' => __( 'Currencies to display for each language', 'woocommerce-multilingual' ),
|
|
|
184 |
'placeholderEnableFor' => __( 'Enable %1$s for %2$s', 'woocommerce-multilingual' ),
|
|
|
185 |
'placeholderDisableFor' => __( 'Disable %1$s for %2$s', 'woocommerce-multilingual' ),
|
186 |
'labelSettings' => __( 'Settings', 'woocommerce-multilingual' ),
|
187 |
'labelAddNewCurrency' => __( 'Add new currency', 'woocommerce-multilingual' ),
|
|
|
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 |
'placeholderPreviousRate' => __( '(previous value: %s)', 'woocommerce-multilingual' ),
|
193 |
'labelCurrencyPreview' => __( 'Currency Preview', 'woocommerce-multilingual' ),
|
194 |
'labelPosition' => __( 'Currency Position', 'woocommerce-multilingual' ),
|
@@ -206,15 +214,18 @@ class Hooks implements \IWPML_Action {
|
|
206 |
'optionDown' => __( 'Down', 'woocommerce-multilingual' ),
|
207 |
'optionNearest' => __( 'Nearest', 'woocommerce-multilingual' ),
|
208 |
'labelIncrement' => __( 'Increment for nearest integer', 'woocommerce-multilingual' ),
|
|
|
209 |
'tooltipIncrement' => sprintf( __( 'The resulting price will be an increment of this value after initial rounding.%se.g.:', 'woocommerce-multilingual' ), '<br>' ) . '<br />' .
|
210 |
__( '1454.07 » 1454 when set to 1', 'woocommerce-multilingual' ) . '<br />' .
|
211 |
__( '1454.07 » 1450 when set to 10', 'woocommerce-multilingual' ) . '<br />' .
|
212 |
__( '1454.07 » 1500 when set to 100', 'woocommerce-multilingual' ) . '<br />',
|
|
|
213 |
'tooltipRounding' => sprintf( __( 'Round the converted price to the closest integer. %se.g. 15.78 becomes 16.00', 'woocommerce-multilingual' ), '<br />' ),
|
214 |
'tooltipAutosubtract' => __( 'The value to be subtracted from the amount obtained previously.', 'woocommerce-multilingual' ) . '<br /><br />' .
|
215 |
__( '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' ),
|
216 |
'labelAutosubtract' => __( 'Autosubtract amount', 'woocommerce-multilingual' ),
|
217 |
'labelPaymentGateways' => __( 'Payment Gateways', 'woocommerce-multilingual' ),
|
|
|
218 |
'placeholderCustomSettings' => __( 'Custom settings for %s', 'woocommerce-multilingual' ),
|
219 |
'linkUrlLearn' => $trackingLink->getWcmlMultiCurrencyDoc( '#payment-gateways-settings' ),
|
220 |
'linkLabelLearn' => __( 'Learn more', 'woocommerce-multilingual' ),
|
@@ -227,19 +238,20 @@ class Hooks implements \IWPML_Action {
|
|
227 |
'labelAllCountriesExceptDots' => __( 'All countries except...', 'woocommerce-multilingual' ),
|
228 |
'labelSpecificCountries' => __( 'Specific countries', 'woocommerce-multilingual' ),
|
229 |
'labelModeSelect' => __( 'Show currencies based on', 'woocommerce-multilingual' ),
|
230 |
-
'
|
|
|
231 |
'labelSiteLanguage' => __( 'Site Language', 'woocommerce-multilingual' ),
|
232 |
'labelClientLocation' => __( 'Client Location', 'woocommerce-multilingual' ),
|
233 |
'labelLocationBased' => __( 'Location based', 'woocommerce-multilingual' ),
|
234 |
-
'maxMindDescription' => __( 'WooCommerce
|
235 |
'maxMindSuccess' => __( 'Great! Now you can use Geolocation to determine default currency for chosen languages. You can edit that key in ', 'woocommerce-multilingual' ),
|
236 |
'maxMindSettingLink' => admin_url( 'admin.php?page=wc-settings&tab=integration' ),
|
237 |
'maxMindSettingLinkText' => __( 'WooCommerce settings page.', 'woocommerce-multilingual' ),
|
238 |
'maxMindLabel' => __( 'MaxMind Licence Key', 'woocommerce-multilingual' ),
|
239 |
'apply' => __( 'Apply', 'woocommerce-multilingual' ),
|
240 |
-
'
|
241 |
'maxMindDocLink' => 'https://docs.woocommerce.com/document/maxmind-geolocation-integration/',
|
242 |
-
'maxMindDocLinkText' => __( '
|
243 |
];
|
244 |
}
|
245 |
|
@@ -258,13 +270,6 @@ class Hooks implements \IWPML_Action {
|
|
258 |
return wpml_collect( WC()->countries->get_countries() )->map( $buildCountry )->values()->toArray();
|
259 |
}
|
260 |
|
261 |
-
/**
|
262 |
-
* @return string
|
263 |
-
*/
|
264 |
-
private function getMode(){
|
265 |
-
return isset( $this->wcmlSettings['currency_mode'] ) ? $this->wcmlSettings['currency_mode'] : '';
|
266 |
-
}
|
267 |
-
|
268 |
/**
|
269 |
* @return bool
|
270 |
*/
|
@@ -282,6 +287,7 @@ class Hooks implements \IWPML_Action {
|
|
282 |
public static function formatLastRateUpdate( $lastRateUpdate ) {
|
283 |
return $lastRateUpdate
|
284 |
? sprintf(
|
|
|
285 |
__( 'Set on %s', 'woocommerce-multilingual' ),
|
286 |
date( 'F j, Y g:i a', strtotime( $lastRateUpdate ) )
|
287 |
)
|
2 |
|
3 |
namespace WCML\Multicurrency\UI;
|
4 |
|
5 |
+
use WCML\MultiCurrency\Settings;
|
6 |
+
use WCML\StandAlone\IStandAloneAction;
|
7 |
use WCML\Utilities\Resources;
|
8 |
use WPML\Collect\Support\Collection;
|
9 |
use WPML\FP\Fns;
|
10 |
use WPML\FP\Obj;
|
11 |
+
use function WCML\functions\isStandAlone;
|
12 |
use function WPML\FP\curryN;
|
13 |
|
14 |
+
class Hooks implements \IWPML_Action, IStandAloneAction {
|
15 |
|
16 |
const HANDLE = 'wcml-multicurrency-options';
|
17 |
|
30 |
public function __construct(
|
31 |
\WCML_Multi_Currency $multiCurrency,
|
32 |
\WCML_Currencies_Payment_Gateways $currenciesPaymentGateways,
|
33 |
+
\WPML\Core\ISitePress $sitepress,
|
34 |
array $wcmlSettings
|
35 |
) {
|
36 |
$this->multiCurrency = $multiCurrency;
|
50 |
$enqueue( [
|
51 |
'name' => 'wcmlMultiCurrency',
|
52 |
'data' => [
|
53 |
+
'endpoint' => self::HANDLE,
|
54 |
+
'activeCurrencies' => $this->getActiveCurrencies( $gateways ),
|
55 |
+
'allCurrencies' => $this->getAllCurrencies(),
|
56 |
+
'allCountries' => $this->getAllCountries(),
|
57 |
+
'languages' => $this->getLanguages(),
|
58 |
+
'gateways' => $gateways->toArray(),
|
59 |
+
'strings' => $this->getStrings(),
|
60 |
+
'mode' => Settings::getMode(),
|
61 |
+
'maxMindKeyExist' => $this->checkMaxMindKeyExist(),
|
62 |
+
'isStandalone' => isStandAlone(),
|
63 |
+
'isAutoRateEnabled' => Settings::isAutomaticRateEnabled(),
|
64 |
],
|
65 |
] );
|
66 |
}
|
185 |
'labelKeep' => __( 'Keep', 'woocommerce-multilingual' ),
|
186 |
'labelDelete' => __( 'Delete', 'woocommerce-multilingual' ),
|
187 |
'labelCurrenciesToDisplay' => __( 'Currencies to display for each language', 'woocommerce-multilingual' ),
|
188 |
+
/* translators: %1$s is for language name and %2$s for currency name */
|
189 |
'placeholderEnableFor' => __( 'Enable %1$s for %2$s', 'woocommerce-multilingual' ),
|
190 |
+
/* translators: %1$s is for language name and %2$s for currency name */
|
191 |
'placeholderDisableFor' => __( 'Disable %1$s for %2$s', 'woocommerce-multilingual' ),
|
192 |
'labelSettings' => __( 'Settings', 'woocommerce-multilingual' ),
|
193 |
'labelAddNewCurrency' => __( 'Add new currency', 'woocommerce-multilingual' ),
|
194 |
+
/* translators: %s for currency label */
|
195 |
'placeholderCurrencySettingsFor' => __( 'Currency settings for %s', 'woocommerce-multilingual' ),
|
196 |
'labelSelectCurrency' => __( 'Select currency', 'woocommerce-multilingual' ),
|
197 |
'labelExchangeRate' => __( 'Exchange Rate', 'woocommerce-multilingual' ),
|
198 |
'labelOnlyNumeric' => __( 'Only numeric', 'woocommerce-multilingual' ),
|
199 |
+
/* translators: %s for currency exchange rate value */
|
200 |
'placeholderPreviousRate' => __( '(previous value: %s)', 'woocommerce-multilingual' ),
|
201 |
'labelCurrencyPreview' => __( 'Currency Preview', 'woocommerce-multilingual' ),
|
202 |
'labelPosition' => __( 'Currency Position', 'woocommerce-multilingual' ),
|
214 |
'optionDown' => __( 'Down', 'woocommerce-multilingual' ),
|
215 |
'optionNearest' => __( 'Nearest', 'woocommerce-multilingual' ),
|
216 |
'labelIncrement' => __( 'Increment for nearest integer', 'woocommerce-multilingual' ),
|
217 |
+
/* translators: %s is an HTML break line */
|
218 |
'tooltipIncrement' => sprintf( __( 'The resulting price will be an increment of this value after initial rounding.%se.g.:', 'woocommerce-multilingual' ), '<br>' ) . '<br />' .
|
219 |
__( '1454.07 » 1454 when set to 1', 'woocommerce-multilingual' ) . '<br />' .
|
220 |
__( '1454.07 » 1450 when set to 10', 'woocommerce-multilingual' ) . '<br />' .
|
221 |
__( '1454.07 » 1500 when set to 100', 'woocommerce-multilingual' ) . '<br />',
|
222 |
+
/* translators: %s is an HTML break line */
|
223 |
'tooltipRounding' => sprintf( __( 'Round the converted price to the closest integer. %se.g. 15.78 becomes 16.00', 'woocommerce-multilingual' ), '<br />' ),
|
224 |
'tooltipAutosubtract' => __( 'The value to be subtracted from the amount obtained previously.', 'woocommerce-multilingual' ) . '<br /><br />' .
|
225 |
__( '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' ),
|
226 |
'labelAutosubtract' => __( 'Autosubtract amount', 'woocommerce-multilingual' ),
|
227 |
'labelPaymentGateways' => __( 'Payment Gateways', 'woocommerce-multilingual' ),
|
228 |
+
/* translators: %s is a currency code */
|
229 |
'placeholderCustomSettings' => __( 'Custom settings for %s', 'woocommerce-multilingual' ),
|
230 |
'linkUrlLearn' => $trackingLink->getWcmlMultiCurrencyDoc( '#payment-gateways-settings' ),
|
231 |
'linkLabelLearn' => __( 'Learn more', 'woocommerce-multilingual' ),
|
238 |
'labelAllCountriesExceptDots' => __( 'All countries except...', 'woocommerce-multilingual' ),
|
239 |
'labelSpecificCountries' => __( 'Specific countries', 'woocommerce-multilingual' ),
|
240 |
'labelModeSelect' => __( 'Show currencies based on', 'woocommerce-multilingual' ),
|
241 |
+
'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 />' .
|
242 |
+
'<a href="' . \WCML_Tracking_Link::getWpmlPurchase( true ) . '" class="wpml-external-link" target="_blank">' . esc_html__( 'Purchase WPML now', 'woocommerce-multilingual' ) . '</a>',
|
243 |
'labelSiteLanguage' => __( 'Site Language', 'woocommerce-multilingual' ),
|
244 |
'labelClientLocation' => __( 'Client Location', 'woocommerce-multilingual' ),
|
245 |
'labelLocationBased' => __( 'Location based', 'woocommerce-multilingual' ),
|
246 |
+
'maxMindDescription' => __( 'WooCommerce integrates with MaxMind Geolocation to reliably determine the location of your customers.', 'woocommerce-multilingual' ),
|
247 |
'maxMindSuccess' => __( 'Great! Now you can use Geolocation to determine default currency for chosen languages. You can edit that key in ', 'woocommerce-multilingual' ),
|
248 |
'maxMindSettingLink' => admin_url( 'admin.php?page=wc-settings&tab=integration' ),
|
249 |
'maxMindSettingLinkText' => __( 'WooCommerce settings page.', 'woocommerce-multilingual' ),
|
250 |
'maxMindLabel' => __( 'MaxMind Licence Key', 'woocommerce-multilingual' ),
|
251 |
'apply' => __( 'Apply', 'woocommerce-multilingual' ),
|
252 |
+
'maxMindNote' => __( 'Please note: without a free MaxMind key, your geolocation calls will be limited and your site performance may be impacted.', 'woocommerce-multilingual' ),
|
253 |
'maxMindDocLink' => 'https://docs.woocommerce.com/document/maxmind-geolocation-integration/',
|
254 |
+
'maxMindDocLinkText' => __( 'Learn how to generate a free license key', 'woocommerce-multilingual' ),
|
255 |
];
|
256 |
}
|
257 |
|
270 |
return wpml_collect( WC()->countries->get_countries() )->map( $buildCountry )->values()->toArray();
|
271 |
}
|
272 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
273 |
/**
|
274 |
* @return bool
|
275 |
*/
|
287 |
public static function formatLastRateUpdate( $lastRateUpdate ) {
|
288 |
return $lastRateUpdate
|
289 |
? sprintf(
|
290 |
+
/* translators: %s is a date */
|
291 |
__( 'Set on %s', 'woocommerce-multilingual' ),
|
292 |
date( 'F j, Y g:i a', strtotime( $lastRateUpdate ) )
|
293 |
)
|
classes/Options/WPML.php
CHANGED
@@ -22,4 +22,12 @@ class WPML {
|
|
22 |
Automatic::set( $postType, $state );
|
23 |
}
|
24 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
25 |
}
|
22 |
Automatic::set( $postType, $state );
|
23 |
}
|
24 |
}
|
25 |
+
|
26 |
+
/**
|
27 |
+
* @return bool
|
28 |
+
*/
|
29 |
+
public static function useAte() {
|
30 |
+
return method_exists( \WPML_TM_ATE_Status::class, 'is_enabled_and_activated' )
|
31 |
+
&& \WPML_TM_ATE_Status::is_enabled_and_activated();
|
32 |
+
}
|
33 |
}
|
classes/PaymentGateways/Hooks.php
CHANGED
@@ -6,13 +6,14 @@ use IWPML_Backend_Action;
|
|
6 |
use IWPML_Frontend_Action;
|
7 |
use IWPML_DIC_Action;
|
8 |
use WCML\MultiCurrency\Geolocation;
|
|
|
9 |
use WCML\Utilities\Resources;
|
10 |
use WPML\FP\Maybe;
|
11 |
use WPML\FP\Obj;
|
12 |
use WPML\FP\Relation;
|
13 |
|
14 |
|
15 |
-
class Hooks implements IWPML_Backend_Action, IWPML_Frontend_Action, IWPML_DIC_Action {
|
16 |
|
17 |
const OPTION_KEY = 'wcml_payment_gateways';
|
18 |
/* took this priority from wcgcl but we could not recall the reason of this number.*/
|
@@ -153,7 +154,7 @@ class Hooks implements IWPML_Backend_Action, IWPML_Frontend_Action, IWPML_DIC_Ac
|
|
153 |
|
154 |
$text = '<div id="message" class="updated error">';
|
155 |
$text .= '<p>';
|
156 |
-
$text .= __( 'We noticed that you\'re using WooCommerce Gateways Country Limiter plugin which is now integrated into WooCommerce Multilingual. Please remove it!', 'woocommerce-multilingual' );
|
157 |
$text .= '</p>';
|
158 |
$text .= '</div>';
|
159 |
|
6 |
use IWPML_Frontend_Action;
|
7 |
use IWPML_DIC_Action;
|
8 |
use WCML\MultiCurrency\Geolocation;
|
9 |
+
use WCML\StandAlone\IStandAloneAction;
|
10 |
use WCML\Utilities\Resources;
|
11 |
use WPML\FP\Maybe;
|
12 |
use WPML\FP\Obj;
|
13 |
use WPML\FP\Relation;
|
14 |
|
15 |
|
16 |
+
class Hooks implements IWPML_Backend_Action, IWPML_Frontend_Action, IWPML_DIC_Action, IStandAloneAction {
|
17 |
|
18 |
const OPTION_KEY = 'wcml_payment_gateways';
|
19 |
/* took this priority from wcgcl but we could not recall the reason of this number.*/
|
154 |
|
155 |
$text = '<div id="message" class="updated error">';
|
156 |
$text .= '<p>';
|
157 |
+
$text .= __( 'We noticed that you\'re using WooCommerce Gateways Country Limiter plugin which is now integrated into WooCommerce Multilingual & Multicurrency. Please remove it!', 'woocommerce-multilingual' );
|
158 |
$text .= '</p>';
|
159 |
$text .= '</div>';
|
160 |
|
classes/Reports/Orders/Factory.php
DELETED
@@ -1,29 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
namespace WCML\Reports\Orders;
|
4 |
-
|
5 |
-
class Factory implements \IWPML_Backend_Action_Loader, \IWPML_REST_Action_Loader, \IWPML_Deferred_Action_Loader {
|
6 |
-
|
7 |
-
/**
|
8 |
-
* @return string
|
9 |
-
*/
|
10 |
-
public function get_load_action() {
|
11 |
-
return 'init';
|
12 |
-
}
|
13 |
-
|
14 |
-
/**
|
15 |
-
* @return \IWPML_Action|null
|
16 |
-
*/
|
17 |
-
public function create() {
|
18 |
-
/**
|
19 |
-
* @global \wpdb $GLOBALS['wpdb']
|
20 |
-
* @name $wpdb
|
21 |
-
*/
|
22 |
-
global $wpdb;
|
23 |
-
|
24 |
-
if ( wcml_is_multi_currency_on() ) {
|
25 |
-
return new Hooks( $wpdb );
|
26 |
-
}
|
27 |
-
}
|
28 |
-
|
29 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
classes/Reports/Orders/Hooks.php
CHANGED
@@ -4,10 +4,8 @@ namespace WCML\Reports\Orders;
|
|
4 |
|
5 |
use WCML\Utilities\Resources;
|
6 |
use WCML\Rest\Functions;
|
7 |
-
use WPML\FP\Obj;
|
8 |
-
use WPML\FP\Fns;
|
9 |
|
10 |
-
class Hooks implements \
|
11 |
|
12 |
/** @var \wpdb $wpdb */
|
13 |
private $wpdb;
|
4 |
|
5 |
use WCML\Utilities\Resources;
|
6 |
use WCML\Rest\Functions;
|
|
|
|
|
7 |
|
8 |
+
class Hooks implements \IWPML_Backend_Action, \IWPML_REST_Action, \IWPML_DIC_Action {
|
9 |
|
10 |
/** @var \wpdb $wpdb */
|
11 |
private $wpdb;
|
classes/Reports/Products/Query.php
CHANGED
@@ -15,6 +15,8 @@ class Query implements \IWPML_REST_Action {
|
|
15 |
if ( Functions::isAnalyticsRestRequest() ) {
|
16 |
add_filter( 'woocommerce_analytics_products_select_query', [ $this, 'joinProductTranslations' ] );
|
17 |
add_filter( 'woocommerce_analytics_products_select_query', [ $this, 'translateProductTitles' ] );
|
|
|
|
|
18 |
}
|
19 |
}
|
20 |
|
@@ -177,10 +179,12 @@ class Query implements \IWPML_REST_Action {
|
|
177 |
if ( $product ) {
|
178 |
$row['extended_info']['name'] = $product->get_title();
|
179 |
}
|
180 |
-
|
181 |
-
|
182 |
-
|
183 |
-
|
|
|
|
|
184 |
}
|
185 |
return $row;
|
186 |
} )->toArray();
|
15 |
if ( Functions::isAnalyticsRestRequest() ) {
|
16 |
add_filter( 'woocommerce_analytics_products_select_query', [ $this, 'joinProductTranslations' ] );
|
17 |
add_filter( 'woocommerce_analytics_products_select_query', [ $this, 'translateProductTitles' ] );
|
18 |
+
add_filter( 'woocommerce_analytics_variations_select_query', [ $this, 'joinProductTranslations' ] );
|
19 |
+
add_filter( 'woocommerce_analytics_variations_select_query', [ $this, 'translateProductTitles' ] );
|
20 |
}
|
21 |
}
|
22 |
|
179 |
if ( $product ) {
|
180 |
$row['extended_info']['name'] = $product->get_title();
|
181 |
}
|
182 |
+
if ( isset( $row['extended_info']['category_ids'] ) ) {
|
183 |
+
$row['extended_info']['category_ids'] = wpml_collect( $row['extended_info']['category_ids'] )
|
184 |
+
->map( function( $id ) {
|
185 |
+
return apply_filters( 'wpml_object_id', $id, 'product_cat', true );
|
186 |
+
} )->toArray();
|
187 |
+
}
|
188 |
}
|
189 |
return $row;
|
190 |
} )->toArray();
|
classes/Rest/Exceptions/InvalidCurrency.php
CHANGED
@@ -12,6 +12,7 @@ class InvalidCurrency extends WC_REST_Exception {
|
|
12 |
public function __construct( $currency_code ) {
|
13 |
parent::__construct(
|
14 |
422,
|
|
|
15 |
sprintf( __( 'Invalid currency parameter: "%s"', 'woocommerce-multilingual' ),
|
16 |
$currency_code ),
|
17 |
422
|
12 |
public function __construct( $currency_code ) {
|
13 |
parent::__construct(
|
14 |
422,
|
15 |
+
/* translators: $s is a currency code */
|
16 |
sprintf( __( 'Invalid currency parameter: "%s"', 'woocommerce-multilingual' ),
|
17 |
$currency_code ),
|
18 |
422
|
classes/Rest/Exceptions/InvalidLanguage.php
CHANGED
@@ -12,6 +12,7 @@ class InvalidLanguage extends WC_REST_Exception {
|
|
12 |
public function __construct( $language_code ) {
|
13 |
parent::__construct(
|
14 |
422,
|
|
|
15 |
sprintf( __( 'Invalid language parameter: "%s"', 'woocommerce-multilingual' ),
|
16 |
$language_code ),
|
17 |
422
|
12 |
public function __construct( $language_code ) {
|
13 |
parent::__construct(
|
14 |
422,
|
15 |
+
/* translators: $s is a language code */
|
16 |
sprintf( __( 'Invalid language parameter: "%s"', 'woocommerce-multilingual' ),
|
17 |
$language_code ),
|
18 |
422
|
classes/Rest/Exceptions/InvalidProduct.php
CHANGED
@@ -12,6 +12,7 @@ class InvalidProduct extends WC_REST_Exception {
|
|
12 |
public function __construct( $product_id ) {
|
13 |
parent::__construct(
|
14 |
422,
|
|
|
15 |
sprintf( __( 'Product not found: %d', 'woocommerce-multilingual' ),
|
16 |
$product_id ),
|
17 |
422
|
12 |
public function __construct( $product_id ) {
|
13 |
parent::__construct(
|
14 |
422,
|
15 |
+
/* translators: $s is a product ID */
|
16 |
sprintf( __( 'Product not found: %d', 'woocommerce-multilingual' ),
|
17 |
$product_id ),
|
18 |
422
|
classes/Rest/Exceptions/InvalidTerm.php
CHANGED
@@ -12,6 +12,7 @@ class InvalidTerm extends WC_REST_Exception {
|
|
12 |
public function __construct( $term_id ) {
|
13 |
parent::__construct(
|
14 |
422,
|
|
|
15 |
sprintf( __( 'Term not found: %d', 'woocommerce-multilingual' ),
|
16 |
$term_id ),
|
17 |
422
|
12 |
public function __construct( $term_id ) {
|
13 |
parent::__construct(
|
14 |
422,
|
15 |
+
/* translators: $s is a term ID */
|
16 |
sprintf( __( 'Term not found: %d', 'woocommerce-multilingual' ),
|
17 |
$term_id ),
|
18 |
422
|
classes/Rest/Functions.php
CHANGED
@@ -71,11 +71,4 @@ class Functions {
|
|
71 |
return ( false !== stripos( $_SERVER['REQUEST_URI'], $rest_prefix . $endpoint ) );
|
72 |
}
|
73 |
|
74 |
-
/**
|
75 |
-
* Use url without the language parameter. Needed for the signature match.
|
76 |
-
*/
|
77 |
-
public static function removeWpmlGlobalUrlFilters() {
|
78 |
-
global $wpml_url_filters;
|
79 |
-
remove_filter( 'home_url', [ $wpml_url_filters, 'home_url_filter' ], - 10 );
|
80 |
-
}
|
81 |
}
|
71 |
return ( false !== stripos( $_SERVER['REQUEST_URI'], $rest_prefix . $endpoint ) );
|
72 |
}
|
73 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
74 |
}
|
classes/Rest/Generic.php
CHANGED
@@ -2,6 +2,8 @@
|
|
2 |
|
3 |
namespace WCML\Rest;
|
4 |
|
|
|
|
|
5 |
class Generic {
|
6 |
|
7 |
/**
|
@@ -19,7 +21,7 @@ class Generic {
|
|
19 |
}
|
20 |
|
21 |
/**
|
22 |
-
* @param WP_Query $wp_query
|
23 |
*/
|
24 |
public static function autoAdjustIncludedIds( \WP_Query $wp_query ) {
|
25 |
$lang = $wp_query->get( 'lang' );
|
@@ -33,4 +35,22 @@ class Generic {
|
|
33 |
}
|
34 |
}
|
35 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
36 |
}
|
2 |
|
3 |
namespace WCML\Rest;
|
4 |
|
5 |
+
use WPML\FP\Fns;
|
6 |
+
|
7 |
class Generic {
|
8 |
|
9 |
/**
|
21 |
}
|
22 |
|
23 |
/**
|
24 |
+
* @param \WP_Query $wp_query
|
25 |
*/
|
26 |
public static function autoAdjustIncludedIds( \WP_Query $wp_query ) {
|
27 |
$lang = $wp_query->get( 'lang' );
|
35 |
}
|
36 |
}
|
37 |
|
38 |
+
/**
|
39 |
+
* We need an unfiltered 'home_url' so that the REST signature matches.
|
40 |
+
*
|
41 |
+
* Note that WPML already does this, but fails to recognize a REST
|
42 |
+
* request when we get a 'relative' home_url.
|
43 |
+
*/
|
44 |
+
public static function removeHomeUrlFilterOnRestAuthentication() {
|
45 |
+
$returnTrue = Fns::always( true );
|
46 |
+
|
47 |
+
add_filter( 'determine_current_user', Fns::tap( function() use ( $returnTrue ) {
|
48 |
+
add_filter( 'wpml_skip_convert_url_string', $returnTrue );
|
49 |
+
} ), 10 );
|
50 |
+
|
51 |
+
add_filter( 'determine_current_user', Fns::tap( function() use ( $returnTrue ) {
|
52 |
+
remove_filter( 'wpml_skip_convert_url_string', $returnTrue );
|
53 |
+
} ), 20 );
|
54 |
+
}
|
55 |
+
|
56 |
}
|
classes/Rest/ProductSaveActions.php
CHANGED
@@ -22,7 +22,7 @@ class ProductSaveActions extends \WPML_Post_Translation {
|
|
22 |
public function __construct(
|
23 |
array $settings,
|
24 |
\wpdb $wpdb,
|
25 |
-
\
|
26 |
\WCML_Synchronize_Product_Data $productDataSync
|
27 |
) {
|
28 |
parent::__construct( $settings, $wpdb );
|
22 |
public function __construct(
|
23 |
array $settings,
|
24 |
\wpdb $wpdb,
|
25 |
+
\WPML\Core\ISitePress $sitepress,
|
26 |
\WCML_Synchronize_Product_Data $productDataSync
|
27 |
) {
|
28 |
parent::__construct( $settings, $wpdb );
|
classes/Rest/Wrapper/ProductTerms.php
CHANGED
@@ -18,7 +18,7 @@ class ProductTerms extends Handler {
|
|
18 |
private $wcmlTerms;
|
19 |
|
20 |
public function __construct(
|
21 |
-
\
|
22 |
\WPML_Term_Translation $wpmlTermTranslations,
|
23 |
\WCML_Terms $wcmlTerms
|
24 |
) {
|
18 |
private $wcmlTerms;
|
19 |
|
20 |
public function __construct(
|
21 |
+
\WPML\Core\ISitePress $sitepress,
|
22 |
\WPML_Term_Translation $wpmlTermTranslations,
|
23 |
\WCML_Terms $wcmlTerms
|
24 |
) {
|
classes/Rest/Wrapper/Products/Products.php
CHANGED
@@ -22,7 +22,7 @@ class Products extends Handler {
|
|
22 |
private $productSaveActions;
|
23 |
|
24 |
public function __construct(
|
25 |
-
\
|
26 |
\WPML_Post_Translation $wpmlPostTranslations,
|
27 |
\WPML_Query_Filter $wpmlQueryFilter,
|
28 |
ProductSaveActions $productSaveActions
|
22 |
private $productSaveActions;
|
23 |
|
24 |
public function __construct(
|
25 |
+
\WPML\Core\ISitePress $sitepress,
|
26 |
\WPML_Post_Translation $wpmlPostTranslations,
|
27 |
\WPML_Query_Filter $wpmlQueryFilter,
|
28 |
ProductSaveActions $productSaveActions
|
classes/Rest/Wrapper/Reports/ProductsCount.php
CHANGED
@@ -14,7 +14,7 @@ class ProductsCount extends Handler {
|
|
14 |
private $wpdb;
|
15 |
|
16 |
public function __construct(
|
17 |
-
\
|
18 |
\wpdb $wpdb
|
19 |
) {
|
20 |
$this->sitepress = $sitepress;
|
14 |
private $wpdb;
|
15 |
|
16 |
public function __construct(
|
17 |
+
\WPML\Core\ISitePress $sitepress,
|
18 |
\wpdb $wpdb
|
19 |
) {
|
20 |
$this->sitepress = $sitepress;
|
classes/Rest/Wrapper/Reports/TopSeller.php
CHANGED
@@ -12,7 +12,7 @@ class TopSeller extends Handler {
|
|
12 |
private $sitepress;
|
13 |
|
14 |
public function __construct(
|
15 |
-
\
|
16 |
) {
|
17 |
$this->sitepress = $sitepress;
|
18 |
}
|
12 |
private $sitepress;
|
13 |
|
14 |
public function __construct(
|
15 |
+
\WPML\Core\ISitePress $sitepress
|
16 |
) {
|
17 |
$this->sitepress = $sitepress;
|
18 |
}
|
classes/Reviews/Translations/Factory.php
CHANGED
@@ -4,7 +4,7 @@ namespace WCML\Reviews\Translations;
|
|
4 |
|
5 |
use function WPML\Container\make;
|
6 |
|
7 |
-
class Factory implements \IWPML_Deferred_Action_Loader, \IWPML_Frontend_Action_Loader {
|
8 |
|
9 |
|
10 |
public function create() {
|
4 |
|
5 |
use function WPML\Container\make;
|
6 |
|
7 |
+
class Factory implements \IWPML_Deferred_Action_Loader, \IWPML_Frontend_Action_Loader, \IWPML_AJAX_Action_Loader {
|
8 |
|
9 |
|
10 |
public function create() {
|
classes/RewriteRules/Hooks.php
CHANGED
@@ -7,7 +7,7 @@ class Hooks implements \IWPML_Backend_Action, \IWPML_Frontend_Action, \IWPML_DIC
|
|
7 |
/** @var \SitePress $sitepress */
|
8 |
private $sitepress;
|
9 |
|
10 |
-
public function __construct( \
|
11 |
$this->sitepress = $sitepress;
|
12 |
}
|
13 |
|
7 |
/** @var \SitePress $sitepress */
|
8 |
private $sitepress;
|
9 |
|
10 |
+
public function __construct( \WPML\Core\ISitePress $sitepress ) {
|
11 |
$this->sitepress = $sitepress;
|
12 |
}
|
13 |
|
classes/StandAlone/ActionFilterLoader.php
ADDED
@@ -0,0 +1,47 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace WCML\StandAlone;
|
4 |
+
|
5 |
+
use WPML_Action_Filter_Loader;
|
6 |
+
|
7 |
+
use function WCML\functions\isStandAlone;
|
8 |
+
|
9 |
+
class ActionFilterLoader {
|
10 |
+
|
11 |
+
/**
|
12 |
+
* @var WPML_Action_Filter_Loader
|
13 |
+
*/
|
14 |
+
private $loader;
|
15 |
+
|
16 |
+
public function __construct( WPML_Action_Filter_Loader $loader = null ) {
|
17 |
+
$this->loader = null === $loader ? new WPML_Action_Filter_Loader() : $loader;
|
18 |
+
}
|
19 |
+
|
20 |
+
/**
|
21 |
+
* Load action filter limiting the loaders processed depending on whether WPML is installed
|
22 |
+
*
|
23 |
+
* @param string[] $loaders Action loaders.
|
24 |
+
*/
|
25 |
+
public function load( $loaders ) {
|
26 |
+
$this->loader->load( $this->mayBeFilterLoaders( $loaders ) );
|
27 |
+
}
|
28 |
+
|
29 |
+
/**
|
30 |
+
* Only pass through IStandAloneAction loaders if WPML is not available.
|
31 |
+
*
|
32 |
+
* @param string[] $loaders Action loaders.
|
33 |
+
* @return string[] $loaders.
|
34 |
+
*/
|
35 |
+
private function mayBeFilterLoaders( $loaders ) {
|
36 |
+
if ( isStandAlone() ) {
|
37 |
+
$filtered_loaders = [];
|
38 |
+
foreach ( $loaders as $loader ) {
|
39 |
+
if ( is_subclass_of( $loader, IStandAloneAction::class ) ) {
|
40 |
+
$filtered_loaders[] = $loader;
|
41 |
+
}
|
42 |
+
}
|
43 |
+
return $filtered_loaders;
|
44 |
+
}
|
45 |
+
return $loaders;
|
46 |
+
}
|
47 |
+
}
|
classes/StandAlone/Container/Config.php
ADDED
@@ -0,0 +1,53 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace WCML\StandAlone\Container;
|
4 |
+
|
5 |
+
class Config {
|
6 |
+
|
7 |
+
/**
|
8 |
+
* @return array
|
9 |
+
*/
|
10 |
+
public static function getSharedInstances() {
|
11 |
+
global $wpdb;
|
12 |
+
|
13 |
+
return [
|
14 |
+
$wpdb
|
15 |
+
];
|
16 |
+
}
|
17 |
+
|
18 |
+
/**
|
19 |
+
* @return array
|
20 |
+
*/
|
21 |
+
public static function getAliases() {
|
22 |
+
global $wpdb;
|
23 |
+
|
24 |
+
$aliases = [];
|
25 |
+
|
26 |
+
$wpdb_class = get_class( $wpdb );
|
27 |
+
|
28 |
+
if ( 'wpdb' !== $wpdb_class ) {
|
29 |
+
$aliases['wpdb'] = $wpdb_class;
|
30 |
+
}
|
31 |
+
|
32 |
+
return $aliases;
|
33 |
+
}
|
34 |
+
|
35 |
+
/**
|
36 |
+
* @return array
|
37 |
+
*/
|
38 |
+
public static function getSharedClasses() {
|
39 |
+
return [
|
40 |
+
\WPML\Core\ISitePress::class,
|
41 |
+
\WPML_Notices::class,
|
42 |
+
];
|
43 |
+
}
|
44 |
+
|
45 |
+
/**
|
46 |
+
* @return array
|
47 |
+
*/
|
48 |
+
public static function getDelegated() {
|
49 |
+
return [
|
50 |
+
\WPML_Notices::class => 'wcml_wpml_get_admin_notices',
|
51 |
+
];
|
52 |
+
}
|
53 |
+
}
|
classes/StandAlone/DependencyAssets.php
ADDED
@@ -0,0 +1,45 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace WCML\StandAlone;
|
4 |
+
|
5 |
+
use WCML\Utilities\AdminPages;
|
6 |
+
|
7 |
+
class DependencyAssets {
|
8 |
+
|
9 |
+
/** @var string $dependencyBaseUrl */
|
10 |
+
private $dependencyBaseUrl;
|
11 |
+
|
12 |
+
/**
|
13 |
+
* @param string $dependencyBaseUrl
|
14 |
+
*/
|
15 |
+
public function __construct( $dependencyBaseUrl ) {
|
16 |
+
$this->dependencyBaseUrl = $dependencyBaseUrl;
|
17 |
+
}
|
18 |
+
|
19 |
+
public function add_hooks() {
|
20 |
+
add_action( 'admin_enqueue_scripts', [ $this, 'enqueue' ] );
|
21 |
+
}
|
22 |
+
|
23 |
+
public function enqueue() {
|
24 |
+
wp_register_script( 'wpml-scripts', $this->dependencyBaseUrl . '/res/js/scripts.js', [], WCML_VERSION );
|
25 |
+
wp_register_style( 'wpml-styles', $this->dependencyBaseUrl . '/res/css/styles.css', [], WCML_VERSION );
|
26 |
+
wp_register_style( 'otgs-dialogs', $this->dependencyBaseUrl . '/res/css/otgs-dialogs.css', [ 'wp-jquery-ui-dialog' ], WCML_VERSION );
|
27 |
+
wp_register_style( 'wpml-dialog', $this->dependencyBaseUrl . '/res/css/dialog.css', [ 'otgs-dialogs' ], WCML_VERSION );
|
28 |
+
wp_register_style( 'otgs-ico', $this->dependencyBaseUrl . '/res/css/otgs-ico.css', [], WCML_VERSION );
|
29 |
+
|
30 |
+
if ( AdminPages::isMultiCurrency() || AdminPages::isTab( 'multilingual' ) ) {
|
31 |
+
wp_enqueue_script( 'wpml-scripts' );
|
32 |
+
|
33 |
+
wp_enqueue_style( 'wpml-styles' );
|
34 |
+
wp_enqueue_style( 'wpml-dialog' );
|
35 |
+
|
36 |
+
wp_enqueue_style( \OTGS_Assets_Handles::SWITCHER );
|
37 |
+
wp_enqueue_script( \OTGS_Assets_Handles::SWITCHER );
|
38 |
+
wp_enqueue_style( \OTGS_Assets_Handles::POPOVER_TOOLTIP );
|
39 |
+
wp_enqueue_script( \OTGS_Assets_Handles::POPOVER_TOOLTIP );
|
40 |
+
|
41 |
+
wp_enqueue_style( \OTGS_ASSETS_ICONS_STYLES );
|
42 |
+
wp_enqueue_style( 'otgs-ico' );
|
43 |
+
}
|
44 |
+
}
|
45 |
+
}
|
classes/StandAlone/IStandAloneAction.php
ADDED
@@ -0,0 +1,5 @@
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace WCML\StandAlone;
|
4 |
+
|
5 |
+
interface IStandAloneAction {}
|
classes/StandAlone/NullSitePress.php
ADDED
@@ -0,0 +1,143 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace WCML\StandAlone;
|
4 |
+
|
5 |
+
use WPML\Core\ISitePress;
|
6 |
+
use WPML_WP_API;
|
7 |
+
|
8 |
+
class NullSitePress implements ISitePress {
|
9 |
+
|
10 |
+
/** @var WPML_WP_API */
|
11 |
+
private $wp_api;
|
12 |
+
|
13 |
+
/**
|
14 |
+
* @param bool $refresh
|
15 |
+
* @param bool $major_first
|
16 |
+
* @param string $order_by
|
17 |
+
* @return array
|
18 |
+
*/
|
19 |
+
public function get_active_languages( $refresh = false, $major_first = false, $order_by = 'english_name' ) {
|
20 |
+
$code = $this->get_current_language();
|
21 |
+
return [
|
22 |
+
$code => [
|
23 |
+
'id' => 1,
|
24 |
+
'code' => $code,
|
25 |
+
'major' => 1,
|
26 |
+
'active' => 1,
|
27 |
+
'default_locale' => get_locale(),
|
28 |
+
'encode_url' => 0,
|
29 |
+
'tag' => $code,
|
30 |
+
'english_name' => $code,
|
31 |
+
'native_name' => $code,
|
32 |
+
'display_name' => $code,
|
33 |
+
],
|
34 |
+
];
|
35 |
+
}
|
36 |
+
|
37 |
+
/** @return bool|mixed|null|string */
|
38 |
+
public function get_admin_language() {
|
39 |
+
return $this->get_current_language();
|
40 |
+
}
|
41 |
+
|
42 |
+
/** @return string */
|
43 |
+
public function get_current_language() {
|
44 |
+
return preg_replace( '/_.+/', '', get_locale() );
|
45 |
+
}
|
46 |
+
|
47 |
+
/** @return string|false */
|
48 |
+
public function get_default_language() {
|
49 |
+
return $this->get_current_language();
|
50 |
+
}
|
51 |
+
|
52 |
+
/**
|
53 |
+
* @param int $trid
|
54 |
+
* @param string|null $el_type Use comment, post, page, {custom post time name}, nav_menu, nav_menu_item, category, post_tag, etc. (prefixed with 'post_', 'tax_', or nothing for 'comment').
|
55 |
+
* @param bool|null $skip_empty
|
56 |
+
* @param bool|null $all_statuses
|
57 |
+
* @param bool|null $skip_cache
|
58 |
+
* @param bool|null $skip_recursions
|
59 |
+
* @param bool|null $skipPrivilegeChecking
|
60 |
+
*
|
61 |
+
* @return array<string,\stdClass>
|
62 |
+
*/
|
63 |
+
public function get_element_translations(
|
64 |
+
$trid,
|
65 |
+
$el_type = 'post_post',
|
66 |
+
$skip_empty = false,
|
67 |
+
$all_statuses = false,
|
68 |
+
$skip_cache = false,
|
69 |
+
$skip_recursions = false,
|
70 |
+
$skipPrivilegeChecking = false
|
71 |
+
) {
|
72 |
+
return [];
|
73 |
+
}
|
74 |
+
|
75 |
+
/**
|
76 |
+
* @param string $code
|
77 |
+
* @return string
|
78 |
+
*/
|
79 |
+
public function get_flag_url( $code ) {
|
80 |
+
return '';
|
81 |
+
}
|
82 |
+
|
83 |
+
/**
|
84 |
+
* Find language of document based on given permalink
|
85 |
+
*
|
86 |
+
* @param string $url Local url in permalink form.
|
87 |
+
* @return string language code
|
88 |
+
*/
|
89 |
+
public function get_language_from_url( $url ) {
|
90 |
+
return $this->get_current_language();
|
91 |
+
}
|
92 |
+
|
93 |
+
/**
|
94 |
+
* Filter to add language field to WordPress search form
|
95 |
+
*
|
96 |
+
* @param string $form HTML code of search for before filtering.
|
97 |
+
*
|
98 |
+
* @return string HTML code of search form
|
99 |
+
*/
|
100 |
+
public function get_search_form_filter( $form ) {
|
101 |
+
return $form;
|
102 |
+
}
|
103 |
+
|
104 |
+
/**
|
105 |
+
* @param string $key
|
106 |
+
* @param mixed|bool $default
|
107 |
+
* @return bool|mixed
|
108 |
+
* @since 3.1
|
109 |
+
*/
|
110 |
+
public function get_setting( $key, $default = false ) {
|
111 |
+
return $default;
|
112 |
+
}
|
113 |
+
|
114 |
+
/** @return array */
|
115 |
+
public function get_settings() {
|
116 |
+
return [];
|
117 |
+
}
|
118 |
+
|
119 |
+
/** @return \WPML_WP_API */
|
120 |
+
public function get_wp_api() {
|
121 |
+
$this->wp_api = $this->wp_api ? $this->wp_api : new WPML_WP_API();
|
122 |
+
return $this->wp_api;
|
123 |
+
}
|
124 |
+
|
125 |
+
/**
|
126 |
+
* @param string|bool|null $lang
|
127 |
+
* @return bool
|
128 |
+
*/
|
129 |
+
public function is_rtl( $lang = false ) {
|
130 |
+
return is_rtl();
|
131 |
+
}
|
132 |
+
|
133 |
+
/**
|
134 |
+
* @param int $element_id Use term_taxonomy_id for taxonomies, post_id for posts.
|
135 |
+
* @param string $element_type Use comment, post, page, {custom post time name}, nav_menu, nav_menu_item, category,
|
136 |
+
* post_tag, etc. (prefixed with 'post_', 'tax_', or nothing for 'comment').
|
137 |
+
*
|
138 |
+
* @return null|string
|
139 |
+
*/
|
140 |
+
public function get_language_for_element( $element_id, $element_type ) {
|
141 |
+
return $this->get_current_language();
|
142 |
+
}
|
143 |
+
}
|
classes/StandAlone/UI/AdminMenu.php
ADDED
@@ -0,0 +1,103 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace WCML\StandAlone\UI;
|
4 |
+
|
5 |
+
use WCML\Utilities\AdminPages;
|
6 |
+
use WCML_Admin_Menus;
|
7 |
+
use WCML_Multi_Currency_UI;
|
8 |
+
use WPML\FP\Str;
|
9 |
+
|
10 |
+
class AdminMenu extends \WCML_Menu_Wrap_Base {
|
11 |
+
|
12 |
+
/** @var \SitePress|\WCML\StandAlone\NullSitePress */
|
13 |
+
private $sitepress;
|
14 |
+
|
15 |
+
/**
|
16 |
+
* WCML_Menus_Wrap constructor.
|
17 |
+
*
|
18 |
+
* @param \SitePress|\WCML\StandAlone\NullSitePress $sitepress
|
19 |
+
* @param \woocommerce_wpml $woocommerce_wpml
|
20 |
+
*/
|
21 |
+
public function __construct( \WPML\Core\ISitePress $sitepress, $woocommerce_wpml ) {
|
22 |
+
parent::__construct( $woocommerce_wpml );
|
23 |
+
|
24 |
+
$this->sitepress = $sitepress;
|
25 |
+
}
|
26 |
+
|
27 |
+
/**
|
28 |
+
* @return array
|
29 |
+
*/
|
30 |
+
protected function get_child_model() {
|
31 |
+
$current_tab = AdminPages::getTabToDisplay();
|
32 |
+
|
33 |
+
$model = [
|
34 |
+
'strings' => [
|
35 |
+
'title' => WCML_Admin_Menus::getWcmlLabel(),
|
36 |
+
],
|
37 |
+
'is_standalone' => true,
|
38 |
+
'menu' => [
|
39 |
+
'multilingual' => [
|
40 |
+
'title' => __( 'Multilingual', 'woocommerce-multilingual' ),
|
41 |
+
'active' => 'multilingual' === $current_tab ? 'nav-tab-active' : '',
|
42 |
+
'url' => admin_url( 'admin.php?page=wpml-wcml&tab=multilingual' ),
|
43 |
+
],
|
44 |
+
'multi_currency' => [
|
45 |
+
'name' => __( 'Multicurrency', 'woocommerce-multilingual' ),
|
46 |
+
'active' => 'multi-currency' === $current_tab ? 'nav-tab-active' : '',
|
47 |
+
'url' => admin_url( 'admin.php?page=wpml-wcml&tab=multi-currency' ),
|
48 |
+
],
|
49 |
+
],
|
50 |
+
'content' => $this->get_current_menu_content( $current_tab ),
|
51 |
+
];
|
52 |
+
|
53 |
+
return $model;
|
54 |
+
}
|
55 |
+
|
56 |
+
protected function get_current_menu_content( $current_tab ) {
|
57 |
+
$content = '';
|
58 |
+
switch ( $current_tab ) {
|
59 |
+
case 'multilingual':
|
60 |
+
$inP = Str::wrap( '<p>', '</p>' );
|
61 |
+
$inWrapper = Str::wrap( '<div class="wcml-banner">', '</div>' );
|
62 |
+
|
63 |
+
$wrapLink = function( $text, $url, $isExternal = true ) {
|
64 |
+
$attrs = $isExternal ? ' target="_blank" class="wpml-external-link" ' : '';
|
65 |
+
return sprintf( $text, '<a href="' . $url . '"' . $attrs . '">', '</a>' );
|
66 |
+
};
|
67 |
+
|
68 |
+
/* translators: %1$s and %2$s are opening and closing HTML link tags */
|
69 |
+
$content .= $inP( $wrapLink( esc_html__( 'To run your store in multiple languages, you need to use the %1$sWPML plugin%2$s.', 'woocommerce-multilingual' ), \WCML_Tracking_Link::getWpmlHome( true ) ) );
|
70 |
+
|
71 |
+
$content .= $inP(
|
72 |
+
/* translators: %1$s and %2$s are opening and closing HTML link tags */
|
73 |
+
$wrapLink( esc_html__( 'If you have it already, install and activate it. Otherwise, %1$sbuy WPML%2$s.', 'woocommerce-multilingual' ), \WCML_Tracking_Link::getWpmlPurchase( true ) )
|
74 |
+
. ' ' . esc_html__( 'You will need either the Multilingual CMS or Multilingual Agency package to use WPML with WooCommerce.', 'woocommerce-multilingual' )
|
75 |
+
);
|
76 |
+
|
77 |
+
$content .= $inP(
|
78 |
+
$wrapLink(
|
79 |
+
/* translators: %1$s and %2$s are opening and closing HTML link tags */
|
80 |
+
esc_html__( 'You can still use the %1$smulticurrency features%2$s without buying anything.', 'woocommerce-multilingual' ),
|
81 |
+
admin_url( 'admin.php?page=wpml-wcml&tab=multi-currency' ),
|
82 |
+
false
|
83 |
+
)
|
84 |
+
);
|
85 |
+
|
86 |
+
$content = $inWrapper( $content );
|
87 |
+
break;
|
88 |
+
|
89 |
+
case 'multi-currency':
|
90 |
+
default:
|
91 |
+
if ( current_user_can( 'wpml_operate_woocommerce_multilingual' ) ) {
|
92 |
+
$wcml_mc_ui = new WCML_Multi_Currency_UI( $this->woocommerce_wpml, $this->sitepress );
|
93 |
+
$content = $wcml_mc_ui->get_view();
|
94 |
+
}
|
95 |
+
|
96 |
+
break;
|
97 |
+
}
|
98 |
+
|
99 |
+
return $content;
|
100 |
+
|
101 |
+
}
|
102 |
+
|
103 |
+
}
|
classes/Utilities/AdminPages.php
ADDED
@@ -0,0 +1,103 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace WCML\Utilities;
|
4 |
+
|
5 |
+
use WCML_Admin_Menus;
|
6 |
+
use WCML_Capabilities;
|
7 |
+
use WPML\FP\Lst;
|
8 |
+
use WPML\FP\Obj;
|
9 |
+
use WPML\FP\Relation;
|
10 |
+
use function sanitize_key;
|
11 |
+
use function WCML\functions\isStandAlone;
|
12 |
+
|
13 |
+
class AdminPages {
|
14 |
+
|
15 |
+
const TAB_MULTICURRENCY = 'multi-currency';
|
16 |
+
const TAB_PRODUCTS = 'products';
|
17 |
+
|
18 |
+
/**
|
19 |
+
* @return string
|
20 |
+
*/
|
21 |
+
public static function getDefaultTab() {
|
22 |
+
return isStandAlone() ? self::TAB_MULTICURRENCY : self::TAB_PRODUCTS;
|
23 |
+
}
|
24 |
+
|
25 |
+
/**
|
26 |
+
* @param null|string $fallback
|
27 |
+
*
|
28 |
+
* @return string|null
|
29 |
+
*/
|
30 |
+
public static function getCurrentTab( $fallback = null ) {
|
31 |
+
return sanitize_key( Obj::prop( 'tab', $_GET ) ) ?: $fallback;
|
32 |
+
}
|
33 |
+
|
34 |
+
/**
|
35 |
+
* @return string
|
36 |
+
*/
|
37 |
+
public static function getTabToDisplay() {
|
38 |
+
return WCML_Capabilities::canAccessAllWcmlTabs()
|
39 |
+
? self::getCurrentTab( self::getDefaultTab() )
|
40 |
+
: self::getDefaultTab();
|
41 |
+
}
|
42 |
+
|
43 |
+
/**
|
44 |
+
* @param string|array $tabs A single tab (string) or one of multiple tabs (array).
|
45 |
+
*
|
46 |
+
* @return bool
|
47 |
+
*/
|
48 |
+
public static function isTab( $tabs ) {
|
49 |
+
return Lst::includes( self::getCurrentTab(), (array) $tabs );
|
50 |
+
}
|
51 |
+
|
52 |
+
/**
|
53 |
+
* @param string $page
|
54 |
+
*
|
55 |
+
* @return bool
|
56 |
+
*/
|
57 |
+
public static function isPage( $page ) {
|
58 |
+
return Relation::propEq( 'page', $page, $_GET );
|
59 |
+
}
|
60 |
+
|
61 |
+
/**
|
62 |
+
* @return bool
|
63 |
+
*/
|
64 |
+
public static function isWcmlSettings() {
|
65 |
+
return self::isPage( WCML_Admin_Menus::SLUG );
|
66 |
+
}
|
67 |
+
|
68 |
+
/**
|
69 |
+
* @return bool
|
70 |
+
*/
|
71 |
+
public static function isMultiCurrency() {
|
72 |
+
$tabs = [ self::TAB_MULTICURRENCY ];
|
73 |
+
|
74 |
+
if ( isStandAlone() ) {
|
75 |
+
$tabs[] = null; // Also the default tab in Standalone mode.
|
76 |
+
}
|
77 |
+
|
78 |
+
return self::isWcmlSettings() && self::isTab( $tabs );
|
79 |
+
}
|
80 |
+
|
81 |
+
/**
|
82 |
+
* @return bool
|
83 |
+
*/
|
84 |
+
public static function isTranslationQueue() {
|
85 |
+
return ! isStandAlone() && self::isTmPage( '/menu/translations-queue.php' );
|
86 |
+
}
|
87 |
+
|
88 |
+
/**
|
89 |
+
* @return bool
|
90 |
+
*/
|
91 |
+
public static function isTranslationsDashboard() {
|
92 |
+
return ! isStandAlone() && self::isTmPage( '/menu/main.php' );
|
93 |
+
}
|
94 |
+
|
95 |
+
/**
|
96 |
+
* @param string $path Path after the TM folder (e.g. '/menu/main.php')
|
97 |
+
*
|
98 |
+
* @return bool
|
99 |
+
*/
|
100 |
+
private static function isTmPage( $path ) {
|
101 |
+
return defined( 'WPML_TM_FOLDER' ) && self::isPage( WPML_TM_FOLDER . $path );
|
102 |
+
}
|
103 |
+
}
|
classes/Utilities/DB.php
ADDED
@@ -0,0 +1,38 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace WCML\Utilities;
|
4 |
+
|
5 |
+
use wpdb;
|
6 |
+
|
7 |
+
class DB {
|
8 |
+
|
9 |
+
/**
|
10 |
+
* Changes array of items into string of items, separated by comma and sql-escaped
|
11 |
+
*
|
12 |
+
* @see https://coderwall.com/p/zepnaw
|
13 |
+
* @see wpml_prepare_in
|
14 |
+
*
|
15 |
+
* @global wpdb $wpdb
|
16 |
+
*
|
17 |
+
* @param mixed|array $items item(s) to be joined into string
|
18 |
+
* @param string $format %s or %d
|
19 |
+
*
|
20 |
+
* @return string Items separated by comma and sql-escaped
|
21 |
+
*/
|
22 |
+
public static function prepareIn( $items, $format = '%s') {
|
23 |
+
/** @var wpdb $wpdb */
|
24 |
+
global $wpdb;
|
25 |
+
|
26 |
+
$items = (array) $items;
|
27 |
+
$how_many = count( $items );
|
28 |
+
if ( $how_many > 0 ) {
|
29 |
+
$placeholders = array_fill( 0, $how_many, $format );
|
30 |
+
$prepared_format = implode( ',', $placeholders );
|
31 |
+
$prepared_in = $wpdb->prepare( $prepared_format, $items );
|
32 |
+
} else {
|
33 |
+
$prepared_in = '';
|
34 |
+
}
|
35 |
+
|
36 |
+
return $prepared_in;
|
37 |
+
}
|
38 |
+
}
|
classes/Utilities/WcAdminPages.php
ADDED
@@ -0,0 +1,53 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace WCML\Utilities;
|
4 |
+
|
5 |
+
use WPML\FP\Lst;
|
6 |
+
use WPML\FP\Obj;
|
7 |
+
|
8 |
+
class WcAdminPages {
|
9 |
+
|
10 |
+
const SECTION_BACS = 'bacs';
|
11 |
+
|
12 |
+
/**
|
13 |
+
* @param string|array $sections A single section (string) or one of multiple sections (array).
|
14 |
+
*
|
15 |
+
* @return bool
|
16 |
+
*/
|
17 |
+
public static function isSection( $sections ) {
|
18 |
+
return Lst::includes( Obj::prop( 'section', $_GET ), (array) $sections );
|
19 |
+
}
|
20 |
+
|
21 |
+
/**
|
22 |
+
* @return bool
|
23 |
+
*/
|
24 |
+
private static function isSettingsPage() {
|
25 |
+
return self::isAdminPhpPage( 'wc-settings' );
|
26 |
+
}
|
27 |
+
|
28 |
+
/**
|
29 |
+
* @return bool
|
30 |
+
*/
|
31 |
+
public static function isHomeScreen() {
|
32 |
+
return self::isAdminPhpPage( 'wc-admin' );
|
33 |
+
}
|
34 |
+
|
35 |
+
/**
|
36 |
+
* @return bool
|
37 |
+
*/
|
38 |
+
public static function isPaymentSettings() {
|
39 |
+
return self::isSettingsPage() && AdminPages::isTab( 'checkout' );
|
40 |
+
}
|
41 |
+
|
42 |
+
/**
|
43 |
+
* @param string $page
|
44 |
+
*
|
45 |
+
* @return bool
|
46 |
+
*/
|
47 |
+
private static function isAdminPhpPage( $page ) {
|
48 |
+
global $pagenow;
|
49 |
+
|
50 |
+
return is_admin() && 'admin.php' === $pagenow && AdminPages::isPage( $page );
|
51 |
+
}
|
52 |
+
|
53 |
+
}
|
classes/Utilities/WpAdminPages.php
ADDED
@@ -0,0 +1,15 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace WCML\Utilities;
|
4 |
+
|
5 |
+
class WpAdminPages {
|
6 |
+
|
7 |
+
/**
|
8 |
+
* @return bool
|
9 |
+
*/
|
10 |
+
public static function isDashboard() {
|
11 |
+
global $pagenow;
|
12 |
+
|
13 |
+
return is_admin() && 'index.php' === $pagenow;
|
14 |
+
}
|
15 |
+
}
|
classes/class-wcml-tracking-link.php
CHANGED
@@ -4,6 +4,7 @@ class WCML_Tracking_Link {
|
|
4 |
|
5 |
// WPML general links
|
6 |
const WPML_HOME = 'https://wpml.org/';
|
|
|
7 |
const WPML_SUPPORT = 'https://wpml.org/forums/forum/english-support/';
|
8 |
const WPML_ACCOUNT = 'https://wpml.org/shop/account/';
|
9 |
const WPML_AUTO_TRANSLATION_DOC = 'https://wpml.org/documentation/automatic-translation/';
|
@@ -28,12 +29,12 @@ class WCML_Tracking_Link {
|
|
28 |
*
|
29 |
* @return string
|
30 |
*/
|
31 |
-
public static function generate( $link, $id = false ) {
|
32 |
-
$params = [
|
33 |
'utm_source' => 'plugin',
|
34 |
'utm_medium' => 'gui',
|
35 |
'utm_campaign' => 'wcml',
|
36 |
-
];
|
37 |
|
38 |
$link = add_query_arg( $params, $link );
|
39 |
|
@@ -45,10 +46,30 @@ class WCML_Tracking_Link {
|
|
45 |
}
|
46 |
|
47 |
/**
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
48 |
* @return string
|
49 |
*/
|
50 |
-
public static function
|
51 |
-
return self::generate( self::
|
52 |
}
|
53 |
|
54 |
/**
|
4 |
|
5 |
// WPML general links
|
6 |
const WPML_HOME = 'https://wpml.org/';
|
7 |
+
const WPML_PURCHASE = 'https://wpml.org/purchase/';
|
8 |
const WPML_SUPPORT = 'https://wpml.org/forums/forum/english-support/';
|
9 |
const WPML_ACCOUNT = 'https://wpml.org/shop/account/';
|
10 |
const WPML_AUTO_TRANSLATION_DOC = 'https://wpml.org/documentation/automatic-translation/';
|
29 |
*
|
30 |
* @return string
|
31 |
*/
|
32 |
+
public static function generate( $link, $id = false, $params = [] ) {
|
33 |
+
$params = array_merge( [
|
34 |
'utm_source' => 'plugin',
|
35 |
'utm_medium' => 'gui',
|
36 |
'utm_campaign' => 'wcml',
|
37 |
+
], $params );
|
38 |
|
39 |
$link = add_query_arg( $params, $link );
|
40 |
|
46 |
}
|
47 |
|
48 |
/**
|
49 |
+
* @param bool $isStandalone
|
50 |
+
*
|
51 |
+
* @return array
|
52 |
+
*/
|
53 |
+
private static function getStandaloneParams( $isStandalone ) {
|
54 |
+
return $isStandalone ? [ 'utm_campaign' => 'wcml-standalone' ] : [];
|
55 |
+
}
|
56 |
+
|
57 |
+
/**
|
58 |
+
* @param bool $isStandalone
|
59 |
+
*
|
60 |
+
* @return string
|
61 |
+
*/
|
62 |
+
public static function getWpmlHome( $isStandalone = false ) {
|
63 |
+
return self::generate( self::WPML_HOME, false, self::getStandaloneParams( $isStandalone ) );
|
64 |
+
}
|
65 |
+
|
66 |
+
/**
|
67 |
+
* @param bool $isStandalone
|
68 |
+
*
|
69 |
* @return string
|
70 |
*/
|
71 |
+
public static function getWpmlPurchase( $isStandalone = false ) {
|
72 |
+
return self::generate( self::WPML_PURCHASE, false, self::getStandaloneParams( $isStandalone ) );
|
73 |
}
|
74 |
|
75 |
/**
|
classes/class-woocommerce-wpml.php
CHANGED
@@ -1,5 +1,8 @@
|
|
1 |
<?php
|
2 |
|
|
|
|
|
|
|
3 |
use function WPML\Container\make;
|
4 |
|
5 |
/**
|
@@ -57,10 +60,21 @@ class woocommerce_wpml {
|
|
57 |
public $comments;
|
58 |
/** @var WCML_Translation_Editor */
|
59 |
public $translation_editor;
|
60 |
-
|
|
|
|
|
|
|
|
|
|
|
61 |
public $dependencies;
|
62 |
-
|
|
|
|
|
|
|
|
|
|
|
63 |
public $dependencies_are_ok;
|
|
|
64 |
/** @var WCML_Cart */
|
65 |
public $cart;
|
66 |
/** @var WCML_Cart_Sync_Warnings */
|
@@ -86,7 +100,7 @@ class woocommerce_wpml {
|
|
86 |
private $wcml_products_screen;
|
87 |
|
88 |
public function __construct() {
|
89 |
-
|
90 |
|
91 |
$this->settings = $this->get_settings();
|
92 |
$this->currencies = new WCML_Currencies( $this );
|
@@ -95,20 +109,20 @@ class woocommerce_wpml {
|
|
95 |
|
96 |
add_action( 'init', [ $this, 'init' ], 2 );
|
97 |
|
98 |
-
|
99 |
-
|
100 |
-
|
101 |
-
$this->cs_templates = new WCML_Currency_Switcher_Templates( $this, $wpml_wp_api, new WPML_File( $wpml_wp_api ) );
|
102 |
-
$this->cs_templates->init_hooks();
|
103 |
|
104 |
-
|
105 |
-
|
106 |
-
|
|
|
|
|
107 |
|
108 |
}
|
109 |
|
110 |
private function load_rest_api() {
|
111 |
-
|
112 |
|
113 |
if ( class_exists( 'WooCommerce' ) && defined( 'WC_VERSION' ) && ! is_null( $sitepress ) && WCML\Rest\Functions::isRestApiRequest() ) {
|
114 |
WCML\Rest\Hooks::addHooks();
|
@@ -130,16 +144,17 @@ class woocommerce_wpml {
|
|
130 |
* @return bool
|
131 |
*/
|
132 |
public function init() {
|
133 |
-
global $
|
134 |
|
135 |
-
$
|
|
|
|
|
136 |
$this->dependencies_are_ok = $this->dependencies->check();
|
137 |
|
138 |
WCML_Admin_Menus::set_up_menus( $this, $sitepress, $wpdb );
|
139 |
|
140 |
if ( ! $this->dependencies_are_ok ) {
|
141 |
-
|
142 |
-
if ( is_admin() && $is_dashboard_page ) {
|
143 |
WCML_Capabilities::set_up_capabilities();
|
144 |
|
145 |
wp_register_style( 'otgs-ico', WCML_PLUGIN_URL . '/res/css/otgs-ico.css', null, WCML_VERSION );
|
@@ -148,13 +163,12 @@ class woocommerce_wpml {
|
|
148 |
WCML_Resources::load_management_css();
|
149 |
WCML_Resources::load_tooltip_resources();
|
150 |
}
|
|
|
151 |
return false;
|
152 |
}
|
153 |
|
154 |
new WCML_Upgrade();
|
155 |
|
156 |
-
$this->compatibility = new WCML_Compatibility( $sitepress, $this, $wpdb, new WPML_Element_Translation_Package(), $wpml_post_translations );
|
157 |
-
|
158 |
$actions_that_need_mc = [
|
159 |
'save-mc-options',
|
160 |
'wcml_save_currency',
|
@@ -172,17 +186,31 @@ class woocommerce_wpml {
|
|
172 |
|
173 |
$this->cart = new WCML_Cart( $this, $sitepress, $woocommerce );
|
174 |
|
|
|
175 |
if ( WCML_MULTI_CURRENCIES_INDEPENDENT === (int) $this->settings['enable_multi_currency']
|
176 |
-
|| (
|
177 |
-
|| (
|
178 |
) {
|
179 |
$this->get_multi_currency();
|
180 |
-
$wcml_price_filters
|
181 |
$wcml_price_filters->add_hooks();
|
182 |
} else {
|
183 |
add_shortcode( 'currency_switcher', '__return_empty_string' );
|
184 |
}
|
185 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
186 |
$this->currencies = new WCML_Currencies( $this );
|
187 |
$this->currencies->add_hooks();
|
188 |
|
@@ -214,7 +242,7 @@ class woocommerce_wpml {
|
|
214 |
$this->store->add_hooks();
|
215 |
$this->strings = new WCML_WC_Strings( $this, $sitepress, $wpdb );
|
216 |
$this->strings->add_hooks();
|
217 |
-
// do not pass mailer instance instead of $woocommerce
|
218 |
$this->emails = new WCML_Emails( $this->strings, $sitepress, $woocommerce, $wpdb );
|
219 |
$this->emails->add_hooks();
|
220 |
$this->terms = new WCML_Terms( $this, $sitepress, $wpdb );
|
@@ -273,6 +301,31 @@ class woocommerce_wpml {
|
|
273 |
return true;
|
274 |
}
|
275 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
276 |
/**
|
277 |
* Get settings
|
278 |
*
|
@@ -470,7 +523,7 @@ class woocommerce_wpml {
|
|
470 |
* @return bool
|
471 |
*/
|
472 |
public function is_wpml_prior_4_2() {
|
473 |
-
|
474 |
|
475 |
return $sitepress->get_wp_api()->version_compare( $this->get_constant( 'ICL_SITEPRESS_VERSION' ), '4.2.0', '<' ) ||
|
476 |
$sitepress->get_wp_api()->version_compare( $this->get_constant( 'WPML_TM_VERSION' ), '2.8.0', '<' );
|
@@ -482,8 +535,6 @@ class woocommerce_wpml {
|
|
482 |
* @return int|string
|
483 |
*/
|
484 |
private function get_constant( $name ) {
|
485 |
-
|
486 |
-
|
487 |
-
return $sitepress->get_wp_api()->constant( $name );
|
488 |
}
|
489 |
}
|
1 |
<?php
|
2 |
|
3 |
+
use WCML\Utilities\AdminPages;
|
4 |
+
use function WCML\functions\getSitePress;
|
5 |
+
use function WCML\functions\isStandAlone;
|
6 |
use function WPML\Container\make;
|
7 |
|
8 |
/**
|
60 |
public $comments;
|
61 |
/** @var WCML_Translation_Editor */
|
62 |
public $translation_editor;
|
63 |
+
|
64 |
+
/**
|
65 |
+
* @depreacted Use `make( WCML_Dependencies::class )` instead.
|
66 |
+
*
|
67 |
+
* @var WCML_Dependencies
|
68 |
+
*/
|
69 |
public $dependencies;
|
70 |
+
|
71 |
+
/**
|
72 |
+
* @depreacted Use `make( WCML_Dependencies::class )->check()` instead.
|
73 |
+
*
|
74 |
+
* @var bool|int
|
75 |
+
*/
|
76 |
public $dependencies_are_ok;
|
77 |
+
|
78 |
/** @var WCML_Cart */
|
79 |
public $cart;
|
80 |
/** @var WCML_Cart_Sync_Warnings */
|
100 |
private $wcml_products_screen;
|
101 |
|
102 |
public function __construct() {
|
103 |
+
$sitepress = getSitePress();
|
104 |
|
105 |
$this->settings = $this->get_settings();
|
106 |
$this->currencies = new WCML_Currencies( $this );
|
109 |
|
110 |
add_action( 'init', [ $this, 'init' ], 2 );
|
111 |
|
112 |
+
$this->cs_properties = new WCML_Currency_Switcher_Properties();
|
113 |
+
$wpml_wp_api = $sitepress->get_wp_api();
|
114 |
+
$wpml_wp_api->get_wp_filesystem_direct();
|
|
|
|
|
115 |
|
116 |
+
$this->cs_templates = new WCML_Currency_Switcher_Templates( $this, $wpml_wp_api, make( WPML_File::class ) );
|
117 |
+
$this->cs_templates->init_hooks();
|
118 |
+
|
119 |
+
$wc_shortccode_product_category = new WCML_WC_Shortcode_Product_Category( $sitepress );
|
120 |
+
$wc_shortccode_product_category->add_hooks();
|
121 |
|
122 |
}
|
123 |
|
124 |
private function load_rest_api() {
|
125 |
+
$sitepress = getSitePress();
|
126 |
|
127 |
if ( class_exists( 'WooCommerce' ) && defined( 'WC_VERSION' ) && ! is_null( $sitepress ) && WCML\Rest\Functions::isRestApiRequest() ) {
|
128 |
WCML\Rest\Hooks::addHooks();
|
144 |
* @return bool
|
145 |
*/
|
146 |
public function init() {
|
147 |
+
global $wpdb, $woocommerce, $wpml_url_converter, $wpml_post_translations, $wpml_term_translations;
|
148 |
|
149 |
+
$sitepress = getSitePress();
|
150 |
+
|
151 |
+
$this->dependencies = make( WCML_Dependencies::class );
|
152 |
$this->dependencies_are_ok = $this->dependencies->check();
|
153 |
|
154 |
WCML_Admin_Menus::set_up_menus( $this, $sitepress, $wpdb );
|
155 |
|
156 |
if ( ! $this->dependencies_are_ok ) {
|
157 |
+
if ( is_admin() && AdminPages::isWcmlSettings() ) {
|
|
|
158 |
WCML_Capabilities::set_up_capabilities();
|
159 |
|
160 |
wp_register_style( 'otgs-ico', WCML_PLUGIN_URL . '/res/css/otgs-ico.css', null, WCML_VERSION );
|
163 |
WCML_Resources::load_management_css();
|
164 |
WCML_Resources::load_tooltip_resources();
|
165 |
}
|
166 |
+
|
167 |
return false;
|
168 |
}
|
169 |
|
170 |
new WCML_Upgrade();
|
171 |
|
|
|
|
|
172 |
$actions_that_need_mc = [
|
173 |
'save-mc-options',
|
174 |
'wcml_save_currency',
|
186 |
|
187 |
$this->cart = new WCML_Cart( $this, $sitepress, $woocommerce );
|
188 |
|
189 |
+
$action = filter_input( INPUT_POST, 'action' );
|
190 |
if ( WCML_MULTI_CURRENCIES_INDEPENDENT === (int) $this->settings['enable_multi_currency']
|
191 |
+
|| AdminPages::isMultiCurrency()
|
192 |
+
|| ( in_array( $action, $actions_that_need_mc, true ) )
|
193 |
) {
|
194 |
$this->get_multi_currency();
|
195 |
+
$wcml_price_filters = new WCML_Price_Filter( $this );
|
196 |
$wcml_price_filters->add_hooks();
|
197 |
} else {
|
198 |
add_shortcode( 'currency_switcher', '__return_empty_string' );
|
199 |
}
|
200 |
|
201 |
+
if ( $this->dependencies_are_ok ) {
|
202 |
+
$this->compatibility = new WCML_Compatibility();
|
203 |
+
$this->compatibility->init();
|
204 |
+
|
205 |
+
if ( isStandAlone() ) {
|
206 |
+
return $this->init_standalone( $sitepress, $wpdb );
|
207 |
+
} else {
|
208 |
+
return $this->init_full( $sitepress, $wpdb, $woocommerce, $wpml_url_converter, $wpml_post_translations, $wpml_term_translations );
|
209 |
+
}
|
210 |
+
}
|
211 |
+
}
|
212 |
+
|
213 |
+
private function init_full( $sitepress, $wpdb, $woocommerce, $wpml_url_converter, $wpml_post_translations, $wpml_term_translations ) {
|
214 |
$this->currencies = new WCML_Currencies( $this );
|
215 |
$this->currencies->add_hooks();
|
216 |
|
242 |
$this->store->add_hooks();
|
243 |
$this->strings = new WCML_WC_Strings( $this, $sitepress, $wpdb );
|
244 |
$this->strings->add_hooks();
|
245 |
+
// do not pass mailer instance instead of $woocommerce.
|
246 |
$this->emails = new WCML_Emails( $this->strings, $sitepress, $woocommerce, $wpdb );
|
247 |
$this->emails->add_hooks();
|
248 |
$this->terms = new WCML_Terms( $this, $sitepress, $wpdb );
|
301 |
return true;
|
302 |
}
|
303 |
|
304 |
+
private function init_standalone( $sitepress, $wpdb ) {
|
305 |
+
$this->currencies = new WCML_Currencies( $this );
|
306 |
+
$this->currencies->add_hooks();
|
307 |
+
|
308 |
+
if ( is_admin() ) {
|
309 |
+
( new WCML_Pointers() )->add_hooks();
|
310 |
+
}
|
311 |
+
|
312 |
+
$this->products = new WCML_Products( $this, $sitepress, null, $wpdb );
|
313 |
+
$this->products->add_hooks();
|
314 |
+
$this->gateways = new WCML_WC_Gateways( $this, $sitepress );
|
315 |
+
$this->gateways->add_hooks();
|
316 |
+
$this->cart->add_hooks(); // object is instantiated before.
|
317 |
+
|
318 |
+
WCML_Locale::load_locale();
|
319 |
+
WCML_Install::initialize( $this, $sitepress );
|
320 |
+
|
321 |
+
WCML_Resources::set_up_resources( $this, $sitepress );
|
322 |
+
WCML_Resources::add_hooks();
|
323 |
+
|
324 |
+
add_action( 'wp_ajax_wcml_update_setting_ajx', [ $this, 'update_setting_ajx' ] );
|
325 |
+
|
326 |
+
return true;
|
327 |
+
}
|
328 |
+
|
329 |
/**
|
330 |
* Get settings
|
331 |
*
|
523 |
* @return bool
|
524 |
*/
|
525 |
public function is_wpml_prior_4_2() {
|
526 |
+
$sitepress = getSitePress();
|
527 |
|
528 |
return $sitepress->get_wp_api()->version_compare( $this->get_constant( 'ICL_SITEPRESS_VERSION' ), '4.2.0', '<' ) ||
|
529 |
$sitepress->get_wp_api()->version_compare( $this->get_constant( 'WPML_TM_VERSION' ), '2.8.0', '<' );
|
535 |
* @return int|string
|
536 |
*/
|
537 |
private function get_constant( $name ) {
|
538 |
+
return getSitePress()->get_wp_api()->constant( $name );
|
|
|
|
|
539 |
}
|
540 |
}
|
classes/multi-currency/class-wcml-exchange-rates.php
CHANGED
@@ -1,5 +1,8 @@
|
|
1 |
<?php
|
2 |
|
|
|
|
|
|
|
3 |
/**
|
4 |
* Class WCML_Exchange_Rates
|
5 |
*/
|
@@ -11,23 +14,37 @@ class WCML_Exchange_Rates {
|
|
11 |
private $services = [];
|
12 |
/** @var array */
|
13 |
private $settings;
|
14 |
-
/** @var
|
15 |
private $wp_locale;
|
16 |
|
17 |
const CRONJOB_EVENT = 'wcml_exchange_rates_update';
|
18 |
const DIGITS_AFTER_DECIMAL_POINT = 6;
|
|
|
19 |
|
20 |
/**
|
21 |
-
*
|
22 |
-
*
|
23 |
-
* @param $woocommerce_wpml
|
24 |
-
* @param WP_Locale
|
25 |
*/
|
26 |
-
public function __construct( $woocommerce_wpml, $wp_locale ) {
|
27 |
$this->woocommerce_wpml = $woocommerce_wpml;
|
28 |
$this->wp_locale = $wp_locale;
|
29 |
}
|
30 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
31 |
public function add_actions() {
|
32 |
if ( is_admin() ) {
|
33 |
add_action( 'wcml_saved_mc_options', [ $this, 'update_exchange_rate_options' ] ); // before init
|
@@ -49,7 +66,7 @@ class WCML_Exchange_Rates {
|
|
49 |
if ( ! isset( $this->woocommerce_wpml->settings['multi_currency']['exchange_rates'] ) ) {
|
50 |
$this->settings = [
|
51 |
'automatic' => 0,
|
52 |
-
'service' => '
|
53 |
'lifting_charge' => 0,
|
54 |
'schedule' => 'manual',
|
55 |
'week_day' => 1,
|
@@ -70,7 +87,7 @@ class WCML_Exchange_Rates {
|
|
70 |
|
71 |
/**
|
72 |
* @param string $service_id
|
73 |
-
* @param
|
74 |
*/
|
75 |
public function add_service( $service_id, $service ) {
|
76 |
$this->services[ $service_id ] = $service;
|
@@ -131,14 +148,35 @@ class WCML_Exchange_Rates {
|
|
131 |
* @throws Exception
|
132 |
*/
|
133 |
public function update_exchange_rates() {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
134 |
if ( ! isset( $this->services[ $this->settings['service'] ] ) ) {
|
135 |
throw new Exception( 'The exchange rate service "' . $this->settings['service'] . '" is not defined.' );
|
136 |
}
|
137 |
|
138 |
-
/** @var
|
139 |
-
$service
|
140 |
|
141 |
-
$currencies = $this->woocommerce_wpml->multi_currency->get_currency_codes();
|
142 |
$default_currency = wcml_get_woocommerce_currency_option();
|
143 |
$secondary_currencies = array_diff( $currencies, [ $default_currency ] );
|
144 |
|
@@ -153,15 +191,6 @@ class WCML_Exchange_Rates {
|
|
153 |
|
154 |
$this->apply_lifting_charge( $rates );
|
155 |
|
156 |
-
foreach ( $rates as $to => $rate ) {
|
157 |
-
if ( $rate && is_numeric( $rate ) ) {
|
158 |
-
$this->save_exchage_rate( $to, $rate );
|
159 |
-
}
|
160 |
-
}
|
161 |
-
|
162 |
-
$this->settings['last_updated'] = current_time( 'timestamp' );
|
163 |
-
$this->save_settings();
|
164 |
-
|
165 |
return $rates;
|
166 |
}
|
167 |
|
@@ -197,6 +226,10 @@ class WCML_Exchange_Rates {
|
|
197 |
public function update_exchange_rate_options( $post_data ) {
|
198 |
|
199 |
if ( isset( $post_data['exchange-rates-automatic'] ) && $post_data['exchange-rates-automatic'] ) {
|
|
|
|
|
|
|
|
|
200 |
|
201 |
$this->settings['automatic'] = (int) $post_data['exchange-rates-automatic'];
|
202 |
|
@@ -208,14 +241,19 @@ class WCML_Exchange_Rates {
|
|
208 |
}
|
209 |
|
210 |
$this->settings['service'] = sanitize_text_field( $post_data['exchange-rates-service'] );
|
211 |
-
|
212 |
}
|
213 |
|
214 |
if ( isset( $post_data['services'] ) ) {
|
|
|
215 |
|
216 |
foreach ( $post_data['services'] as $service_id => $service_data ) {
|
217 |
if ( isset( $service_data['api-key'] ) ) {
|
218 |
$this->services[ $service_id ]->saveSetting( 'api-key', $service_data['api-key'] );
|
|
|
|
|
|
|
|
|
219 |
}
|
220 |
}
|
221 |
}
|
@@ -243,13 +281,33 @@ class WCML_Exchange_Rates {
|
|
243 |
} else {
|
244 |
$this->enable_update_cronjob();
|
245 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
246 |
} else {
|
247 |
$this->settings['automatic'] = 0;
|
248 |
$this->delete_update_cronjob();
|
249 |
}
|
250 |
|
251 |
$this->save_settings();
|
|
|
252 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
253 |
}
|
254 |
|
255 |
public function enable_update_cronjob() {
|
@@ -337,6 +395,7 @@ class WCML_Exchange_Rates {
|
|
337 |
|
338 |
$schedules[ 'wcml_monthly_on_' . $this->settings['month_day'] ] = [
|
339 |
'interval' => $interval,
|
|
|
340 |
'display' => sprintf( __( 'Monthly on the %s', 'woocommerce-multilingual' ), $month_day ),
|
341 |
];
|
342 |
|
@@ -345,6 +404,7 @@ class WCML_Exchange_Rates {
|
|
345 |
$week_day = $this->wp_locale->get_weekday( $this->settings['week_day'] );
|
346 |
$schedules[ 'wcml_weekly_on_' . $this->settings['week_day'] ] = [
|
347 |
'interval' => WEEK_IN_SECONDS,
|
|
|
348 |
'display' => sprintf( __( 'Weekly on %s', 'woocommerce-multilingual' ), $week_day ),
|
349 |
];
|
350 |
|
@@ -372,4 +432,25 @@ class WCML_Exchange_Rates {
|
|
372 |
return $month_day;
|
373 |
}
|
374 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
375 |
}
|
1 |
<?php
|
2 |
|
3 |
+
use WCML\MultiCurrency\ExchangeRateServices\Service;
|
4 |
+
use WPML\FP\Obj;
|
5 |
+
|
6 |
/**
|
7 |
* Class WCML_Exchange_Rates
|
8 |
*/
|
14 |
private $services = [];
|
15 |
/** @var array */
|
16 |
private $settings;
|
17 |
+
/** @var WP_Locale|mixed */
|
18 |
private $wp_locale;
|
19 |
|
20 |
const CRONJOB_EVENT = 'wcml_exchange_rates_update';
|
21 |
const DIGITS_AFTER_DECIMAL_POINT = 6;
|
22 |
+
const KEY_RATES_UPDATED_FLAG = 'wcml_exchange_rates_manually_updated';
|
23 |
|
24 |
/**
|
25 |
+
* @param woocommerce_wpml $woocommerce_wpml
|
26 |
+
* @param WP_Locale|mixed $wp_locale
|
|
|
|
|
27 |
*/
|
28 |
+
public function __construct( woocommerce_wpml $woocommerce_wpml, $wp_locale ) {
|
29 |
$this->woocommerce_wpml = $woocommerce_wpml;
|
30 |
$this->wp_locale = $wp_locale;
|
31 |
}
|
32 |
|
33 |
+
/**
|
34 |
+
* Please use `make( WCML_Exchange_Rates::class )` to get the instance of this class.
|
35 |
+
*
|
36 |
+
* @return WCML_Exchange_Rates
|
37 |
+
*/
|
38 |
+
public static function create() {
|
39 |
+
/**
|
40 |
+
* @var woocommerce_wpml $woocommerce_wpml
|
41 |
+
* @var WP_Locale|mixed $wp_locale
|
42 |
+
*/
|
43 |
+
global $woocommerce_wpml, $wp_locale;
|
44 |
+
|
45 |
+
return new self( $woocommerce_wpml, $wp_locale );
|
46 |
+
}
|
47 |
+
|
48 |
public function add_actions() {
|
49 |
if ( is_admin() ) {
|
50 |
add_action( 'wcml_saved_mc_options', [ $this, 'update_exchange_rate_options' ] ); // before init
|
66 |
if ( ! isset( $this->woocommerce_wpml->settings['multi_currency']['exchange_rates'] ) ) {
|
67 |
$this->settings = [
|
68 |
'automatic' => 0,
|
69 |
+
'service' => 'currencylayer',
|
70 |
'lifting_charge' => 0,
|
71 |
'schedule' => 'manual',
|
72 |
'week_day' => 1,
|
87 |
|
88 |
/**
|
89 |
* @param string $service_id
|
90 |
+
* @param Service $service
|
91 |
*/
|
92 |
public function add_service( $service_id, $service ) {
|
93 |
$this->services[ $service_id ] = $service;
|
148 |
* @throws Exception
|
149 |
*/
|
150 |
public function update_exchange_rates() {
|
151 |
+
$currencies = $this->woocommerce_wpml->multi_currency->get_currency_codes();
|
152 |
+
$rates = $this->fetch_exchange_rates_from_active_service( $currencies );
|
153 |
+
|
154 |
+
foreach ( $rates as $to => $rate ) {
|
155 |
+
if ( $rate && is_numeric( $rate ) ) {
|
156 |
+
$this->save_exchage_rate( $to, $rate );
|
157 |
+
}
|
158 |
+
}
|
159 |
+
|
160 |
+
$this->settings['last_updated'] = current_time( 'timestamp' );
|
161 |
+
$this->save_settings();
|
162 |
+
|
163 |
+
return $rates;
|
164 |
+
}
|
165 |
+
|
166 |
+
/**
|
167 |
+
* @param array $currencies
|
168 |
+
*
|
169 |
+
* @return array
|
170 |
+
* @throws Exception
|
171 |
+
*/
|
172 |
+
public function fetch_exchange_rates_from_active_service( $currencies ) {
|
173 |
if ( ! isset( $this->services[ $this->settings['service'] ] ) ) {
|
174 |
throw new Exception( 'The exchange rate service "' . $this->settings['service'] . '" is not defined.' );
|
175 |
}
|
176 |
|
177 |
+
/** @var Service $service */
|
178 |
+
$service = $this->get_current_service();
|
179 |
|
|
|
180 |
$default_currency = wcml_get_woocommerce_currency_option();
|
181 |
$secondary_currencies = array_diff( $currencies, [ $default_currency ] );
|
182 |
|
191 |
|
192 |
$this->apply_lifting_charge( $rates );
|
193 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
194 |
return $rates;
|
195 |
}
|
196 |
|
226 |
public function update_exchange_rate_options( $post_data ) {
|
227 |
|
228 |
if ( isset( $post_data['exchange-rates-automatic'] ) && $post_data['exchange-rates-automatic'] ) {
|
229 |
+
$active_service_changed = false;
|
230 |
+
$active_key_changed = false;
|
231 |
+
$active_service_id = Obj::prop( 'service', $this->settings );
|
232 |
+
$active_service = Obj::prop( $active_service_id, $this->services );
|
233 |
|
234 |
$this->settings['automatic'] = (int) $post_data['exchange-rates-automatic'];
|
235 |
|
241 |
}
|
242 |
|
243 |
$this->settings['service'] = sanitize_text_field( $post_data['exchange-rates-service'] );
|
244 |
+
$active_service_changed = $active_service_id !== $this->settings['service'];
|
245 |
}
|
246 |
|
247 |
if ( isset( $post_data['services'] ) ) {
|
248 |
+
$active_service_key = $active_service ? $active_service->getSetting( 'api-key' ) : '';
|
249 |
|
250 |
foreach ( $post_data['services'] as $service_id => $service_data ) {
|
251 |
if ( isset( $service_data['api-key'] ) ) {
|
252 |
$this->services[ $service_id ]->saveSetting( 'api-key', $service_data['api-key'] );
|
253 |
+
|
254 |
+
if ( $service_id === $active_service_id ) {
|
255 |
+
$active_key_changed = $active_service_key !== $service_data['api-key'];
|
256 |
+
}
|
257 |
}
|
258 |
}
|
259 |
}
|
281 |
} else {
|
282 |
$this->enable_update_cronjob();
|
283 |
}
|
284 |
+
|
285 |
+
if ( $active_key_changed || $active_service_changed ) {
|
286 |
+
$currentService = $this->get_current_service();
|
287 |
+
|
288 |
+
if ( $currentService ) {
|
289 |
+
$currentService->resetConnectionCache();
|
290 |
+
}
|
291 |
+
|
292 |
+
add_action( 'init', [ $this, 'update_rates_on_service_or_key_changed' ], 5 );
|
293 |
+
}
|
294 |
} else {
|
295 |
$this->settings['automatic'] = 0;
|
296 |
$this->delete_update_cronjob();
|
297 |
}
|
298 |
|
299 |
$this->save_settings();
|
300 |
+
}
|
301 |
|
302 |
+
public function update_rates_on_service_or_key_changed() {
|
303 |
+
try {
|
304 |
+
$this->update_exchange_rates();
|
305 |
+
$this->woocommerce_wpml->get_multi_currency()->init_currencies(); // Re-init currencies.
|
306 |
+
wp_cache_add( self::KEY_RATES_UPDATED_FLAG, true );
|
307 |
+
add_action( 'shutdown', function() {
|
308 |
+
wp_cache_delete( WCML_Exchange_Rates::KEY_RATES_UPDATED_FLAG );
|
309 |
+
} );
|
310 |
+
} catch ( \Exception $e ) {} // Exception is handled inside `update_exchange_rates`.
|
311 |
}
|
312 |
|
313 |
public function enable_update_cronjob() {
|
395 |
|
396 |
$schedules[ 'wcml_monthly_on_' . $this->settings['month_day'] ] = [
|
397 |
'interval' => $interval,
|
398 |
+
/* translators: %s is the month day */
|
399 |
'display' => sprintf( __( 'Monthly on the %s', 'woocommerce-multilingual' ), $month_day ),
|
400 |
];
|
401 |
|
404 |
$week_day = $this->wp_locale->get_weekday( $this->settings['week_day'] );
|
405 |
$schedules[ 'wcml_weekly_on_' . $this->settings['week_day'] ] = [
|
406 |
'interval' => WEEK_IN_SECONDS,
|
407 |
+
/* translators: %s is the week day */
|
408 |
'display' => sprintf( __( 'Weekly on %s', 'woocommerce-multilingual' ), $week_day ),
|
409 |
];
|
410 |
|
432 |
return $month_day;
|
433 |
}
|
434 |
|
435 |
+
/**
|
436 |
+
* @return Service|null
|
437 |
+
*/
|
438 |
+
private function get_current_service() {
|
439 |
+
return Obj::prop( Obj::prop( 'service', (array) $this->settings ), (array) $this->services );
|
440 |
+
}
|
441 |
+
|
442 |
+
/**
|
443 |
+
* Check if a service is defined and has a key if needed.
|
444 |
+
*
|
445 |
+
* @return bool
|
446 |
+
*/
|
447 |
+
public function is_current_service_actionable() {
|
448 |
+
$current_service = $this->get_current_service();
|
449 |
+
|
450 |
+
return $current_service
|
451 |
+
&& (
|
452 |
+
! $current_service->isKeyRequired()
|
453 |
+
|| $current_service->getSetting( 'api-key' )
|
454 |
+
);
|
455 |
+
}
|
456 |
}
|
classes/multi-currency/exchange-rate-services/ApiLayerService.php
ADDED
@@ -0,0 +1,93 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace WCML\MultiCurrency\ExchangeRateServices;
|
4 |
+
|
5 |
+
use WPML\FP\Obj;
|
6 |
+
|
7 |
+
abstract class ApiLayerService extends Service {
|
8 |
+
|
9 |
+
/**
|
10 |
+
* @return string
|
11 |
+
*/
|
12 |
+
abstract protected function getApiLayerUrl();
|
13 |
+
|
14 |
+
/**
|
15 |
+
* @return string
|
16 |
+
*/
|
17 |
+
abstract protected function getApiLegacyUrl();
|
18 |
+
|
19 |
+
/**
|
20 |
+
* @return string
|
21 |
+
*/
|
22 |
+
public function getApiUrl() {
|
23 |
+
return $this->getSelectedApiEndpoint();
|
24 |
+
}
|
25 |
+
|
26 |
+
/**
|
27 |
+
* @return void
|
28 |
+
*/
|
29 |
+
public function resetConnectionCache() {
|
30 |
+
$this->setSelectedApiEndpoint( null );
|
31 |
+
}
|
32 |
+
|
33 |
+
/**
|
34 |
+
* @param string|null $endpoint
|
35 |
+
*
|
36 |
+
* @return void
|
37 |
+
*/
|
38 |
+
private function setSelectedApiEndpoint( $endpoint ) {
|
39 |
+
$this->saveSetting( 'selected-endpoint', $endpoint );
|
40 |
+
}
|
41 |
+
|
42 |
+
/**
|
43 |
+
* @return string|null
|
44 |
+
*/
|
45 |
+
private function getSelectedApiEndpoint() {
|
46 |
+
return $this->getSetting( 'selected-endpoint' );
|
47 |
+
}
|
48 |
+
|
49 |
+
/**
|
50 |
+
* @param string $from The base currency code.
|
51 |
+
* @param array $tos The target currency codes.
|
52 |
+
*
|
53 |
+
* @return array|\WP_Error
|
54 |
+
*/
|
55 |
+
protected function makeRequest( $from, $tos ) {
|
56 |
+
if ( $this->getSelectedApiEndpoint() ) {
|
57 |
+
$response = parent::makeRequest( $from, $tos );
|
58 |
+
} else {
|
59 |
+
$this->setSelectedApiEndpoint( $this->getApiLayerUrl() );
|
60 |
+
$response = parent::makeRequest( $from, $tos );
|
61 |
+
|
62 |
+
if ( $this->isWrongAuthenticationWithApiLayer( $response ) ) {
|
63 |
+
$this->setSelectedApiEndpoint( $this->getApiLegacyUrl() );
|
64 |
+
$response = parent::makeRequest( $from, $tos );
|
65 |
+
}
|
66 |
+
}
|
67 |
+
|
68 |
+
return $response;
|
69 |
+
}
|
70 |
+
|
71 |
+
/**
|
72 |
+
* @param object $data
|
73 |
+
*
|
74 |
+
* @return bool
|
75 |
+
*/
|
76 |
+
private function isWrongAuthenticationWithApiLayer( $data ) {
|
77 |
+
return Obj::path( [ 'response', 'code' ], $data ) === 401;
|
78 |
+
}
|
79 |
+
|
80 |
+
/**
|
81 |
+
* @return array
|
82 |
+
*/
|
83 |
+
protected function getRequestHeaders() {
|
84 |
+
return [ 'apikey' => $this->getApiKey() ];
|
85 |
+
}
|
86 |
+
|
87 |
+
/**
|
88 |
+
* @return bool
|
89 |
+
*/
|
90 |
+
public function isKeyRequired() {
|
91 |
+
return true;
|
92 |
+
}
|
93 |
+
}
|
classes/multi-currency/exchange-rate-services/CurrencyLayer.php
CHANGED
@@ -5,7 +5,7 @@ namespace WCML\MultiCurrency\ExchangeRateServices;
|
|
5 |
/**
|
6 |
* Class CurrencyLayer
|
7 |
*/
|
8 |
-
class CurrencyLayer extends
|
9 |
|
10 |
/**
|
11 |
* @return string
|
@@ -31,67 +31,42 @@ class CurrencyLayer extends Service {
|
|
31 |
/**
|
32 |
* @return string
|
33 |
*/
|
34 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
35 |
return 'http://apilayer.net/api/live?access_key=%s&source=%s¤cies=%s&amount=1';
|
36 |
}
|
37 |
|
38 |
/**
|
|
|
|
|
39 |
* @return bool
|
40 |
*/
|
41 |
-
|
42 |
-
return
|
43 |
}
|
44 |
|
45 |
/**
|
46 |
-
* @param
|
47 |
-
* @param
|
|
|
48 |
*
|
49 |
* @return array
|
50 |
-
* @throws \Exception Thrown where there are connection problems.
|
51 |
*/
|
52 |
-
|
53 |
-
$this->clearLastError();
|
54 |
-
|
55 |
$rates = [];
|
56 |
|
57 |
-
|
58 |
-
|
59 |
-
|
60 |
-
|
61 |
-
if ( is_wp_error( $data ) ) {
|
62 |
-
|
63 |
-
$http_error = implode( "\n", $data->get_error_messages() );
|
64 |
-
$this->saveLastError( $http_error );
|
65 |
-
throw new \Exception( $http_error );
|
66 |
-
|
67 |
-
}
|
68 |
-
|
69 |
-
$json = json_decode( $data['body'] );
|
70 |
-
|
71 |
-
if ( empty( $json->success ) ) {
|
72 |
-
if ( ! empty( $json->error->info ) ) {
|
73 |
-
if ( strpos( $json->error->info, 'You have not supplied an API Access Key' ) !== false ) {
|
74 |
-
$error = __( 'You have entered an incorrect API Access Key', 'woocommerce-multilingual' );
|
75 |
-
} else {
|
76 |
-
$error = $json->error->info;
|
77 |
-
}
|
78 |
-
} else {
|
79 |
-
$error = __( 'Cannot get exchange rates. Connection failed.', 'woocommerce-multilingual' );
|
80 |
-
}
|
81 |
-
$this->saveLastError( $error );
|
82 |
-
throw new \Exception( $error );
|
83 |
-
}
|
84 |
-
|
85 |
-
if ( isset( $json->quotes ) ) {
|
86 |
-
foreach ( $tos as $to ) {
|
87 |
-
if ( isset( $json->quotes->{$from . $to} ) ) {
|
88 |
-
$rates[ $to ] = round( $json->quotes->{$from . $to}, \WCML_Exchange_Rates::DIGITS_AFTER_DECIMAL_POINT );
|
89 |
-
}
|
90 |
}
|
91 |
}
|
92 |
|
93 |
return $rates;
|
94 |
-
|
95 |
}
|
96 |
-
|
97 |
}
|
5 |
/**
|
6 |
* Class CurrencyLayer
|
7 |
*/
|
8 |
+
class CurrencyLayer extends ApiLayerService {
|
9 |
|
10 |
/**
|
11 |
* @return string
|
31 |
/**
|
32 |
* @return string
|
33 |
*/
|
34 |
+
protected function getApiLayerUrl() {
|
35 |
+
return 'https://api.apilayer.com/currency_data/live?source=%2$s¤cies=%3$s';
|
36 |
+
}
|
37 |
+
|
38 |
+
/**
|
39 |
+
* @return string
|
40 |
+
*/
|
41 |
+
protected function getApiLegacyUrl() {
|
42 |
return 'http://apilayer.net/api/live?access_key=%s&source=%s¤cies=%s&amount=1';
|
43 |
}
|
44 |
|
45 |
/**
|
46 |
+
* @param object $decodedData
|
47 |
+
*
|
48 |
* @return bool
|
49 |
*/
|
50 |
+
protected function isInvalidResponse( $decodedData ) {
|
51 |
+
return empty( $decodedData->quotes );
|
52 |
}
|
53 |
|
54 |
/**
|
55 |
+
* @param object $validData
|
56 |
+
* @param string $from
|
57 |
+
* @param array $tos
|
58 |
*
|
59 |
* @return array
|
|
|
60 |
*/
|
61 |
+
protected function extractRates( $validData, $from, $tos ) {
|
|
|
|
|
62 |
$rates = [];
|
63 |
|
64 |
+
foreach ( $tos as $to ) {
|
65 |
+
if ( isset( $validData->quotes->{$from . $to} ) ) {
|
66 |
+
$rates[ $to ] = round( $validData->quotes->{$from . $to}, \WCML_Exchange_Rates::DIGITS_AFTER_DECIMAL_POINT );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
67 |
}
|
68 |
}
|
69 |
|
70 |
return $rates;
|
|
|
71 |
}
|
|
|
72 |
}
|
classes/multi-currency/exchange-rate-services/ExchangeRatesApi.php
CHANGED
@@ -5,7 +5,7 @@ namespace WCML\MultiCurrency\ExchangeRateServices;
|
|
5 |
/**
|
6 |
* Class ExchangeRatesApi
|
7 |
*/
|
8 |
-
class ExchangeRatesApi extends
|
9 |
|
10 |
/**
|
11 |
* @return string
|
@@ -31,15 +31,14 @@ class ExchangeRatesApi extends Service {
|
|
31 |
/**
|
32 |
* @return string
|
33 |
*/
|
34 |
-
|
35 |
-
return '
|
36 |
}
|
37 |
|
38 |
/**
|
39 |
-
* @return
|
40 |
*/
|
41 |
-
|
42 |
-
return
|
43 |
}
|
44 |
-
|
45 |
}
|
5 |
/**
|
6 |
* Class ExchangeRatesApi
|
7 |
*/
|
8 |
+
class ExchangeRatesApi extends ApiLayerService {
|
9 |
|
10 |
/**
|
11 |
* @return string
|
31 |
/**
|
32 |
* @return string
|
33 |
*/
|
34 |
+
protected function getApiLayerUrl() {
|
35 |
+
return 'https://api.apilayer.com/exchangerates_data/latest?base=%2$s&symbols=%3$s&amount=1';
|
36 |
}
|
37 |
|
38 |
/**
|
39 |
+
* @return string
|
40 |
*/
|
41 |
+
protected function getApiLegacyUrl() {
|
42 |
+
return 'http://api.exchangeratesapi.io/v1/latest?access_key=%1$s&base=%2$s&symbols=%3$s';
|
43 |
}
|
|
|
44 |
}
|
classes/multi-currency/exchange-rate-services/Fixerio.php
CHANGED
@@ -5,7 +5,7 @@ namespace WCML\MultiCurrency\ExchangeRateServices;
|
|
5 |
/**
|
6 |
* Class Fixerio
|
7 |
*/
|
8 |
-
class Fixerio extends
|
9 |
|
10 |
/**
|
11 |
* @return string
|
@@ -31,15 +31,14 @@ class Fixerio extends Service {
|
|
31 |
/**
|
32 |
* @return string
|
33 |
*/
|
34 |
-
|
35 |
-
return '
|
36 |
}
|
37 |
|
38 |
/**
|
39 |
-
* @return
|
40 |
*/
|
41 |
-
|
42 |
-
return
|
43 |
}
|
44 |
-
|
45 |
}
|
5 |
/**
|
6 |
* Class Fixerio
|
7 |
*/
|
8 |
+
class Fixerio extends ApiLayerService {
|
9 |
|
10 |
/**
|
11 |
* @return string
|
31 |
/**
|
32 |
* @return string
|
33 |
*/
|
34 |
+
protected function getApiLayerUrl() {
|
35 |
+
return 'https://api.apilayer.com/fixer/latest?base=%2$s&symbols=%3$s';
|
36 |
}
|
37 |
|
38 |
/**
|
39 |
+
* @return string
|
40 |
*/
|
41 |
+
protected function getApiLegacyUrl() {
|
42 |
+
return 'http://data.fixer.io/api/latest?access_key=%1$s&base=%2$s&symbols=%3$s';
|
43 |
}
|
|
|
44 |
}
|
classes/multi-currency/exchange-rate-services/Service.php
CHANGED
@@ -37,6 +37,13 @@ abstract class Service {
|
|
37 |
*/
|
38 |
abstract public function isKeyRequired();
|
39 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
40 |
/**
|
41 |
* @param string $from Base currency.
|
42 |
* @param array $tos Target currencies.
|
@@ -47,43 +54,120 @@ abstract class Service {
|
|
47 |
public function getRates( $from, $tos ) {
|
48 |
$this->clearLastError();
|
49 |
|
50 |
-
$
|
51 |
|
52 |
-
if ( $
|
53 |
-
$
|
54 |
-
} else {
|
55 |
-
$url = sprintf( $this->getApiUrl(), $from, implode( ',', $tos ) );
|
56 |
-
}
|
57 |
-
|
58 |
-
$data = wp_safe_remote_get( $url );
|
59 |
-
|
60 |
-
if ( is_wp_error( $data ) ) {
|
61 |
-
|
62 |
-
$http_error = implode( "\n", $data->get_error_messages() );
|
63 |
$this->saveLastError( $http_error );
|
64 |
throw new \Exception( $http_error );
|
65 |
-
|
66 |
}
|
67 |
|
68 |
-
$
|
69 |
|
70 |
-
if (
|
71 |
-
|
72 |
-
$error = $json->error->info;
|
73 |
-
} else {
|
74 |
-
$error = __( 'Cannot get exchange rates. Connection failed.', 'woocommerce-multilingual' );
|
75 |
-
}
|
76 |
$this->saveLastError( $error );
|
77 |
throw new \Exception( $error );
|
78 |
}
|
79 |
|
80 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
81 |
$rates[ $to ] = round( $rate, \WCML_Exchange_Rates::DIGITS_AFTER_DECIMAL_POINT );
|
82 |
}
|
83 |
|
84 |
return $rates;
|
85 |
}
|
86 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
87 |
/**
|
88 |
* @return array
|
89 |
*/
|
@@ -142,4 +226,10 @@ abstract class Service {
|
|
142 |
return $this->getSetting( 'last_error' );
|
143 |
}
|
144 |
|
|
|
|
|
|
|
|
|
|
|
|
|
145 |
}
|
37 |
*/
|
38 |
abstract public function isKeyRequired();
|
39 |
|
40 |
+
/**
|
41 |
+
* @return void
|
42 |
+
*/
|
43 |
+
public function resetConnectionCache() {
|
44 |
+
|
45 |
+
}
|
46 |
+
|
47 |
/**
|
48 |
* @param string $from Base currency.
|
49 |
* @param array $tos Target currencies.
|
54 |
public function getRates( $from, $tos ) {
|
55 |
$this->clearLastError();
|
56 |
|
57 |
+
$response = $this->makeRequest( $from, $tos );
|
58 |
|
59 |
+
if ( is_wp_error( $response ) ) {
|
60 |
+
$http_error = implode( "\n", $response->get_error_messages() );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
61 |
$this->saveLastError( $http_error );
|
62 |
throw new \Exception( $http_error );
|
|
|
63 |
}
|
64 |
|
65 |
+
$data = json_decode( $response['body'] );
|
66 |
|
67 |
+
if ( $this->isInvalidResponse( $data ) ) {
|
68 |
+
$error = self::get_formatted_error( $data );
|
|
|
|
|
|
|
|
|
69 |
$this->saveLastError( $error );
|
70 |
throw new \Exception( $error );
|
71 |
}
|
72 |
|
73 |
+
return $this->extractRates( $data, $from, $tos );
|
74 |
+
}
|
75 |
+
|
76 |
+
/**
|
77 |
+
* @param string $from The base currency code.
|
78 |
+
* @param array $tos The target currency codes.
|
79 |
+
*
|
80 |
+
* @return array|\WP_Error
|
81 |
+
*/
|
82 |
+
protected function makeRequest( $from, $tos ) {
|
83 |
+
if ( $this->isKeyRequired() ) {
|
84 |
+
$url = sprintf( $this->getApiUrl(), $this->getApiKey(), $from, implode( ',', $tos ) );
|
85 |
+
} else {
|
86 |
+
$url = sprintf( $this->getApiUrl(), $from, implode( ',', $tos ) );
|
87 |
+
}
|
88 |
+
|
89 |
+
return wp_safe_remote_get( $url, [ 'headers' => $this->getRequestHeaders() ] );
|
90 |
+
}
|
91 |
+
|
92 |
+
/**
|
93 |
+
* @return array
|
94 |
+
*/
|
95 |
+
protected function getRequestHeaders() {
|
96 |
+
return [];
|
97 |
+
}
|
98 |
+
|
99 |
+
/**
|
100 |
+
* @param object $decodedData
|
101 |
+
*
|
102 |
+
* @return bool
|
103 |
+
*/
|
104 |
+
protected function isInvalidResponse( $decodedData ) {
|
105 |
+
return empty( $decodedData->rates );
|
106 |
+
}
|
107 |
+
|
108 |
+
/**
|
109 |
+
* @param object $validData
|
110 |
+
* @param string $from
|
111 |
+
* @param array $tos
|
112 |
+
*
|
113 |
+
* @return array
|
114 |
+
*/
|
115 |
+
protected function extractRates( $validData, $from, $tos ) {
|
116 |
+
$rates = [];
|
117 |
+
|
118 |
+
foreach ( $validData->rates as $to => $rate ) {
|
119 |
$rates[ $to ] = round( $rate, \WCML_Exchange_Rates::DIGITS_AFTER_DECIMAL_POINT );
|
120 |
}
|
121 |
|
122 |
return $rates;
|
123 |
}
|
124 |
|
125 |
+
/**
|
126 |
+
* Each service has its own response signature,
|
127 |
+
* and I also noticed that it does not always
|
128 |
+
* respect their own doc.
|
129 |
+
*
|
130 |
+
* So the idea is to just catch all possible information
|
131 |
+
* and return it as raw output.
|
132 |
+
*
|
133 |
+
* Example: "error_code: 104 - error_message: ..."
|
134 |
+
*
|
135 |
+
* @param array|\stdClass $response
|
136 |
+
*
|
137 |
+
* @return string
|
138 |
+
*/
|
139 |
+
public static function get_formatted_error( $response ) {
|
140 |
+
// $getFromPath :: array -> string|null
|
141 |
+
$getFromPath = function( $path ) use ( $response ) {
|
142 |
+
try {
|
143 |
+
$value = Obj::path( $path, $response );
|
144 |
+
return is_string( $value ) || is_int( $value ) ? $value : null;
|
145 |
+
} catch ( \Exception $e ) {
|
146 |
+
return null;
|
147 |
+
}
|
148 |
+
};
|
149 |
+
|
150 |
+
$formattedError = wpml_collect( [
|
151 |
+
// Codes or types
|
152 |
+
'error' => $getFromPath( [ 'error' ] ),
|
153 |
+
'error_code' => $getFromPath( [ 'error', 'code' ] ),
|
154 |
+
'error_type' => $getFromPath( [ 'error', 'type' ] ),
|
155 |
+
// Descriptions or messages
|
156 |
+
'error_info' => $getFromPath( [ 'error', 'info' ] ),
|
157 |
+
'error_message' => $getFromPath( [ 'error', 'message' ] ),
|
158 |
+
'message' => $getFromPath( [ 'message' ] ),
|
159 |
+
'description' => $getFromPath( [ 'description' ] ),
|
160 |
+
] )->filter()
|
161 |
+
->map( function( $value, $key ) {
|
162 |
+
return "$key: $value";
|
163 |
+
} )
|
164 |
+
->implode( ' - ' );
|
165 |
+
|
166 |
+
return $formattedError
|
167 |
+
? strip_tags( $formattedError )
|
168 |
+
: esc_html__( 'Cannot get exchange rates. Connection failed.', 'woocommerce-multilingual' );
|
169 |
+
}
|
170 |
+
|
171 |
/**
|
172 |
* @return array
|
173 |
*/
|
226 |
return $this->getSetting( 'last_error' );
|
227 |
}
|
228 |
|
229 |
+
/**
|
230 |
+
* @return string|null
|
231 |
+
*/
|
232 |
+
protected function getApiKey() {
|
233 |
+
return $this->getSetting( 'api-key' );
|
234 |
+
}
|
235 |
}
|
classes/multi-currency/geolocation/Geolocation.php
CHANGED
@@ -2,15 +2,17 @@
|
|
2 |
|
3 |
namespace WCML\MultiCurrency;
|
4 |
|
|
|
5 |
use WPML\FP\Obj;
|
6 |
use WPML\FP\Relation;
|
7 |
use WPML\FP\Logic;
|
8 |
|
9 |
class Geolocation {
|
10 |
|
11 |
-
const DEFAULT_COUNTRY_CURRENCY_CONFIG = 'country-currency.json';
|
12 |
-
|
13 |
-
const
|
|
|
14 |
|
15 |
/**
|
16 |
* @return bool
|
@@ -19,17 +21,13 @@ class Geolocation {
|
|
19 |
/** @var \woocommerce_wpml $woocommerce_wpml */
|
20 |
global $woocommerce_wpml;
|
21 |
|
22 |
-
$isByLocationMode = function() use ( $woocommerce_wpml ) {
|
23 |
-
return Geolocation::MODE_BY_LOCATION === $woocommerce_wpml->get_setting( 'currency_mode' );
|
24 |
-
};
|
25 |
-
|
26 |
$useDefaultCurrencyByLocation = function() use ( $woocommerce_wpml ) {
|
27 |
return (bool) wpml_collect( $woocommerce_wpml->get_setting( 'default_currencies', [] ) )
|
28 |
->first( Relation::equals( 'location' ) );
|
29 |
};
|
30 |
|
31 |
return wcml_is_multi_currency_on()
|
32 |
-
&& (
|
33 |
}
|
34 |
|
35 |
/**
|
@@ -63,7 +61,7 @@ class Geolocation {
|
|
63 |
*/
|
64 |
private static function parseConfigFile() {
|
65 |
$config = [];
|
66 |
-
$configuration_file = WCML_PLUGIN_PATH .
|
67 |
|
68 |
if ( file_exists( $configuration_file ) ) {
|
69 |
$json_content = file_get_contents( $configuration_file );
|
@@ -74,48 +72,18 @@ class Geolocation {
|
|
74 |
}
|
75 |
|
76 |
/**
|
77 |
-
*
|
78 |
-
*
|
79 |
-
* @return string|bool
|
80 |
-
*/
|
81 |
-
public static function getCurrencyCodeByUserCountry() {
|
82 |
-
|
83 |
-
$country = self::getUserCountry();
|
84 |
-
|
85 |
-
if ( $country ) {
|
86 |
-
$config = self::parseConfigFile();
|
87 |
-
|
88 |
-
return isset( $config[ $country ] ) ? $config[ $country ] : false;
|
89 |
-
}
|
90 |
-
|
91 |
-
return false;
|
92 |
-
}
|
93 |
-
|
94 |
-
/**
|
95 |
-
* Get first available country currency from settings if default country currency not active
|
96 |
*
|
97 |
-
* @
|
98 |
-
*
|
99 |
-
* @return string|bool
|
100 |
*/
|
101 |
-
public static function
|
102 |
-
|
103 |
-
$currency = false;
|
104 |
-
|
105 |
-
wpml_collect( $currenciesSettings )->each( function ( $settings, $code ) use ( &$currency ) {
|
106 |
-
if ( self::isCurrencyAvailableForCountry( $settings ) ) {
|
107 |
-
$currency = $code;
|
108 |
-
}
|
109 |
-
} );
|
110 |
-
|
111 |
-
return $currency;
|
112 |
}
|
113 |
|
114 |
/**
|
115 |
* @return string
|
116 |
*/
|
117 |
public static function getUserCountry(){
|
118 |
-
|
119 |
if ( defined( 'WCML_GEOLOCATED_COUNTRY' ) ) {
|
120 |
return WCML_GEOLOCATED_COUNTRY;
|
121 |
}
|
@@ -125,7 +93,8 @@ class Geolocation {
|
|
125 |
'shipping' => self::getUserCountryByAddress( 'shipping' ),
|
126 |
'geolocation' => self::getCountryByUserIp()
|
127 |
];
|
128 |
-
|
|
|
129 |
|
130 |
/**
|
131 |
* This filter allows to override the address country declared by the user.
|
@@ -152,8 +121,8 @@ class Geolocation {
|
|
152 |
* @return string
|
153 |
*/
|
154 |
private static function getUserCountryByAddress( $addressType ){
|
155 |
-
|
156 |
$orderCountry = self::getUserCountryFromOrder( $addressType );
|
|
|
157 |
if( $orderCountry ){
|
158 |
return $orderCountry;
|
159 |
}
|
@@ -161,7 +130,7 @@ class Geolocation {
|
|
161 |
$current_user_id = get_current_user_id();
|
162 |
|
163 |
if ( $current_user_id ) {
|
164 |
-
$customer = new \WC_Customer( $current_user_id, WC()->session
|
165 |
|
166 |
return 'shipping' === $addressType ? $customer->get_shipping_country() : $customer->get_billing_country();
|
167 |
}
|
@@ -177,42 +146,15 @@ class Geolocation {
|
|
177 |
* @return string
|
178 |
*/
|
179 |
private static function getUserCountryFromOrder( $addressType ) {
|
180 |
-
|
181 |
$country = '';
|
182 |
-
$
|
183 |
|
184 |
-
if ( 'update_order_review'
|
185 |
$country = $_POST['country'];
|
186 |
-
} elseif ( 'checkout'
|
187 |
$country = $_POST[ $addressType . '_country' ];
|
188 |
}
|
189 |
|
190 |
return wc_clean( wp_unslash( $country ) );
|
191 |
}
|
192 |
-
|
193 |
-
/**
|
194 |
-
* @param array $currencySettings
|
195 |
-
*
|
196 |
-
* @return bool
|
197 |
-
*/
|
198 |
-
public static function isCurrencyAvailableForCountry( $currencySettings ) {
|
199 |
-
|
200 |
-
if ( isset( $currencySettings['location_mode'] ) ) {
|
201 |
-
|
202 |
-
if ( 'all' === $currencySettings['location_mode'] ) {
|
203 |
-
return true;
|
204 |
-
}
|
205 |
-
|
206 |
-
if ( 'include' === $currencySettings['location_mode'] && in_array( self::getUserCountry(), $currencySettings['countries'] ) ) {
|
207 |
-
return true;
|
208 |
-
}
|
209 |
-
|
210 |
-
if ( 'exclude' === $currencySettings['location_mode'] && ! in_array( self::getUserCountry(), $currencySettings['countries'] ) ) {
|
211 |
-
return true;
|
212 |
-
}
|
213 |
-
|
214 |
-
}
|
215 |
-
|
216 |
-
return false;
|
217 |
-
}
|
218 |
}
|
2 |
|
3 |
namespace WCML\MultiCurrency;
|
4 |
|
5 |
+
use WPML\FP\Fns;
|
6 |
use WPML\FP\Obj;
|
7 |
use WPML\FP\Relation;
|
8 |
use WPML\FP\Logic;
|
9 |
|
10 |
class Geolocation {
|
11 |
|
12 |
+
const DEFAULT_COUNTRY_CURRENCY_CONFIG = '/res/geolocation/country-currency.json';
|
13 |
+
|
14 |
+
const MODE_BY_LANGUAGE = Settings::MODE_BY_LANGUAGE;
|
15 |
+
const MODE_BY_LOCATION = Settings::MODE_BY_LOCATION;
|
16 |
|
17 |
/**
|
18 |
* @return bool
|
21 |
/** @var \woocommerce_wpml $woocommerce_wpml */
|
22 |
global $woocommerce_wpml;
|
23 |
|
|
|
|
|
|
|
|
|
24 |
$useDefaultCurrencyByLocation = function() use ( $woocommerce_wpml ) {
|
25 |
return (bool) wpml_collect( $woocommerce_wpml->get_setting( 'default_currencies', [] ) )
|
26 |
->first( Relation::equals( 'location' ) );
|
27 |
};
|
28 |
|
29 |
return wcml_is_multi_currency_on()
|
30 |
+
&& ( Settings::isModeByLocation() || $useDefaultCurrencyByLocation() );
|
31 |
}
|
32 |
|
33 |
/**
|
61 |
*/
|
62 |
private static function parseConfigFile() {
|
63 |
$config = [];
|
64 |
+
$configuration_file = WCML_PLUGIN_PATH . self::DEFAULT_COUNTRY_CURRENCY_CONFIG;
|
65 |
|
66 |
if ( file_exists( $configuration_file ) ) {
|
67 |
$json_content = file_get_contents( $configuration_file );
|
72 |
}
|
73 |
|
74 |
/**
|
75 |
+
* @param string
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
76 |
*
|
77 |
+
* @return string|null
|
|
|
|
|
78 |
*/
|
79 |
+
public static function getOfficialCurrencyCodeByCountry( $country ) {
|
80 |
+
return Obj::prop( $country, self::parseConfigFile() );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
81 |
}
|
82 |
|
83 |
/**
|
84 |
* @return string
|
85 |
*/
|
86 |
public static function getUserCountry(){
|
|
|
87 |
if ( defined( 'WCML_GEOLOCATED_COUNTRY' ) ) {
|
88 |
return WCML_GEOLOCATED_COUNTRY;
|
89 |
}
|
93 |
'shipping' => self::getUserCountryByAddress( 'shipping' ),
|
94 |
'geolocation' => self::getCountryByUserIp()
|
95 |
];
|
96 |
+
|
97 |
+
$userCountry = $allUserCountries['billing'] ?: $allUserCountries['geolocation'];
|
98 |
|
99 |
/**
|
100 |
* This filter allows to override the address country declared by the user.
|
121 |
* @return string
|
122 |
*/
|
123 |
private static function getUserCountryByAddress( $addressType ){
|
|
|
124 |
$orderCountry = self::getUserCountryFromOrder( $addressType );
|
125 |
+
|
126 |
if( $orderCountry ){
|
127 |
return $orderCountry;
|
128 |
}
|
130 |
$current_user_id = get_current_user_id();
|
131 |
|
132 |
if ( $current_user_id ) {
|
133 |
+
$customer = new \WC_Customer( $current_user_id, (bool) WC()->session );
|
134 |
|
135 |
return 'shipping' === $addressType ? $customer->get_shipping_country() : $customer->get_billing_country();
|
136 |
}
|
146 |
* @return string
|
147 |
*/
|
148 |
private static function getUserCountryFromOrder( $addressType ) {
|
|
|
149 |
$country = '';
|
150 |
+
$isWcAjax = Relation::propEq( 'wc-ajax', Fns::__, $_GET );
|
151 |
|
152 |
+
if ( $isWcAjax( 'update_order_review' ) && isset( $_POST['country'] ) ) {
|
153 |
$country = $_POST['country'];
|
154 |
+
} elseif ( $isWcAjax( 'checkout' ) && isset( $_POST[ $addressType . '_country' ] ) ) {
|
155 |
$country = $_POST[ $addressType . '_country' ];
|
156 |
}
|
157 |
|
158 |
return wc_clean( wp_unslash( $country ) );
|
159 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
160 |
}
|
classes/multi-currency/geolocation/GeolocationBackendHooks.php
CHANGED
@@ -2,7 +2,9 @@
|
|
2 |
|
3 |
namespace WCML\MultiCurrency;
|
4 |
|
5 |
-
|
|
|
|
|
6 |
|
7 |
public function add_hooks() {
|
8 |
add_filter( 'wcml_geolocation_is_used', [ Geolocation::class, 'isUsed' ] );
|
2 |
|
3 |
namespace WCML\MultiCurrency;
|
4 |
|
5 |
+
use WCML\StandAlone\IStandAloneAction;
|
6 |
+
|
7 |
+
class GeolocationBackendHooks implements \IWPML_Backend_Action, IStandAloneAction {
|
8 |
|
9 |
public function add_hooks() {
|
10 |
add_filter( 'wcml_geolocation_is_used', [ Geolocation::class, 'isUsed' ] );
|
classes/multi-currency/geolocation/GeolocationFrontendHooks.php
CHANGED
@@ -2,7 +2,9 @@
|
|
2 |
|
3 |
namespace WCML\MultiCurrency;
|
4 |
|
5 |
-
|
|
|
|
|
6 |
|
7 |
const KEY_CLIENT_COUNTRY = 'wcml_client_country';
|
8 |
|
2 |
|
3 |
namespace WCML\MultiCurrency;
|
4 |
|
5 |
+
use WCML\StandAlone\IStandAloneAction;
|
6 |
+
|
7 |
+
class GeolocationFrontendHooks implements \IWPML_Frontend_Action, IStandAloneAction {
|
8 |
|
9 |
const KEY_CLIENT_COUNTRY = 'wcml_client_country';
|
10 |
|
classes/multi-currency/payment-gateways/class-wcml-currencies-payment-gateways.php
CHANGED
@@ -1,5 +1,7 @@
|
|
1 |
<?php
|
2 |
|
|
|
|
|
3 |
/**
|
4 |
* Class WCML_Currencies_Payment_Gateways
|
5 |
*/
|
@@ -36,9 +38,9 @@ class WCML_Currencies_Payment_Gateways {
|
|
36 |
|
37 |
add_filter( 'woocommerce_gateway_description', [ $this, 'filter_gateway_description' ], 10, 2 );
|
38 |
add_filter( 'option_woocommerce_stripe_settings', [ 'WCML_Payment_Gateway_Stripe', 'filter_stripe_settings' ] );
|
|
|
39 |
|
40 |
-
|
41 |
-
add_filter( 'woocommerce_should_load_paypal_standard', '__return_true' );
|
42 |
|
43 |
if ( ! is_admin() && wcml_is_multi_currency_on() ) {
|
44 |
add_filter(
|
@@ -95,9 +97,10 @@ class WCML_Currencies_Payment_Gateways {
|
|
95 |
$this->available_gateways = $this->get_available_payment_gateways();
|
96 |
|
97 |
$this->supported_gateways = [
|
98 |
-
'bacs'
|
99 |
-
'paypal'
|
100 |
-
'
|
|
|
101 |
];
|
102 |
$this->supported_gateways = apply_filters( 'wcml_supported_currency_payment_gateways', $this->supported_gateways );
|
103 |
|
1 |
<?php
|
2 |
|
3 |
+
use WCML\Multicurrency\Transient\Hooks as TransientHooks;
|
4 |
+
|
5 |
/**
|
6 |
* Class WCML_Currencies_Payment_Gateways
|
7 |
*/
|
38 |
|
39 |
add_filter( 'woocommerce_gateway_description', [ $this, 'filter_gateway_description' ], 10, 2 );
|
40 |
add_filter( 'option_woocommerce_stripe_settings', [ 'WCML_Payment_Gateway_Stripe', 'filter_stripe_settings' ] );
|
41 |
+
add_filter( 'option_woocommerce-ppcp-settings', [ 'WCML_Payment_Gateway_PayPal_V2', 'filter_ppcp_args' ] );
|
42 |
|
43 |
+
TransientHooks::addHooks( WCML_Payment_Gateway_PayPal_V2::BEARER_TOKEN_TRANSIENT );
|
|
|
44 |
|
45 |
if ( ! is_admin() && wcml_is_multi_currency_on() ) {
|
46 |
add_filter(
|
97 |
$this->available_gateways = $this->get_available_payment_gateways();
|
98 |
|
99 |
$this->supported_gateways = [
|
100 |
+
'bacs' => 'WCML_Payment_Gateway_Bacs',
|
101 |
+
'paypal' => 'WCML_Payment_Gateway_PayPal',
|
102 |
+
'ppcp-gateway' => 'WCML_Payment_Gateway_PayPal_V2',
|
103 |
+
'stripe' => 'WCML_Payment_Gateway_Stripe',
|
104 |
];
|
105 |
$this->supported_gateways = apply_filters( 'wcml_supported_currency_payment_gateways', $this->supported_gateways );
|
106 |
|
classes/multi-currency/payment-gateways/class-wcml-payment-gateway-paypal-v2.php
ADDED
@@ -0,0 +1,95 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
use WPML\FP\Obj;
|
4 |
+
use WPML\FP\Fns;
|
5 |
+
use function WCML\functions\getClientCurrency;
|
6 |
+
|
7 |
+
/**
|
8 |
+
* @see https://wordpress.org/plugins/woocommerce-paypal-payments/
|
9 |
+
*/
|
10 |
+
class WCML_Payment_Gateway_PayPal_V2 extends WCML_Payment_Gateway_PayPal {
|
11 |
+
|
12 |
+
const ID = 'ppcp-gateway';
|
13 |
+
|
14 |
+
const FIELDS = [
|
15 |
+
'merchant_email',
|
16 |
+
'merchant_id',
|
17 |
+
'client_id',
|
18 |
+
'client_secret',
|
19 |
+
];
|
20 |
+
|
21 |
+
const BEARER_TOKEN_TRANSIENT = 'ppcp-paypal-bearerppcp-bearer';
|
22 |
+
|
23 |
+
public function get_output_model() {
|
24 |
+
return [
|
25 |
+
'id' => $this->get_id(),
|
26 |
+
'title' => $this->get_title(),
|
27 |
+
'isSupported' => true,
|
28 |
+
'settings' => $this->get_currencies_details(),
|
29 |
+
'tooltip' => '',
|
30 |
+
'strings' => [
|
31 |
+
'labelCurrency' => __( 'Currency', 'woocommerce-multilingual' ),
|
32 |
+
'labelPayPalEmail' => __( 'PayPal Email', 'woocommerce-multilingual' ),
|
33 |
+
'labelMerchantId' => __( 'Merchant ID', 'woocommerce-multilingual' ),
|
34 |
+
'labelClientId' => __( 'Client ID', 'woocommerce-multilingual' ),
|
35 |
+
'labelSecretKey' => __( 'Secret Key', 'woocommerce-multilingual' ),
|
36 |
+
// translators: %s is currency code.
|
37 |
+
'tooltipNotSupported' => __( 'This gateway does not support %s. To show this gateway please select another currency.', 'woocommerce-multilingual' ),
|
38 |
+
],
|
39 |
+
];
|
40 |
+
}
|
41 |
+
|
42 |
+
/**
|
43 |
+
* @return array
|
44 |
+
*/
|
45 |
+
public function get_currencies_details() {
|
46 |
+
$currencies_details = [];
|
47 |
+
$default_currency = wcml_get_woocommerce_currency_option();
|
48 |
+
$woocommerce_currencies = get_woocommerce_currencies();
|
49 |
+
|
50 |
+
foreach ( $woocommerce_currencies as $code => $currency ) {
|
51 |
+
if ( $default_currency === $code ) {
|
52 |
+
$getSetting = Obj::propOr( '', Fns::__, $this->get_gateway()->settings );
|
53 |
+
} else {
|
54 |
+
$getSetting = Obj::propOr( '', Fns::__, $this->get_setting( $code ) );
|
55 |
+
}
|
56 |
+
|
57 |
+
foreach ( self::FIELDS as $key ) {
|
58 |
+
$currencies_details[ $code ][ $key ] = $getSetting( $key );
|
59 |
+
}
|
60 |
+
|
61 |
+
$currencies_details[ $code ]['currency'] = $code;
|
62 |
+
$currencies_details[ $code ]['isValid'] = $this->is_valid_for_use( $code );
|
63 |
+
}
|
64 |
+
|
65 |
+
return $currencies_details;
|
66 |
+
}
|
67 |
+
|
68 |
+
public function add_hooks() {
|
69 |
+
|
70 |
+
}
|
71 |
+
|
72 |
+
/**
|
73 |
+
* @param array $settings
|
74 |
+
*
|
75 |
+
* @return array
|
76 |
+
*/
|
77 |
+
public static function filter_ppcp_args( $settings ) {
|
78 |
+
if ( is_admin() ) {
|
79 |
+
return $settings;
|
80 |
+
}
|
81 |
+
|
82 |
+
$gateway = Obj::prop( getClientCurrency(), get_option( self::OPTION_KEY . self::ID, [] ) );
|
83 |
+
|
84 |
+
if ( $gateway ) {
|
85 |
+
$getSetting = Obj::prop( Fns::__, $gateway );
|
86 |
+
|
87 |
+
foreach ( self::FIELDS as $key ) {
|
88 |
+
$settings[ $key ] = $getSetting( $key ) ?: $settings[ $key ];
|
89 |
+
}
|
90 |
+
}
|
91 |
+
|
92 |
+
return $settings;
|
93 |
+
}
|
94 |
+
|
95 |
+
}
|
classes/multi-currency/payment-gateways/class-wcml-payment-gateway-paypal.php
CHANGED
@@ -46,13 +46,14 @@ class WCML_Payment_Gateway_PayPal extends WCML_Payment_Gateway {
|
|
46 |
'strings' => [
|
47 |
'labelCurrency' => __( 'Currency', 'woocommerce-multilingual' ),
|
48 |
'labelPayPalEmail' => __( 'PayPal Email', 'woocommerce-multilingual' ),
|
|
|
49 |
'tooltipNotSupported' => __( 'This gateway does not support %s. To show this gateway please select another currency.', 'woocommerce-multilingual' ),
|
50 |
],
|
51 |
];
|
52 |
}
|
53 |
|
54 |
/**
|
55 |
-
* @param $currency
|
56 |
*
|
57 |
* @return bool
|
58 |
*/
|
@@ -77,8 +78,6 @@ class WCML_Payment_Gateway_PayPal extends WCML_Payment_Gateway {
|
|
77 |
}
|
78 |
|
79 |
/**
|
80 |
-
* @param array $active_currencies
|
81 |
-
*
|
82 |
* @return array
|
83 |
*/
|
84 |
public function get_currencies_details() {
|
@@ -90,14 +89,14 @@ class WCML_Payment_Gateway_PayPal extends WCML_Payment_Gateway {
|
|
90 |
foreach ( $woocommerce_currencies as $code => $currency ) {
|
91 |
|
92 |
if ( $default_currency === $code ) {
|
93 |
-
$currencies_details[ $code ]['value'] = $this->get_gateway()->settings['email'];
|
94 |
$currencies_details[ $code ]['currency'] = $code;
|
95 |
-
$currencies_details[ $code ]['isValid']
|
96 |
} else {
|
97 |
$currency_gateway_setting = $this->get_setting( $code );
|
98 |
$currencies_details[ $code ]['value'] = $currency_gateway_setting ? $currency_gateway_setting['value'] : '';
|
99 |
$currencies_details[ $code ]['currency'] = $currency_gateway_setting ? $currency_gateway_setting['currency'] : $code;
|
100 |
-
$currencies_details[ $code ]['isValid']
|
101 |
}
|
102 |
}
|
103 |
|
46 |
'strings' => [
|
47 |
'labelCurrency' => __( 'Currency', 'woocommerce-multilingual' ),
|
48 |
'labelPayPalEmail' => __( 'PayPal Email', 'woocommerce-multilingual' ),
|
49 |
+
// translators: %s is currency code.
|
50 |
'tooltipNotSupported' => __( 'This gateway does not support %s. To show this gateway please select another currency.', 'woocommerce-multilingual' ),
|
51 |
],
|
52 |
];
|
53 |
}
|
54 |
|
55 |
/**
|
56 |
+
* @param string $currency
|
57 |
*
|
58 |
* @return bool
|
59 |
*/
|
78 |
}
|
79 |
|
80 |
/**
|
|
|
|
|
81 |
* @return array
|
82 |
*/
|
83 |
public function get_currencies_details() {
|
89 |
foreach ( $woocommerce_currencies as $code => $currency ) {
|
90 |
|
91 |
if ( $default_currency === $code ) {
|
92 |
+
$currencies_details[ $code ]['value'] = isset( $this->get_gateway()->settings['email'] ) ? $this->get_gateway()->settings['email'] : '';
|
93 |
$currencies_details[ $code ]['currency'] = $code;
|
94 |
+
$currencies_details[ $code ]['isValid'] = $this->is_valid_for_use( $default_currency );
|
95 |
} else {
|
96 |
$currency_gateway_setting = $this->get_setting( $code );
|
97 |
$currencies_details[ $code ]['value'] = $currency_gateway_setting ? $currency_gateway_setting['value'] : '';
|
98 |
$currencies_details[ $code ]['currency'] = $currency_gateway_setting ? $currency_gateway_setting['currency'] : $code;
|
99 |
+
$currencies_details[ $code ]['isValid'] = $this->is_valid_for_use( $code );
|
100 |
}
|
101 |
}
|
102 |
|
classes/pointers/class-wcml-pointers.php
CHANGED
@@ -1,5 +1,7 @@
|
|
1 |
<?php
|
2 |
|
|
|
|
|
3 |
class WCML_Pointers{
|
4 |
|
5 |
public function add_hooks() {
|
@@ -8,24 +10,29 @@ class WCML_Pointers{
|
|
8 |
|
9 |
public function setup() {
|
10 |
$current_screen = get_current_screen();
|
11 |
-
|
12 |
if ( empty( $current_screen ) ) {
|
13 |
return;
|
14 |
}
|
|
|
|
|
|
|
|
|
15 |
|
16 |
-
$tab
|
17 |
-
$section
|
|
|
18 |
wp_register_style( 'wcml-pointers', WCML_PLUGIN_URL . '/res/css/wcml-pointers.css' );
|
19 |
|
20 |
-
if ( 'edit-product' === $current_screen->id ) {
|
21 |
add_action( 'admin_footer', array( $this, 'add_products_translation_link' ), 100 );
|
22 |
} elseif ( 'woocommerce_page_wc-settings' === $current_screen->id ) {
|
23 |
-
if ( 'shipping' === $tab && 'classes' === $section ) {
|
24 |
add_action( 'admin_footer', array( $this, 'add_shipping_classes_translation_link' ) );
|
25 |
} elseif ( ! $tab || 'general' === $tab ) {
|
26 |
add_filter( 'woocommerce_general_settings', array( $this, 'add_multi_currency_link' ) );
|
27 |
-
} elseif ( '
|
28 |
-
add_filter( '
|
29 |
}
|
30 |
}
|
31 |
}
|
@@ -53,7 +60,7 @@ class WCML_Pointers{
|
|
53 |
*/
|
54 |
public function add_multi_currency_link( array $settings ) {
|
55 |
$link = admin_url( 'admin.php?page=wpml-wcml&tab=multi-currency' );
|
56 |
-
$name = __( 'Configure
|
57 |
|
58 |
$anchor = '<a class="button button-small button-wpml wcml-pointer-multi_currency" href="{{ url }}">{{ text }}</a>';
|
59 |
|
@@ -71,7 +78,7 @@ class WCML_Pointers{
|
|
71 |
|
72 |
$anchor = '<a class="button button-small button-wpml wcml-pointer-endpoints_translation" href="{{ url }}">{{ text }}</a>';
|
73 |
|
74 |
-
return $this->add_link_with_settings( $link, $name, '
|
75 |
}
|
76 |
|
77 |
/**
|
1 |
<?php
|
2 |
|
3 |
+
use function WCML\functions\isStandAlone;
|
4 |
+
|
5 |
class WCML_Pointers{
|
6 |
|
7 |
public function add_hooks() {
|
10 |
|
11 |
public function setup() {
|
12 |
$current_screen = get_current_screen();
|
13 |
+
|
14 |
if ( empty( $current_screen ) ) {
|
15 |
return;
|
16 |
}
|
17 |
+
|
18 |
+
if ( ! WCML_Capabilities::canManageWcml() ) {
|
19 |
+
return;
|
20 |
+
}
|
21 |
|
22 |
+
$tab = isset( $_GET['tab'] ) ? $_GET['tab'] : '';
|
23 |
+
$section = isset( $_GET['section'] ) ? $_GET['section'] : '';
|
24 |
+
$isFullMode = ! isStandAlone();
|
25 |
wp_register_style( 'wcml-pointers', WCML_PLUGIN_URL . '/res/css/wcml-pointers.css' );
|
26 |
|
27 |
+
if ( $isFullMode && 'edit-product' === $current_screen->id ) {
|
28 |
add_action( 'admin_footer', array( $this, 'add_products_translation_link' ), 100 );
|
29 |
} elseif ( 'woocommerce_page_wc-settings' === $current_screen->id ) {
|
30 |
+
if ( $isFullMode && 'shipping' === $tab && 'classes' === $section ) {
|
31 |
add_action( 'admin_footer', array( $this, 'add_shipping_classes_translation_link' ) );
|
32 |
} elseif ( ! $tab || 'general' === $tab ) {
|
33 |
add_filter( 'woocommerce_general_settings', array( $this, 'add_multi_currency_link' ) );
|
34 |
+
} elseif ( $isFullMode && 'advanced' === $tab ) {
|
35 |
+
add_filter( 'woocommerce_settings_pages', array( $this, 'add_endpoints_translation_link' ) );
|
36 |
}
|
37 |
}
|
38 |
}
|
60 |
*/
|
61 |
public function add_multi_currency_link( array $settings ) {
|
62 |
$link = admin_url( 'admin.php?page=wpml-wcml&tab=multi-currency' );
|
63 |
+
$name = __( 'Configure multicurrency for multilingual sites', 'woocommerce-multilingual' );
|
64 |
|
65 |
$anchor = '<a class="button button-small button-wpml wcml-pointer-multi_currency" href="{{ url }}">{{ text }}</a>';
|
66 |
|
78 |
|
79 |
$anchor = '<a class="button button-small button-wpml wcml-pointer-endpoints_translation" href="{{ url }}">{{ text }}</a>';
|
80 |
|
81 |
+
return $this->add_link_with_settings( $link, $name, 'checkout_endpoint_options', $settings, $anchor );
|
82 |
}
|
83 |
|
84 |
/**
|
classes/privacy/class-wcml-privacy-content.php
CHANGED
@@ -9,7 +9,7 @@ class WCML_Privacy_Content extends WPML_Privacy_Content {
|
|
9 |
* @return string
|
10 |
*/
|
11 |
protected function get_plugin_name() {
|
12 |
-
return 'WooCommerce Multilingual';
|
13 |
}
|
14 |
|
15 |
/**
|
@@ -17,8 +17,8 @@ class WCML_Privacy_Content extends WPML_Privacy_Content {
|
|
17 |
*/
|
18 |
protected function get_privacy_policy() {
|
19 |
return [
|
20 |
-
__( 'WooCommerce Multilingual will use cookies to understand the basket info when using languages in domains and to transfer data between the domains.', 'woocommerce-multilingual' ),
|
21 |
-
__( 'WooCommerce Multilingual will also use cookies to identify the language and currency of each customer’s order as well as the currency of the reports created by WooCommerce. WooCommerce Multilingual extends these reports by adding the currency’s information.', 'woocommerce-multilingual' ),
|
22 |
];
|
23 |
}
|
24 |
|
9 |
* @return string
|
10 |
*/
|
11 |
protected function get_plugin_name() {
|
12 |
+
return 'WooCommerce Multilingual & Multicurrency';
|
13 |
}
|
14 |
|
15 |
/**
|
17 |
*/
|
18 |
protected function get_privacy_policy() {
|
19 |
return [
|
20 |
+
__( 'WooCommerce Multilingual & Multicurrency will use cookies to understand the basket info when using languages in domains and to transfer data between the domains.', 'woocommerce-multilingual' ),
|
21 |
+
__( 'WooCommerce Multilingual & Multicurrency will also use cookies to identify the language and currency of each customer’s order as well as the currency of the reports created by WooCommerce. WooCommerce Multilingual extends these reports by adding the currency’s information.', 'woocommerce-multilingual' ),
|
22 |
];
|
23 |
}
|
24 |
|
classes/shortcodes/class-wcml-wc-shortcode-product-category.php
CHANGED
@@ -19,7 +19,7 @@ class WCML_WC_Shortcode_Product_Category {
|
|
19 |
*
|
20 |
* @param SitePress $sitepress
|
21 |
*/
|
22 |
-
public function __construct(
|
23 |
$this->sitepress = $sitepress;
|
24 |
}
|
25 |
|
19 |
*
|
20 |
* @param SitePress $sitepress
|
21 |
*/
|
22 |
+
public function __construct( \WPML\Core\ISitePress $sitepress ) {
|
23 |
$this->sitepress = $sitepress;
|
24 |
}
|
25 |
|
classes/taxonomy-translation/class-wcml-taxonomy-translation-link-filters.php
CHANGED
@@ -31,10 +31,12 @@ class WCML_Taxonomy_Translation_Link_Filters {
|
|
31 |
$link = sprintf(
|
32 |
'<a href="%s">%s</a>',
|
33 |
$this->get_screen_url( $taxonomy->name ),
|
|
|
34 |
sprintf( esc_html__( '%s translation', 'woocommerce-multilingual' ), $taxonomy->labels->singular_name )
|
35 |
);
|
36 |
|
37 |
$text = sprintf(
|
|
|
38 |
esc_html__( 'Translating %1$s? Use the %2$s table for easier translation.', 'woocommerce-multilingual' ),
|
39 |
$taxonomy->labels->name,
|
40 |
$link
|
31 |
$link = sprintf(
|
32 |
'<a href="%s">%s</a>',
|
33 |
$this->get_screen_url( $taxonomy->name ),
|
34 |
+
/* translators: %s is a taxonomy singular label */
|
35 |
sprintf( esc_html__( '%s translation', 'woocommerce-multilingual' ), $taxonomy->labels->singular_name )
|
36 |
);
|
37 |
|
38 |
$text = sprintf(
|
39 |
+
/* translators: %1$s is a taxonomy singular label and %2$s is an HTML link */
|
40 |
esc_html__( 'Translating %1$s? Use the %2$s table for easier translation.', 'woocommerce-multilingual' ),
|
41 |
$taxonomy->labels->name,
|
42 |
$link
|
classes/urls/class-wcml-xdomain-data.php
CHANGED
@@ -4,7 +4,7 @@
|
|
4 |
* Handles data being passed between different domains using WPML xDomain logic
|
5 |
* https://wpml.org/?page_id=693147
|
6 |
*/
|
7 |
-
class WCML_xDomain_Data {
|
8 |
|
9 |
/**
|
10 |
* @var WPML_Cookie
|
4 |
* Handles data being passed between different domains using WPML xDomain logic
|
5 |
* https://wpml.org/?page_id=693147
|
6 |
*/
|
7 |
+
class WCML_xDomain_Data implements \IWPML_Backend_Action, \IWPML_Frontend_Action, \IWPML_DIC_Action {
|
8 |
|
9 |
/**
|
10 |
* @var WPML_Cookie
|
classes/wcml-setup/class-wcml-setup.php
CHANGED
@@ -28,7 +28,7 @@ class WCML_Setup {
|
|
28 |
* @param woocommerce_wpml $woocommerce_wpml
|
29 |
* @param SitePress $sitepress
|
30 |
*/
|
31 |
-
public function __construct( WCML_Setup_UI $ui, WCML_Setup_Handlers $handlers, woocommerce_wpml $woocommerce_wpml,
|
32 |
|
33 |
$this->ui = $ui;
|
34 |
$this->handlers = $handlers;
|
@@ -153,7 +153,7 @@ class WCML_Setup {
|
|
153 |
|
154 |
$this->step = isset( $_GET['step'] ) ? sanitize_key( $_GET['step'] ) : current( array_keys( $this->steps ) );
|
155 |
|
156 |
-
wp_enqueue_style( 'otgs-ico',
|
157 |
wp_enqueue_style(
|
158 |
'wcml-setup',
|
159 |
WCML_PLUGIN_URL . '/res/css/wcml-setup.css',
|
@@ -204,7 +204,7 @@ class WCML_Setup {
|
|
204 |
}
|
205 |
|
206 |
if ( ! current_user_can( 'manage_options' ) ) {
|
207 |
-
wp_die( esc_html__( "Cheatin' huh?", 'woocommerce' ) );
|
208 |
}
|
209 |
|
210 |
$this->complete_setup();
|
28 |
* @param woocommerce_wpml $woocommerce_wpml
|
29 |
* @param SitePress $sitepress
|
30 |
*/
|
31 |
+
public function __construct( WCML_Setup_UI $ui, WCML_Setup_Handlers $handlers, woocommerce_wpml $woocommerce_wpml, \WPML\Core\ISitePress $sitepress ) {
|
32 |
|
33 |
$this->ui = $ui;
|
34 |
$this->handlers = $handlers;
|
153 |
|
154 |
$this->step = isset( $_GET['step'] ) ? sanitize_key( $_GET['step'] ) : current( array_keys( $this->steps ) );
|
155 |
|
156 |
+
wp_enqueue_style( 'otgs-ico', \WCML\functions\assetLink( '/res/css/otgs-ico.css' ), null, ICL_SITEPRESS_VERSION );
|
157 |
wp_enqueue_style(
|
158 |
'wcml-setup',
|
159 |
WCML_PLUGIN_URL . '/res/css/wcml-setup.css',
|
204 |
}
|
205 |
|
206 |
if ( ! current_user_can( 'manage_options' ) ) {
|
207 |
+
wp_die( esc_html__( "Cheatin' huh?", 'woocommerce-multilingual' ) );
|
208 |
}
|
209 |
|
210 |
$this->complete_setup();
|
compatibility/AdventureTours/Factory.php
ADDED
@@ -0,0 +1,18 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace WCML\Compatibility\AdventureTours;
|
4 |
+
|
5 |
+
use WCML\Compatibility\ComponentFactory;
|
6 |
+
use WCML_Adventure_tours;
|
7 |
+
use function WCML\functions\getSitePress;
|
8 |
+
use function WCML\functions\getWooCommerceWpml;
|
9 |
+
|
10 |
+
class Factory extends ComponentFactory {
|
11 |
+
|
12 |
+
/**
|
13 |
+
* @inheritDoc
|
14 |
+
*/
|
15 |
+
public function create() {
|
16 |
+
return new WCML_Adventure_tours( getWooCommerceWpml(), getSitePress(), self::getElementTranslationPackage() );
|
17 |
+
}
|
18 |
+
}
|
compatibility/{class-wcml-adventure-tours.php → AdventureTours/class-wcml-adventure-tours.php}
RENAMED
@@ -1,6 +1,6 @@
|
|
1 |
<?php
|
2 |
|
3 |
-
class WCML_Adventure_tours {
|
4 |
|
5 |
/**
|
6 |
* @var woocommerce_wpml
|
1 |
<?php
|
2 |
|
3 |
+
class WCML_Adventure_tours implements \IWPML_Action {
|
4 |
|
5 |
/**
|
6 |
* @var woocommerce_wpml
|
compatibility/Aurum/Factory.php
ADDED
@@ -0,0 +1,25 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace WCML\Compatibility\Aurum;
|
4 |
+
|
5 |
+
use WCML\Compatibility\ComponentFactory;
|
6 |
+
use WCML\StandAlone\IStandAloneAction;
|
7 |
+
|
8 |
+
/**
|
9 |
+
* @see https://laborator.co/themes/aurum/
|
10 |
+
*/
|
11 |
+
class Factory extends ComponentFactory implements IStandAloneAction {
|
12 |
+
|
13 |
+
/**
|
14 |
+
* @inheritDoc
|
15 |
+
*/
|
16 |
+
public function create() {
|
17 |
+
$hooks = [];
|
18 |
+
|
19 |
+
if ( wcml_is_multi_currency_on() ) {
|
20 |
+
$hooks[] = new MulticurrencyHooks();
|
21 |
+
}
|
22 |
+
|
23 |
+
return $hooks;
|
24 |
+
}
|
25 |
+
}
|
compatibility/{class-wcml-aurum.php → Aurum/MulticurrencyHooks.php}
RENAMED
@@ -1,17 +1,21 @@
|
|
1 |
<?php
|
2 |
|
3 |
-
|
4 |
|
5 |
-
|
6 |
|
|
|
7 |
add_filter( 'wcml_multi_currency_ajax_actions', [ $this, 'add_ajax_action' ] );
|
8 |
}
|
9 |
|
|
|
|
|
|
|
|
|
|
|
10 |
public function add_ajax_action( $actions ) {
|
11 |
-
|
12 |
$actions[] = 'lab_wc_add_to_cart';
|
13 |
|
14 |
return $actions;
|
15 |
}
|
16 |
-
|
17 |
}
|
1 |
<?php
|
2 |
|
3 |
+
namespace WCML\Compatibility\Aurum;
|
4 |
|
5 |
+
class MulticurrencyHooks implements \IWPML_Action {
|
6 |
|
7 |
+
public function add_hooks() {
|
8 |
add_filter( 'wcml_multi_currency_ajax_actions', [ $this, 'add_ajax_action' ] );
|
9 |
}
|
10 |
|
11 |
+
/**
|
12 |
+
* @param array $actions
|
13 |
+
*
|
14 |
+
* @return array
|
15 |
+
*/
|
16 |
public function add_ajax_action( $actions ) {
|
|
|
17 |
$actions[] = 'lab_wc_add_to_cart';
|
18 |
|
19 |
return $actions;
|
20 |
}
|
|
|
21 |
}
|
compatibility/ComponentFactory.php
ADDED
@@ -0,0 +1,58 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace WCML\Compatibility;
|
4 |
+
|
5 |
+
use WooCommerce;
|
6 |
+
use wpdb;
|
7 |
+
use WPML_Element_Translation_Package;
|
8 |
+
|
9 |
+
abstract class ComponentFactory implements \IWPML_Backend_Action_Loader, \IWPML_Frontend_Action_Loader {
|
10 |
+
|
11 |
+
/**
|
12 |
+
* @return callable|\IWPML_Action|\IWPML_Action[]|void|null
|
13 |
+
*/
|
14 |
+
abstract public function create();
|
15 |
+
|
16 |
+
/**
|
17 |
+
* @return wpdb
|
18 |
+
*/
|
19 |
+
protected static function getWpdb() {
|
20 |
+
/**
|
21 |
+
* @var wpdb $wpdb
|
22 |
+
*/
|
23 |
+
global $wpdb;
|
24 |
+
|
25 |
+
return $wpdb;
|
26 |
+
}
|
27 |
+
|
28 |
+
/**
|
29 |
+
* @return WooCommerce
|
30 |
+
*/
|
31 |
+
protected static function getWooCommerce() {
|
32 |
+
/**
|
33 |
+
* @var WooCommerce $woocommerce
|
34 |
+
*/
|
35 |
+
global $woocommerce;
|
36 |
+
|
37 |
+
return $woocommerce;
|
38 |
+
}
|
39 |
+
|
40 |
+
/**
|
41 |
+
* @return WPML_Element_Translation_Package|null
|
42 |
+
*/
|
43 |
+
protected static function getElementTranslationPackage() {
|
44 |
+
return class_exists( 'WPML_Element_Translation_Package' ) ? new WPML_Element_Translation_Package() : null;
|
45 |
+
}
|
46 |
+
|
47 |
+
/**
|
48 |
+
* @return \WPML_Post_Translation|null
|
49 |
+
*/
|
50 |
+
protected static function getPostTranslations() {
|
51 |
+
/**
|
52 |
+
* @var \WPML_Post_Translation|null $wpml_post_translations
|
53 |
+
*/
|
54 |
+
global $wpml_post_translations;
|
55 |
+
|
56 |
+
return $wpml_post_translations;
|
57 |
+
}
|
58 |
+
}
|
compatibility/Flatsome/Factory.php
ADDED
@@ -0,0 +1,16 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace WCML\Compatibility\Flatsome;
|
4 |
+
|
5 |
+
use WCML\Compatibility\ComponentFactory;
|
6 |
+
use WCML_Flatsome;
|
7 |
+
|
8 |
+
class Factory extends ComponentFactory {
|
9 |
+
|
10 |
+
/**
|
11 |
+
* @inheritDoc
|
12 |
+
*/
|
13 |
+
public function create() {
|
14 |
+
return new WCML_Flatsome();
|
15 |
+
}
|
16 |
+
}
|
compatibility/{class-wcml-flatsome.php → Flatsome/class-wcml-flatsome.php}
RENAMED
@@ -1,8 +1,8 @@
|
|
1 |
<?php
|
2 |
|
3 |
-
class WCML_Flatsome {
|
4 |
|
5 |
-
public function
|
6 |
add_filter( 'wcml_multi_currency_ajax_actions', [ $this, 'add_action_to_multi_currency_ajax' ] );
|
7 |
}
|
8 |
|
1 |
<?php
|
2 |
|
3 |
+
class WCML_Flatsome implements \IWPML_Action {
|
4 |
|
5 |
+
public function add_hooks() {
|
6 |
add_filter( 'wcml_multi_currency_ajax_actions', [ $this, 'add_action_to_multi_currency_ajax' ] );
|
7 |
}
|
8 |
|
compatibility/GravityForms/Factory.php
ADDED
@@ -0,0 +1,34 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace WCML\Compatibility\GravityForms;
|
4 |
+
|
5 |
+
use WCML\Compatibility\ComponentFactory;
|
6 |
+
use WCML\StandAlone\IStandAloneAction;
|
7 |
+
use WCML_gravityforms;
|
8 |
+
use function WCML\functions\getSitePress;
|
9 |
+
use function WCML\functions\getWooCommerceWpml;
|
10 |
+
use function WCML\functions\isStandAlone;
|
11 |
+
|
12 |
+
/**
|
13 |
+
* @see https://www.gravityforms.com/
|
14 |
+
*/
|
15 |
+
class Factory extends ComponentFactory implements IStandAloneAction {
|
16 |
+
|
17 |
+
/**
|
18 |
+
* @inheritDoc
|
19 |
+
*/
|
20 |
+
public function create() {
|
21 |
+
$hooks = [];
|
22 |
+
|
23 |
+
if ( wcml_is_multi_currency_on() ) {
|
24 |
+
$hooks[] = new MulticurrencyHooks();
|
25 |
+
}
|
26 |
+
|
27 |
+
if ( ! isStandAlone() ) {
|
28 |
+
$hooks[] = new WCML_gravityforms( getSitePress(), getWooCommerceWpml() );
|
29 |
+
}
|
30 |
+
|
31 |
+
return $hooks;
|
32 |
+
}
|
33 |
+
|
34 |
+
}
|
compatibility/GravityForms/MulticurrencyHooks.php
ADDED
@@ -0,0 +1,37 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace WCML\Compatibility\GravityForms;
|
4 |
+
|
5 |
+
class MulticurrencyHooks implements \IWPML_Action {
|
6 |
+
|
7 |
+
public function add_hooks() {
|
8 |
+
add_filter( 'gform_formatted_money', [ $this, 'wcml_convert_price' ], 10, 2 );
|
9 |
+
add_filter( 'wcml_multi_currency_ajax_actions', [ $this, 'add_ajax_action' ] );
|
10 |
+
}
|
11 |
+
|
12 |
+
/**
|
13 |
+
* @param string $formatted
|
14 |
+
* @param string $unformatted
|
15 |
+
*
|
16 |
+
* @return string
|
17 |
+
*/
|
18 |
+
public function wcml_convert_price( $formatted, $unformatted ) {
|
19 |
+
if ( ! is_admin() ) {
|
20 |
+
$currency = apply_filters( 'wcml_price_currency', wcml_get_woocommerce_currency_option() );
|
21 |
+
$formatted = strip_tags( wc_price( apply_filters( 'wcml_raw_price_amount', $unformatted ), [ 'currency' => $currency ] ) );
|
22 |
+
}
|
23 |
+
return $formatted;
|
24 |
+
}
|
25 |
+
|
26 |
+
/**
|
27 |
+
* @param string[] $actions
|
28 |
+
*
|
29 |
+
* @return string[]
|
30 |
+
*/
|
31 |
+
public function add_ajax_action( $actions ) {
|
32 |
+
$actions[] = 'get_updated_price'; // Deprecated from 2.7.
|
33 |
+
$actions[] = 'gforms_get_updated_price';
|
34 |
+
return $actions;
|
35 |
+
}
|
36 |
+
|
37 |
+
}
|
compatibility/{class-wcml-gravityforms.php → GravityForms/class-wcml-gravityforms.php}
RENAMED
@@ -1,9 +1,9 @@
|
|
1 |
<?php
|
2 |
|
3 |
-
class WCML_gravityforms {
|
4 |
|
5 |
/**
|
6 |
-
* @
|
7 |
*/
|
8 |
private $sitepress;
|
9 |
|
@@ -18,33 +18,15 @@ class WCML_gravityforms {
|
|
18 |
}
|
19 |
|
20 |
public function add_hooks() {
|
21 |
-
add_filter( 'gform_formatted_money', [ $this, 'wcml_convert_price' ], 10, 2 );
|
22 |
-
add_filter( 'wcml_multi_currency_ajax_actions', [ $this, 'add_ajax_action' ] );
|
23 |
-
|
24 |
add_action( 'wcml_after_duplicate_product_post_meta', [ $this, 'sync_gf_data' ], 10, 2 );
|
25 |
}
|
26 |
|
27 |
-
public function wcml_convert_price( $formatted, $unformatted ) {
|
28 |
-
if ( ! is_admin() ) {
|
29 |
-
$currency = apply_filters( 'wcml_price_currency', wcml_get_woocommerce_currency_option() );
|
30 |
-
$formatted = strip_tags( wc_price( apply_filters( 'wcml_raw_price_amount', $unformatted ), [ 'currency' => $currency ] ) );
|
31 |
-
}
|
32 |
-
return $formatted;
|
33 |
-
}
|
34 |
-
|
35 |
-
|
36 |
-
public function add_ajax_action( $actions ) {
|
37 |
-
$actions[] = 'get_updated_price'; // Deprecated from 2.7.
|
38 |
-
$actions[] = 'gforms_get_updated_price';
|
39 |
-
return $actions;
|
40 |
-
}
|
41 |
-
|
42 |
/**
|
43 |
* @param int $original_product_id
|
44 |
* @param int $trnsl_product_id
|
45 |
*/
|
46 |
public function sync_gf_data( $original_product_id, $trnsl_product_id ) {
|
47 |
-
// sync only if WCML editor is in use
|
48 |
if ( $this->woocommerce_wpml->is_wpml_prior_4_2() ) {
|
49 |
$wcml_settings = get_option( '_wcml_settings' );
|
50 |
$is_using_tm_editor = $wcml_settings['trnsl_interface'];
|
@@ -53,7 +35,7 @@ class WCML_gravityforms {
|
|
53 |
}
|
54 |
|
55 |
if ( $is_using_tm_editor ) {
|
56 |
-
$orig_gf
|
57 |
|
58 |
if ( $orig_gf ) {
|
59 |
$trnsl_gf = maybe_unserialize( get_post_meta( $trnsl_product_id, '_gravity_form_data', true ) );
|
1 |
<?php
|
2 |
|
3 |
+
class WCML_gravityforms implements \IWPML_Action {
|
4 |
|
5 |
/**
|
6 |
+
* @var SitePress $sitepress
|
7 |
*/
|
8 |
private $sitepress;
|
9 |
|
18 |
}
|
19 |
|
20 |
public function add_hooks() {
|
|
|
|
|
|
|
21 |
add_action( 'wcml_after_duplicate_product_post_meta', [ $this, 'sync_gf_data' ], 10, 2 );
|
22 |
}
|
23 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
24 |
/**
|
25 |
* @param int $original_product_id
|
26 |
* @param int $trnsl_product_id
|
27 |
*/
|
28 |
public function sync_gf_data( $original_product_id, $trnsl_product_id ) {
|
29 |
+
// sync only if WCML editor is in use.
|
30 |
if ( $this->woocommerce_wpml->is_wpml_prior_4_2() ) {
|
31 |
$wcml_settings = get_option( '_wcml_settings' );
|
32 |
$is_using_tm_editor = $wcml_settings['trnsl_interface'];
|
35 |
}
|
36 |
|
37 |
if ( $is_using_tm_editor ) {
|
38 |
+
$orig_gf = maybe_unserialize( get_post_meta( $original_product_id, '_gravity_form_data', true ) );
|
39 |
|
40 |
if ( $orig_gf ) {
|
41 |
$trnsl_gf = maybe_unserialize( get_post_meta( $trnsl_product_id, '_gravity_form_data', true ) );
|
compatibility/KlarnaPayments/Factory.php
ADDED
@@ -0,0 +1,26 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace WCML\Compatibility\KlarnaPayments;
|
4 |
+
|
5 |
+
use WCML\Compatibility\ComponentFactory;
|
6 |
+
use WCML\StandAlone\IStandAloneAction;
|
7 |
+
|
8 |
+
/**
|
9 |
+
* @see https://wordpress.org/plugins/klarna-checkout-for-woocommerce/
|
10 |
+
*/
|
11 |
+
class Factory extends ComponentFactory implements IStandAloneAction {
|
12 |
+
|
13 |
+
/**
|
14 |
+
* @inheritDoc
|
15 |
+
*/
|
16 |
+
public function create() {
|
17 |
+
$hooks = [];
|
18 |
+
|
19 |
+
if ( wcml_is_multi_currency_on() ) {
|
20 |
+
$hooks[] = new MulticurrencyHooks();
|
21 |
+
}
|
22 |
+
|
23 |
+
return $hooks;
|
24 |
+
}
|
25 |
+
|
26 |
+
}
|
compatibility/{class-wcml-klarna-gateway.php → KlarnaPayments/MulticurrencyHooks.php}
RENAMED
@@ -1,15 +1,14 @@
|
|
1 |
<?php
|
2 |
|
3 |
-
|
4 |
|
5 |
-
|
6 |
|
|
|
7 |
add_filter( 'wcml_multi_currency_ajax_actions', [ $this, 'ajax_action_needs_multi_currency' ] );
|
8 |
-
|
9 |
}
|
10 |
|
11 |
public function ajax_action_needs_multi_currency( $actions ) {
|
12 |
-
|
13 |
$actions[] = 'klarna_checkout_cart_callback_update';
|
14 |
$actions[] = 'klarna_checkout_coupons_callback';
|
15 |
$actions[] = 'klarna_checkout_remove_coupon_callback';
|
1 |
<?php
|
2 |
|
3 |
+
namespace WCML\Compatibility\KlarnaPayments;
|
4 |
|
5 |
+
class MulticurrencyHooks implements \IWPML_Action {
|
6 |
|
7 |
+
public function add_hooks() {
|
8 |
add_filter( 'wcml_multi_currency_ajax_actions', [ $this, 'ajax_action_needs_multi_currency' ] );
|
|
|
9 |
}
|
10 |
|
11 |
public function ajax_action_needs_multi_currency( $actions ) {
|
|
|
12 |
$actions[] = 'klarna_checkout_cart_callback_update';
|
13 |
$actions[] = 'klarna_checkout_coupons_callback';
|
14 |
$actions[] = 'klarna_checkout_remove_coupon_callback';
|
compatibility/MaxStorePro/Factory.php
ADDED
@@ -0,0 +1,16 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace WCML\Compatibility\MaxStorePro;
|
4 |
+
|
5 |
+
use WCML\Compatibility\ComponentFactory;
|
6 |
+
use WCML_MaxStore;
|
7 |
+
|
8 |
+
class Factory extends ComponentFactory {
|
9 |
+
|
10 |
+
/**
|
11 |
+
* @inheritDoc
|
12 |
+
*/
|
13 |
+
public function create() {
|
14 |
+
return new WCML_MaxStore();
|
15 |
+
}
|
16 |
+
}
|
compatibility/{class-wcml-maxstore.php → MaxStorePro/class-wcml-maxstore.php}
RENAMED
@@ -1,6 +1,6 @@
|
|
1 |
<?php
|
2 |
|
3 |
-
class WCML_MaxStore {
|
4 |
|
5 |
public function add_hooks() {
|
6 |
|
1 |
<?php
|
2 |
|
3 |
+
class WCML_MaxStore implements \IWPML_Action {
|
4 |
|
5 |
public function add_hooks() {
|
6 |
|
compatibility/PerProductShipping/Factory.php
ADDED
@@ -0,0 +1,16 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace WCML\Compatibility\PerProductShipping;
|
4 |
+
|
5 |
+
use WCML\Compatibility\ComponentFactory;
|
6 |
+
use WCML_Per_Product_Shipping;
|
7 |
+
|
8 |
+
class Factory extends ComponentFactory {
|
9 |
+
|
10 |
+
/**
|
11 |
+
* @inheritDoc
|
12 |
+
*/
|
13 |
+
public function create() {
|
14 |
+
return new WCML_Per_Product_Shipping();
|
15 |
+
}
|
16 |
+
}
|
compatibility/{class-wcml-per-product-shipping.php → PerProductShipping/class-wcml-per-product-shipping.php}
RENAMED
@@ -1,15 +1,11 @@
|
|
1 |
<?php
|
2 |
|
3 |
-
class WCML_Per_Product_Shipping {
|
4 |
-
|
5 |
-
public function __construct() {
|
6 |
|
|
|
7 |
if ( ! is_admin() ) {
|
8 |
-
|
9 |
add_filter( 'woocommerce_per_product_shipping_get_matching_rule_product_id', [ $this, 'original_product_id' ] );
|
10 |
-
|
11 |
}
|
12 |
-
|
13 |
}
|
14 |
|
15 |
public function original_product_id( $product_id ) {
|
1 |
<?php
|
2 |
|
3 |
+
class WCML_Per_Product_Shipping implements \IWPML_Action {
|
|
|
|
|
4 |
|
5 |
+
public function add_hooks() {
|
6 |
if ( ! is_admin() ) {
|
|
|
7 |
add_filter( 'woocommerce_per_product_shipping_get_matching_rule_product_id', [ $this, 'original_product_id' ] );
|
|
|
8 |
}
|
|
|
9 |
}
|
10 |
|
11 |
public function original_product_id( $product_id ) {
|
compatibility/Relevanssi/Factory.php
ADDED
@@ -0,0 +1,16 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace WCML\Compatibility\Relevanssi;
|
4 |
+
|
5 |
+
use WCML\Compatibility\ComponentFactory;
|
6 |
+
use WCML_Relevanssi;
|
7 |
+
|
8 |
+
class Factory extends ComponentFactory {
|
9 |
+
|
10 |
+
/**
|
11 |
+
* @inheritDoc
|
12 |
+
*/
|
13 |
+
public function create() {
|
14 |
+
return new WCML_Relevanssi();
|
15 |
+
}
|
16 |
+
}
|
compatibility/{class-wcml-relevanssi.php → Relevanssi/class-wcml-relevanssi.php}
RENAMED
@@ -1,6 +1,6 @@
|
|
1 |
<?php
|
2 |
|
3 |
-
class WCML_Relevanssi {
|
4 |
|
5 |
public function add_hooks() {
|
6 |
// Re-index translated product to add missing terms (wcml-2282)
|
1 |
<?php
|
2 |
|
3 |
+
class WCML_Relevanssi implements \IWPML_Action {
|
4 |
|
5 |
public function add_hooks() {
|
6 |
// Re-index translated product to add missing terms (wcml-2282)
|
compatibility/Sensei/Factory.php
ADDED
@@ -0,0 +1,18 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace WCML\Compatibility\Sensei;
|
4 |
+
|
5 |
+
use WCML\Compatibility\ComponentFactory;
|
6 |
+
use WCML_Sensei;
|
7 |
+
use WPML_Custom_Columns;
|
8 |
+
use function WCML\functions\getSitePress;
|
9 |
+
|
10 |
+
class Factory extends ComponentFactory {
|
11 |
+
|
12 |
+
/**
|
13 |
+
* @inheritDoc
|
14 |
+
*/
|
15 |
+
public function create() {
|
16 |
+
return new WCML_Sensei( getSitePress(), self::getWpdb(), new WPML_Custom_Columns( getSitePress() ) );
|
17 |
+
}
|
18 |
+
}
|
compatibility/{class-wcml-sensei.php → Sensei/class-wcml-sensei.php}
RENAMED
@@ -1,6 +1,6 @@
|
|
1 |
<?php
|
2 |
|
3 |
-
class WCML_Sensei {
|
4 |
|
5 |
/** @var SitePress */
|
6 |
private $sitepress;
|
1 |
<?php
|
2 |
|
3 |
+
class WCML_Sensei implements \IWPML_Action {
|
4 |
|
5 |
/** @var SitePress */
|
6 |
private $sitepress;
|
compatibility/StripePayments/Factory.php
ADDED
@@ -0,0 +1,27 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace WCML\Compatibility\StripePayments;
|
4 |
+
|
5 |
+
use WCML\Compatibility\ComponentFactory;
|
6 |
+
use WCML\StandAlone\IStandAloneAction;
|
7 |
+
|
8 |
+
use function WCML\functions\getWooCommerceWpml;
|
9 |
+
|
10 |
+
/**
|
11 |
+
* @see https://wordpress.org/plugins/woocommerce-gateway-stripe/
|
12 |
+
*/
|
13 |
+
class Factory extends ComponentFactory implements IStandAloneAction {
|
14 |
+
|
15 |
+
/**
|
16 |
+
* @inheritDoc
|
17 |
+
*/
|
18 |
+
public function create() {
|
19 |
+
$hooks = [];
|
20 |
+
|
21 |
+
if ( wcml_is_multi_currency_on() ) {
|
22 |
+
$hooks[] = new MulticurrencyHooks( getWooCommerceWpml()->get_multi_currency()->orders );
|
23 |
+
}
|
24 |
+
|
25 |
+
return $hooks;
|
26 |
+
}
|
27 |
+
}
|
compatibility/StripePayments/MulticurrencyHooks.php
ADDED
@@ -0,0 +1,33 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace WCML\Compatibility\StripePayments;
|
4 |
+
|
5 |
+
class MulticurrencyHooks implements \IWPML_Action {
|
6 |
+
|
7 |
+
/**
|
8 |
+
* @var \WCML_Multi_Currency_Orders
|
9 |
+
*/
|
10 |
+
private $orders;
|
11 |
+
|
12 |
+
const PRIORITY = 10;
|
13 |
+
|
14 |
+
public function __construct( \WCML_Multi_Currency_Orders $orders ) {
|
15 |
+
$this->orders = $orders;
|
16 |
+
}
|
17 |
+
|
18 |
+
public function add_hooks() {
|
19 |
+
add_action( 'woocommerce_admin_order_totals_after_total', [ $this, 'suspendCurrencySymbolFilter' ], self::PRIORITY - 1 );
|
20 |
+
}
|
21 |
+
|
22 |
+
public function suspendCurrencySymbolFilter() {
|
23 |
+
if ( remove_filter( 'woocommerce_currency_symbol', [ $this->orders, '_use_order_currency_symbol' ] ) ) {
|
24 |
+
add_action(
|
25 |
+
'woocommerce_admin_order_totals_after_total',
|
26 |
+
function() {
|
27 |
+
add_filter( 'woocommerce_currency_symbol', [ $this->orders, '_use_order_currency_symbol' ] );
|
28 |
+
},
|
29 |
+
self::PRIORITY + 100
|
30 |
+
);
|
31 |
+
}
|
32 |
+
}
|
33 |
+
}
|
compatibility/TableRateShipping/Factory.php
ADDED
@@ -0,0 +1,36 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace WCML\Compatibility\TableRateShipping;
|
4 |
+
|
5 |
+
use WCML\Compatibility\ComponentFactory;
|
6 |
+
use WCML\StandAlone\IStandAloneAction;
|
7 |
+
use WCML_Table_Rate_Shipping;
|
8 |
+
use function WCML\functions\getSitePress;
|
9 |
+
use function WCML\functions\getWooCommerceWpml;
|
10 |
+
use function WCML\functions\isStandAlone;
|
11 |
+
|
12 |
+
/**
|
13 |
+
* @see https://woocommerce.com/products/table-rate-shipping/
|
14 |
+
*/
|
15 |
+
class Factory extends ComponentFactory implements IStandAloneAction {
|
16 |
+
|
17 |
+
/**
|
18 |
+
* @inheritDoc
|
19 |
+
*/
|
20 |
+
public function create() {
|
21 |
+
$hooks = [];
|
22 |
+
|
23 |
+
$woocommerce_wpml = getWooCommerceWpml();
|
24 |
+
|
25 |
+
if ( wcml_is_multi_currency_on() ) {
|
26 |
+
$hooks[] = new MulticurrencyHooks( $woocommerce_wpml, $woocommerce_wpml->get_multi_currency() );
|
27 |
+
}
|
28 |
+
|
29 |
+
if ( ! isStandAlone() ) {
|
30 |
+
$hooks[] = new WCML_Table_Rate_Shipping( getSitePress(), $woocommerce_wpml, self::getWpdb() );
|
31 |
+
}
|
32 |
+
|
33 |
+
return $hooks;
|
34 |
+
}
|
35 |
+
|
36 |
+
}
|
compatibility/TableRateShipping/MulticurrencyHooks.php
ADDED
@@ -0,0 +1,64 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace WCML\Compatibility\TableRateShipping;
|
4 |
+
|
5 |
+
class MulticurrencyHooks implements \IWPML_Action {
|
6 |
+
|
7 |
+
/**
|
8 |
+
* @var \woocommerce_wpml
|
9 |
+
*/
|
10 |
+
public $woocommerce_wpml;
|
11 |
+
|
12 |
+
/**
|
13 |
+
* @var \WCML_Multi_Currency
|
14 |
+
*/
|
15 |
+
public $multicurrency;
|
16 |
+
|
17 |
+
/**
|
18 |
+
* @param \woocommerce_wpml $woocommerce_wpml
|
19 |
+
* @param \WCML_Multi_Currency $multicurrency
|
20 |
+
*/
|
21 |
+
public function __construct( \woocommerce_wpml $woocommerce_wpml, \WCML_Multi_Currency $multicurrency ) {
|
22 |
+
$this->woocommerce_wpml = $woocommerce_wpml;
|
23 |
+
$this->multicurrency = $multicurrency;
|
24 |
+
}
|
25 |
+
|
26 |
+
public function add_hooks() {
|
27 |
+
if ( version_compare( constant( 'TABLE_RATE_SHIPPING_VERSION' ), '3.0.11', '<' ) ) {
|
28 |
+
add_filter( 'woocommerce_table_rate_query_rates_args', [ $this, 'filterQueryRatesArgs' ] );
|
29 |
+
}
|
30 |
+
|
31 |
+
add_filter( 'woocommerce_table_rate_package_row_base_price', [ $this, 'filterProductBasePrice' ], 10, 3 );
|
32 |
+
}
|
33 |
+
|
34 |
+
/**
|
35 |
+
* It's not possible to filter rate_min and rate_max so we use the original price to compare against these values
|
36 |
+
*
|
37 |
+
* @param array $args
|
38 |
+
*
|
39 |
+
* @return array
|
40 |
+
*/
|
41 |
+
public function filterQueryRatesArgs( $args ) {
|
42 |
+
if ( isset( $args['price'] ) && wcml_get_woocommerce_currency_option() !== $this->multicurrency->get_client_currency() ) {
|
43 |
+
$args['price'] = $this->multicurrency->prices->unconvert_price_amount( $args['price'] );
|
44 |
+
}
|
45 |
+
|
46 |
+
return $args;
|
47 |
+
}
|
48 |
+
|
49 |
+
/**
|
50 |
+
* @param float $rowBasePrice
|
51 |
+
* @param \WC_Product $product
|
52 |
+
* @param int $quantity
|
53 |
+
*
|
54 |
+
* @return float
|
55 |
+
*/
|
56 |
+
public function filterProductBasePrice( $rowBasePrice, $product, $quantity ) {
|
57 |
+
if ( $product && wcml_get_woocommerce_currency_option() !== $this->multicurrency->get_client_currency() ) {
|
58 |
+
$rowBasePrice = $this->woocommerce_wpml->products->get_product_price_from_db( $product->get_id() ) * $quantity;
|
59 |
+
}
|
60 |
+
|
61 |
+
return $rowBasePrice;
|
62 |
+
}
|
63 |
+
|
64 |
+
}
|
compatibility/{class-wcml-table-rate-shipping.php → TableRateShipping/class-wcml-table-rate-shipping.php}
RENAMED
@@ -7,7 +7,7 @@ use WPML\FP\Obj;
|
|
7 |
/**
|
8 |
* Class WCML_Table_Rate_Shipping
|
9 |
*/
|
10 |
-
class WCML_Table_Rate_Shipping {
|
11 |
|
12 |
/**
|
13 |
* @var SitePress
|
@@ -48,20 +48,6 @@ class WCML_Table_Rate_Shipping {
|
|
48 |
add_filter( 'woocommerce_shipping_table_rate_is_available', [ $this, 'shipping_table_rate_is_available' ], 10, 3 );
|
49 |
}
|
50 |
|
51 |
-
if ( wcml_is_multi_currency_on() ) {
|
52 |
-
$wpml_api = $this->sitepress->get_wp_api();
|
53 |
-
if ( $wpml_api->version_compare( $wpml_api->constant( 'TABLE_RATE_SHIPPING_VERSION' ), '3.0.11', '<' ) ) {
|
54 |
-
add_filter( 'woocommerce_table_rate_query_rates_args', [ $this, 'filter_query_rates_args' ] );
|
55 |
-
}
|
56 |
-
|
57 |
-
add_filter(
|
58 |
-
'woocommerce_table_rate_package_row_base_price',
|
59 |
-
[ $this, 'filter_product_base_price' ],
|
60 |
-
10,
|
61 |
-
3
|
62 |
-
);
|
63 |
-
}
|
64 |
-
|
65 |
if ( is_admin() ) {
|
66 |
// phpcs:disable WordPress.Security.NonceVerification.Missing
|
67 |
if ( Obj::prop( 'shipping_abort_reason', $_POST ) ) {
|
@@ -154,23 +140,9 @@ class WCML_Table_Rate_Shipping {
|
|
154 |
return $terms;
|
155 |
}
|
156 |
|
157 |
-
/**
|
158 |
-
* It's not possible to filter rate_min and rate_max so we use the original price to compare against these values
|
159 |
-
*
|
160 |
-
* @param array $args
|
161 |
-
*
|
162 |
-
* @return mixed
|
163 |
-
*/
|
164 |
-
public function filter_query_rates_args( $args ) {
|
165 |
-
if ( isset( $args['price'] ) && wcml_get_woocommerce_currency_option() !== $this->woocommerce_wpml->multi_currency->get_client_currency() ) {
|
166 |
-
$args['price'] = $this->woocommerce_wpml->multi_currency->prices->unconvert_price_amount( $args['price'] );
|
167 |
-
}
|
168 |
-
|
169 |
-
return $args;
|
170 |
-
}
|
171 |
-
|
172 |
public function show_pointer_info() {
|
173 |
$pointer_ui = new WCML_Pointer_UI(
|
|
|
174 |
sprintf( __( 'You can translate this method title on the %1$sWPML String Translation page%2$s. Use the search on the top of that page to find the method title string.', 'woocommerce-multilingual' ), '<a href="' . admin_url( 'admin.php?page=' . WPML_ST_FOLDER . '/menu/string-translation.php' ) . '">', '</a>' ),
|
175 |
WCML_Tracking_Link::getWcmlTableRateShippingDoc(),
|
176 |
'woocommerce_table_rate_title'
|
@@ -179,6 +151,7 @@ class WCML_Table_Rate_Shipping {
|
|
179 |
$pointer_ui->show();
|
180 |
|
181 |
$pointer_ui = new WCML_Pointer_UI(
|
|
|
182 |
sprintf( __( 'You can translate the labels of your table rates on the %1$sWPML String Translation page%2$s. Use the search on the top of that page to find the labels strings.', 'woocommerce-multilingual' ), '<a href="' . admin_url( 'admin.php?page=' . WPML_ST_FOLDER . '/menu/string-translation.php' ) . '">', '</a>' ),
|
183 |
WCML_Tracking_Link::getWcmlTableRateShippingDoc(),
|
184 |
'shipping_rates .shipping_label a'
|
@@ -187,22 +160,6 @@ class WCML_Table_Rate_Shipping {
|
|
187 |
$pointer_ui->show();
|
188 |
}
|
189 |
|
190 |
-
/**
|
191 |
-
* @param $row_base_price
|
192 |
-
* @param WC_Product $_product
|
193 |
-
* @param $qty
|
194 |
-
*
|
195 |
-
* @return mixed
|
196 |
-
*/
|
197 |
-
public function filter_product_base_price( $row_base_price, $_product, $qty ) {
|
198 |
-
|
199 |
-
if ( $_product && wcml_get_woocommerce_currency_option() !== $this->woocommerce_wpml->multi_currency->get_client_currency() ) {
|
200 |
-
$row_base_price = $this->woocommerce_wpml->products->get_product_price_from_db( $_product->get_id() ) * $qty;
|
201 |
-
}
|
202 |
-
|
203 |
-
return $row_base_price;
|
204 |
-
}
|
205 |
-
|
206 |
/**
|
207 |
* Register the new rate's shipping abort reasons.
|
208 |
*
|
7 |
/**
|
8 |
* Class WCML_Table_Rate_Shipping
|
9 |
*/
|
10 |
+
class WCML_Table_Rate_Shipping implements \IWPML_Action {
|
11 |
|
12 |
/**
|
13 |
* @var SitePress
|
48 |
add_filter( 'woocommerce_shipping_table_rate_is_available', [ $this, 'shipping_table_rate_is_available' ], 10, 3 );
|
49 |
}
|
50 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
51 |
if ( is_admin() ) {
|
52 |
// phpcs:disable WordPress.Security.NonceVerification.Missing
|
53 |
if ( Obj::prop( 'shipping_abort_reason', $_POST ) ) {
|
140 |
return $terms;
|
141 |
}
|
142 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
143 |
public function show_pointer_info() {
|
144 |
$pointer_ui = new WCML_Pointer_UI(
|
145 |
+
/* translators: %1$s and %2$s are opening and closing HTML link tag */
|
146 |
sprintf( __( 'You can translate this method title on the %1$sWPML String Translation page%2$s. Use the search on the top of that page to find the method title string.', 'woocommerce-multilingual' ), '<a href="' . admin_url( 'admin.php?page=' . WPML_ST_FOLDER . '/menu/string-translation.php' ) . '">', '</a>' ),
|
147 |
WCML_Tracking_Link::getWcmlTableRateShippingDoc(),
|
148 |
'woocommerce_table_rate_title'
|
151 |
$pointer_ui->show();
|
152 |
|
153 |
$pointer_ui = new WCML_Pointer_UI(
|
154 |
+
/* translators: %1$s and %2$s are opening and closing HTML link tag */
|
155 |
sprintf( __( 'You can translate the labels of your table rates on the %1$sWPML String Translation page%2$s. Use the search on the top of that page to find the labels strings.', 'woocommerce-multilingual' ), '<a href="' . admin_url( 'admin.php?page=' . WPML_ST_FOLDER . '/menu/string-translation.php' ) . '">', '</a>' ),
|
156 |
WCML_Tracking_Link::getWcmlTableRateShippingDoc(),
|
157 |
'shipping_rates .shipping_label a'
|
160 |
$pointer_ui->show();
|
161 |
}
|
162 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
163 |
/**
|
164 |
* Register the new rate's shipping abort reasons.
|
165 |
*
|
compatibility/TheEventsCalendar/Factory.php
ADDED
@@ -0,0 +1,34 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace WCML\Compatibility\TheEventsCalendar;
|
4 |
+
|
5 |
+
use WCML\Compatibility\ComponentFactory;
|
6 |
+
use WCML\StandAlone\IStandAloneAction;
|
7 |
+
|
8 |
+
use function WCML\functions\getSitePress;
|
9 |
+
use function WCML\functions\getWooCommerceWpml;
|
10 |
+
use function WCML\functions\isStandAlone;
|
11 |
+
|
12 |
+
/**
|
13 |
+
* @see https://wordpress.org/plugins/the-events-calendar/
|
14 |
+
*/
|
15 |
+
class Factory extends ComponentFactory implements IStandAloneAction {
|
16 |
+
|
17 |
+
/**
|
18 |
+
* @inheritDoc
|
19 |
+
*/
|
20 |
+
public function create() {
|
21 |
+
$hooks = [];
|
22 |
+
|
23 |
+
if ( wcml_is_multi_currency_on() ) {
|
24 |
+
$hooks[] = new MulticurrencyHooks();
|
25 |
+
}
|
26 |
+
|
27 |
+
if ( ! isStandAlone() ) {
|
28 |
+
$hooks[] = new \WCML_The_Events_Calendar( getSitePress(), getWooCommerceWpml() );
|
29 |
+
}
|
30 |
+
|
31 |
+
return $hooks;
|
32 |
+
}
|
33 |
+
|
34 |
+
}
|
compatibility/TheEventsCalendar/MulticurrencyHooks.php
ADDED
@@ -0,0 +1,22 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace WCML\Compatibility\TheEventsCalendar;
|
4 |
+
|
5 |
+
class MulticurrencyHooks implements \IWPML_Action {
|
6 |
+
|
7 |
+
public function add_hooks() {
|
8 |
+
if ( ! is_admin() ) {
|
9 |
+
add_filter( 'tribe_events_cost_unformatted', [ $this, 'convert_events_cost' ], 10, 1 );
|
10 |
+
}
|
11 |
+
}
|
12 |
+
|
13 |
+
/**
|
14 |
+
* @param float $cost
|
15 |
+
*
|
16 |
+
* @return float
|
17 |
+
*/
|
18 |
+
public function convert_events_cost( $cost ) {
|
19 |
+
return apply_filters( 'wcml_raw_price_amount', $cost );
|
20 |
+
}
|
21 |
+
|
22 |
+
}
|
compatibility/{class-wcml-the-events-calendar.php → TheEventsCalendar/class-wcml-the-events-calendar.php}
RENAMED
@@ -1,6 +1,6 @@
|
|
1 |
<?php
|
2 |
|
3 |
-
class WCML_The_Events_Calendar {
|
4 |
|
5 |
/** @var SitePress */
|
6 |
private $sitepress;
|
@@ -23,11 +23,13 @@ class WCML_The_Events_Calendar {
|
|
23 |
// @todo Cover by tests, required for wcml-3037.
|
24 |
$this->sitepress = $sitepress;
|
25 |
$this->woocommerce_wpml = $woocommerce_wpml;
|
|
|
26 |
|
|
|
|
|
27 |
if ( isset( $_POST['action'] ) && 0 === strpos( $_POST['action'], 'tribe-ticket-add-' ) ) {
|
28 |
add_action( 'tribe_tickets_ticket_add', [ $this, 'unset_post_post_id' ] );
|
29 |
add_action( 'event_tickets_after_save_ticket', [ $this, 'restore_post_post_id' ] );
|
30 |
-
|
31 |
}
|
32 |
|
33 |
if ( is_admin() ) {
|
@@ -50,7 +52,6 @@ class WCML_The_Events_Calendar {
|
|
50 |
} else {
|
51 |
add_action( 'event_tickets_rsvp_tickets_generated', [ $this, 'sync_rsvp_fields_on_attendee_created' ], 10, 3 );
|
52 |
add_filter( 'tribe_get_organizer_ids', [ $this, 'get_translated_organizer_ids' ], 10, 2 );
|
53 |
-
add_filter( 'tribe_events_cost_unformatted', [ $this, 'convert_events_cost' ], 10, 1 );
|
54 |
}
|
55 |
|
56 |
}
|
@@ -482,9 +483,4 @@ class WCML_The_Events_Calendar {
|
|
482 |
return $organizer_ids;
|
483 |
}
|
484 |
|
485 |
-
public function convert_events_cost( $cost ) {
|
486 |
-
return apply_filters( 'wcml_raw_price_amount', $cost );
|
487 |
-
}
|
488 |
-
|
489 |
}
|
490 |
-
|
1 |
<?php
|
2 |
|
3 |
+
class WCML_The_Events_Calendar implements \IWPML_Action {
|
4 |
|
5 |
/** @var SitePress */
|
6 |
private $sitepress;
|
23 |
// @todo Cover by tests, required for wcml-3037.
|
24 |
$this->sitepress = $sitepress;
|
25 |
$this->woocommerce_wpml = $woocommerce_wpml;
|
26 |
+
}
|
27 |
|
28 |
+
public function add_hooks() {
|
29 |
+
/* phpcs:ignore WordPress.VIP.SuperGlobalInputUsage.AccessDetected */
|
30 |
if ( isset( $_POST['action'] ) && 0 === strpos( $_POST['action'], 'tribe-ticket-add-' ) ) {
|
31 |
add_action( 'tribe_tickets_ticket_add', [ $this, 'unset_post_post_id' ] );
|
32 |
add_action( 'event_tickets_after_save_ticket', [ $this, 'restore_post_post_id' ] );
|
|
|
33 |
}
|
34 |
|
35 |
if ( is_admin() ) {
|
52 |
} else {
|
53 |
add_action( 'event_tickets_rsvp_tickets_generated', [ $this, 'sync_rsvp_fields_on_attendee_created' ], 10, 3 );
|
54 |
add_filter( 'tribe_get_organizer_ids', [ $this, 'get_translated_organizer_ids' ], 10, 2 );
|
|
|
55 |
}
|
56 |
|
57 |
}
|
483 |
return $organizer_ids;
|
484 |
}
|
485 |
|
|
|
|
|
|
|
|
|
486 |
}
|
|
compatibility/TmExtraProductOptions/Factory.php
ADDED
@@ -0,0 +1,16 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace WCML\Compatibility\TmExtraProductOptions;
|
4 |
+
|
5 |
+
use WCML\Compatibility\ComponentFactory;
|
6 |
+
use WCML_Extra_Product_Options;
|
7 |
+
|
8 |
+
class Factory extends ComponentFactory {
|
9 |
+
|
10 |
+
/**
|
11 |
+
* @inheritDoc
|
12 |
+
*/
|
13 |
+
public function create() {
|
14 |
+
return new WCML_Extra_Product_Options();
|
15 |
+
}
|
16 |
+
}
|
compatibility/{class-wcml-extra-product-options.php → TmExtraProductOptions/class-wcml-extra-product-options.php}
RENAMED
@@ -1,9 +1,8 @@
|
|
1 |
<?php
|
2 |
|
3 |
-
class WCML_Extra_Product_Options {
|
4 |
-
|
5 |
-
public function __construct() {
|
6 |
|
|
|
7 |
add_action( 'tm_before_extra_product_options', [ $this, 'inf_translate_product_page_strings' ] );
|
8 |
add_action( 'tm_before_price_rules', [ $this, 'inf_translate_strings' ] );
|
9 |
}
|
@@ -20,6 +19,7 @@ class WCML_Extra_Product_Options {
|
|
20 |
|
21 |
public function inf_message( $text ) {
|
22 |
$message = '<div><p class="icl_cyan_box">';
|
|
|
23 |
$message .= sprintf( __( 'To translate Extra Options strings please save %1$s and go to the <b><a href="%2$s">String Translation interface</a></b>', 'woocommerce-multilingual' ), esc_html( $text ), admin_url( 'admin.php?page=' . WPML_ST_FOLDER . '/menu/string-translation.php&context=wc_extra_product_options' ) );
|
24 |
$message .= '</p></div>';
|
25 |
|
1 |
<?php
|
2 |
|
3 |
+
class WCML_Extra_Product_Options implements \IWPML_Action {
|
|
|
|
|
4 |
|
5 |
+
public function add_hooks() {
|
6 |
add_action( 'tm_before_extra_product_options', [ $this, 'inf_translate_product_page_strings' ] );
|
7 |
add_action( 'tm_before_price_rules', [ $this, 'inf_translate_strings' ] );
|
8 |
}
|
19 |
|
20 |
public function inf_message( $text ) {
|
21 |
$message = '<div><p class="icl_cyan_box">';
|
22 |
+
/* translators: %1$s is a dynamic text and %2$s is a URL */
|
23 |
$message .= sprintf( __( 'To translate Extra Options strings please save %1$s and go to the <b><a href="%2$s">String Translation interface</a></b>', 'woocommerce-multilingual' ), esc_html( $text ), admin_url( 'admin.php?page=' . WPML_ST_FOLDER . '/menu/string-translation.php&context=wc_extra_product_options' ) );
|
24 |
$message .= '</p></div>';
|
25 |
|
compatibility/WcAjaxLayeredNav/Factory.php
ADDED
@@ -0,0 +1,16 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace WCML\Compatibility\WcAjaxLayeredNav;
|
4 |
+
|
5 |
+
use WCML\Compatibility\ComponentFactory;
|
6 |
+
use WCML_Ajax_Layered_Nav_Widget;
|
7 |
+
|
8 |
+
class Factory extends ComponentFactory {
|
9 |
+
|
10 |
+
/**
|
11 |
+
* @inheritDoc
|
12 |
+
*/
|
13 |
+
public function create() {
|
14 |
+
return new WCML_Ajax_Layered_Nav_Widget();
|
15 |
+
}
|
16 |
+
}
|
compatibility/{class-wcml-ajax-layered-nav-widget.php → WcAjaxLayeredNav/class-wcml-ajax-layered-nav-widget.php}
RENAMED
@@ -4,8 +4,9 @@
|
|
4 |
Class for WooCommerce Advanced Ajax Layered Navigation
|
5 |
*/
|
6 |
|
7 |
-
class WCML_Ajax_Layered_Nav_Widget {
|
8 |
-
|
|
|
9 |
add_filter( 'wc_ajax_layered_nav_sizeselector_term_id', [ $this, 'wc_ajax_layered_nav_sizeselector_term_id' ] );
|
10 |
add_filter( 'wc_ajax_layered_nav_query_editor', [ $this, 'wc_ajax_layered_nav_query_editor' ], 10, 3 );
|
11 |
}
|
4 |
Class for WooCommerce Advanced Ajax Layered Navigation
|
5 |
*/
|
6 |
|
7 |
+
class WCML_Ajax_Layered_Nav_Widget implements \IWPML_Action {
|
8 |
+
|
9 |
+
public function add_hooks() {
|
10 |
add_filter( 'wc_ajax_layered_nav_sizeselector_term_id', [ $this, 'wc_ajax_layered_nav_sizeselector_term_id' ] );
|
11 |
add_filter( 'wc_ajax_layered_nav_query_editor', [ $this, 'wc_ajax_layered_nav_query_editor' ], 10, 3 );
|
12 |
}
|
compatibility/WcBookings/Factory.php
ADDED
@@ -0,0 +1,42 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace WCML\Compatibility\WcBookings;
|
4 |
+
|
5 |
+
use WCML\Compatibility\ComponentFactory;
|
6 |
+
use WCML\StandAlone\IStandAloneAction;
|
7 |
+
use function WCML\functions\getSitePress;
|
8 |
+
use function WCML\functions\getWooCommerceWpml;
|
9 |
+
use function WCML\functions\isStandAlone;
|
10 |
+
|
11 |
+
class Factory extends ComponentFactory implements IStandAloneAction {
|
12 |
+
|
13 |
+
/**
|
14 |
+
* @inheritDoc
|
15 |
+
*/
|
16 |
+
public function create() {
|
17 |
+
$hooks = [
|
18 |
+
new SharedHooks( self::getWpdb() ),
|
19 |
+
];
|
20 |
+
|
21 |
+
if ( wcml_is_multi_currency_on() ) {
|
22 |
+
$hooks[] = new MulticurrencyHooks( getWooCommerceWpml() );
|
23 |
+
}
|
24 |
+
|
25 |
+
if ( ! isStandAlone() ) {
|
26 |
+
$hooks[] = new \WCML_Bookings(
|
27 |
+
getSitePress(),
|
28 |
+
getWooCommerceWpml(),
|
29 |
+
self::getWooCommerce(),
|
30 |
+
self::getWpdb(),
|
31 |
+
self::getElementTranslationPackage(),
|
32 |
+
self::getPostTranslations()
|
33 |
+
);
|
34 |
+
}
|
35 |
+
|
36 |
+
if ( defined( 'WC_ACCOMMODATION_BOOKINGS_VERSION' ) && wcml_is_multi_currency_on() ) {
|
37 |
+
$hooks[] = new \WCML_Accommodation_Bookings( getWooCommerceWpml() );
|
38 |
+
}
|
39 |
+
|
40 |
+
return $hooks;
|
41 |
+
}
|
42 |
+
}
|
compatibility/WcBookings/MulticurrencyHooks.php
ADDED
@@ -0,0 +1,936 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace WCML\Compatibility\WcBookings;
|
4 |
+
|
5 |
+
/**
|
6 |
+
* @todo: Most of the code in this class was just moved from
|
7 |
+
* the original \WCML_Bookings class with the minimal
|
8 |
+
* adjustments. There's a lot of weak/obsolete formatting
|
9 |
+
* and code duplication that we should fix in the future.
|
10 |
+
*/
|
11 |
+
class MulticurrencyHooks implements \IWPML_Action {
|
12 |
+
|
13 |
+
|
14 |
+
/** @var \woocommerce_wpml $woocommerce_wpml */
|
15 |
+
private $woocommerce_wpml;
|
16 |
+
|
17 |
+
public function __construct( \woocommerce_wpml $woocommerce_wpml ) {
|
18 |
+
$this->woocommerce_wpml = $woocommerce_wpml;
|
19 |
+
}
|
20 |
+
|
21 |
+
public function add_hooks() {
|
22 |
+
add_action( 'woocommerce_bookings_after_booking_base_cost', [ $this, 'wcml_price_field_after_booking_base_cost' ] );
|
23 |
+
add_action( 'woocommerce_bookings_after_booking_block_cost', [ $this, 'wcml_price_field_after_booking_block_cost' ] );
|
24 |
+
add_action( 'woocommerce_bookings_after_display_cost', [ $this, 'wcml_price_field_after_display_cost' ] );
|
25 |
+
add_action( 'woocommerce_bookings_after_booking_pricing_base_cost', [ $this, 'wcml_price_field_after_booking_pricing_base_cost' ], 10, 2 );
|
26 |
+
add_action( 'woocommerce_bookings_after_booking_pricing_cost', [ $this, 'wcml_price_field_after_booking_pricing_cost' ], 10, 2 );
|
27 |
+
add_action( 'woocommerce_bookings_after_person_cost', [ $this, 'wcml_price_field_after_person_cost' ] );
|
28 |
+
add_action( 'woocommerce_bookings_after_person_block_cost', [ $this, 'wcml_price_field_after_person_block_cost' ] );
|
29 |
+
add_action( 'woocommerce_bookings_after_resource_cost', [ $this, 'wcml_price_field_after_resource_cost' ], 10, 2 );
|
30 |
+
add_action( 'woocommerce_bookings_after_resource_block_cost', [ $this, 'wcml_price_field_after_resource_block_cost' ], 10, 2 );
|
31 |
+
|
32 |
+
add_action( 'woocommerce_bookings_after_bookings_pricing', [ $this, 'after_bookings_pricing' ] );
|
33 |
+
|
34 |
+
add_action( 'save_post', [ $this, 'save_custom_costs' ], \WCML_Bookings::PRIORITY_SAVE_POST_ACTION - 1 );
|
35 |
+
|
36 |
+
add_filter( 'woocommerce_bookings_process_cost_rules_cost', [ $this, 'wc_bookings_process_cost_rules_cost' ], 10, 3 );
|
37 |
+
add_filter( 'woocommerce_bookings_process_cost_rules_base_cost', [ $this, 'wc_bookings_process_cost_rules_base_cost' ], 10, 3 );
|
38 |
+
add_filter( 'woocommerce_bookings_process_cost_rules_override_block', [ $this, 'wc_bookings_process_cost_rules_override_block_cost' ], 10, 3 );
|
39 |
+
|
40 |
+
add_action( 'woocommerce_bookings_after_create_booking_page', [ $this, 'booking_currency_dropdown' ] );
|
41 |
+
add_action( 'init', [ $this, 'set_booking_currency' ] );
|
42 |
+
add_action( 'wp_ajax_wcml_booking_set_currency', [ $this, 'set_booking_currency_ajax' ] );
|
43 |
+
|
44 |
+
add_action( 'woocommerce_bookings_create_booking_page_add_order_item', [ $this, 'set_order_currency_on_create_booking_page' ] );
|
45 |
+
add_filter( 'woocommerce_currency_symbol', [ $this, 'filter_booking_currency_symbol' ] );
|
46 |
+
|
47 |
+
add_filter( 'wcml_filter_currency_position', [ $this, 'create_booking_page_client_currency' ] );
|
48 |
+
add_filter( 'wcml_client_currency', [ $this, 'create_booking_page_client_currency' ] );
|
49 |
+
|
50 |
+
if ( ! is_admin() || isset( $_POST['action'] ) && 'wc_bookings_calculate_costs' === $_POST['action'] ) {
|
51 |
+
add_filter( 'get_post_metadata', [ $this, 'filter_wc_booking_cost' ], 10, 4 );
|
52 |
+
}
|
53 |
+
}
|
54 |
+
|
55 |
+
/**
|
56 |
+
* @param int $postId
|
57 |
+
*
|
58 |
+
* @return void
|
59 |
+
*/
|
60 |
+
public function wcml_price_field_after_booking_base_cost( $postId ) {
|
61 |
+
$this->echo_wcml_price_field( $postId, 'wcml_wc_booking_cost' );
|
62 |
+
}
|
63 |
+
|
64 |
+
/**
|
65 |
+
* @param int $postId
|
66 |
+
*
|
67 |
+
* @return void
|
68 |
+
*/
|
69 |
+
public function wcml_price_field_after_booking_block_cost( $postId ) {
|
70 |
+
if ( self::isWcBookingsBefore_1_10_9() ) {
|
71 |
+
$this->echo_wcml_price_field( $postId, 'wcml_wc_booking_base_cost' );
|
72 |
+
} else {
|
73 |
+
$this->echo_wcml_price_field( $postId, 'wcml_wc_booking_block_cost' );
|
74 |
+
}
|
75 |
+
}
|
76 |
+
|
77 |
+
/**
|
78 |
+
* @param int $postId
|
79 |
+
*
|
80 |
+
* @return void
|
81 |
+
*/
|
82 |
+
public function wcml_price_field_after_display_cost( $postId ) {
|
83 |
+
$this->echo_wcml_price_field( $postId, 'wcml_wc_display_cost' );
|
84 |
+
}
|
85 |
+
|
86 |
+
/**
|
87 |
+
* @param array $pricing
|
88 |
+
* @param int $postId
|
89 |
+
*
|
90 |
+
* @return void
|
91 |
+
*/
|
92 |
+
public function wcml_price_field_after_booking_pricing_base_cost( $pricing, $postId ) {
|
93 |
+
$this->echo_wcml_price_field( $postId, 'wcml_wc_booking_pricing_base_cost', $pricing );
|
94 |
+
}
|
95 |
+
|
96 |
+
/**
|
97 |
+
* @param array $pricing
|
98 |
+
* @param int $postId
|
99 |
+
*
|
100 |
+
* @return void
|
101 |
+
*/
|
102 |
+
public function wcml_price_field_after_booking_pricing_cost( $pricing, $postId ) {
|
103 |
+
$this->echo_wcml_price_field( $postId, 'wcml_wc_booking_pricing_cost', $pricing );
|
104 |
+
}
|
105 |
+
|
106 |
+
/**
|
107 |
+
* @param int $personTypeId
|
108 |
+
*
|
109 |
+
* @return void
|
110 |
+
*/
|
111 |
+
public function wcml_price_field_after_person_cost( $personTypeId ) {
|
112 |
+
$this->echo_wcml_price_field( $personTypeId, 'wcml_wc_booking_person_cost', false, false );
|
113 |
+
}
|
114 |
+
|
115 |
+
/**
|
116 |
+
* @param int $personTypeId
|
117 |
+
*
|
118 |
+
* @return void
|
119 |
+
*/
|
120 |
+
public function wcml_price_field_after_person_block_cost( $personTypeId ) {
|
121 |
+
$this->echo_wcml_price_field( $personTypeId, 'wcml_wc_booking_person_block_cost', false, false );
|
122 |
+
}
|
123 |
+
|
124 |
+
/**
|
125 |
+
* @param int $resourceId
|
126 |
+
* @param int $postId
|
127 |
+
*
|
128 |
+
* @return void
|
129 |
+
*/
|
130 |
+
public function wcml_price_field_after_resource_cost( $resourceId, $postId ) {
|
131 |
+
$this->echo_wcml_price_field( $postId, 'wcml_wc_booking_resource_cost', false, true, $resourceId );
|
132 |
+
}
|
133 |
+
|
134 |
+
/**
|
135 |
+
* @param int $resourceId
|
136 |
+
* @param int $postId
|
137 |
+
*
|
138 |
+
* @return void
|
139 |
+
*/
|
140 |
+
public function wcml_price_field_after_resource_block_cost( $resourceId, $postId ) {
|
141 |
+
$this->echo_wcml_price_field( $postId, 'wcml_wc_booking_resource_block_cost', false, true, $resourceId );
|
142 |
+
}
|
143 |
+
|
144 |
+
/**
|
145 |
+
* @param int $postId
|
146 |
+
* @param string $field
|
147 |
+
* @param array|false $pricing
|
148 |
+
* @param bool $check
|
149 |
+
* @param int|false $resourceId
|
150 |
+
*
|
151 |
+
* @return void
|
152 |
+
*/
|
153 |
+
public function echo_wcml_price_field( $postId, $field, $pricing = false, $check = true, $resourceId = false ) {
|
154 |
+
if ( ( ! $check || $this->woocommerce_wpml->products->is_original_product( $postId ) ) ) {
|
155 |
+
|
156 |
+
$currencies = $this->woocommerce_wpml->multi_currency->get_currencies();
|
157 |
+
|
158 |
+
$wc_currencies = get_woocommerce_currencies();
|
159 |
+
|
160 |
+
if ( ! function_exists( 'woocommerce_wp_text_input' ) ) {
|
161 |
+
include_once dirname( WC_PLUGIN_FILE ) . '/includes/admin/wc-meta-box-functions.php';
|
162 |
+
}
|
163 |
+
|
164 |
+
echo '<div class="wcml_custom_cost_field" >';
|
165 |
+
|
166 |
+
foreach ( $currencies as $currency_code => $currency ) {
|
167 |
+
|
168 |
+
switch ( $field ) {
|
169 |
+
case 'wcml_wc_booking_cost':
|
170 |
+
woocommerce_wp_text_input(
|
171 |
+
[
|
172 |
+
'id' => 'wcml_wc_booking_cost',
|
173 |
+
'class' => 'wcml_bookings_custom_price',
|
174 |
+
'name' => 'wcml_wc_booking_cost[' . $currency_code . ']',
|
175 |
+
'label' => get_woocommerce_currency_symbol( $currency_code ),
|
176 |
+
'description' => __( 'One-off cost for the booking as a whole.', 'woocommerce-bookings' ),
|
177 |
+
'value' => get_post_meta( $postId, '_wc_booking_cost_' . $currency_code, true ),
|
178 |
+
'type' => 'number',
|
179 |
+
'desc_tip' => true,
|
180 |
+
'custom_attributes' => [
|
181 |
+
'min' => '',
|
182 |
+
'step' => '0.01',
|
183 |
+
],
|
184 |
+
]
|
185 |
+
);
|
186 |
+
break;
|
187 |
+
case 'wcml_wc_booking_block_cost':
|
188 |
+
case 'wcml_wc_booking_base_cost':
|
189 |
+
$block_cost_key = '_wc_booking_base_cost_';
|
190 |
+
if ( $field === 'wcml_wc_booking_block_cost' ) {
|
191 |
+
$block_cost_key = '_wc_booking_block_cost_';
|
192 |
+
}
|
193 |
+
$block_cost_key .= $currency_code;
|
194 |
+
woocommerce_wp_text_input(
|
195 |
+
[
|
196 |
+
'id' => $field,
|
197 |
+
'class' => 'wcml_bookings_custom_price',
|
198 |
+
'name' => $field . '[' . $currency_code . ']',
|
199 |
+
'label' => get_woocommerce_currency_symbol( $currency_code ),
|
200 |
+
'description' => __( 'This is the cost per block booked. All other costs (for resources and persons) are added to this.', 'woocommerce-bookings' ),
|
201 |
+
'value' => get_post_meta( $postId, $block_cost_key, true ),
|
202 |
+
'type' => 'number',
|
203 |
+
'desc_tip' => true,
|
204 |
+
'custom_attributes' => [
|
205 |
+
'min' => '',
|
206 |
+
'step' => '0.01',
|
207 |
+
],
|
208 |
+
]
|
209 |
+
);
|
210 |
+
break;
|
211 |
+
case 'wcml_wc_display_cost':
|
212 |
+
woocommerce_wp_text_input(
|
213 |
+
[
|
214 |
+
'id' => 'wcml_wc_display_cost',
|
215 |
+
'class' => 'wcml_bookings_custom_price',
|
216 |
+
'name' => 'wcml_wc_display_cost[' . $currency_code . ']',
|
217 |
+
'label' => get_woocommerce_currency_symbol( $currency_code ),
|
218 |
+
'description' => __( 'The cost is displayed to the user on the frontend. Leave blank to have it calculated for you. If a booking has varying costs, this will be prefixed with the word "from:".', 'woocommerce-bookings' ),
|
219 |
+
'value' => get_post_meta( $postId, '_wc_display_cost_' . $currency_code, true ),
|
220 |
+
'type' => 'number',
|
221 |
+
'desc_tip' => true,
|
222 |
+
'custom_attributes' => [
|
223 |
+
'min' => '',
|
224 |
+
'step' => '0.01',
|
225 |
+
],
|
226 |
+
]
|
227 |
+
);
|
228 |
+
break;
|
229 |
+
|
230 |
+
case 'wcml_wc_booking_pricing_base_cost':
|
231 |
+
if ( isset( $pricing[ 'base_cost_' . $currency_code ] ) ) {
|
232 |
+
$value = $pricing[ 'base_cost_' . $currency_code ];
|
233 |
+
} else {
|
234 |
+
$value = '';
|
235 |
+
}
|
236 |
+
|
237 |
+
echo '<div class="wcml_bookings_range_block" >';
|
238 |
+
echo '<label>' . wp_kses_post( get_woocommerce_currency_symbol( $currency_code ) ) . '</label>';
|
239 |
+
echo '<input type="number" step="0.01" name="wcml_wc_booking_pricing_base_cost[' . esc_html( $currency_code ) . '][]" class="wcml_bookings_custom_price" value="' . esc_html( $value ) . '" placeholder="0" />';
|
240 |
+
echo '</div>';
|
241 |
+
break;
|
242 |
+
|
243 |
+
case 'wcml_wc_booking_pricing_cost':
|
244 |
+
if ( isset( $pricing[ 'cost_' . $currency_code ] ) ) {
|
245 |
+
$value = $pricing[ 'cost_' . $currency_code ];
|
246 |
+
} else {
|
247 |
+
$value = '';
|
248 |
+
}
|
249 |
+
|
250 |
+
echo '<div class="wcml_bookings_range_block" >';
|
251 |
+
echo '<label>' . wp_kses_post( get_woocommerce_currency_symbol( $currency_code ) ) . '</label>';
|
252 |
+
echo '<input type="number" step="0.01" name="wcml_wc_booking_pricing_cost[' . esc_html( $currency_code ) . '][]" class="wcml_bookings_custom_price" value="' . esc_html( $value ) . '" placeholder="0" />';
|
253 |
+
echo '</div>';
|
254 |
+
break;
|
255 |
+
|
256 |
+
case 'wcml_wc_booking_person_cost':
|
257 |
+
$value = get_post_meta( $postId, 'cost_' . $currency_code, true );
|
258 |
+
|
259 |
+
echo '<div class="wcml_bookings_person_block" >';
|
260 |
+
echo '<label>' . wp_kses_post( get_woocommerce_currency_symbol( $currency_code ) ) . '</label>';
|
261 |
+
echo '<input type="number" step="0.01" name="wcml_wc_booking_person_cost[' . intval( $postId ) . '][' . esc_html( $currency_code ) . ']" class="wcml_bookings_custom_price" value="' . esc_html( $value ) . '" placeholder="0" />';
|
262 |
+
echo '</div>';
|
263 |
+
break;
|
264 |
+
|
265 |
+
case 'wcml_wc_booking_person_block_cost':
|
266 |
+
$value = get_post_meta( $postId, 'block_cost_' . $currency_code, true );
|
267 |
+
|
268 |
+
echo '<div class="wcml_bookings_person_block" >';
|
269 |
+
echo '<label>' . wp_kses_post( get_woocommerce_currency_symbol( $currency_code ) ) . '</label>';
|
270 |
+
echo '<input type="number" step="0.01" name="wcml_wc_booking_person_block_cost[' . intval( $postId ) . '][' . esc_html( $currency_code ) . ']" class="wcml_bookings_custom_price" value="' . esc_html( $value ) . '" placeholder="0" />';
|
271 |
+
echo '</div>';
|
272 |
+
break;
|
273 |
+
|
274 |
+
case 'wcml_wc_booking_resource_cost':
|
275 |
+
$resource_base_costs = maybe_unserialize( get_post_meta( $postId, '_resource_base_costs', true ) );
|
276 |
+
|
277 |
+
if ( isset( $resource_base_costs['custom_costs'][ $currency_code ][ $resourceId ] ) ) {
|
278 |
+
$value = $resource_base_costs['custom_costs'][ $currency_code ][ $resourceId ];
|
279 |
+
} else {
|
280 |
+
$value = '';
|
281 |
+
}
|
282 |
+
|
283 |
+
echo '<div class="wcml_bookings_resource_block" >';
|
284 |
+
echo '<label>' . wp_kses_post( get_woocommerce_currency_symbol( $currency_code ) ) . '</label>';
|
285 |
+
echo '<input type="number" step="0.01" name="wcml_wc_booking_resource_cost[' . esc_html( $resourceId ) . '][' . esc_html( $currency_code ) . ']" class="wcml_bookings_custom_price" value="' . esc_html( $value ) . '" placeholder="0" />';
|
286 |
+
echo '</div>';
|
287 |
+
break;
|
288 |
+
|
289 |
+
case 'wcml_wc_booking_resource_block_cost':
|
290 |
+
$resource_block_costs = maybe_unserialize( get_post_meta( $postId, '_resource_block_costs', true ) );
|
291 |
+
|
292 |
+
if ( isset( $resource_block_costs['custom_costs'][ $currency_code ][ $resourceId ] ) ) {
|
293 |
+
$value = $resource_block_costs['custom_costs'][ $currency_code ][ $resourceId ];
|
294 |
+
} else {
|
295 |
+
$value = '';
|
296 |
+
}
|
297 |
+
|
298 |
+
echo '<div class="wcml_bookings_resource_block" >';
|
299 |
+
echo '<label>' . wp_kses_post( get_woocommerce_currency_symbol( $currency_code ) ) . '</label>';
|
300 |
+
echo '<input type="number" step="0.01" name="wcml_wc_booking_resource_block_cost[' . esc_html( $resourceId ) . '][' . esc_html( $currency_code ) . ']" class="wcml_bookings_custom_price" value="' . esc_html( $value ) . '" placeholder="0" />';
|
301 |
+
echo '</div>';
|
302 |
+
break;
|
303 |
+
|
304 |
+
default:
|
305 |
+
break;
|
306 |
+
|
307 |
+
}
|
308 |
+
}
|
309 |
+
|
310 |
+
echo '</div>';
|
311 |
+
}
|
312 |
+
}
|
313 |
+
|
314 |
+
/**
|
315 |
+
* @param int $postId
|
316 |
+
*
|
317 |
+
* @return void
|
318 |
+
*/
|
319 |
+
public function after_bookings_pricing( $postId ) {
|
320 |
+
|
321 |
+
if ( in_array( 'booking', wp_get_post_terms( $postId, 'product_type', [ 'fields' => 'names' ] ) ) && $this->woocommerce_wpml->products->is_original_product( $postId ) ) {
|
322 |
+
|
323 |
+
$customCostsStatus = get_post_meta( $postId, '_wcml_custom_costs_status', true );
|
324 |
+
|
325 |
+
$checked = ! $customCostsStatus ? 'checked="checked"' : ' ';
|
326 |
+
|
327 |
+
echo '<div class="wcml_custom_costs">';
|
328 |
+
|
329 |
+
echo '<input type="radio" name="_wcml_custom_costs" id="wcml_custom_costs_auto" value="0" class="wcml_custom_costs_input" ' . esc_html( $checked ) . ' />';
|
330 |
+
echo '<label for="wcml_custom_costs_auto">' . esc_html__( 'Calculate costs in other currencies automatically', 'woocommerce-multilingual' ) . '</label>';
|
331 |
+
|
332 |
+
$checked = 1 === (int) $customCostsStatus ? 'checked="checked"' : ' ';
|
333 |
+
|
334 |
+
echo '<input type="radio" name="_wcml_custom_costs" value="1" id="wcml_custom_costs_manually" class="wcml_custom_costs_input" ' . esc_html( $checked ) . ' />';
|
335 |
+
echo '<label for="wcml_custom_costs_manually">' . esc_html__( 'Set costs in other currencies manually', 'woocommerce-multilingual' ) . '</label>';
|
336 |
+
|
337 |
+
wp_nonce_field( 'wcml_save_custom_costs', '_wcml_custom_costs_nonce' );
|
338 |
+
|
339 |
+
echo '</div>';
|
340 |
+
}
|
341 |
+
}
|
342 |
+
|
343 |
+
/**
|
344 |
+
* @param int $postId
|
345 |
+
*
|
346 |
+
* @return false|void
|
347 |
+
*/
|
348 |
+
public function save_custom_costs( $postId ) {
|
349 |
+
$nonce = filter_var( isset( $_POST['_wcml_custom_costs_nonce'] ) ? $_POST['_wcml_custom_costs_nonce'] : '', FILTER_SANITIZE_FULL_SPECIAL_CHARS );
|
350 |
+
|
351 |
+
if ( isset( $_POST['_wcml_custom_costs'] ) && isset( $nonce ) && wp_verify_nonce( $nonce, 'wcml_save_custom_costs' ) ) {
|
352 |
+
|
353 |
+
update_post_meta( $postId, '_wcml_custom_costs_status', $_POST['_wcml_custom_costs'] );
|
354 |
+
|
355 |
+
if ( 1 === (int) $_POST['_wcml_custom_costs'] ) {
|
356 |
+
|
357 |
+
$currencies = $this->woocommerce_wpml->multi_currency->get_currencies();
|
358 |
+
if ( empty( $currencies ) || 0 === $postId ) {
|
359 |
+
return false;
|
360 |
+
}
|
361 |
+
|
362 |
+
$this->update_booking_costs( $currencies, $postId );
|
363 |
+
$this->update_booking_pricing( $currencies, $postId );
|
364 |
+
|
365 |
+
if ( isset( $_POST['wcml_wc_booking_person_cost'] ) && is_array( $_POST['wcml_wc_booking_person_cost'] ) ) {
|
366 |
+
$this->update_booking_person_cost( $currencies, $_POST['wcml_wc_booking_person_cost'] );
|
367 |
+
}
|
368 |
+
|
369 |
+
if ( isset( $_POST['wcml_wc_booking_person_block_cost'] ) && is_array( $_POST['wcml_wc_booking_person_block_cost'] ) ) {
|
370 |
+
$this->update_booking_person_block_cost( $currencies, $_POST['wcml_wc_booking_person_block_cost'] );
|
371 |
+
}
|
372 |
+
|
373 |
+
if ( isset( $_POST['wcml_wc_booking_resource_cost'] ) && is_array( $_POST['wcml_wc_booking_resource_cost'] ) ) {
|
374 |
+
$this->update_booking_resource_cost( $currencies, $postId, $_POST['wcml_wc_booking_resource_cost'] );
|
375 |
+
}
|
376 |
+
|
377 |
+
if ( isset( $_POST['wcml_wc_booking_resource_block_cost'] ) && is_array( $_POST['wcml_wc_booking_resource_block_cost'] ) ) {
|
378 |
+
$this->update_booking_resource_block_cost( $currencies, $postId, $_POST['wcml_wc_booking_resource_block_cost'] );
|
379 |
+
}
|
380 |
+
|
381 |
+
update_post_meta( $postId, '_price', '' );
|
382 |
+
} else {
|
383 |
+
return false;
|
384 |
+
}
|
385 |
+
}
|
386 |
+
}
|
387 |
+
|
388 |
+
/**
|
389 |
+
* @param array $currencies
|
390 |
+
* @param int $postId
|
391 |
+
*
|
392 |
+
* @return bool
|
393 |
+
*/
|
394 |
+
private function update_booking_costs( $currencies = [], $postId = 0 ) {
|
395 |
+
$bookingOptions = [
|
396 |
+
'wcml_wc_booking_cost' => '_wc_booking_cost_',
|
397 |
+
'wcml_wc_booking_block_cost' => '_wc_booking_block_cost_',
|
398 |
+
'wcml_wc_display_cost' => '_wc_display_cost_',
|
399 |
+
];
|
400 |
+
|
401 |
+
if ( self::isWcBookingsBefore_1_10_9() ) {
|
402 |
+
unset( $bookingOptions['wcml_wc_booking_block_cost'] );
|
403 |
+
$bookingOptions['wcml_wc_booking_base_cost'] = '_wc_booking_base_cost_';
|
404 |
+
}
|
405 |
+
|
406 |
+
foreach ( $currencies as $code => $currency ) {
|
407 |
+
foreach ( $bookingOptions as $bookingOptionsPostKey => $bookingOptionsMetaKeyPrefix ) {
|
408 |
+
if ( isset( $_POST[ $bookingOptionsPostKey ][ $code ] ) ) {
|
409 |
+
update_post_meta( $postId, $bookingOptionsMetaKeyPrefix . $code, sanitize_text_field( $_POST[ $bookingOptionsPostKey ][ $code ] ) );
|
410 |
+
}
|
411 |
+
}
|
412 |
+
}
|
413 |
+
|
414 |
+
return true;
|
415 |
+
}
|
416 |
+
|
417 |
+
/**
|
418 |
+
* @param array $currencies
|
419 |
+
* @param int $postId
|
420 |
+
*
|
421 |
+
* @return bool
|
422 |
+
*/
|
423 |
+
private function update_booking_pricing( $currencies = [], $postId = 0 ) {
|
424 |
+
$updatedMeta = [];
|
425 |
+
$bookingPricing = get_post_meta( $postId, '_wc_booking_pricing', true );
|
426 |
+
if ( empty( $bookingPricing ) ) {
|
427 |
+
return false;
|
428 |
+
}
|
429 |
+
|
430 |
+
foreach ( $bookingPricing as $key => $prices ) {
|
431 |
+
$updatedMeta[ $key ] = $prices;
|
432 |
+
foreach ( $currencies as $code => $currency ) {
|
433 |
+
if ( isset( $_POST['wcml_wc_booking_pricing_base_cost'][ $code ][ $key ] ) ) {
|
434 |
+
$updatedMeta[ $key ][ 'base_cost_' . $code ] = sanitize_text_field( $_POST['wcml_wc_booking_pricing_base_cost'][ $code ][ $key ] );
|
435 |
+
}
|
436 |
+
if ( isset( $_POST['wcml_wc_booking_pricing_cost'][ $code ][ $key ] ) ) {
|
437 |
+
$updatedMeta[ $key ][ 'cost_' . $code ] = sanitize_text_field( $_POST['wcml_wc_booking_pricing_cost'][ $code ][ $key ] );
|
438 |
+
}
|
439 |
+
}
|
440 |
+
}
|
441 |
+
|
442 |
+
update_post_meta( $postId, '_wc_booking_pricing', $updatedMeta );
|
443 |
+
|
444 |
+
return true;
|
445 |
+
}
|
446 |
+
|
447 |
+
/**
|
448 |
+
* @param array $currencies
|
449 |
+
* @param array $personCosts
|
450 |
+
*
|
451 |
+
* @return bool
|
452 |
+
*/
|
453 |
+
private function update_booking_person_cost( $currencies = [], $personCosts = [] ) {
|
454 |
+
if ( empty( $personCosts ) ) {
|
455 |
+
return false;
|
456 |
+
}
|
457 |
+
|
458 |
+
foreach ( $personCosts as $personId => $costs ) {
|
459 |
+
foreach ( $currencies as $code => $currency ) {
|
460 |
+
if ( isset( $costs[ $code ] ) ) {
|
461 |
+
update_post_meta( $personId, 'cost_' . $code, sanitize_text_field( $costs[ $code ] ) );
|
462 |
+
}
|
463 |
+
}
|
464 |
+
}
|
465 |
+
|
466 |
+
return true;
|
467 |
+
}
|
468 |
+
|
469 |
+
/**
|
470 |
+
* @param array $currencies
|
471 |
+
* @param array $blockCosts
|
472 |
+
*
|
473 |
+
* @return bool
|
474 |
+
*/
|
475 |
+
private function update_booking_person_block_cost( $currencies = [], $blockCosts = [] ) {
|
476 |
+
if ( empty( $blockCosts ) ) {
|
477 |
+
return false;
|
478 |
+
}
|
479 |
+
|
480 |
+
foreach ( $blockCosts as $personId => $costs ) {
|
481 |
+
foreach ( $currencies as $code => $currency ) {
|
482 |
+
if ( isset( $costs[ $code ] ) ) {
|
483 |
+
update_post_meta( $personId, 'block_cost_' . $code, sanitize_text_field( $costs[ $code ] ) );
|
484 |
+
}
|
485 |
+
}
|
486 |
+
}
|
487 |
+
|
488 |
+
return true;
|
489 |
+
}
|
490 |
+
|
491 |
+
/**
|
492 |
+
* @param array $currencies
|
493 |
+
* @param int $postId
|
494 |
+
* @param array $resourceCost
|
495 |
+
*
|
496 |
+
* @return bool
|
497 |
+
*/
|
498 |
+
private function update_booking_resource_cost( $currencies = [], $postId = 0, $resourceCost = [] ) {
|
499 |
+
if ( empty( $resourceCost ) ) {
|
500 |
+
return false;
|
501 |
+
}
|
502 |
+
|
503 |
+
$updatedMeta = get_post_meta( $postId, '_resource_base_costs', true );
|
504 |
+
if ( ! is_array( $updatedMeta ) ) {
|
505 |
+
$updatedMeta = [];
|
506 |
+
}
|
507 |
+
|
508 |
+
$wcBookingResourceCosts = [];
|
509 |
+
|
510 |
+
foreach ( $resourceCost as $resourceId => $costs ) {
|
511 |
+
|
512 |
+
foreach ( $currencies as $code => $currency ) {
|
513 |
+
|
514 |
+
if ( isset( $costs[ $code ] ) ) {
|
515 |
+
$wcBookingResourceCosts[ $code ][ $resourceId ] = sanitize_text_field( $costs[ $code ] );
|
516 |
+
}
|
517 |
+
}
|
518 |
+
}
|
519 |
+
|
520 |
+
$updatedMeta['custom_costs'] = $wcBookingResourceCosts;
|
521 |
+
|
522 |
+
update_post_meta( $postId, '_resource_base_costs', $updatedMeta );
|
523 |
+
|
524 |
+
self::triggerActionResourceCostsUpdated( $postId, '_resource_base_costs' );
|
525 |
+
|
526 |
+
return true;
|
527 |
+
}
|
528 |
+
|
529 |
+
/**
|
530 |
+
* @param array $currencies
|
531 |
+
* @param int $postId
|
532 |
+
* @param array $resourceBlockCost
|
533 |
+
*
|
534 |
+
* @return bool
|
535 |
+
*/
|
536 |
+
private function update_booking_resource_block_cost( $currencies = [], $postId = 0, $resourceBlockCost = [] ) {
|
537 |
+
if ( empty( $resourceBlockCost ) ) {
|
538 |
+
return false;
|
539 |
+
}
|
540 |
+
|
541 |
+
$updatedMeta = get_post_meta( $postId, '_resource_block_costs', true );
|
542 |
+
if ( ! is_array( $updatedMeta ) ) {
|
543 |
+
$updatedMeta = [];
|
544 |
+
}
|
545 |
+
|
546 |
+
$wc_booking_resource_block_costs = [];
|
547 |
+
|
548 |
+
foreach ( $resourceBlockCost as $resource_id => $costs ) {
|
549 |
+
|
550 |
+
foreach ( $currencies as $code => $currency ) {
|
551 |
+
|
552 |
+
if ( isset( $costs[ $code ] ) ) {
|
553 |
+
$wc_booking_resource_block_costs[ $code ][ $resource_id ] = sanitize_text_field( $costs[ $code ] );
|
554 |
+
}
|
555 |
+
}
|
556 |
+
}
|
557 |
+
|
558 |
+
$updatedMeta['custom_costs'] = $wc_booking_resource_block_costs;
|
559 |
+
|
560 |
+
update_post_meta( $postId, '_resource_block_costs', $updatedMeta );
|
561 |
+
|
562 |
+
self::triggerActionResourceCostsUpdated( $postId, '_resource_block_costs' );
|
563 |
+
|
564 |
+
return true;
|
565 |
+
}
|
566 |
+
|
567 |
+
/**
|
568 |
+
* This is an internal action hook required after splitting
|
569 |
+
* the original WC Bookings compatibility code.
|
570 |
+
*
|
571 |
+
* @see \WCML_Bookings::sync_resource_costs_with_translations
|
572 |
+
*
|
573 |
+
* @param int|string $postId
|
574 |
+
* @param string $key
|
575 |
+
*
|
576 |
+
* @return void
|
577 |
+
*/
|
578 |
+
private static function triggerActionResourceCostsUpdated( $postId, $key ) {
|
579 |
+
do_action( 'wcml_bookings_resource_costs_updated', $postId, $key );
|
580 |
+
}
|
581 |
+
|
582 |
+
/**
|
583 |
+
* @param float|int $cost
|
584 |
+
* @param array $fields
|
585 |
+
* @param string $key
|
586 |
+
*
|
587 |
+
* @return float|int
|
588 |
+
*/
|
589 |
+
public function wc_bookings_process_cost_rules_cost( $cost, $fields, $key ) {
|
590 |
+
return $this->filter_pricing_cost( $cost, $fields, 'cost_', $key );
|
591 |
+
}
|
592 |
+
|
593 |
+
/**
|
594 |
+
* @param float|int $base_cost
|
595 |
+
* @param array $fields
|
596 |
+
* @param string $key
|
597 |
+
*
|
598 |
+
* @return float|int
|
599 |
+
*/
|
600 |
+
public function wc_bookings_process_cost_rules_base_cost( $base_cost, $fields, $key ) {
|
601 |
+
return $this->filter_pricing_cost( $base_cost, $fields, 'base_cost_', $key );
|
602 |
+
}
|
603 |
+
|
604 |
+
/**
|
605 |
+
* @param float|int $override_cost
|
606 |
+
* @param array $fields
|
607 |
+
* @param string $key
|
608 |
+
*
|
609 |
+
* @return float|int
|
610 |
+
*/
|
611 |
+
public function wc_bookings_process_cost_rules_override_block_cost( $override_cost, $fields, $key ) {
|
612 |
+
return $this->filter_pricing_cost( $override_cost, $fields, 'override_block_', $key );
|
613 |
+
}
|
614 |
+
|
615 |
+
/**
|
616 |
+
* @param float|int $cost
|
617 |
+
* @param array $fields
|
618 |
+
* @param string $name
|
619 |
+
* @param string $key
|
620 |
+
*
|
621 |
+
* @return float|int|mixed|string
|
622 |
+
*/
|
623 |
+
public function filter_pricing_cost( $cost, $fields, $name, $key ) {
|
624 |
+
$currency = $this->woocommerce_wpml->multi_currency->get_client_currency();
|
625 |
+
|
626 |
+
if ( $currency === wcml_get_woocommerce_currency_option() ) {
|
627 |
+
return $cost;
|
628 |
+
}
|
629 |
+
|
630 |
+
if ( isset( $_POST['form'] ) ) {
|
631 |
+
parse_str( $_POST['form'], $posted );
|
632 |
+
|
633 |
+
$booking_id = $posted['add-to-cart'];
|
634 |
+
|
635 |
+
} elseif ( isset( $_POST['add-to-cart'] ) ) {
|
636 |
+
|
637 |
+
$booking_id = $_POST['add-to-cart'];
|
638 |
+
|
639 |
+
}
|
640 |
+
|
641 |
+
if ( isset( $booking_id ) ) {
|
642 |
+
$original_id = $this->woocommerce_wpml->products->get_original_product_id( $booking_id );
|
643 |
+
|
644 |
+
if ( $booking_id != $original_id ) {
|
645 |
+
$fields = maybe_unserialize( get_post_meta( $original_id, '_wc_booking_pricing', true ) );
|
646 |
+
$fields = $fields[ $key ];
|
647 |
+
}
|
648 |
+
}
|
649 |
+
|
650 |
+
$needs_filter_pricing_cost = $this->needs_filter_pricing_cost( $name, $fields );
|
651 |
+
|
652 |
+
if ( $needs_filter_pricing_cost ) {
|
653 |
+
if ( isset( $fields[ $name . $currency ] ) ) {
|
654 |
+
return $fields[ $name . $currency ];
|
655 |
+
} else {
|
656 |
+
return $this->woocommerce_wpml->multi_currency->prices->convert_price_amount( $cost, $currency );
|
657 |
+
}
|
658 |
+
}
|
659 |
+
|
660 |
+
return $cost;
|
661 |
+
}
|
662 |
+
|
663 |
+
/**
|
664 |
+
* @param string $name
|
665 |
+
* @param array $fields
|
666 |
+
*
|
667 |
+
* @return bool
|
668 |
+
*/
|
669 |
+
public function needs_filter_pricing_cost( $name, $fields ) {
|
670 |
+
|
671 |
+
$modifier_skip_values = [ 'divide', 'times' ];
|
672 |
+
|
673 |
+
if (
|
674 |
+
'override_block_' === $name ||
|
675 |
+
( 'cost_' === $name && ! in_array( $fields['modifier'], $modifier_skip_values ) ) ||
|
676 |
+
( 'base_cost_' === $name && ! in_array( $fields['base_modifier'], $modifier_skip_values ) )
|
677 |
+
) {
|
678 |
+
return true;
|
679 |
+
} else {
|
680 |
+
return false;
|
681 |
+
}
|
682 |
+
}
|
683 |
+
|
684 |
+
public function booking_currency_dropdown() {
|
685 |
+
$current_booking_currency = $this->get_cookie_booking_currency();
|
686 |
+
|
687 |
+
$wc_currencies = get_woocommerce_currencies();
|
688 |
+
$currencies = $this->woocommerce_wpml->multi_currency->get_currencies( true );
|
689 |
+
?>
|
690 |
+
<tr valign="top">
|
691 |
+
<th scope="row"><?php _e( 'Booking currency', 'woocommerce-multilingual' ); ?></th>
|
692 |
+
<td>
|
693 |
+
<select id="dropdown_booking_currency">
|
694 |
+
<?php foreach ( $currencies as $currency => $count ) : ?>
|
695 |
+
<option
|
696 |
+
value="<?php echo esc_html( $currency ); ?>" <?php echo $current_booking_currency == $currency ? 'selected="selected"' : ''; ?>><?php echo esc_html( $wc_currencies[ $currency ] ); ?></option>
|
697 |
+
<?php endforeach; ?>
|
698 |
+
</select>
|
699 |
+
</td>
|
700 |
+
</tr>
|
701 |
+
|
702 |
+
<?php
|
703 |
+
|
704 |
+
$wcml_booking_set_currency_nonce = wp_create_nonce( 'booking_set_currency' );
|
705 |
+
|
706 |
+
wc_enqueue_js(
|
707 |
+
"
|
708 |
+
|
709 |
+
jQuery(document).on('change', '#dropdown_booking_currency', function(){
|
710 |
+
jQuery.ajax({
|
711 |
+
url: ajaxurl,
|
712 |
+
type: 'post',
|
713 |
+
data: {
|
714 |
+
action: 'wcml_booking_set_currency',
|
715 |
+
currency: jQuery('#dropdown_booking_currency').val(),
|
716 |
+
wcml_nonce: '" . $wcml_booking_set_currency_nonce . "'
|
717 |
+
},
|
718 |
+
success: function( response ){
|
719 |
+
if(typeof response.error !== 'undefined'){
|
720 |
+
alert(response.error);
|
721 |
+
}else{
|
722 |
+
window.location = window.location.href;
|
723 |
+
}
|
724 |
+
}
|
725 |
+
})
|
726 |
+
});
|
727 |
+
"
|
728 |
+
);
|
729 |
+
}
|
730 |
+
|
731 |
+
public function set_booking_currency_ajax() {
|
732 |
+
$nonce = filter_input( INPUT_POST, 'wcml_nonce', FILTER_SANITIZE_FULL_SPECIAL_CHARS );
|
733 |
+
if ( ! $nonce || ! wp_verify_nonce( $nonce, 'booking_set_currency' ) ) {
|
734 |
+
echo json_encode( [ 'error' => __( 'Invalid nonce', 'woocommerce-multilingual' ) ] );
|
735 |
+
die();
|
736 |
+
}
|
737 |
+
|
738 |
+
$this->set_booking_currency( filter_input( INPUT_POST, 'currency', FILTER_SANITIZE_FULL_SPECIAL_CHARS ) );
|
739 |
+
|
740 |
+
die();
|
741 |
+
}
|
742 |
+
|
743 |
+
public function set_booking_currency( $currency_code = false ) {
|
744 |
+
$cookie_name = '_wcml_booking_currency';
|
745 |
+
|
746 |
+
if ( ! isset( $_COOKIE[ $cookie_name ] ) && ! headers_sent() ) {
|
747 |
+
$currency_code = $this->woocommerce_wpml->multi_currency->get_currency_code();
|
748 |
+
}
|
749 |
+
|
750 |
+
if ( $currency_code ) {
|
751 |
+
// @todo uncomment or delete when #wpmlcore-5796 is resolved
|
752 |
+
// do_action( 'wpsc_add_cookie', $cookie_name );
|
753 |
+
setcookie( $cookie_name, $currency_code, time() + 86400, COOKIEPATH, COOKIE_DOMAIN );
|
754 |
+
}
|
755 |
+
}
|
756 |
+
|
757 |
+
public function get_cookie_booking_currency() {
|
758 |
+
if ( isset( $_COOKIE ['_wcml_booking_currency'] ) ) {
|
759 |
+
$currency = $_COOKIE['_wcml_booking_currency'];
|
760 |
+
} else {
|
761 |
+
$currency = wcml_get_woocommerce_currency_option();
|
762 |
+
}
|
763 |
+
|
764 |
+
return $currency;
|
765 |
+
}
|
766 |
+
|
767 |
+
public function set_order_currency_on_create_booking_page( $order_id ) {
|
768 |
+
update_post_meta( $order_id, '_order_currency', $this->get_cookie_booking_currency() );
|
769 |
+
}
|
770 |
+
|
771 |
+
public function filter_booking_currency_symbol( $currency ) {
|
772 |
+
global $pagenow;
|
773 |
+
|
774 |
+
remove_filter( 'woocommerce_currency_symbol', [ $this, 'filter_booking_currency_symbol' ] );
|
775 |
+
if ( isset( $_COOKIE ['_wcml_booking_currency'] ) && $pagenow == 'edit.php' && isset( $_GET['page'] ) && $_GET['page'] == 'create_booking' ) {
|
776 |
+
$currency = get_woocommerce_currency_symbol( $_COOKIE ['_wcml_booking_currency'] );
|
777 |
+
}
|
778 |
+
add_filter( 'woocommerce_currency_symbol', [ $this, 'filter_booking_currency_symbol' ] );
|
779 |
+
|
780 |
+
return $currency;
|
781 |
+
}
|
782 |
+
|
783 |
+
public function create_booking_page_client_currency( $currency ) {
|
784 |
+
global $pagenow;
|
785 |
+
|
786 |
+
if ( wpml_is_ajax() && isset( $_POST['form'] ) ) {
|
787 |
+
parse_str( $_POST['form'], $posted );
|
788 |
+
}
|
789 |
+
|
790 |
+
if ( ( $pagenow == 'edit.php' && isset( $_GET['page'] ) && $_GET['page'] == 'create_booking' ) || ( isset( $posted['_wp_http_referer'] ) && strpos( $posted['_wp_http_referer'], 'page=create_booking' ) !== false ) ) {
|
791 |
+
$currency = $this->get_cookie_booking_currency();
|
792 |
+
}
|
793 |
+
|
794 |
+
return $currency;
|
795 |
+
}
|
796 |
+
|
797 |
+
public function filter_wc_booking_cost( $check, $object_id, $meta_key, $single ) {
|
798 |
+
|
799 |
+
if ( in_array(
|
800 |
+
$meta_key,
|
801 |
+
[
|
802 |
+
'_wc_booking_cost',
|
803 |
+
'_wc_booking_base_cost',
|
804 |
+
'_wc_display_cost',
|
805 |
+
'_wc_booking_pricing',
|
806 |
+
'cost',
|
807 |
+
'_wc_booking_block_cost',
|
808 |
+
'block_cost',
|
809 |
+
'_resource_base_costs',
|
810 |
+
'_resource_block_costs',
|
811 |
+
]
|
812 |
+
) ) {
|
813 |
+
|
814 |
+
$original_id = $this->woocommerce_wpml->products->get_original_product_id( $object_id );
|
815 |
+
|
816 |
+
$cost_status = get_post_meta( $original_id, '_wcml_custom_costs_status', true );
|
817 |
+
|
818 |
+
$currency = $this->woocommerce_wpml->multi_currency->get_client_currency();
|
819 |
+
|
820 |
+
if ( $currency === wcml_get_woocommerce_currency_option() ) {
|
821 |
+
return $check;
|
822 |
+
}
|
823 |
+
|
824 |
+
if ( in_array( $meta_key, [ 'cost', 'block_cost' ] ) ) {
|
825 |
+
|
826 |
+
if ( get_post_type( $object_id ) == 'bookable_person' ) {
|
827 |
+
|
828 |
+
$original_id = apply_filters( 'translate_object_id', wp_get_post_parent_id( $object_id ), 'product', true, $this->woocommerce_wpml->products->get_original_product_language( wp_get_post_parent_id( $object_id ) ) );
|
829 |
+
$cost_status = get_post_meta( $original_id, '_wcml_custom_costs_status', true );
|
830 |
+
|
831 |
+
$value = get_post_meta( $object_id, $meta_key . '_' . $currency, true );
|
832 |
+
|
833 |
+
if ( $cost_status && $value ) {
|
834 |
+
|
835 |
+
return $value;
|
836 |
+
|
837 |
+
} else {
|
838 |
+
|
839 |
+
remove_filter( 'get_post_metadata', [ $this, 'filter_wc_booking_cost' ], 10 );
|
840 |
+
|
841 |
+
$cost = get_post_meta( $object_id, $meta_key, true );
|
842 |
+
|
843 |
+
add_filter( 'get_post_metadata', [ $this, 'filter_wc_booking_cost' ], 10, 4 );
|
844 |
+
|
845 |
+
return $this->woocommerce_wpml->multi_currency->prices->convert_price_amount( $cost, $currency );
|
846 |
+
}
|
847 |
+
} else {
|
848 |
+
|
849 |
+
return $check;
|
850 |
+
|
851 |
+
}
|
852 |
+
}
|
853 |
+
|
854 |
+
if ( in_array(
|
855 |
+
$meta_key,
|
856 |
+
[
|
857 |
+
'_wc_booking_pricing',
|
858 |
+
'_resource_base_costs',
|
859 |
+
'_resource_block_costs',
|
860 |
+
]
|
861 |
+
) ) {
|
862 |
+
|
863 |
+
remove_filter( 'get_post_metadata', [ $this, 'filter_wc_booking_cost' ], 10 );
|
864 |
+
|
865 |
+
if ( $meta_key == '_wc_booking_pricing' ) {
|
866 |
+
|
867 |
+
if ( $original_id != $object_id ) {
|
868 |
+
$value = get_post_meta( $original_id, $meta_key );
|
869 |
+
} else {
|
870 |
+
$value = $check;
|
871 |
+
}
|
872 |
+
} else {
|
873 |
+
|
874 |
+
$costs = maybe_unserialize( get_post_meta( $object_id, $meta_key, true ) );
|
875 |
+
|
876 |
+
if ( ! $costs ) {
|
877 |
+
$value = $check;
|
878 |
+
} elseif ( $cost_status && isset( $costs['custom_costs'][ $currency ] ) ) {
|
879 |
+
|
880 |
+
$res_costs = [];
|
881 |
+
foreach ( $costs['custom_costs'][ $currency ] as $resource_id => $cost ) {
|
882 |
+
$trns_resource_id = apply_filters( 'translate_object_id', $resource_id, 'bookable_resource', true );
|
883 |
+
$res_costs[ $trns_resource_id ] = $cost;
|
884 |
+
}
|
885 |
+
$value = [ 0 => $res_costs ];
|
886 |
+
} elseif ( $cost_status && isset( $costs[0]['custom_costs'][ $currency ] ) ) {
|
887 |
+
$value = [ 0 => $costs[0]['custom_costs'][ $currency ] ];
|
888 |
+
} else {
|
889 |
+
|
890 |
+
$converted_values = [];
|
891 |
+
|
892 |
+
foreach ( $costs as $resource_id => $cost ) {
|
893 |
+
$converted_values[0][ $resource_id ] = $this->woocommerce_wpml->multi_currency->prices->convert_price_amount( $cost, $currency );
|
894 |
+
}
|
895 |
+
|
896 |
+
$value = $converted_values;
|
897 |
+
}
|
898 |
+
}
|
899 |
+
|
900 |
+
add_filter( 'get_post_metadata', [ $this, 'filter_wc_booking_cost' ], 10, 4 );
|
901 |
+
|
902 |
+
return $value;
|
903 |
+
|
904 |
+
}
|
905 |
+
|
906 |
+
$value = get_post_meta( $original_id, $meta_key . '_' . $currency, true );
|
907 |
+
|
908 |
+
if ( $cost_status && ( ! empty( $value ) || ( empty( $value ) && $meta_key == '_wc_display_cost' ) ) ) {
|
909 |
+
|
910 |
+
return $value;
|
911 |
+
|
912 |
+
} else {
|
913 |
+
|
914 |
+
remove_filter( 'get_post_metadata', [ $this, 'filter_wc_booking_cost' ], 10 );
|
915 |
+
|
916 |
+
$value = get_post_meta( $original_id, $meta_key, true );
|
917 |
+
|
918 |
+
$value = $this->woocommerce_wpml->multi_currency->prices->convert_price_amount( $value, $currency );
|
919 |
+
|
920 |
+
add_filter( 'get_post_metadata', [ $this, 'filter_wc_booking_cost' ], 10, 4 );
|
921 |
+
|
922 |
+
return $value;
|
923 |
+
|
924 |
+
}
|
925 |
+
}
|
926 |
+
|
927 |
+
return $check;
|
928 |
+
}
|
929 |
+
|
930 |
+
/**
|
931 |
+
* @return bool
|
932 |
+
*/
|
933 |
+
public static function isWcBookingsBefore_1_10_9() {
|
934 |
+
return version_compare( WC_BOOKINGS_VERSION, '1.10.9', '<' );
|
935 |
+
}
|
936 |
+
}
|
compatibility/WcBookings/SharedHooks.php
ADDED
@@ -0,0 +1,86 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace WCML\Compatibility\WcBookings;
|
4 |
+
|
5 |
+
use WC_Product;
|
6 |
+
|
7 |
+
class SharedHooks implements \IWPML_Action {
|
8 |
+
|
9 |
+
/** @var \wpdb $wpdb */
|
10 |
+
private $wpdb;
|
11 |
+
|
12 |
+
/**
|
13 |
+
* @param \wpdb $wpdb
|
14 |
+
*/
|
15 |
+
public function __construct( \wpdb $wpdb ) {
|
16 |
+
$this->wpdb = $wpdb;
|
17 |
+
}
|
18 |
+
|
19 |
+
public function add_hooks() {
|
20 |
+
add_action( 'init', [ __CLASS__, 'load_assets' ] );
|
21 |
+
add_filter( 'wcml_multi_currency_ajax_actions', [ __CLASS__, 'wcml_multi_currency_is_ajax' ] );
|
22 |
+
|
23 |
+
$this->clear_transient_fields();
|
24 |
+
}
|
25 |
+
|
26 |
+
/**
|
27 |
+
* @param string|false $externalProductType
|
28 |
+
*
|
29 |
+
* @return void
|
30 |
+
*/
|
31 |
+
public static function load_assets( $externalProductType = false ) {
|
32 |
+
global $pagenow;
|
33 |
+
|
34 |
+
$productId = $pagenow == 'post.php' && isset( $_GET['post'] ) ? (int) $_GET['post'] : false;
|
35 |
+
|
36 |
+
if ( $productId && get_post_type( $productId ) === 'product' ) {
|
37 |
+
$product = wc_get_product( $productId );
|
38 |
+
$productType = $product->get_type();
|
39 |
+
|
40 |
+
if ( ( self::isBooking( $product ) || $productType === $externalProductType ) || $pagenow == 'post-new.php' ) {
|
41 |
+
wp_register_style( 'wcml-bookings-css', WCML_PLUGIN_URL . '/compatibility/res/css/wcml-bookings.css', [], WCML_VERSION );
|
42 |
+
wp_enqueue_style( 'wcml-bookings-css' );
|
43 |
+
|
44 |
+
wp_register_script( 'wcml-bookings-js', WCML_PLUGIN_URL . '/compatibility/res/js/wcml-bookings.js', [ 'jquery' ], WCML_VERSION, true );
|
45 |
+
wp_enqueue_script( 'wcml-bookings-js' );
|
46 |
+
}
|
47 |
+
}
|
48 |
+
}
|
49 |
+
|
50 |
+
/**
|
51 |
+
* @param array $actions
|
52 |
+
*
|
53 |
+
* @return array
|
54 |
+
*/
|
55 |
+
public static function wcml_multi_currency_is_ajax( $actions ) {
|
56 |
+
$actions[] = 'wc_bookings_calculate_costs';
|
57 |
+
|
58 |
+
return $actions;
|
59 |
+
}
|
60 |
+
|
61 |
+
public function clear_transient_fields() {
|
62 |
+
if ( isset( $_GET['post_type'] ) && $_GET['post_type'] == 'wc_booking' && isset( $_GET['page'] ) && $_GET['page'] == 'booking_calendar' ) {
|
63 |
+
|
64 |
+
// delete transient fields
|
65 |
+
$this->wpdb->query(
|
66 |
+
"
|
67 |
+
DELETE FROM {$this->wpdb->options}
|
68 |
+
WHERE option_name LIKE '%book_dr_%'
|
69 |
+
"
|
70 |
+
);
|
71 |
+
}
|
72 |
+
}
|
73 |
+
|
74 |
+
/**
|
75 |
+
* @param WC_Product|int|string $product
|
76 |
+
*
|
77 |
+
* @return bool
|
78 |
+
*/
|
79 |
+
public static function isBooking( $product ) {
|
80 |
+
if ( ! $product instanceof WC_Product ) {
|
81 |
+
$product = wc_get_product( $product );
|
82 |
+
}
|
83 |
+
|
84 |
+
return $product && $product->get_type() === 'booking';
|
85 |
+
}
|
86 |
+
}
|
compatibility/{class-wcml-accommodation-bookings.php → WcBookings/class-wcml-accommodation-bookings.php}
RENAMED
@@ -1,26 +1,17 @@
|
|
1 |
<?php
|
2 |
|
3 |
-
|
4 |
|
5 |
-
|
6 |
-
* @var woocommerce_wpml
|
7 |
-
*/
|
8 |
-
private $woocommerce_wpml;
|
9 |
|
10 |
-
/**
|
11 |
-
|
12 |
-
*/
|
13 |
-
private $bookings;
|
14 |
-
|
15 |
-
public function __construct(
|
16 |
-
woocommerce_wpml $woocommerce_wpml,
|
17 |
-
WCML_Bookings $bookings
|
18 |
-
) {
|
19 |
-
// @todo Cover by tests, required for wcml-3037.
|
20 |
|
|
|
21 |
$this->woocommerce_wpml = $woocommerce_wpml;
|
22 |
-
|
23 |
|
|
|
24 |
add_action( 'woocommerce_accommodation_bookings_after_booking_base_cost', [ $this, 'wcml_price_field_after_booking_base_cost', ] );
|
25 |
add_action( 'woocommerce_accommodation_bookings_after_booking_pricing_override_block_cost', [ $this, 'wcml_price_field_after_booking_pricing_override_block_cost', ], 10, 2 );
|
26 |
add_action( 'woocommerce_accommodation_bookings_after_bookings_pricing', [ $this, 'after_bookings_pricing' ] );
|
@@ -48,8 +39,7 @@ class WCML_Accommodation_Bookings{
|
|
48 |
$product_terms = wp_get_post_terms( $post_id, 'product_type', array( "fields" => "names" ) );
|
49 |
|
50 |
if(
|
51 |
-
in_array( 'accommodation-booking', $product_terms )&&
|
52 |
-
$this->woocommerce_wpml->settings['enable_multi_currency'] == WCML_MULTI_CURRENCIES_INDEPENDENT &&
|
53 |
$this->woocommerce_wpml->products->is_original_product( $post_id )
|
54 |
){
|
55 |
|
@@ -76,15 +66,10 @@ class WCML_Accommodation_Bookings{
|
|
76 |
|
77 |
function echo_wcml_price_field( $post_id, $field, $pricing = false, $check = true, $resource_id = false ){
|
78 |
|
79 |
-
if(
|
80 |
-
$this->woocommerce_wpml->settings['enable_multi_currency'] == WCML_MULTI_CURRENCIES_INDEPENDENT &&
|
81 |
-
( !$check || $this->woocommerce_wpml->products->is_original_product( $post_id ) )
|
82 |
-
){
|
83 |
|
84 |
$currencies = $this->woocommerce_wpml->multi_currency->get_currencies();
|
85 |
|
86 |
-
$wc_currencies = get_woocommerce_currencies();
|
87 |
-
|
88 |
echo '<div class="wcml_custom_cost_field" >';
|
89 |
|
90 |
foreach($currencies as $currency_code => $currency){
|
@@ -170,7 +155,6 @@ class WCML_Accommodation_Bookings{
|
|
170 |
|
171 |
if(
|
172 |
$meta_key == '_price' &&
|
173 |
-
$this->woocommerce_wpml->settings[ 'enable_multi_currency' ] == WCML_MULTI_CURRENCIES_INDEPENDENT &&
|
174 |
!is_admin() &&
|
175 |
get_post_type( $object_id ) == 'product' &&
|
176 |
( $currency = $this->woocommerce_wpml->multi_currency->get_client_currency() ) !== wcml_get_woocommerce_currency_option()
|
@@ -191,9 +175,8 @@ class WCML_Accommodation_Bookings{
|
|
191 |
return isset( $price) ? $price : $value;
|
192 |
}
|
193 |
|
194 |
-
public function load_assets(){
|
195 |
-
|
196 |
-
$this->bookings->load_assets( 'accommodation-booking' );
|
197 |
}
|
198 |
|
199 |
}
|
1 |
<?php
|
2 |
|
3 |
+
use WCML\Compatibility\WcBookings\SharedHooks;
|
4 |
|
5 |
+
class WCML_Accommodation_Bookings implements \IWPML_Action {
|
|
|
|
|
|
|
6 |
|
7 |
+
/** @var \woocommerce_wpml $woocommerce_wpml */
|
8 |
+
private $woocommerce_wpml;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
9 |
|
10 |
+
public function __construct( \woocommerce_wpml $woocommerce_wpml ) {
|
11 |
$this->woocommerce_wpml = $woocommerce_wpml;
|
12 |
+
}
|
13 |
|
14 |
+
public function add_hooks() {
|
15 |
add_action( 'woocommerce_accommodation_bookings_after_booking_base_cost', [ $this, 'wcml_price_field_after_booking_base_cost', ] );
|
16 |
add_action( 'woocommerce_accommodation_bookings_after_booking_pricing_override_block_cost', [ $this, 'wcml_price_field_after_booking_pricing_override_block_cost', ], 10, 2 );
|
17 |
add_action( 'woocommerce_accommodation_bookings_after_bookings_pricing', [ $this, 'after_bookings_pricing' ] );
|
39 |
$product_terms = wp_get_post_terms( $post_id, 'product_type', array( "fields" => "names" ) );
|
40 |
|
41 |
if(
|
42 |
+
in_array( 'accommodation-booking', $product_terms ) &&
|
|
|
43 |
$this->woocommerce_wpml->products->is_original_product( $post_id )
|
44 |
){
|
45 |
|
66 |
|
67 |
function echo_wcml_price_field( $post_id, $field, $pricing = false, $check = true, $resource_id = false ){
|
68 |
|
69 |
+
if ( ! $check || $this->woocommerce_wpml->products->is_original_product( $post_id ) ) {
|
|
|
|
|
|
|
70 |
|
71 |
$currencies = $this->woocommerce_wpml->multi_currency->get_currencies();
|
72 |
|
|
|
|
|
73 |
echo '<div class="wcml_custom_cost_field" >';
|
74 |
|
75 |
foreach($currencies as $currency_code => $currency){
|
155 |
|
156 |
if(
|
157 |
$meta_key == '_price' &&
|
|
|
158 |
!is_admin() &&
|
159 |
get_post_type( $object_id ) == 'product' &&
|
160 |
( $currency = $this->woocommerce_wpml->multi_currency->get_client_currency() ) !== wcml_get_woocommerce_currency_option()
|
175 |
return isset( $price) ? $price : $value;
|
176 |
}
|
177 |
|
178 |
+
public function load_assets() {
|
179 |
+
SharedHooks::load_assets( 'accommodation-booking' );
|
|
|
180 |
}
|
181 |
|
182 |
}
|
compatibility/{class-wcml-bookings.php → WcBookings/class-wcml-bookings.php}
RENAMED
@@ -1,16 +1,19 @@
|
|
1 |
<?php
|
2 |
|
3 |
use WPML\FP\Maybe;
|
|
|
4 |
use function WPML\FP\invoke;
|
5 |
use function WPML\FP\pipe;
|
6 |
|
7 |
/**
|
8 |
* Class WCML_Bookings.
|
9 |
*/
|
10 |
-
class WCML_Bookings {
|
11 |
|
12 |
const DOMAIN = 'woocommerce-bookings';
|
13 |
|
|
|
|
|
14 |
/**
|
15 |
* @var WPML_Element_Translation_Package
|
16 |
*/
|
@@ -76,104 +79,12 @@ class WCML_Bookings {
|
|
76 |
add_filter( 'woocommerce_booking_reminder_notification', [ $this, 'translate_notification' ], 9 );
|
77 |
add_filter( 'woocommerce_booking_cancelled_notification', [ $this, 'translate_notification' ], 9 );
|
78 |
|
79 |
-
add_action(
|
80 |
-
|
81 |
-
[
|
82 |
-
$this,
|
83 |
-
'wcml_price_field_after_booking_base_cost',
|
84 |
-
]
|
85 |
-
);
|
86 |
-
add_action(
|
87 |
-
'woocommerce_bookings_after_booking_block_cost',
|
88 |
-
[
|
89 |
-
$this,
|
90 |
-
'wcml_price_field_after_booking_block_cost',
|
91 |
-
]
|
92 |
-
);
|
93 |
-
add_action( 'woocommerce_bookings_after_display_cost', [ $this, 'wcml_price_field_after_display_cost' ] );
|
94 |
-
add_action(
|
95 |
-
'woocommerce_bookings_after_booking_pricing_base_cost',
|
96 |
-
[
|
97 |
-
$this,
|
98 |
-
'wcml_price_field_after_booking_pricing_base_cost',
|
99 |
-
],
|
100 |
-
10,
|
101 |
-
2
|
102 |
-
);
|
103 |
-
add_action(
|
104 |
-
'woocommerce_bookings_after_booking_pricing_cost',
|
105 |
-
[
|
106 |
-
$this,
|
107 |
-
'wcml_price_field_after_booking_pricing_cost',
|
108 |
-
],
|
109 |
-
10,
|
110 |
-
2
|
111 |
-
);
|
112 |
-
add_action( 'woocommerce_bookings_after_person_cost', [ $this, 'wcml_price_field_after_person_cost' ] );
|
113 |
-
add_action(
|
114 |
-
'woocommerce_bookings_after_person_block_cost',
|
115 |
-
[
|
116 |
-
$this,
|
117 |
-
'wcml_price_field_after_person_block_cost',
|
118 |
-
]
|
119 |
-
);
|
120 |
-
add_action(
|
121 |
-
'woocommerce_bookings_after_resource_cost',
|
122 |
-
[
|
123 |
-
$this,
|
124 |
-
'wcml_price_field_after_resource_cost',
|
125 |
-
],
|
126 |
-
10,
|
127 |
-
2
|
128 |
-
);
|
129 |
-
add_action(
|
130 |
-
'woocommerce_bookings_after_resource_block_cost',
|
131 |
-
[
|
132 |
-
$this,
|
133 |
-
'wcml_price_field_after_resource_block_cost',
|
134 |
-
],
|
135 |
-
10,
|
136 |
-
2
|
137 |
-
);
|
138 |
-
add_action( 'woocommerce_bookings_after_bookings_pricing', [ $this, 'after_bookings_pricing' ] );
|
139 |
-
|
140 |
-
add_action( 'init', [ $this, 'load_assets' ] );
|
141 |
-
|
142 |
-
add_action( 'save_post', [ $this, 'save_booking_action_handler' ], 110 );
|
143 |
|
144 |
add_action( 'wcml_before_sync_product_data', [ $this, 'sync_bookings' ], 10, 3 );
|
145 |
add_action( 'wcml_before_sync_product', [ $this, 'sync_booking_data' ], 10, 2 );
|
146 |
|
147 |
-
add_filter(
|
148 |
-
'woocommerce_bookings_process_cost_rules_cost',
|
149 |
-
[
|
150 |
-
$this,
|
151 |
-
'wc_bookings_process_cost_rules_cost',
|
152 |
-
],
|
153 |
-
10,
|
154 |
-
3
|
155 |
-
);
|
156 |
-
add_filter(
|
157 |
-
'woocommerce_bookings_process_cost_rules_base_cost',
|
158 |
-
[
|
159 |
-
$this,
|
160 |
-
'wc_bookings_process_cost_rules_base_cost',
|
161 |
-
],
|
162 |
-
10,
|
163 |
-
3
|
164 |
-
);
|
165 |
-
add_filter(
|
166 |
-
'woocommerce_bookings_process_cost_rules_override_block',
|
167 |
-
[
|
168 |
-
$this,
|
169 |
-
'wc_bookings_process_cost_rules_override_block_cost',
|
170 |
-
],
|
171 |
-
10,
|
172 |
-
3
|
173 |
-
);
|
174 |
-
|
175 |
-
add_filter( 'wcml_multi_currency_ajax_actions', [ $this, 'wcml_multi_currency_is_ajax' ] );
|
176 |
-
|
177 |
add_filter(
|
178 |
'wcml_cart_contents_not_changed',
|
179 |
[
|
@@ -184,22 +95,9 @@ class WCML_Bookings {
|
|
184 |
3
|
185 |
);
|
186 |
|
187 |
-
add_action( '
|
188 |
-
add_action( 'init', [ $this, 'set_booking_currency' ] );
|
189 |
|
190 |
-
add_action( 'wp_ajax_wcml_booking_set_currency', [ $this, 'set_booking_currency_ajax' ] );
|
191 |
-
add_action(
|
192 |
-
'woocommerce_bookings_create_booking_page_add_order_item',
|
193 |
-
[
|
194 |
-
$this,
|
195 |
-
'set_order_currency_on_create_booking_page',
|
196 |
-
]
|
197 |
-
);
|
198 |
-
add_filter( 'woocommerce_currency_symbol', [ $this, 'filter_booking_currency_symbol' ] );
|
199 |
add_filter( 'get_booking_products_args', [ $this, 'filter_get_booking_products_args' ] );
|
200 |
-
add_filter( 'wcml_filter_currency_position', [ $this, 'create_booking_page_client_currency' ] );
|
201 |
-
|
202 |
-
add_filter( 'wcml_client_currency', [ $this, 'create_booking_page_client_currency' ] );
|
203 |
|
204 |
add_action( 'wcml_gui_additional_box_html', [ $this, 'custom_box_html' ], 10, 3 );
|
205 |
add_filter( 'wcml_gui_additional_box_data', [ $this, 'custom_box_html_data' ], 10, 4 );
|
@@ -236,6 +134,7 @@ class WCML_Bookings {
|
|
236 |
add_action( 'before_delete_post', [ $this, 'delete_bookings' ] );
|
237 |
add_action( 'wp_trash_post', [ $this, 'trash_bookings' ] );
|
238 |
add_action( 'wpml_translation_job_saved', [ $this, 'save_booking_data_to_translation' ], 10, 3 );
|
|
|
239 |
|
240 |
if ( is_admin() ) {
|
241 |
|
@@ -302,14 +201,8 @@ class WCML_Bookings {
|
|
302 |
}
|
303 |
}
|
304 |
|
305 |
-
if ( ! is_admin() || isset( $_POST['action'] ) && 'wc_bookings_calculate_costs' === $_POST['action'] ) {
|
306 |
-
add_filter( 'get_post_metadata', [ $this, 'filter_wc_booking_cost' ], 10, 4 );
|
307 |
-
}
|
308 |
-
|
309 |
add_filter( 'wpml_language_filter_extra_conditions_snippet', [ $this, 'extra_conditions_to_filter_bookings' ] );
|
310 |
|
311 |
-
$this->clear_transient_fields();
|
312 |
-
|
313 |
add_filter( 'wpml_tm_dashboard_translatable_types', [ $this, 'hide_bookings_type_on_tm_dashboard' ] );
|
314 |
|
315 |
add_filter( 'wcml_add_to_cart_sold_individually', [ $this, 'add_to_cart_sold_individually' ], 10, 4 );
|
@@ -370,296 +263,9 @@ class WCML_Bookings {
|
|
370 |
|
371 |
$this->maybe_set_booking_language( $booking_id );
|
372 |
|
373 |
-
$this->save_custom_costs( $booking_id );
|
374 |
-
|
375 |
$this->maybe_sync_updated_booking_meta( $booking_id );
|
376 |
}
|
377 |
|
378 |
-
public function wcml_price_field_after_booking_base_cost( $post_id ) {
|
379 |
-
|
380 |
-
$this->echo_wcml_price_field( $post_id, 'wcml_wc_booking_cost' );
|
381 |
-
|
382 |
-
}
|
383 |
-
|
384 |
-
public function wcml_price_field_after_booking_block_cost( $post_id ) {
|
385 |
-
if ( $this->sitepress->get_wp_api()->version_compare( $this->sitepress->get_wp_api()->constant( 'WC_BOOKINGS_VERSION' ), '1.10.9', '<' ) ) {
|
386 |
-
$this->echo_wcml_price_field( $post_id, 'wcml_wc_booking_base_cost' );
|
387 |
-
} else {
|
388 |
-
$this->echo_wcml_price_field( $post_id, 'wcml_wc_booking_block_cost' );
|
389 |
-
}
|
390 |
-
}
|
391 |
-
|
392 |
-
public function wcml_price_field_after_display_cost( $post_id ) {
|
393 |
-
|
394 |
-
$this->echo_wcml_price_field( $post_id, 'wcml_wc_display_cost' );
|
395 |
-
|
396 |
-
}
|
397 |
-
|
398 |
-
public function wcml_price_field_after_booking_pricing_base_cost( $pricing, $post_id ) {
|
399 |
-
|
400 |
-
$this->echo_wcml_price_field( $post_id, 'wcml_wc_booking_pricing_base_cost', $pricing );
|
401 |
-
|
402 |
-
}
|
403 |
-
|
404 |
-
public function wcml_price_field_after_booking_pricing_cost( $pricing, $post_id ) {
|
405 |
-
|
406 |
-
$this->echo_wcml_price_field( $post_id, 'wcml_wc_booking_pricing_cost', $pricing );
|
407 |
-
|
408 |
-
}
|
409 |
-
|
410 |
-
public function wcml_price_field_after_person_cost( $person_type_id ) {
|
411 |
-
|
412 |
-
$this->echo_wcml_price_field( $person_type_id, 'wcml_wc_booking_person_cost', false, false );
|
413 |
-
|
414 |
-
}
|
415 |
-
|
416 |
-
public function wcml_price_field_after_person_block_cost( $person_type_id ) {
|
417 |
-
|
418 |
-
$this->echo_wcml_price_field( $person_type_id, 'wcml_wc_booking_person_block_cost', false, false );
|
419 |
-
|
420 |
-
}
|
421 |
-
|
422 |
-
public function wcml_price_field_after_resource_cost( $resource_id, $post_id ) {
|
423 |
-
|
424 |
-
$this->echo_wcml_price_field( $post_id, 'wcml_wc_booking_resource_cost', false, true, $resource_id );
|
425 |
-
|
426 |
-
}
|
427 |
-
|
428 |
-
public function wcml_price_field_after_resource_block_cost( $resource_id, $post_id ) {
|
429 |
-
|
430 |
-
$this->echo_wcml_price_field( $post_id, 'wcml_wc_booking_resource_block_cost', false, true, $resource_id );
|
431 |
-
|
432 |
-
}
|
433 |
-
|
434 |
-
public function echo_wcml_price_field( $post_id, $field, $pricing = false, $check = true, $resource_id = false ) {
|
435 |
-
|
436 |
-
if ( ( ! $check || $this->woocommerce_wpml->products->is_original_product( $post_id ) ) && $this->woocommerce_wpml->settings['enable_multi_currency'] == WCML_MULTI_CURRENCIES_INDEPENDENT ) {
|
437 |
-
|
438 |
-
$currencies = $this->woocommerce_wpml->multi_currency->get_currencies();
|
439 |
-
|
440 |
-
$wc_currencies = get_woocommerce_currencies();
|
441 |
-
|
442 |
-
if ( ! function_exists( 'woocommerce_wp_text_input' ) ) {
|
443 |
-
include_once dirname( WC_PLUGIN_FILE ) . '/includes/admin/wc-meta-box-functions.php';
|
444 |
-
}
|
445 |
-
|
446 |
-
echo '<div class="wcml_custom_cost_field" >';
|
447 |
-
|
448 |
-
foreach ( $currencies as $currency_code => $currency ) {
|
449 |
-
|
450 |
-
switch ( $field ) {
|
451 |
-
case 'wcml_wc_booking_cost':
|
452 |
-
woocommerce_wp_text_input(
|
453 |
-
[
|
454 |
-
'id' => 'wcml_wc_booking_cost',
|
455 |
-
'class' => 'wcml_bookings_custom_price',
|
456 |
-
'name' => 'wcml_wc_booking_cost[' . $currency_code . ']',
|
457 |
-
'label' => get_woocommerce_currency_symbol( $currency_code ),
|
458 |
-
'description' => __( 'One-off cost for the booking as a whole.', 'woocommerce-bookings' ),
|
459 |
-
'value' => get_post_meta( $post_id, '_wc_booking_cost_' . $currency_code, true ),
|
460 |
-
'type' => 'number',
|
461 |
-
'desc_tip' => true,
|
462 |
-
'custom_attributes' => [
|
463 |
-
'min' => '',
|
464 |
-
'step' => '0.01',
|
465 |
-
],
|
466 |
-
]
|
467 |
-
);
|
468 |
-
break;
|
469 |
-
case 'wcml_wc_booking_block_cost':
|
470 |
-
case 'wcml_wc_booking_base_cost':
|
471 |
-
$block_cost_key = '_wc_booking_base_cost_';
|
472 |
-
if ( $field === 'wcml_wc_booking_block_cost' ) {
|
473 |
-
$block_cost_key = '_wc_booking_block_cost_';
|
474 |
-
}
|
475 |
-
$block_cost_key .= $currency_code;
|
476 |
-
woocommerce_wp_text_input(
|
477 |
-
[
|
478 |
-
'id' => $field,
|
479 |
-
'class' => 'wcml_bookings_custom_price',
|
480 |
-
'name' => $field . '[' . $currency_code . ']',
|
481 |
-
'label' => get_woocommerce_currency_symbol( $currency_code ),
|
482 |
-
'description' => __( 'This is the cost per block booked. All other costs (for resources and persons) are added to this.', 'woocommerce-bookings' ),
|
483 |
-
'value' => get_post_meta( $post_id, $block_cost_key, true ),
|
484 |
-
'type' => 'number',
|
485 |
-
'desc_tip' => true,
|
486 |
-
'custom_attributes' => [
|
487 |
-
'min' => '',
|
488 |
-
'step' => '0.01',
|
489 |
-
],
|
490 |
-
]
|
491 |
-
);
|
492 |
-
break;
|
493 |
-
case 'wcml_wc_display_cost':
|
494 |
-
woocommerce_wp_text_input(
|
495 |
-
[
|
496 |
-
'id' => 'wcml_wc_display_cost',
|
497 |
-
'class' => 'wcml_bookings_custom_price',
|
498 |
-
'name' => 'wcml_wc_display_cost[' . $currency_code . ']',
|
499 |
-
'label' => get_woocommerce_currency_symbol( $currency_code ),
|
500 |
-
'description' => __( 'The cost is displayed to the user on the frontend. Leave blank to have it calculated for you. If a booking has varying costs, this will be prefixed with the word "from:".', 'woocommerce-bookings' ),
|
501 |
-
'value' => get_post_meta( $post_id, '_wc_display_cost_' . $currency_code, true ),
|
502 |
-
'type' => 'number',
|
503 |
-
'desc_tip' => true,
|
504 |
-
'custom_attributes' => [
|
505 |
-
'min' => '',
|
506 |
-
'step' => '0.01',
|
507 |
-
],
|
508 |
-
]
|
509 |
-
);
|
510 |
-
break;
|
511 |
-
|
512 |
-
case 'wcml_wc_booking_pricing_base_cost':
|
513 |
-
if ( isset( $pricing[ 'base_cost_' . $currency_code ] ) ) {
|
514 |
-
$value = $pricing[ 'base_cost_' . $currency_code ];
|
515 |
-
} else {
|
516 |
-
$value = '';
|
517 |
-
}
|
518 |
-
|
519 |
-
echo '<div class="wcml_bookings_range_block" >';
|
520 |
-
echo '<label>' . wp_kses_post( get_woocommerce_currency_symbol( $currency_code ) ) . '</label>';
|
521 |
-
echo '<input type="number" step="0.01" name="wcml_wc_booking_pricing_base_cost[' . esc_html( $currency_code ) . '][]" class="wcml_bookings_custom_price" value="' . esc_html( $value ) . '" placeholder="0" />';
|
522 |
-
echo '</div>';
|
523 |
-
break;
|
524 |
-
|
525 |
-
case 'wcml_wc_booking_pricing_cost':
|
526 |
-
if ( isset( $pricing[ 'cost_' . $currency_code ] ) ) {
|
527 |
-
$value = $pricing[ 'cost_' . $currency_code ];
|
528 |
-
} else {
|
529 |
-
$value = '';
|
530 |
-
}
|
531 |
-
|
532 |
-
echo '<div class="wcml_bookings_range_block" >';
|
533 |
-
echo '<label>' . wp_kses_post( get_woocommerce_currency_symbol( $currency_code ) ) . '</label>';
|
534 |
-
echo '<input type="number" step="0.01" name="wcml_wc_booking_pricing_cost[' . esc_html( $currency_code ) . '][]" class="wcml_bookings_custom_price" value="' . esc_html( $value ) . '" placeholder="0" />';
|
535 |
-
echo '</div>';
|
536 |
-
break;
|
537 |
-
|
538 |
-
case 'wcml_wc_booking_person_cost':
|
539 |
-
$value = get_post_meta( $post_id, 'cost_' . $currency_code, true );
|
540 |
-
|
541 |
-
echo '<div class="wcml_bookings_person_block" >';
|
542 |
-
echo '<label>' . wp_kses_post( get_woocommerce_currency_symbol( $currency_code ) ) . '</label>';
|
543 |
-
echo '<input type="number" step="0.01" name="wcml_wc_booking_person_cost[' . intval( $post_id ) . '][' . esc_html( $currency_code ) . ']" class="wcml_bookings_custom_price" value="' . esc_html( $value ) . '" placeholder="0" />';
|
544 |
-
echo '</div>';
|
545 |
-
break;
|
546 |
-
|
547 |
-
case 'wcml_wc_booking_person_block_cost':
|
548 |
-
$value = get_post_meta( $post_id, 'block_cost_' . $currency_code, true );
|
549 |
-
|
550 |
-
echo '<div class="wcml_bookings_person_block" >';
|
551 |
-
echo '<label>' . wp_kses_post( get_woocommerce_currency_symbol( $currency_code ) ) . '</label>';
|
552 |
-
echo '<input type="number" step="0.01" name="wcml_wc_booking_person_block_cost[' . intval( $post_id ) . '][' . esc_html( $currency_code ) . ']" class="wcml_bookings_custom_price" value="' . esc_html( $value ) . '" placeholder="0" />';
|
553 |
-
echo '</div>';
|
554 |
-
break;
|
555 |
-
|
556 |
-
case 'wcml_wc_booking_resource_cost':
|
557 |
-
$resource_base_costs = maybe_unserialize( get_post_meta( $post_id, '_resource_base_costs', true ) );
|
558 |
-
|
559 |
-
if ( isset( $resource_base_costs['custom_costs'][ $currency_code ][ $resource_id ] ) ) {
|
560 |
-
$value = $resource_base_costs['custom_costs'][ $currency_code ][ $resource_id ];
|
561 |
-
} else {
|
562 |
-
$value = '';
|
563 |
-
}
|
564 |
-
|
565 |
-
echo '<div class="wcml_bookings_resource_block" >';
|
566 |
-
echo '<label>' . wp_kses_post( get_woocommerce_currency_symbol( $currency_code ) ) . '</label>';
|
567 |
-
echo '<input type="number" step="0.01" name="wcml_wc_booking_resource_cost[' . esc_html( $resource_id ) . '][' . esc_html( $currency_code ) . ']" class="wcml_bookings_custom_price" value="' . esc_html( $value ) . '" placeholder="0" />';
|
568 |
-
echo '</div>';
|
569 |
-
break;
|
570 |
-
|
571 |
-
case 'wcml_wc_booking_resource_block_cost':
|
572 |
-
$resource_block_costs = maybe_unserialize( get_post_meta( $post_id, '_resource_block_costs', true ) );
|
573 |
-
|
574 |
-
if ( isset( $resource_block_costs['custom_costs'][ $currency_code ][ $resource_id ] ) ) {
|
575 |
-
$value = $resource_block_costs['custom_costs'][ $currency_code ][ $resource_id ];
|
576 |
-
} else {
|
577 |
-
$value = '';
|
578 |
-
}
|
579 |
-
|
580 |
-
echo '<div class="wcml_bookings_resource_block" >';
|
581 |
-
echo '<label>' . wp_kses_post( get_woocommerce_currency_symbol( $currency_code ) ) . '</label>';
|
582 |
-
echo '<input type="number" step="0.01" name="wcml_wc_booking_resource_block_cost[' . esc_html( $resource_id ) . '][' . esc_html( $currency_code ) . ']" class="wcml_bookings_custom_price" value="' . esc_html( $value ) . '" placeholder="0" />';
|
583 |
-
echo '</div>';
|
584 |
-
break;
|
585 |
-
|
586 |
-
default:
|
587 |
-
break;
|
588 |
-
|
589 |
-
}
|
590 |
-
}
|
591 |
-
|
592 |
-
echo '</div>';
|
593 |
-
|
594 |
-
}
|
595 |
-
}
|
596 |
-
|
597 |
-
public function after_bookings_pricing( $post_id ) {
|
598 |
-
|
599 |
-
if ( in_array( 'booking', wp_get_post_terms( $post_id, 'product_type', [ 'fields' => 'names' ] ) ) && $this->woocommerce_wpml->products->is_original_product( $post_id ) && $this->woocommerce_wpml->settings['enable_multi_currency'] == WCML_MULTI_CURRENCIES_INDEPENDENT ) {
|
600 |
-
|
601 |
-
$custom_costs_status = get_post_meta( $post_id, '_wcml_custom_costs_status', true );
|
602 |
-
|
603 |
-
$checked = ! $custom_costs_status ? 'checked="checked"' : ' ';
|
604 |
-
|
605 |
-
echo '<div class="wcml_custom_costs">';
|
606 |
-
|
607 |
-
echo '<input type="radio" name="_wcml_custom_costs" id="wcml_custom_costs_auto" value="0" class="wcml_custom_costs_input" ' . esc_html( $checked ) . ' />';
|
608 |
-
echo '<label for="wcml_custom_costs_auto">' . esc_html__( 'Calculate costs in other currencies automatically', 'woocommerce-multilingual' ) . '</label>';
|
609 |
-
|
610 |
-
$checked = 1 === (int) $custom_costs_status ? 'checked="checked"' : ' ';
|
611 |
-
|
612 |
-
echo '<input type="radio" name="_wcml_custom_costs" value="1" id="wcml_custom_costs_manually" class="wcml_custom_costs_input" ' . esc_html( $checked ) . ' />';
|
613 |
-
echo '<label for="wcml_custom_costs_manually">' . esc_html__( 'Set costs in other currencies manually', 'woocommerce-multilingual' ) . '</label>';
|
614 |
-
|
615 |
-
wp_nonce_field( 'wcml_save_custom_costs', '_wcml_custom_costs_nonce' );
|
616 |
-
|
617 |
-
echo '</div>';
|
618 |
-
}
|
619 |
-
|
620 |
-
}
|
621 |
-
|
622 |
-
public function save_custom_costs( $post_id ) {
|
623 |
-
$nonce = filter_var( isset( $_POST['_wcml_custom_costs_nonce'] ) ? $_POST['_wcml_custom_costs_nonce'] : '', FILTER_SANITIZE_FULL_SPECIAL_CHARS );
|
624 |
-
|
625 |
-
if ( isset( $_POST['_wcml_custom_costs'] ) && isset( $nonce ) && wp_verify_nonce( $nonce, 'wcml_save_custom_costs' ) ) {
|
626 |
-
|
627 |
-
update_post_meta( $post_id, '_wcml_custom_costs_status', $_POST['_wcml_custom_costs'] );
|
628 |
-
|
629 |
-
if ( 1 === (int) $_POST['_wcml_custom_costs'] ) {
|
630 |
-
|
631 |
-
$currencies = $this->woocommerce_wpml->multi_currency->get_currencies();
|
632 |
-
if ( empty( $currencies ) || 0 === $post_id ) {
|
633 |
-
return false;
|
634 |
-
}
|
635 |
-
|
636 |
-
$this->update_booking_costs( $currencies, $post_id );
|
637 |
-
$this->update_booking_pricing( $currencies, $post_id );
|
638 |
-
|
639 |
-
if ( isset( $_POST['wcml_wc_booking_person_cost'] ) && is_array( $_POST['wcml_wc_booking_person_cost'] ) ) {
|
640 |
-
$this->update_booking_person_cost( $currencies, $_POST['wcml_wc_booking_person_cost'] );
|
641 |
-
}
|
642 |
-
|
643 |
-
if ( isset( $_POST['wcml_wc_booking_person_block_cost'] ) && is_array( $_POST['wcml_wc_booking_person_block_cost'] ) ) {
|
644 |
-
$this->update_booking_person_block_cost( $currencies, $_POST['wcml_wc_booking_person_block_cost'] );
|
645 |
-
}
|
646 |
-
|
647 |
-
if ( isset( $_POST['wcml_wc_booking_resource_cost'] ) && is_array( $_POST['wcml_wc_booking_resource_cost'] ) ) {
|
648 |
-
$this->update_booking_resource_cost( $currencies, $post_id, $_POST['wcml_wc_booking_resource_cost'] );
|
649 |
-
}
|
650 |
-
|
651 |
-
if ( isset( $_POST['wcml_wc_booking_resource_block_cost'] ) && is_array( $_POST['wcml_wc_booking_resource_block_cost'] ) ) {
|
652 |
-
$this->update_booking_resource_block_cost( $currencies, $post_id, $_POST['wcml_wc_booking_resource_block_cost'] );
|
653 |
-
}
|
654 |
-
|
655 |
-
update_post_meta( $post_id, '_price', '' );
|
656 |
-
} else {
|
657 |
-
return false;
|
658 |
-
}
|
659 |
-
}
|
660 |
-
|
661 |
-
}
|
662 |
-
|
663 |
// sync existing product bookings for translations.
|
664 |
public function sync_bookings( $original_product_id, $product_id, $language ) {
|
665 |
$all_bookings_for_product = $this->wpdb->get_results( $this->wpdb->prepare( "SELECT post_id as id FROM {$this->wpdb->postmeta} WHERE meta_key = '_booking_product_id' AND meta_value = %d", $original_product_id ) );
|
@@ -915,142 +521,6 @@ class WCML_Bookings {
|
|
915 |
return $new_person_id;
|
916 |
}
|
917 |
|
918 |
-
public function filter_wc_booking_cost( $check, $object_id, $meta_key, $single ) {
|
919 |
-
|
920 |
-
if ( in_array(
|
921 |
-
$meta_key,
|
922 |
-
[
|
923 |
-
'_wc_booking_cost',
|
924 |
-
'_wc_booking_base_cost',
|
925 |
-
'_wc_display_cost',
|
926 |
-
'_wc_booking_pricing',
|
927 |
-
'cost',
|
928 |
-
'_wc_booking_block_cost',
|
929 |
-
'block_cost',
|
930 |
-
'_resource_base_costs',
|
931 |
-
'_resource_block_costs',
|
932 |
-
]
|
933 |
-
) ) {
|
934 |
-
|
935 |
-
if ( WCML_MULTI_CURRENCIES_INDEPENDENT === $this->woocommerce_wpml->settings['enable_multi_currency'] ) {
|
936 |
-
|
937 |
-
$original_id = $this->woocommerce_wpml->products->get_original_product_id( $object_id );
|
938 |
-
|
939 |
-
$cost_status = get_post_meta( $original_id, '_wcml_custom_costs_status', true );
|
940 |
-
|
941 |
-
$currency = $this->woocommerce_wpml->multi_currency->get_client_currency();
|
942 |
-
|
943 |
-
if ( $currency === wcml_get_woocommerce_currency_option() ) {
|
944 |
-
return $check;
|
945 |
-
}
|
946 |
-
|
947 |
-
if ( in_array( $meta_key, [ 'cost', 'block_cost' ] ) ) {
|
948 |
-
|
949 |
-
if ( get_post_type( $object_id ) == 'bookable_person' ) {
|
950 |
-
|
951 |
-
$original_id = apply_filters( 'translate_object_id', wp_get_post_parent_id( $object_id ), 'product', true, $this->woocommerce_wpml->products->get_original_product_language( wp_get_post_parent_id( $object_id ) ) );
|
952 |
-
$cost_status = get_post_meta( $original_id, '_wcml_custom_costs_status', true );
|
953 |
-
|
954 |
-
$value = get_post_meta( $object_id, $meta_key . '_' . $currency, true );
|
955 |
-
|
956 |
-
if ( $cost_status && $value ) {
|
957 |
-
|
958 |
-
return $value;
|
959 |
-
|
960 |
-
} else {
|
961 |
-
|
962 |
-
remove_filter( 'get_post_metadata', [ $this, 'filter_wc_booking_cost' ], 10 );
|
963 |
-
|
964 |
-
$cost = get_post_meta( $object_id, $meta_key, true );
|
965 |
-
|
966 |
-
add_filter( 'get_post_metadata', [ $this, 'filter_wc_booking_cost' ], 10, 4 );
|
967 |
-
|
968 |
-
return $this->woocommerce_wpml->multi_currency->prices->convert_price_amount( $cost, $currency );
|
969 |
-
}
|
970 |
-
} else {
|
971 |
-
|
972 |
-
return $check;
|
973 |
-
|
974 |
-
}
|
975 |
-
}
|
976 |
-
|
977 |
-
if ( in_array(
|
978 |
-
$meta_key,
|
979 |
-
[
|
980 |
-
'_wc_booking_pricing',
|
981 |
-
'_resource_base_costs',
|
982 |
-
'_resource_block_costs',
|
983 |
-
]
|
984 |
-
) ) {
|
985 |
-
|
986 |
-
remove_filter( 'get_post_metadata', [ $this, 'filter_wc_booking_cost' ], 10 );
|
987 |
-
|
988 |
-
if ( $meta_key == '_wc_booking_pricing' ) {
|
989 |
-
|
990 |
-
if ( $original_id != $object_id ) {
|
991 |
-
$value = get_post_meta( $original_id, $meta_key );
|
992 |
-
} else {
|
993 |
-
$value = $check;
|
994 |
-
}
|
995 |
-
} else {
|
996 |
-
|
997 |
-
$costs = maybe_unserialize( get_post_meta( $object_id, $meta_key, true ) );
|
998 |
-
|
999 |
-
if ( ! $costs ) {
|
1000 |
-
$value = $check;
|
1001 |
-
} elseif ( $cost_status && isset( $costs['custom_costs'][ $currency ] ) ) {
|
1002 |
-
|
1003 |
-
$res_costs = [];
|
1004 |
-
foreach ( $costs['custom_costs'][ $currency ] as $resource_id => $cost ) {
|
1005 |
-
$trns_resource_id = apply_filters( 'translate_object_id', $resource_id, 'bookable_resource', true, $this->sitepress->get_current_language() );
|
1006 |
-
$res_costs[ $trns_resource_id ] = $cost;
|
1007 |
-
}
|
1008 |
-
$value = [ 0 => $res_costs ];
|
1009 |
-
} elseif ( $cost_status && isset( $costs[0]['custom_costs'][ $currency ] ) ) {
|
1010 |
-
$value = [ 0 => $costs[0]['custom_costs'][ $currency ] ];
|
1011 |
-
} else {
|
1012 |
-
|
1013 |
-
$converted_values = [];
|
1014 |
-
|
1015 |
-
foreach ( $costs as $resource_id => $cost ) {
|
1016 |
-
$converted_values[0][ $resource_id ] = $this->woocommerce_wpml->multi_currency->prices->convert_price_amount( $cost, $currency );
|
1017 |
-
}
|
1018 |
-
|
1019 |
-
$value = $converted_values;
|
1020 |
-
}
|
1021 |
-
}
|
1022 |
-
|
1023 |
-
add_filter( 'get_post_metadata', [ $this, 'filter_wc_booking_cost' ], 10, 4 );
|
1024 |
-
|
1025 |
-
return $value;
|
1026 |
-
|
1027 |
-
}
|
1028 |
-
|
1029 |
-
$value = get_post_meta( $original_id, $meta_key . '_' . $currency, true );
|
1030 |
-
|
1031 |
-
if ( $cost_status && ( ! empty( $value ) || ( empty( $value ) && $meta_key == '_wc_display_cost' ) ) ) {
|
1032 |
-
|
1033 |
-
return $value;
|
1034 |
-
|
1035 |
-
} else {
|
1036 |
-
|
1037 |
-
remove_filter( 'get_post_metadata', [ $this, 'filter_wc_booking_cost' ], 10 );
|
1038 |
-
|
1039 |
-
$value = get_post_meta( $original_id, $meta_key, true );
|
1040 |
-
|
1041 |
-
$value = $this->woocommerce_wpml->multi_currency->prices->convert_price_amount( $value, $currency );
|
1042 |
-
|
1043 |
-
add_filter( 'get_post_metadata', [ $this, 'filter_wc_booking_cost' ], 10, 4 );
|
1044 |
-
|
1045 |
-
return $value;
|
1046 |
-
|
1047 |
-
}
|
1048 |
-
}
|
1049 |
-
}
|
1050 |
-
|
1051 |
-
return $check;
|
1052 |
-
}
|
1053 |
-
|
1054 |
public function sync_resource_costs_with_translations( $object_id, $meta_key, $check = false ) {
|
1055 |
|
1056 |
$original_product_id = $this->woocommerce_wpml->products->get_original_product_id( $object_id );
|
@@ -1115,112 +585,10 @@ class WCML_Bookings {
|
|
1115 |
|
1116 |
}
|
1117 |
|
1118 |
-
public function wc_bookings_process_cost_rules_cost( $cost, $fields, $key ) {
|
1119 |
-
return $this->filter_pricing_cost( $cost, $fields, 'cost_', $key );
|
1120 |
-
}
|
1121 |
-
|
1122 |
-
public function wc_bookings_process_cost_rules_base_cost( $base_cost, $fields, $key ) {
|
1123 |
-
return $this->filter_pricing_cost( $base_cost, $fields, 'base_cost_', $key );
|
1124 |
-
}
|
1125 |
-
|
1126 |
-
public function wc_bookings_process_cost_rules_override_block_cost( $override_cost, $fields, $key ) {
|
1127 |
-
return $this->filter_pricing_cost( $override_cost, $fields, 'override_block_', $key );
|
1128 |
-
}
|
1129 |
-
|
1130 |
-
public function filter_pricing_cost( $cost, $fields, $name, $key ) {
|
1131 |
-
global $product;
|
1132 |
-
|
1133 |
-
if ( $this->woocommerce_wpml->settings['enable_multi_currency'] == WCML_MULTI_CURRENCIES_INDEPENDENT ) {
|
1134 |
-
|
1135 |
-
$currency = $this->woocommerce_wpml->multi_currency->get_client_currency();
|
1136 |
-
|
1137 |
-
if ( $currency === wcml_get_woocommerce_currency_option() ) {
|
1138 |
-
return $cost;
|
1139 |
-
}
|
1140 |
-
|
1141 |
-
if ( isset( $_POST['form'] ) ) {
|
1142 |
-
parse_str( $_POST['form'], $posted );
|
1143 |
-
|
1144 |
-
$booking_id = $posted['add-to-cart'];
|
1145 |
-
|
1146 |
-
} elseif ( isset( $_POST['add-to-cart'] ) ) {
|
1147 |
-
|
1148 |
-
$booking_id = $_POST['add-to-cart'];
|
1149 |
-
|
1150 |
-
}
|
1151 |
-
|
1152 |
-
if ( isset( $booking_id ) ) {
|
1153 |
-
$original_id = $this->woocommerce_wpml->products->get_original_product_id( $booking_id );
|
1154 |
-
|
1155 |
-
if ( $booking_id != $original_id ) {
|
1156 |
-
$fields = maybe_unserialize( get_post_meta( $original_id, '_wc_booking_pricing', true ) );
|
1157 |
-
$fields = $fields[ $key ];
|
1158 |
-
}
|
1159 |
-
}
|
1160 |
-
|
1161 |
-
$needs_filter_pricing_cost = $this->needs_filter_pricing_cost( $name, $fields );
|
1162 |
-
|
1163 |
-
if ( $needs_filter_pricing_cost ) {
|
1164 |
-
if ( isset( $fields[ $name . $currency ] ) ) {
|
1165 |
-
return $fields[ $name . $currency ];
|
1166 |
-
} else {
|
1167 |
-
return $this->woocommerce_wpml->multi_currency->prices->convert_price_amount( $cost, $currency );
|
1168 |
-
}
|
1169 |
-
}
|
1170 |
-
}
|
1171 |
-
|
1172 |
-
return $cost;
|
1173 |
-
|
1174 |
-
}
|
1175 |
-
|
1176 |
-
public function needs_filter_pricing_cost( $name, $fields ) {
|
1177 |
-
|
1178 |
-
$modifier_skip_values = [ 'divide', 'times' ];
|
1179 |
-
|
1180 |
-
if (
|
1181 |
-
'override_block_' === $name ||
|
1182 |
-
( 'cost_' === $name && ! in_array( $fields['modifier'], $modifier_skip_values ) ) ||
|
1183 |
-
( 'base_cost_' === $name && ! in_array( $fields['base_modifier'], $modifier_skip_values ) )
|
1184 |
-
) {
|
1185 |
-
return true;
|
1186 |
-
} else {
|
1187 |
-
return false;
|
1188 |
-
}
|
1189 |
-
}
|
1190 |
-
|
1191 |
-
public function load_assets( $external_product_type = false ) {
|
1192 |
-
global $pagenow;
|
1193 |
-
|
1194 |
-
$product_id = $pagenow == 'post.php' && isset( $_GET['post'] ) ? (int) $_GET['post'] : false;
|
1195 |
-
|
1196 |
-
if ( $product_id && get_post_type( $product_id ) === 'product' ) {
|
1197 |
-
$product = wc_get_product( $product_id );
|
1198 |
-
$product_type = $product->get_type();
|
1199 |
-
|
1200 |
-
if ( ( $this->is_booking( $product ) || $product_type === $external_product_type ) || $pagenow == 'post-new.php' ) {
|
1201 |
-
|
1202 |
-
wp_register_style( 'wcml-bookings-css', WCML_PLUGIN_URL . '/compatibility/res/css/wcml-bookings.css', [], WCML_VERSION );
|
1203 |
-
wp_enqueue_style( 'wcml-bookings-css' );
|
1204 |
-
|
1205 |
-
wp_register_script( 'wcml-bookings-js', WCML_PLUGIN_URL . '/compatibility/res/js/wcml-bookings.js', [ 'jquery' ], WCML_VERSION, true );
|
1206 |
-
wp_enqueue_script( 'wcml-bookings-js' );
|
1207 |
-
|
1208 |
-
}
|
1209 |
-
}
|
1210 |
-
|
1211 |
-
}
|
1212 |
-
|
1213 |
public function localize_lock_fields_js() {
|
1214 |
wp_localize_script( 'wcml-bookings-js', 'lock_settings', [ 'lock_fields' => 1 ] );
|
1215 |
}
|
1216 |
|
1217 |
-
public function wcml_multi_currency_is_ajax( $actions ) {
|
1218 |
-
|
1219 |
-
$actions[] = 'wc_bookings_calculate_costs';
|
1220 |
-
|
1221 |
-
return $actions;
|
1222 |
-
}
|
1223 |
-
|
1224 |
public function filter_bundled_product_in_cart_contents( $cart_item, $key, $current_language ) {
|
1225 |
|
1226 |
if ( $cart_item['data'] instanceof WC_Product_Booking && isset( $cart_item['booking'] ) ) {
|
@@ -1285,132 +653,9 @@ class WCML_Bookings {
|
|
1285 |
return $cost;
|
1286 |
}
|
1287 |
|
1288 |
-
|
1289 |
-
|
1290 |
-
|
1291 |
-
$current_booking_currency = $this->get_cookie_booking_currency();
|
1292 |
-
|
1293 |
-
$wc_currencies = get_woocommerce_currencies();
|
1294 |
-
$currencies = $this->woocommerce_wpml->multi_currency->get_currencies( $include_default = true );
|
1295 |
-
?>
|
1296 |
-
<tr valign="top">
|
1297 |
-
<th scope="row"><?php _e( 'Booking currency', 'woocommerce-multilingual' ); ?></th>
|
1298 |
-
<td>
|
1299 |
-
<select id="dropdown_booking_currency">
|
1300 |
-
<?php foreach ( $currencies as $currency => $count ) : ?>
|
1301 |
-
<option
|
1302 |
-
value="<?php echo esc_html( $currency ); ?>" <?php echo $current_booking_currency == $currency ? 'selected="selected"' : ''; ?>><?php echo esc_html( $wc_currencies[ $currency ] ); ?></option>
|
1303 |
-
<?php endforeach; ?>
|
1304 |
-
</select>
|
1305 |
-
</td>
|
1306 |
-
</tr>
|
1307 |
-
|
1308 |
-
<?php
|
1309 |
-
|
1310 |
-
$wcml_booking_set_currency_nonce = wp_create_nonce( 'booking_set_currency' );
|
1311 |
-
|
1312 |
-
wc_enqueue_js(
|
1313 |
-
"
|
1314 |
-
|
1315 |
-
jQuery(document).on('change', '#dropdown_booking_currency', function(){
|
1316 |
-
jQuery.ajax({
|
1317 |
-
url: ajaxurl,
|
1318 |
-
type: 'post',
|
1319 |
-
data: {
|
1320 |
-
action: 'wcml_booking_set_currency',
|
1321 |
-
currency: jQuery('#dropdown_booking_currency').val(),
|
1322 |
-
wcml_nonce: '" . $wcml_booking_set_currency_nonce . "'
|
1323 |
-
},
|
1324 |
-
success: function( response ){
|
1325 |
-
if(typeof response.error !== 'undefined'){
|
1326 |
-
alert(response.error);
|
1327 |
-
}else{
|
1328 |
-
window.location = window.location.href;
|
1329 |
-
}
|
1330 |
-
}
|
1331 |
-
})
|
1332 |
-
});
|
1333 |
-
"
|
1334 |
-
);
|
1335 |
-
|
1336 |
-
}
|
1337 |
-
|
1338 |
-
}
|
1339 |
-
|
1340 |
-
public function set_booking_currency_ajax() {
|
1341 |
-
|
1342 |
-
$nonce = filter_input( INPUT_POST, 'wcml_nonce', FILTER_SANITIZE_FULL_SPECIAL_CHARS );
|
1343 |
-
if ( ! $nonce || ! wp_verify_nonce( $nonce, 'booking_set_currency' ) ) {
|
1344 |
-
echo json_encode( [ 'error' => __( 'Invalid nonce', 'woocommerce-multilingual' ) ] );
|
1345 |
-
die();
|
1346 |
-
}
|
1347 |
-
|
1348 |
-
$this->set_booking_currency( filter_input( INPUT_POST, 'currency', FILTER_SANITIZE_FULL_SPECIAL_CHARS ) );
|
1349 |
-
|
1350 |
-
die();
|
1351 |
-
}
|
1352 |
-
|
1353 |
-
public function set_booking_currency( $currency_code = false ) {
|
1354 |
-
$cookie_name = '_wcml_booking_currency';
|
1355 |
-
|
1356 |
-
if ( ! isset( $_COOKIE[ $cookie_name ] ) && ! headers_sent() ) {
|
1357 |
-
$currency_code = wcml_get_woocommerce_currency_option();
|
1358 |
-
|
1359 |
-
if ( WCML_MULTI_CURRENCIES_INDEPENDENT === $this->woocommerce_wpml->settings['enable_multi_currency'] ) {
|
1360 |
-
$currency_code = $this->woocommerce_wpml->multi_currency->get_currency_code();
|
1361 |
-
}
|
1362 |
-
}
|
1363 |
-
|
1364 |
-
if ( $currency_code ) {
|
1365 |
-
// @todo uncomment or delete when #wpmlcore-5796 is resolved
|
1366 |
-
// do_action( 'wpsc_add_cookie', $cookie_name );
|
1367 |
-
setcookie( $cookie_name, $currency_code, time() + 86400, COOKIEPATH, COOKIE_DOMAIN );
|
1368 |
-
}
|
1369 |
-
}
|
1370 |
-
|
1371 |
-
public function get_cookie_booking_currency() {
|
1372 |
-
|
1373 |
-
if ( isset( $_COOKIE ['_wcml_booking_currency'] ) ) {
|
1374 |
-
$currency = $_COOKIE['_wcml_booking_currency'];
|
1375 |
-
} else {
|
1376 |
-
$currency = wcml_get_woocommerce_currency_option();
|
1377 |
-
}
|
1378 |
-
|
1379 |
-
return $currency;
|
1380 |
-
}
|
1381 |
-
|
1382 |
-
public function filter_booking_currency_symbol( $currency ) {
|
1383 |
-
global $pagenow;
|
1384 |
-
|
1385 |
-
remove_filter( 'woocommerce_currency_symbol', [ $this, 'filter_booking_currency_symbol' ] );
|
1386 |
-
if ( isset( $_COOKIE ['_wcml_booking_currency'] ) && $pagenow == 'edit.php' && isset( $_GET['page'] ) && $_GET['page'] == 'create_booking' ) {
|
1387 |
-
$currency = get_woocommerce_currency_symbol( $_COOKIE ['_wcml_booking_currency'] );
|
1388 |
-
}
|
1389 |
-
add_filter( 'woocommerce_currency_symbol', [ $this, 'filter_booking_currency_symbol' ] );
|
1390 |
-
|
1391 |
-
return $currency;
|
1392 |
-
}
|
1393 |
-
|
1394 |
-
public function create_booking_page_client_currency( $currency ) {
|
1395 |
-
global $pagenow;
|
1396 |
-
|
1397 |
-
if ( wpml_is_ajax() && isset( $_POST['form'] ) ) {
|
1398 |
-
parse_str( $_POST['form'], $posted );
|
1399 |
-
}
|
1400 |
-
|
1401 |
-
if ( ( $pagenow == 'edit.php' && isset( $_GET['page'] ) && $_GET['page'] == 'create_booking' ) || ( isset( $posted['_wp_http_referer'] ) && strpos( $posted['_wp_http_referer'], 'page=create_booking' ) !== false ) ) {
|
1402 |
-
$currency = $this->get_cookie_booking_currency();
|
1403 |
-
}
|
1404 |
-
|
1405 |
-
return $currency;
|
1406 |
-
}
|
1407 |
-
|
1408 |
-
public function set_order_currency_on_create_booking_page( $order_id ) {
|
1409 |
-
update_post_meta( $order_id, '_order_currency', $this->get_cookie_booking_currency() );
|
1410 |
-
|
1411 |
-
update_post_meta( $order_id, 'wpml_language', $this->sitepress->get_current_language() );
|
1412 |
-
|
1413 |
-
}
|
1414 |
|
1415 |
public function filter_get_booking_products_args( $args ) {
|
1416 |
if ( isset( $args['suppress_filters'] ) ) {
|
@@ -1889,22 +1134,6 @@ class WCML_Bookings {
|
|
1889 |
|
1890 |
}
|
1891 |
|
1892 |
-
public function clear_transient_fields() {
|
1893 |
-
|
1894 |
-
if ( isset( $_GET['post_type'] ) && $_GET['post_type'] == 'wc_booking' && isset( $_GET['page'] ) && $_GET['page'] == 'booking_calendar' ) {
|
1895 |
-
|
1896 |
-
// delete transient fields
|
1897 |
-
$this->wpdb->query(
|
1898 |
-
"
|
1899 |
-
DELETE FROM {$this->wpdb->options}
|
1900 |
-
WHERE option_name LIKE '%book_dr_%'
|
1901 |
-
"
|
1902 |
-
);
|
1903 |
-
|
1904 |
-
}
|
1905 |
-
|
1906 |
-
}
|
1907 |
-
|
1908 |
public function delete_bookings( $booking_id ) {
|
1909 |
|
1910 |
if (
|
@@ -1992,61 +1221,57 @@ class WCML_Bookings {
|
|
1992 |
private function save_person_translation( $post_id, $data, $job ) {
|
1993 |
$person_translations = [];
|
1994 |
|
1995 |
-
|
1996 |
|
1997 |
-
|
1998 |
|
1999 |
-
|
2000 |
|
2001 |
-
|
|
|
2002 |
|
2003 |
-
|
2004 |
-
$field = $exp[3];
|
2005 |
|
2006 |
-
|
2007 |
-
|
2008 |
-
}
|
2009 |
-
}
|
2010 |
|
2011 |
-
|
2012 |
|
2013 |
-
|
2014 |
|
2015 |
-
|
2016 |
|
2017 |
-
|
2018 |
|
2019 |
-
|
2020 |
|
2021 |
-
|
2022 |
|
2023 |
-
|
2024 |
-
|
2025 |
-
|
2026 |
-
|
2027 |
-
|
2028 |
|
2029 |
-
|
2030 |
|
2031 |
-
|
2032 |
|
2033 |
-
|
2034 |
|
2035 |
-
|
2036 |
|
2037 |
-
|
2038 |
-
|
2039 |
-
|
2040 |
-
|
2041 |
-
|
2042 |
|
2043 |
-
|
2044 |
-
|
2045 |
-
}
|
2046 |
-
}
|
2047 |
-
}
|
2048 |
-
}
|
2049 |
|
|
|
|
|
|
|
2050 |
}
|
2051 |
|
2052 |
public function append_resources_to_translation_package( $package, $post ) {
|
@@ -2076,76 +1301,72 @@ class WCML_Bookings {
|
|
2076 |
private function save_resource_translation( $post_id, $data, $job ) {
|
2077 |
$resource_translations = [];
|
2078 |
|
2079 |
-
|
2080 |
-
|
2081 |
-
foreach ( $data as $value ) {
|
2082 |
-
|
2083 |
-
if ( $value['finished'] && strpos( $value['field_type'], 'wc_bookings:resource:' ) === 0 ) {
|
2084 |
|
2085 |
-
|
2086 |
|
2087 |
-
|
2088 |
-
$field = $exp[3];
|
2089 |
|
2090 |
-
|
|
|
2091 |
|
2092 |
-
|
2093 |
-
}
|
2094 |
|
2095 |
-
|
|
|
2096 |
|
2097 |
-
|
2098 |
|
2099 |
-
|
2100 |
|
2101 |
-
|
2102 |
|
2103 |
-
|
2104 |
|
2105 |
-
|
2106 |
|
2107 |
-
|
2108 |
-
'post_status' => 'publish',
|
2109 |
-
'post_title' => $rt['name'],
|
2110 |
-
'post_parent' => $post_id,
|
2111 |
-
];
|
2112 |
|
2113 |
-
|
|
|
|
|
|
|
|
|
2114 |
|
2115 |
-
|
2116 |
|
2117 |
-
|
2118 |
-
$relationship = [
|
2119 |
-
'product_id' => $post_id,
|
2120 |
-
'resource_id' => $resource_id_translated,
|
2121 |
-
'sort_order' => $sort_order,
|
2122 |
-
];
|
2123 |
-
$this->wpdb->insert( $this->wpdb->prefix . 'wc_booking_relationships', $relationship );
|
2124 |
|
2125 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
2126 |
|
2127 |
-
|
2128 |
-
'ID' => $resource_id_translated,
|
2129 |
-
'post_title' => $rt['name'],
|
2130 |
-
];
|
2131 |
|
2132 |
-
|
|
|
|
|
|
|
2133 |
|
2134 |
-
|
2135 |
-
$this->wpdb->update(
|
2136 |
-
$this->wpdb->prefix . 'wc_booking_relationships',
|
2137 |
-
[ 'sort_order' => $sort_order ],
|
2138 |
-
[
|
2139 |
-
'product_id' => $post_id,
|
2140 |
-
'resource_id' => $resource_id_translated,
|
2141 |
-
]
|
2142 |
-
);
|
2143 |
|
2144 |
-
|
2145 |
-
|
2146 |
-
|
2147 |
-
|
|
|
|
|
|
|
|
|
|
|
2148 |
|
|
|
|
|
|
|
2149 |
}
|
2150 |
|
2151 |
public function wcml_js_lock_fields_ids( $ids ) {
|
@@ -2199,181 +1420,6 @@ class WCML_Bookings {
|
|
2199 |
|
2200 |
}
|
2201 |
|
2202 |
-
/**
|
2203 |
-
* @param array $currencies
|
2204 |
-
* @param int $post_id
|
2205 |
-
*
|
2206 |
-
* @return bool
|
2207 |
-
*/
|
2208 |
-
private function update_booking_costs( $currencies = [], $post_id = 0 ) {
|
2209 |
-
$booking_options = [
|
2210 |
-
'wcml_wc_booking_cost' => '_wc_booking_cost_',
|
2211 |
-
'wcml_wc_booking_block_cost' => '_wc_booking_block_cost_',
|
2212 |
-
'wcml_wc_display_cost' => '_wc_display_cost_',
|
2213 |
-
];
|
2214 |
-
|
2215 |
-
if ( $this->sitepress->get_wp_api()->version_compare( $this->sitepress->get_wp_api()->constant( 'WC_BOOKINGS_VERSION' ), '1.10.9', '<' ) ) {
|
2216 |
-
unset( $booking_options['wcml_wc_booking_block_cost'] );
|
2217 |
-
$booking_options['wcml_wc_booking_base_cost'] = '_wc_booking_base_cost_';
|
2218 |
-
}
|
2219 |
-
|
2220 |
-
foreach ( $currencies as $code => $currency ) {
|
2221 |
-
foreach ( $booking_options as $booking_options_post_key => $booking_options_meta_key_prefix ) {
|
2222 |
-
if ( isset( $_POST[ $booking_options_post_key ][ $code ] ) ) {
|
2223 |
-
update_post_meta( $post_id, $booking_options_meta_key_prefix . $code, sanitize_text_field( $_POST[ $booking_options_post_key ][ $code ] ) );
|
2224 |
-
}
|
2225 |
-
}
|
2226 |
-
}
|
2227 |
-
|
2228 |
-
return true;
|
2229 |
-
}
|
2230 |
-
|
2231 |
-
/**
|
2232 |
-
* @param array $currencies
|
2233 |
-
* @param int $post_id
|
2234 |
-
*
|
2235 |
-
* @return bool
|
2236 |
-
*/
|
2237 |
-
private function update_booking_pricing( $currencies = [], $post_id = 0 ) {
|
2238 |
-
$updated_meta = [];
|
2239 |
-
$booking_pricing = get_post_meta( $post_id, '_wc_booking_pricing', true );
|
2240 |
-
if ( empty( $booking_pricing ) ) {
|
2241 |
-
return false;
|
2242 |
-
}
|
2243 |
-
|
2244 |
-
foreach ( $booking_pricing as $key => $prices ) {
|
2245 |
-
$updated_meta[ $key ] = $prices;
|
2246 |
-
foreach ( $currencies as $code => $currency ) {
|
2247 |
-
if ( isset( $_POST['wcml_wc_booking_pricing_base_cost'][ $code ][ $key ] ) ) {
|
2248 |
-
$updated_meta[ $key ][ 'base_cost_' . $code ] = sanitize_text_field( $_POST['wcml_wc_booking_pricing_base_cost'][ $code ][ $key ] );
|
2249 |
-
}
|
2250 |
-
if ( isset( $_POST['wcml_wc_booking_pricing_cost'][ $code ][ $key ] ) ) {
|
2251 |
-
$updated_meta[ $key ][ 'cost_' . $code ] = sanitize_text_field( $_POST['wcml_wc_booking_pricing_cost'][ $code ][ $key ] );
|
2252 |
-
}
|
2253 |
-
}
|
2254 |
-
}
|
2255 |
-
|
2256 |
-
update_post_meta( $post_id, '_wc_booking_pricing', $updated_meta );
|
2257 |
-
|
2258 |
-
return true;
|
2259 |
-
}
|
2260 |
-
|
2261 |
-
/**
|
2262 |
-
* @param array $currencies
|
2263 |
-
* @param array $person_costs
|
2264 |
-
*
|
2265 |
-
* @return bool
|
2266 |
-
*/
|
2267 |
-
private function update_booking_person_cost( $currencies = [], $person_costs = [] ) {
|
2268 |
-
if ( empty( $person_costs ) ) {
|
2269 |
-
return false;
|
2270 |
-
}
|
2271 |
-
|
2272 |
-
foreach ( $person_costs as $person_id => $costs ) {
|
2273 |
-
foreach ( $currencies as $code => $currency ) {
|
2274 |
-
if ( isset( $costs[ $code ] ) ) {
|
2275 |
-
update_post_meta( $person_id, 'cost_' . $code, sanitize_text_field( $costs[ $code ] ) );
|
2276 |
-
}
|
2277 |
-
}
|
2278 |
-
}
|
2279 |
-
|
2280 |
-
return true;
|
2281 |
-
}
|
2282 |
-
|
2283 |
-
/**
|
2284 |
-
* @param array $currencies
|
2285 |
-
* @param array $block_costs
|
2286 |
-
*
|
2287 |
-
* @return bool
|
2288 |
-
*/
|
2289 |
-
private function update_booking_person_block_cost( $currencies = [], $block_costs = [] ) {
|
2290 |
-
if ( empty( $block_costs ) ) {
|
2291 |
-
return false;
|
2292 |
-
}
|
2293 |
-
|
2294 |
-
foreach ( $block_costs as $person_id => $costs ) {
|
2295 |
-
foreach ( $currencies as $code => $currency ) {
|
2296 |
-
if ( isset( $costs[ $code ] ) ) {
|
2297 |
-
update_post_meta( $person_id, 'block_cost_' . $code, sanitize_text_field( $costs[ $code ] ) );
|
2298 |
-
}
|
2299 |
-
}
|
2300 |
-
}
|
2301 |
-
|
2302 |
-
return true;
|
2303 |
-
}
|
2304 |
-
|
2305 |
-
/**
|
2306 |
-
* @param array $currencies
|
2307 |
-
* @param int $post_id
|
2308 |
-
* @param array $resource_cost
|
2309 |
-
*
|
2310 |
-
* @return bool
|
2311 |
-
*/
|
2312 |
-
private function update_booking_resource_cost( $currencies = [], $post_id = 0, $resource_cost = [] ) {
|
2313 |
-
if ( empty( $resource_cost ) ) {
|
2314 |
-
return false;
|
2315 |
-
}
|
2316 |
-
|
2317 |
-
$updated_meta = get_post_meta( $post_id, '_resource_base_costs', true );
|
2318 |
-
if ( ! is_array( $updated_meta ) ) {
|
2319 |
-
$updated_meta = [];
|
2320 |
-
}
|
2321 |
-
|
2322 |
-
$wc_booking_resource_costs = [];
|
2323 |
-
|
2324 |
-
foreach ( $resource_cost as $resource_id => $costs ) {
|
2325 |
-
|
2326 |
-
foreach ( $currencies as $code => $currency ) {
|
2327 |
-
|
2328 |
-
if ( isset( $costs[ $code ] ) ) {
|
2329 |
-
$wc_booking_resource_costs[ $code ][ $resource_id ] = sanitize_text_field( $costs[ $code ] );
|
2330 |
-
}
|
2331 |
-
}
|
2332 |
-
}
|
2333 |
-
|
2334 |
-
$updated_meta['custom_costs'] = $wc_booking_resource_costs;
|
2335 |
-
|
2336 |
-
update_post_meta( $post_id, '_resource_base_costs', $updated_meta );
|
2337 |
-
|
2338 |
-
$this->sync_resource_costs_with_translations( $post_id, '_resource_base_costs' );
|
2339 |
-
|
2340 |
-
return true;
|
2341 |
-
}
|
2342 |
-
|
2343 |
-
/**
|
2344 |
-
* @param array $currencies
|
2345 |
-
* @param int $post_id
|
2346 |
-
*
|
2347 |
-
* @return bool
|
2348 |
-
*/
|
2349 |
-
private function update_booking_resource_block_cost( $currencies = [], $post_id = 0, $resource_block_cost = [] ) {
|
2350 |
-
if ( empty( $resource_block_cost ) ) {
|
2351 |
-
return false;
|
2352 |
-
}
|
2353 |
-
|
2354 |
-
$updated_meta = get_post_meta( $post_id, '_resource_block_costs', true );
|
2355 |
-
|
2356 |
-
$wc_booking_resource_block_costs = [];
|
2357 |
-
|
2358 |
-
foreach ( $resource_block_cost as $resource_id => $costs ) {
|
2359 |
-
|
2360 |
-
foreach ( $currencies as $code => $currency ) {
|
2361 |
-
|
2362 |
-
if ( isset( $costs[ $code ] ) ) {
|
2363 |
-
$wc_booking_resource_block_costs[ $code ][ $resource_id ] = sanitize_text_field( $costs[ $code ] );
|
2364 |
-
}
|
2365 |
-
}
|
2366 |
-
}
|
2367 |
-
|
2368 |
-
$updated_meta['custom_costs'] = $wc_booking_resource_block_costs;
|
2369 |
-
|
2370 |
-
update_post_meta( $post_id, '_resource_block_costs', $updated_meta );
|
2371 |
-
|
2372 |
-
$this->sync_resource_costs_with_translations( $post_id, '_resource_block_costs' );
|
2373 |
-
|
2374 |
-
return true;
|
2375 |
-
}
|
2376 |
-
|
2377 |
public function extra_conditions_to_filter_bookings( $extra_conditions ) {
|
2378 |
|
2379 |
if ( isset( $_GET['post_type'] ) && $_GET['post_type'] == 'wc_booking' && ! isset( $_GET['post_status'] ) ) {
|
@@ -2391,6 +1437,7 @@ class WCML_Bookings {
|
|
2391 |
public function show_pointer_info() {
|
2392 |
|
2393 |
$pointer_ui = new WCML_Pointer_UI(
|
|
|
2394 |
sprintf( __( 'You can translate the titles of your custom Resources on the %1$sWooCommerce product translation page%2$s', 'woocommerce-multilingual' ), '<a href="' . admin_url( 'admin.php?page=wpml-wcml' ) . '">', '</a>' ),
|
2395 |
WCML_Tracking_Link::getWcmlBookingsDoc(),
|
2396 |
'bookings_resources .woocommerce_bookable_resources #message'
|
@@ -2399,6 +1446,7 @@ class WCML_Bookings {
|
|
2399 |
$pointer_ui->show();
|
2400 |
|
2401 |
$pointer_ui = new WCML_Pointer_UI(
|
|
|
2402 |
sprintf( __( 'You can translate the Person Type Name and Description on the %1$sWooCommerce product translation page%2$s', 'woocommerce-multilingual' ), '<a href="' . admin_url( 'admin.php?page=wpml-wcml' ) . '">', '</a>' ),
|
2403 |
WCML_Tracking_Link::getWcmlBookingsDoc(),
|
2404 |
'bookings_persons #persons-types>div.toolbar'
|
@@ -2726,8 +1774,24 @@ class WCML_Bookings {
|
|
2726 |
}
|
2727 |
|
2728 |
public function save_booking_data_to_translation( $post_id, $data, $job ){
|
2729 |
-
|
2730 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2731 |
}
|
2732 |
|
2733 |
/**
|
1 |
<?php
|
2 |
|
3 |
use WPML\FP\Maybe;
|
4 |
+
use WPML\FP\Str;
|
5 |
use function WPML\FP\invoke;
|
6 |
use function WPML\FP\pipe;
|
7 |
|
8 |
/**
|
9 |
* Class WCML_Bookings.
|
10 |
*/
|
11 |
+
class WCML_Bookings implements \IWPML_Action {
|
12 |
|
13 |
const DOMAIN = 'woocommerce-bookings';
|
14 |
|
15 |
+
const PRIORITY_SAVE_POST_ACTION = 110;
|
16 |
+
|
17 |
/**
|
18 |
* @var WPML_Element_Translation_Package
|
19 |
*/
|
79 |
add_filter( 'woocommerce_booking_reminder_notification', [ $this, 'translate_notification' ], 9 );
|
80 |
add_filter( 'woocommerce_booking_cancelled_notification', [ $this, 'translate_notification' ], 9 );
|
81 |
|
82 |
+
add_action( 'save_post', [ $this, 'save_booking_action_handler' ], self::PRIORITY_SAVE_POST_ACTION );
|
83 |
+
add_action( 'wcml_bookings_resource_costs_updated', [ $this, 'sync_resource_costs_with_translations' ], 10, 2 );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
84 |
|
85 |
add_action( 'wcml_before_sync_product_data', [ $this, 'sync_bookings' ], 10, 3 );
|
86 |
add_action( 'wcml_before_sync_product', [ $this, 'sync_booking_data' ], 10, 2 );
|
87 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
88 |
add_filter(
|
89 |
'wcml_cart_contents_not_changed',
|
90 |
[
|
95 |
3
|
96 |
);
|
97 |
|
98 |
+
add_action( 'woocommerce_bookings_create_booking_page_add_order_item', [ $this, 'set_order_language_on_create_booking_page' ] );
|
|
|
99 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
100 |
add_filter( 'get_booking_products_args', [ $this, 'filter_get_booking_products_args' ] );
|
|
|
|
|
|
|
101 |
|
102 |
add_action( 'wcml_gui_additional_box_html', [ $this, 'custom_box_html' ], 10, 3 );
|
103 |
add_filter( 'wcml_gui_additional_box_data', [ $this, 'custom_box_html_data' ], 10, 4 );
|
134 |
add_action( 'before_delete_post', [ $this, 'delete_bookings' ] );
|
135 |
add_action( 'wp_trash_post', [ $this, 'trash_bookings' ] );
|
136 |
add_action( 'wpml_translation_job_saved', [ $this, 'save_booking_data_to_translation' ], 10, 3 );
|
137 |
+
add_action( 'wpml_pro_translation_completed', [ $this, 'synchronize_bookings_on_translation_completed' ], 10, 3 );
|
138 |
|
139 |
if ( is_admin() ) {
|
140 |
|
201 |
}
|
202 |
}
|
203 |
|
|
|
|
|
|
|
|
|
204 |
add_filter( 'wpml_language_filter_extra_conditions_snippet', [ $this, 'extra_conditions_to_filter_bookings' ] );
|
205 |
|
|
|
|
|
206 |
add_filter( 'wpml_tm_dashboard_translatable_types', [ $this, 'hide_bookings_type_on_tm_dashboard' ] );
|
207 |
|
208 |
add_filter( 'wcml_add_to_cart_sold_individually', [ $this, 'add_to_cart_sold_individually' ], 10, 4 );
|
263 |
|
264 |
$this->maybe_set_booking_language( $booking_id );
|
265 |
|
|
|
|
|
266 |
$this->maybe_sync_updated_booking_meta( $booking_id );
|
267 |
}
|
268 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
269 |
// sync existing product bookings for translations.
|
270 |
public function sync_bookings( $original_product_id, $product_id, $language ) {
|
271 |
$all_bookings_for_product = $this->wpdb->get_results( $this->wpdb->prepare( "SELECT post_id as id FROM {$this->wpdb->postmeta} WHERE meta_key = '_booking_product_id' AND meta_value = %d", $original_product_id ) );
|
521 |
return $new_person_id;
|
522 |
}
|
523 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
524 |
public function sync_resource_costs_with_translations( $object_id, $meta_key, $check = false ) {
|
525 |
|
526 |
$original_product_id = $this->woocommerce_wpml->products->get_original_product_id( $object_id );
|
585 |
|
586 |
}
|
587 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
588 |
public function localize_lock_fields_js() {
|
589 |
wp_localize_script( 'wcml-bookings-js', 'lock_settings', [ 'lock_fields' => 1 ] );
|
590 |
}
|
591 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
592 |
public function filter_bundled_product_in_cart_contents( $cart_item, $key, $current_language ) {
|
593 |
|
594 |
if ( $cart_item['data'] instanceof WC_Product_Booking && isset( $cart_item['booking'] ) ) {
|
653 |
return $cost;
|
654 |
}
|
655 |
|
656 |
+
public function set_order_language_on_create_booking_page( $order_id ) {
|
657 |
+
update_post_meta( $order_id, 'wpml_language', $this->sitepress->get_current_language() );
|
658 |
+
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
659 |
|
660 |
public function filter_get_booking_products_args( $args ) {
|
661 |
if ( isset( $args['suppress_filters'] ) ) {
|
1134 |
|
1135 |
}
|
1136 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1137 |
public function delete_bookings( $booking_id ) {
|
1138 |
|
1139 |
if (
|
1221 |
private function save_person_translation( $post_id, $data, $job ) {
|
1222 |
$person_translations = [];
|
1223 |
|
1224 |
+
foreach ( $data as $value ) {
|
1225 |
|
1226 |
+
if ( $value['finished'] && strpos( $value['field_type'], 'wc_bookings:person:' ) === 0 ) {
|
1227 |
|
1228 |
+
$exp = explode( ':', $value['field_type'] );
|
1229 |
|
1230 |
+
$person_id = $exp[2];
|
1231 |
+
$field = $exp[3];
|
1232 |
|
1233 |
+
$person_translations[ $person_id ][ $field ] = $value['data'];
|
|
|
1234 |
|
1235 |
+
}
|
1236 |
+
}
|
|
|
|
|
1237 |
|
1238 |
+
if ( $person_translations ) {
|
1239 |
|
1240 |
+
foreach ( $person_translations as $person_id => $pt ) {
|
1241 |
|
1242 |
+
$person_trid = $this->sitepress->get_element_trid( $person_id, 'post_bookable_person' );
|
1243 |
|
1244 |
+
$person_id_translated = apply_filters( 'translate_object_id', $person_id, 'bookable_person', false, $job->language_code );
|
1245 |
|
1246 |
+
if ( empty( $person_id_translated ) ) {
|
1247 |
|
1248 |
+
$person_post = [
|
1249 |
|
1250 |
+
'post_type' => 'bookable_person',
|
1251 |
+
'post_status' => 'publish',
|
1252 |
+
'post_title' => $pt['name'],
|
1253 |
+
'post_parent' => $post_id,
|
1254 |
+
'post_excerpt' => isset( $pt['description'] ) ? $pt['description'] : '',
|
1255 |
|
1256 |
+
];
|
1257 |
|
1258 |
+
$person_id_translated = wp_insert_post( $person_post );
|
1259 |
|
1260 |
+
$this->sitepress->set_element_language_details( $person_id_translated, 'post_bookable_person', $person_trid, $job->language_code );
|
1261 |
|
1262 |
+
} else {
|
1263 |
|
1264 |
+
$person_post = [
|
1265 |
+
'ID' => $person_id_translated,
|
1266 |
+
'post_title' => $pt['name'],
|
1267 |
+
'post_excerpt' => isset( $pt['description'] ) ? $pt['description'] : '',
|
1268 |
+
];
|
1269 |
|
1270 |
+
wp_update_post( $person_post );
|
|
|
|
|
|
|
|
|
|
|
1271 |
|
1272 |
+
}
|
1273 |
+
}
|
1274 |
+
}
|
1275 |
}
|
1276 |
|
1277 |
public function append_resources_to_translation_package( $package, $post ) {
|
1301 |
private function save_resource_translation( $post_id, $data, $job ) {
|
1302 |
$resource_translations = [];
|
1303 |
|
1304 |
+
foreach ( $data as $value ) {
|
|
|
|
|
|
|
|
|
1305 |
|
1306 |
+
if ( $value['finished'] && strpos( $value['field_type'], 'wc_bookings:resource:' ) === 0 ) {
|
1307 |
|
1308 |
+
$exp = explode( ':', $value['field_type'] );
|
|
|
1309 |
|
1310 |
+
$resource_id = $exp[2];
|
1311 |
+
$field = $exp[3];
|
1312 |
|
1313 |
+
$resource_translations[ $resource_id ][ $field ] = $value['data'];
|
|
|
1314 |
|
1315 |
+
}
|
1316 |
+
}
|
1317 |
|
1318 |
+
if ( $resource_translations ) {
|
1319 |
|
1320 |
+
foreach ( $resource_translations as $resource_id => $rt ) {
|
1321 |
|
1322 |
+
$resource_trid = $this->sitepress->get_element_trid( $resource_id, 'post_bookable_resource' );
|
1323 |
|
1324 |
+
$resource_id_translated = apply_filters( 'translate_object_id', $resource_id, 'bookable_resource', false, $job->language_code );
|
1325 |
|
1326 |
+
if ( empty( $resource_id_translated ) ) {
|
1327 |
|
1328 |
+
$resource_post = [
|
|
|
|
|
|
|
|
|
1329 |
|
1330 |
+
'post_type' => 'bookable_resource',
|
1331 |
+
'post_status' => 'publish',
|
1332 |
+
'post_title' => $rt['name'],
|
1333 |
+
'post_parent' => $post_id,
|
1334 |
+
];
|
1335 |
|
1336 |
+
$resource_id_translated = wp_insert_post( $resource_post );
|
1337 |
|
1338 |
+
$this->sitepress->set_element_language_details( $resource_id_translated, 'post_bookable_resource', $resource_trid, $job->language_code );
|
|
|
|
|
|
|
|
|
|
|
|
|
1339 |
|
1340 |
+
$sort_order = $this->wpdb->get_var( $this->wpdb->prepare( "SELECT sort_order FROM {$this->wpdb->prefix}wc_booking_relationships WHERE resource_id=%d", $resource_id ) );
|
1341 |
+
$relationship = [
|
1342 |
+
'product_id' => $post_id,
|
1343 |
+
'resource_id' => $resource_id_translated,
|
1344 |
+
'sort_order' => $sort_order,
|
1345 |
+
];
|
1346 |
+
$this->wpdb->insert( $this->wpdb->prefix . 'wc_booking_relationships', $relationship );
|
1347 |
|
1348 |
+
} else {
|
|
|
|
|
|
|
1349 |
|
1350 |
+
$resource_post = [
|
1351 |
+
'ID' => $resource_id_translated,
|
1352 |
+
'post_title' => $rt['name'],
|
1353 |
+
];
|
1354 |
|
1355 |
+
wp_update_post( $resource_post );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1356 |
|
1357 |
+
$sort_order = $this->wpdb->get_var( $this->wpdb->prepare( "SELECT sort_order FROM {$this->wpdb->prefix}wc_booking_relationships WHERE resource_id=%d", $resource_id ) );
|
1358 |
+
$this->wpdb->update(
|
1359 |
+
$this->wpdb->prefix . 'wc_booking_relationships',
|
1360 |
+
[ 'sort_order' => $sort_order ],
|
1361 |
+
[
|
1362 |
+
'product_id' => $post_id,
|
1363 |
+
'resource_id' => $resource_id_translated,
|
1364 |
+
]
|
1365 |
+
);
|
1366 |
|
1367 |
+
}
|
1368 |
+
}
|
1369 |
+
}
|
1370 |
}
|
1371 |
|
1372 |
public function wcml_js_lock_fields_ids( $ids ) {
|
1420 |
|
1421 |
}
|
1422 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1423 |
public function extra_conditions_to_filter_bookings( $extra_conditions ) {
|
1424 |
|
1425 |
if ( isset( $_GET['post_type'] ) && $_GET['post_type'] == 'wc_booking' && ! isset( $_GET['post_status'] ) ) {
|
1437 |
public function show_pointer_info() {
|
1438 |
|
1439 |
$pointer_ui = new WCML_Pointer_UI(
|
1440 |
+
/* translators: %1$s and %2$s are opening and closing HTML link tags */
|
1441 |
sprintf( __( 'You can translate the titles of your custom Resources on the %1$sWooCommerce product translation page%2$s', 'woocommerce-multilingual' ), '<a href="' . admin_url( 'admin.php?page=wpml-wcml' ) . '">', '</a>' ),
|
1442 |
WCML_Tracking_Link::getWcmlBookingsDoc(),
|
1443 |
'bookings_resources .woocommerce_bookable_resources #message'
|
1446 |
$pointer_ui->show();
|
1447 |
|
1448 |
$pointer_ui = new WCML_Pointer_UI(
|
1449 |
+
/* translators: %1$s and %2$s are opening and closing HTML link tags */
|
1450 |
sprintf( __( 'You can translate the Person Type Name and Description on the %1$sWooCommerce product translation page%2$s', 'woocommerce-multilingual' ), '<a href="' . admin_url( 'admin.php?page=wpml-wcml' ) . '">', '</a>' ),
|
1451 |
WCML_Tracking_Link::getWcmlBookingsDoc(),
|
1452 |
'bookings_persons #persons-types>div.toolbar'
|
1774 |
}
|
1775 |
|
1776 |
public function save_booking_data_to_translation( $post_id, $data, $job ){
|
1777 |
+
if ( $this->is_booking( $job->original_doc_id ) ) {
|
1778 |
+
$this->save_person_translation( $post_id, $data, $job );
|
1779 |
+
$this->save_resource_translation( $post_id, $data, $job );
|
1780 |
+
}
|
1781 |
+
}
|
1782 |
+
|
1783 |
+
/**
|
1784 |
+
* @param int $new_post_id
|
1785 |
+
* @param array $fields
|
1786 |
+
* @param \stdClass $job
|
1787 |
+
*/
|
1788 |
+
public function synchronize_bookings_on_translation_completed( $new_post_id, $fields, $job ) {
|
1789 |
+
if (
|
1790 |
+
Str::startsWith( 'post_', $job->original_post_type )
|
1791 |
+
&& $this->is_booking( $job->original_doc_id )
|
1792 |
+
) {
|
1793 |
+
$this->woocommerce_wpml->sync_product_data->synchronize_products( $new_post_id, get_post( $new_post_id ), true );
|
1794 |
+
}
|
1795 |
}
|
1796 |
|
1797 |
/**
|
compatibility/WcBulkStockManagement/Factory.php
ADDED
@@ -0,0 +1,19 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace WCML\Compatibility\WcBulkStockManagement;
|
4 |
+
|
5 |
+
use WCML\Compatibility\ComponentFactory;
|
6 |
+
use WCML_Bulk_Stock_Management;
|
7 |
+
|
8 |
+
/**
|
9 |
+
* @see http://www.woothemes.com/products/bulk-stock-management/
|
10 |
+
*/
|
11 |
+
class Factory extends ComponentFactory {
|
12 |
+
|
13 |
+
/**
|
14 |
+
* @inheritDoc
|
15 |
+
*/
|
16 |
+
public function create() {
|
17 |
+
return new WCML_Bulk_Stock_Management();
|
18 |
+
}
|
19 |
+
}
|
compatibility/{class-wcml-bulk-stock-management.php → WcBulkStockManagement/class-wcml-bulk-stock-management.php}
RENAMED
@@ -5,8 +5,9 @@
|
|
5 |
*
|
6 |
* @author konrad
|
7 |
*/
|
8 |
-
class WCML_Bulk_Stock_Management {
|
9 |
-
|
|
|
10 |
if ( is_admin() && isset( $_GET['page'] ) && $_GET['page'] == 'woocommerce-bulk-stock-management' ) {
|
11 |
global $sitepress;
|
12 |
remove_action( 'admin_enqueue_scripts', [ $sitepress, 'language_filter' ] );
|
5 |
*
|
6 |
* @author konrad
|
7 |
*/
|
8 |
+
class WCML_Bulk_Stock_Management implements \IWPML_Action {
|
9 |
+
|
10 |
+
public function add_hooks() {
|
11 |
if ( is_admin() && isset( $_GET['page'] ) && $_GET['page'] == 'woocommerce-bulk-stock-management' ) {
|
12 |
global $sitepress;
|
13 |
remove_action( 'admin_enqueue_scripts', [ $sitepress, 'language_filter' ] );
|
compatibility/WcCheckoutAddons/Factory.php
ADDED
@@ -0,0 +1,31 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace WCML\Compatibility\WcCheckoutAddons;
|
4 |
+
|
5 |
+
use WCML\Compatibility\ComponentFactory;
|
6 |
+
use WCML\StandAlone\IStandAloneAction;
|
7 |
+
use WCML_Checkout_Addons;
|
8 |
+
use function WCML\functions\isStandAlone;
|
9 |
+
|
10 |
+
/**
|
11 |
+
* @see http://www.woocommerce.com/products/woocommerce-checkout-add-ons/
|
12 |
+
*/
|
13 |
+
class Factory extends ComponentFactory implements IStandAloneAction {
|
14 |
+
|
15 |
+
/**
|
16 |
+
* @inheritDoc
|
17 |
+
*/
|
18 |
+
public function create() {
|
19 |
+
$hooks = [];
|
20 |
+
|
21 |
+
if ( wcml_is_multi_currency_on() ) {
|
22 |
+
$hooks[] = new MulticurrencyHooks();
|
23 |
+
}
|
24 |
+
|
25 |
+
if ( ! isStandAlone() ) {
|
26 |
+
$hooks[] = new WCML_Checkout_Addons();
|
27 |
+
}
|
28 |
+
|
29 |
+
return $hooks;
|
30 |
+
}
|
31 |
+
}
|
compatibility/WcCheckoutAddons/MulticurrencyHooks.php
ADDED
@@ -0,0 +1,30 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace WCML\Compatibility\WcCheckoutAddons;
|
4 |
+
|
5 |
+
class MulticurrencyHooks implements \IWPML_Action {
|
6 |
+
|
7 |
+
public function add_hooks() {
|
8 |
+
add_filter( 'option_wc_checkout_add_ons', [ $this, 'optionWcCheckoutAddOnsFilter' ] );
|
9 |
+
}
|
10 |
+
|
11 |
+
/**
|
12 |
+
* @param array|mixed $optionValue
|
13 |
+
*
|
14 |
+
* @return array|mixed
|
15 |
+
*/
|
16 |
+
public function optionWcCheckoutAddOnsFilter( $optionValue ) {
|
17 |
+
$convertPrice = function( $index, $conf ) {
|
18 |
+
if (
|
19 |
+
isset( $conf['adjustment'], $conf['adjustment_type'] )
|
20 |
+
&& 'fixed' === $conf['adjustment_type']
|
21 |
+
) {
|
22 |
+
$conf['adjustment'] = apply_filters( 'wcml_raw_price_amount', $conf['adjustment'] );
|
23 |
+
}
|
24 |
+
|
25 |
+
return $conf;
|
26 |
+
};
|
27 |
+
|
28 |
+
return OptionIterator::apply( $convertPrice, $optionValue );
|
29 |
+
}
|
30 |
+
}
|
compatibility/WcCheckoutAddons/OptionIterator.php
ADDED
@@ -0,0 +1,31 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace WCML\Compatibility\WcCheckoutAddons;
|
4 |
+
|
5 |
+
class OptionIterator {
|
6 |
+
|
7 |
+
/**
|
8 |
+
* @param callable $handler
|
9 |
+
* @param array|mixed $optionValue
|
10 |
+
*
|
11 |
+
* @return array|mixed
|
12 |
+
*/
|
13 |
+
public static function apply( callable $handler, $optionValue ) {
|
14 |
+
if ( is_array( $optionValue ) ) {
|
15 |
+
|
16 |
+
foreach ( $optionValue as $addonId => $addonConf ) {
|
17 |
+
$addonConf = $handler( $addonId, $addonConf );
|
18 |
+
|
19 |
+
if ( isset( $addonConf['options'] ) ) {
|
20 |
+
foreach ( $addonConf['options'] as $index => $fields ) {
|
21 |
+
$addonConf['options'][ $index ] = $handler( $index, $fields );
|
22 |
+
}
|
23 |
+
}
|
24 |
+
|
25 |
+
$optionValue[ $addonId ] = $addonConf;
|
26 |
+
}
|
27 |
+
}
|
28 |
+
|
29 |
+
return $optionValue;
|
30 |
+
}
|
31 |
+
}
|
compatibility/WcCheckoutAddons/class-wcml-checkout-addons.php
ADDED
@@ -0,0 +1,47 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
use WCML\Compatibility\WcCheckoutAddons\OptionIterator;
|
4 |
+
|
5 |
+
/**
|
6 |
+
* Compatibility class for wc_checkout_addons plugin.
|
7 |
+
*
|
8 |
+
* @author konrad
|
9 |
+
*/
|
10 |
+
class WCML_Checkout_Addons implements \IWPML_Action {
|
11 |
+
|
12 |
+
public function add_hooks() {
|
13 |
+
add_filter( 'option_wc_checkout_add_ons', [ $this, 'option_wc_checkout_add_ons' ] );
|
14 |
+
}
|
15 |
+
|
16 |
+
/**
|
17 |
+
* @param array|mixed $option_value
|
18 |
+
*
|
19 |
+
* @return array|mixed
|
20 |
+
*/
|
21 |
+
public function option_wc_checkout_add_ons( $option_value ) {
|
22 |
+
return OptionIterator::apply( [ $this, 'handle_option_part' ], $option_value );
|
23 |
+
}
|
24 |
+
|
25 |
+
public function handle_option_part( $index, $conf ) {
|
26 |
+
$conf = $this->register_or_translate( 'label', $conf, $index );
|
27 |
+
$conf = $this->register_or_translate( 'description', $conf, $index );
|
28 |
+
return $conf;
|
29 |
+
}
|
30 |
+
|
31 |
+
private function register_or_translate( $element, $conf, $index ) {
|
32 |
+
if ( isset( $conf[ $element ] ) ) {
|
33 |
+
$string = $conf[ $element ];
|
34 |
+
$key = $index . '_' . $element . '_' . md5( $string );
|
35 |
+
if ( $this->is_default_language() ) {
|
36 |
+
do_action( 'wpml_register_single_string', 'wc_checkout_addons', $key, $string );
|
37 |
+
} else {
|
38 |
+
$conf[ $element ] = apply_filters( 'wpml_translate_single_string', $string, 'wc_checkout_addons', $key );
|
39 |
+
}
|
40 |
+
}
|
41 |
+
return $conf;
|
42 |
+
}
|
43 |
+
|
44 |
+
private function is_default_language() {
|
45 |
+
return apply_filters( 'wpml_current_language', null ) === apply_filters( 'wpml_default_language', null );
|
46 |
+
}
|
47 |
+
}
|
compatibility/WcCheckoutFieldEditor/Factory.php
ADDED
@@ -0,0 +1,16 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace WCML\Compatibility\WcCheckoutFieldEditor;
|
4 |
+
|
5 |
+
use WCML\Compatibility\ComponentFactory;
|
6 |
+
use WCML_Checkout_Field_Editor;
|
7 |
+
|
8 |
+
class Factory extends ComponentFactory {
|
9 |
+
|
10 |
+
/**
|
11 |
+
* @inheritDoc
|
12 |
+
*/
|
13 |
+
public function create() {
|
14 |
+
return new WCML_Checkout_Field_Editor();
|
15 |
+
}
|
16 |
+
}
|
compatibility/{class-wcml-checkout-field-editor.php → WcCheckoutFieldEditor/class-wcml-checkout-field-editor.php}
RENAMED
@@ -1,6 +1,6 @@
|
|
1 |
<?php
|
2 |
|
3 |
-
class WCML_Checkout_Field_Editor {
|
4 |
|
5 |
protected $package, $billing, $shipping, $additional;
|
6 |
|
1 |
<?php
|
2 |
|
3 |
+
class WCML_Checkout_Field_Editor implements \IWPML_Action {
|
4 |
|
5 |
protected $package, $billing, $shipping, $additional;
|
6 |
|
compatibility/WcCompositeProducts/Factory.php
ADDED
@@ -0,0 +1,33 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace WCML\Compatibility\WcCompositeProducts;
|
4 |
+
|
5 |
+
use WCML\Compatibility\ComponentFactory;
|
6 |
+
use WCML\StandAlone\IStandAloneAction;
|
7 |
+
use WCML_Composite_Products;
|
8 |
+
use function WCML\functions\getSitePress;
|
9 |
+
use function WCML\functions\getWooCommerceWpml;
|
10 |
+
use function WCML\functions\isStandAlone;
|
11 |
+
|
12 |
+
/**
|
13 |
+
* @see https://woocommerce.com/products/composite-products/
|
14 |
+
*/
|
15 |
+
class Factory extends ComponentFactory implements IStandAloneAction {
|
16 |
+
|
17 |
+
/**
|
18 |
+
* @inheritDoc
|
19 |
+
*/
|
20 |
+
public function create() {
|
21 |
+
$hooks = [];
|
22 |
+
|
23 |
+
if ( wcml_is_multi_currency_on() ) {
|
24 |
+
$hooks[] = new MulticurrencyHooks( getWooCommerceWpml() );
|
25 |
+
}
|
26 |
+
|
27 |
+
if ( ! isStandAlone() ) {
|
28 |
+
$hooks[] = new WCML_Composite_Products( getSitePress() );
|
29 |
+
}
|
30 |
+
|
31 |
+
return $hooks;
|
32 |
+
}
|
33 |
+
}
|
compatibility/WcCompositeProducts/MulticurrencyHooks.php
ADDED
@@ -0,0 +1,117 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace WCML\Compatibility\WcCompositeProducts;
|
4 |
+
|
5 |
+
use WCML_Compatibility_Helper;
|
6 |
+
|
7 |
+
class MulticurrencyHooks implements \IWPML_Action {
|
8 |
+
|
9 |
+
const PRICE_FILTERS_PRIORITY_AFTER_COMPOSITE = 99;
|
10 |
+
|
11 |
+
/** @var \woocommerce_wpml $woocommerce_wpml */
|
12 |
+
private $woocommerce_wpml;
|
13 |
+
|
14 |
+
public function __construct( \woocommerce_wpml $woocommerce_wpml ) {
|
15 |
+
$this->woocommerce_wpml = $woocommerce_wpml;
|
16 |
+
}
|
17 |
+
|
18 |
+
public function add_hooks() {
|
19 |
+
if ( is_admin() ) {
|
20 |
+
add_action( 'wcml_after_save_custom_prices', [ $this, 'update_composite_custom_prices' ], 10, 4 );
|
21 |
+
} else {
|
22 |
+
add_filter( 'get_post_metadata', [ $this, 'filter_composite_product_cost' ], 10, 3 );
|
23 |
+
$this->add_price_rounding_filters();
|
24 |
+
}
|
25 |
+
}
|
26 |
+
|
27 |
+
/**
|
28 |
+
* @param int|string $productId
|
29 |
+
* @param string|float|int $productPrice
|
30 |
+
* @param array $customPrices
|
31 |
+
* @param string $code
|
32 |
+
*
|
33 |
+
* @return void
|
34 |
+
*/
|
35 |
+
public function update_composite_custom_prices( $productId, $productPrice, $customPrices, $code ){
|
36 |
+
if( WCML_Compatibility_Helper::get_product_type( $productId ) === 'composite' ) {
|
37 |
+
update_post_meta( $productId, '_bto_base_regular_price' . '_' . $code, $customPrices['_regular_price' ] );
|
38 |
+
update_post_meta( $productId, '_bto_base_sale_price' . '_' . $code, $customPrices['_sale_price' ] );
|
39 |
+
update_post_meta( $productId, '_bto_base_price' . '_' . $code, $productPrice );
|
40 |
+
}
|
41 |
+
}
|
42 |
+
|
43 |
+
/**
|
44 |
+
* @param mixed $value
|
45 |
+
* @param int $objectId
|
46 |
+
* @param string $metaKey
|
47 |
+
*
|
48 |
+
* @return mixed
|
49 |
+
*/
|
50 |
+
public function filter_composite_product_cost( $value, $objectId, $metaKey ) {
|
51 |
+
if ( in_array( $metaKey, [
|
52 |
+
'_bto_base_regular_price',
|
53 |
+
'_bto_base_sale_price',
|
54 |
+
'_bto_base_price'
|
55 |
+
] ) ) {
|
56 |
+
$original_id = $this->woocommerce_wpml->products->get_original_product_id( $objectId );
|
57 |
+
|
58 |
+
$cost_status = get_post_meta( $original_id, '_wcml_custom_prices_status', true );
|
59 |
+
|
60 |
+
$currency = $this->woocommerce_wpml->multi_currency->get_client_currency();
|
61 |
+
|
62 |
+
if ( $currency === wcml_get_woocommerce_currency_option() ) {
|
63 |
+
return $value;
|
64 |
+
}
|
65 |
+
|
66 |
+
$cost = get_post_meta( $original_id, $metaKey . '_' . $currency, true );
|
67 |
+
|
68 |
+
if ( $cost_status && ! empty( $cost ) ) {
|
69 |
+
return $cost;
|
70 |
+
} else {
|
71 |
+
remove_filter( 'get_post_metadata', [ $this, 'filter_composite_product_cost' ], 10 );
|
72 |
+
|
73 |
+
$cost = get_post_meta( $original_id, $metaKey, true );
|
74 |
+
|
75 |
+
add_filter( 'get_post_metadata', [ $this, 'filter_composite_product_cost' ], 10, 4 );
|
76 |
+
|
77 |
+
if ( $cost ){
|
78 |
+
return $this->woocommerce_wpml->multi_currency->prices->convert_price_amount( $cost, $currency );
|
79 |
+
}
|
80 |
+
}
|
81 |
+
}
|
82 |
+
|
83 |
+
return $value;
|
84 |
+
}
|
85 |
+
|
86 |
+
public function add_price_rounding_filters() {
|
87 |
+
$filters = [
|
88 |
+
'woocommerce_product_get_price',
|
89 |
+
'woocommerce_product_get_sale_price',
|
90 |
+
'woocommerce_product_get_regular_price',
|
91 |
+
'woocommerce_product_variation_get_price',
|
92 |
+
'woocommerce_product_variation_get_sale_price',
|
93 |
+
'woocommerce_product_variation_get_regular_price'
|
94 |
+
];
|
95 |
+
|
96 |
+
foreach( $filters as $filter ){
|
97 |
+
add_filter( $filter, [ $this, 'apply_rounding_rules' ], self::PRICE_FILTERS_PRIORITY_AFTER_COMPOSITE );
|
98 |
+
}
|
99 |
+
}
|
100 |
+
|
101 |
+
/**
|
102 |
+
* @param int|float|string $price
|
103 |
+
*
|
104 |
+
* @return int|float|string
|
105 |
+
*/
|
106 |
+
public function apply_rounding_rules( $price ) {
|
107 |
+
if ( $price && is_composite_product() ) {
|
108 |
+
$current_currency = $this->woocommerce_wpml->multi_currency->get_client_currency();
|
109 |
+
|
110 |
+
if ( $current_currency !== wcml_get_woocommerce_currency_option() ) {
|
111 |
+
$price = $this->woocommerce_wpml->multi_currency->prices->apply_rounding_rules( $price, $current_currency );
|
112 |
+
}
|
113 |
+
}
|
114 |
+
|
115 |
+
return $price;
|
116 |
+
}
|
117 |
+
}
|
compatibility/{class-wcml-composite-products.php → WcCompositeProducts/class-wcml-composite-products.php}
RENAMED
@@ -1,38 +1,22 @@
|
|
1 |
<?php
|
2 |
|
|
|
3 |
use WPML\FP\Fns;
|
4 |
use WPML\FP\Obj;
|
|
|
5 |
|
6 |
-
|
7 |
-
use function WPML\FP\pipe;
|
8 |
|
9 |
-
|
10 |
-
|
11 |
-
const PRICE_FILTERS_PRIORITY_AFTER_COMPOSITE = 99;
|
12 |
|
13 |
/**
|
14 |
* @var SitePress
|
15 |
*/
|
16 |
private $sitepress;
|
17 |
-
/**
|
18 |
-
* @var woocommerce_wpml
|
19 |
-
*/
|
20 |
-
private $woocommerce_wpml;
|
21 |
-
/**
|
22 |
-
* @var WPML_Element_Translation_Package
|
23 |
-
*/
|
24 |
-
private $tp;
|
25 |
|
26 |
-
|
27 |
-
|
28 |
-
* @param SitePress $sitepress
|
29 |
-
* @param woocommerce_wpml $woocommerce_wpml
|
30 |
-
* @param WPML_Element_Translation_Package $tp
|
31 |
-
*/
|
32 |
-
public function __construct( SitePress $sitepress, woocommerce_wpml $woocommerce_wpml, WPML_Element_Translation_Package $tp ) {
|
33 |
-
$this->sitepress = $sitepress;
|
34 |
-
$this->woocommerce_wpml = $woocommerce_wpml;
|
35 |
-
$this->tp = $tp;
|
36 |
}
|
37 |
|
38 |
public function add_hooks(){
|
@@ -42,11 +26,15 @@ class WCML_Composite_Products extends WCML_Compatibility_Helper{
|
|
42 |
add_filter( 'woocommerce_composite_component_options_query_args', array($this, 'wpml_composites_transients_cache_per_language'), 10, 3 );
|
43 |
add_action( 'wcml_before_sync_product_data', array( $this, 'sync_composite_data_across_translations' ), 10, 2 );
|
44 |
add_action( 'wpml_translation_job_saved', array( $this, 'save_composite_data_translation' ), 10, 3 );
|
|
|
45 |
if( is_admin() ){
|
46 |
|
47 |
-
|
48 |
-
|
49 |
-
|
|
|
|
|
|
|
50 |
add_filter( 'woocommerce_json_search_found_products', array( $this, 'woocommerce_json_search_found_products' ) );
|
51 |
|
52 |
add_filter( 'wpml_tm_translation_job_data', array( $this, 'append_composite_data_translation_package' ), 10, 2 );
|
@@ -57,32 +45,11 @@ class WCML_Composite_Products extends WCML_Compatibility_Helper{
|
|
57 |
add_filter( 'wcml_after_load_lock_fields_js', array( $this, 'localize_lock_fields_js' ) );
|
58 |
add_action( 'init', array( $this, 'load_assets' ) );
|
59 |
|
60 |
-
add_action( 'wcml_after_save_custom_prices', array( $this, 'update_composite_custom_prices' ), 10, 4 );
|
61 |
-
|
62 |
add_filter( 'wcml_do_not_display_custom_fields_for_product', array( $this, 'replace_tm_editor_custom_fields_with_own_sections' ) );
|
63 |
-
}else{
|
64 |
-
add_filter( 'get_post_metadata', array( $this, 'filter_composite_product_cost' ), 10, 4 );
|
65 |
-
$this->add_price_rounding_filters();
|
66 |
}
|
67 |
|
68 |
}
|
69 |
|
70 |
-
public function add_price_rounding_filters(){
|
71 |
-
|
72 |
-
$filters = array(
|
73 |
-
'woocommerce_product_get_price',
|
74 |
-
'woocommerce_product_get_sale_price',
|
75 |
-
'woocommerce_product_get_regular_price',
|
76 |
-
'woocommerce_product_variation_get_price',
|
77 |
-
'woocommerce_product_variation_get_sale_price',
|
78 |
-
'woocommerce_product_variation_get_regular_price'
|
79 |
-
);
|
80 |
-
|
81 |
-
foreach( $filters as $filter ){
|
82 |
-
add_filter( $filter, array( $this, 'apply_rounding_rules' ), self::PRICE_FILTERS_PRIORITY_AFTER_COMPOSITE );
|
83 |
-
}
|
84 |
-
}
|
85 |
-
|
86 |
public function woocommerce_composite_component_default_option($selected_value, $component_id, $object) {
|
87 |
|
88 |
if( !empty( $selected_value ) )
|
@@ -166,7 +133,7 @@ class WCML_Composite_Products extends WCML_Compatibility_Helper{
|
|
166 |
|
167 |
}
|
168 |
|
169 |
-
update_post_meta( $product_translation->element_id,
|
170 |
|
171 |
if ( $composite_scenarios_meta ) {
|
172 |
// sync product ids
|
@@ -185,7 +152,7 @@ class WCML_Composite_Products extends WCML_Compatibility_Helper{
|
|
185 |
->map( Obj::over( Obj::lensPath( [ 'scenario_actions', 'conditional_options', 'component_data' ] ), $translate_product_ids ) )
|
186 |
->toArray();
|
187 |
|
188 |
-
update_post_meta( $product_translation->element_id,
|
189 |
}
|
190 |
}
|
191 |
}
|
@@ -193,6 +160,13 @@ class WCML_Composite_Products extends WCML_Compatibility_Helper{
|
|
193 |
}
|
194 |
}
|
195 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
196 |
public function custom_box_html( $obj, $product_id, $data ){
|
197 |
|
198 |
if( $this->get_product_type( $product_id ) == 'composite' ){
|
@@ -248,6 +222,16 @@ class WCML_Composite_Products extends WCML_Compatibility_Helper{
|
|
248 |
|
249 |
}
|
250 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
251 |
public function custom_box_html_data( $data, $product_id, $translation, $lang ){
|
252 |
|
253 |
if( $this->get_product_type( $product_id ) == 'composite' ){
|
@@ -310,7 +294,16 @@ class WCML_Composite_Products extends WCML_Compatibility_Helper{
|
|
310 |
return $data;
|
311 |
}
|
312 |
|
313 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
314 |
public function update_component_strings( $original_product_id, $product_id, $data, $language ){
|
315 |
|
316 |
$composite_data = $this->get_composite_data( $product_id );
|
@@ -327,7 +320,7 @@ class WCML_Composite_Products extends WCML_Compatibility_Helper{
|
|
327 |
|
328 |
}
|
329 |
|
330 |
-
update_post_meta( $product_id,
|
331 |
|
332 |
$composite_scenarios_meta = $this->get_composite_scenarios_meta( $product_id );
|
333 |
if( $composite_scenarios_meta ){
|
@@ -342,7 +335,7 @@ class WCML_Composite_Products extends WCML_Compatibility_Helper{
|
|
342 |
}
|
343 |
}
|
344 |
|
345 |
-
update_post_meta( $product_id,
|
346 |
|
347 |
return array(
|
348 |
'components' => $composite_data,
|
@@ -350,92 +343,117 @@ class WCML_Composite_Products extends WCML_Compatibility_Helper{
|
|
350 |
);
|
351 |
}
|
352 |
|
|
|
|
|
|
|
|
|
|
|
|
|
353 |
public function append_composite_data_translation_package( $package, $post ){
|
354 |
-
|
355 |
-
|
356 |
-
|
357 |
-
|
358 |
-
|
359 |
-
|
360 |
-
|
361 |
-
|
362 |
-
|
363 |
-
|
364 |
-
|
365 |
-
|
366 |
-
|
367 |
-
|
368 |
-
$package['contents']['wc_composite:' . $component_id . ':' . $field] = array(
|
369 |
-
'translate' => 1,
|
370 |
-
'data' => $this->tp->encode_field_data( $component[$field], 'base64' ),
|
371 |
-
'format' => 'base64'
|
372 |
-
);
|
373 |
-
|
374 |
}
|
375 |
}
|
376 |
-
|
377 |
}
|
|
|
378 |
|
379 |
-
|
380 |
-
|
381 |
}
|
382 |
|
383 |
return $package;
|
|
|
384 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
385 |
}
|
386 |
|
|
|
|
|
|
|
|
|
|
|
387 |
public function save_composite_data_translation( $post_id, $data, $job ){
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
388 |
|
|
|
|
|
389 |
|
390 |
-
|
391 |
-
|
392 |
-
|
393 |
-
|
394 |
-
|
395 |
-
$component_id = $matches[1];
|
396 |
-
$field = $matches[2];
|
397 |
-
|
398 |
-
$translated_composite_data[$component_id][$field] = $value['data'];
|
399 |
-
|
400 |
-
}
|
401 |
-
|
402 |
-
}
|
403 |
-
|
404 |
-
if( $translated_composite_data ){
|
405 |
-
|
406 |
-
$composite_data = get_post_meta( $job->original_doc_id, '_bto_data', true );
|
407 |
-
|
408 |
-
|
409 |
-
foreach ( $composite_data as $component_id => $component ) {
|
410 |
-
|
411 |
-
if( isset( $translated_composite_data[$component_id]['title'] ) ){
|
412 |
-
$composite_data[$component_id]['title'] = $translated_composite_data[$component_id]['title'];
|
413 |
-
}
|
414 |
-
|
415 |
-
if( isset( $translated_composite_data[$component_id]['description'] ) ){
|
416 |
-
$composite_data[$component_id]['description'] = $translated_composite_data[$component_id]['description'];
|
417 |
-
}
|
418 |
|
419 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
420 |
|
421 |
-
|
422 |
-
|
423 |
-
|
|
|
|
|
424 |
}
|
425 |
|
426 |
-
|
427 |
-
|
428 |
-
foreach ( $component['assigned_category_ids'] as $idx => $assigned_id ) {
|
429 |
-
$composite_data[$component_id]['assigned_category_ids'][$idx] =
|
430 |
-
apply_filters( 'wpml_object_id', $assigned_id, 'product_cat', true, $job->language_code );
|
431 |
|
432 |
-
|
433 |
-
|
434 |
-
|
|
|
|
|
435 |
|
|
|
|
|
|
|
|
|
|
|
436 |
}
|
437 |
-
|
438 |
-
update_post_meta( $post_id, '_bto_data', $composite_data );
|
439 |
}
|
440 |
}
|
441 |
|
@@ -494,93 +512,17 @@ class WCML_Composite_Products extends WCML_Compatibility_Helper{
|
|
494 |
}
|
495 |
|
496 |
public function get_composite_scenarios_meta( $product_id ){
|
497 |
-
return get_post_meta( $product_id,
|
498 |
}
|
499 |
|
500 |
public function get_composite_data( $product_id ){
|
501 |
-
return get_post_meta( $product_id,
|
502 |
-
}
|
503 |
-
|
504 |
-
|
505 |
-
public function filter_composite_product_cost( $value, $object_id, $meta_key, $single ) {
|
506 |
-
|
507 |
-
if ( in_array( $meta_key, array(
|
508 |
-
'_bto_base_regular_price',
|
509 |
-
'_bto_base_sale_price',
|
510 |
-
'_bto_base_price'
|
511 |
-
) ) ) {
|
512 |
-
|
513 |
-
if ( $this->woocommerce_wpml->settings['enable_multi_currency'] == WCML_MULTI_CURRENCIES_INDEPENDENT ) {
|
514 |
-
|
515 |
-
$original_id = $this->woocommerce_wpml->products->get_original_product_id( $object_id );
|
516 |
-
|
517 |
-
$cost_status = get_post_meta( $original_id, '_wcml_custom_prices_status', true );
|
518 |
-
|
519 |
-
$currency = $this->woocommerce_wpml->multi_currency->get_client_currency();
|
520 |
-
|
521 |
-
if ( $currency === wcml_get_woocommerce_currency_option() ) {
|
522 |
-
return $value;
|
523 |
-
}
|
524 |
-
|
525 |
-
$cost = get_post_meta( $original_id, $meta_key . '_' . $currency, true );
|
526 |
-
|
527 |
-
if ( $cost_status && !empty( $cost ) ) {
|
528 |
-
|
529 |
-
return $cost;
|
530 |
-
|
531 |
-
} else {
|
532 |
-
|
533 |
-
remove_filter( 'get_post_metadata', array( $this, 'filter_composite_product_cost' ), 10 );
|
534 |
-
|
535 |
-
$cost = get_post_meta( $original_id, $meta_key, true );
|
536 |
-
|
537 |
-
add_filter( 'get_post_metadata', array( $this, 'filter_composite_product_cost' ), 10, 4 );
|
538 |
-
|
539 |
-
if( $cost ){
|
540 |
-
|
541 |
-
$cost = $this->woocommerce_wpml->multi_currency->prices->convert_price_amount( $cost, $currency );
|
542 |
-
|
543 |
-
return $cost;
|
544 |
-
}
|
545 |
-
|
546 |
-
}
|
547 |
-
|
548 |
-
}
|
549 |
-
|
550 |
-
}
|
551 |
-
|
552 |
-
return $value;
|
553 |
-
}
|
554 |
-
|
555 |
-
public function update_composite_custom_prices( $product_id, $product_price, $custom_prices, $code ){
|
556 |
-
|
557 |
-
if( $this->get_product_type( $product_id ) == 'composite' ){
|
558 |
-
|
559 |
-
update_post_meta( $product_id, '_bto_base_regular_price'.'_'.$code, $custom_prices[ '_regular_price' ] );
|
560 |
-
update_post_meta( $product_id, '_bto_base_sale_price'.'_'.$code, $custom_prices[ '_sale_price' ] );
|
561 |
-
update_post_meta( $product_id, '_bto_base_price'.'_'.$code, $product_price );
|
562 |
-
|
563 |
-
}
|
564 |
-
|
565 |
}
|
566 |
|
567 |
public function replace_tm_editor_custom_fields_with_own_sections( $fields ){
|
568 |
-
$fields[] =
|
569 |
-
$fields[] =
|
570 |
|
571 |
return $fields;
|
572 |
}
|
573 |
-
|
574 |
-
public function apply_rounding_rules( $price ) {
|
575 |
-
|
576 |
-
if ( $price && is_composite_product() && wcml_is_multi_currency_on() ) {
|
577 |
-
$current_currency = $this->woocommerce_wpml->multi_currency->get_client_currency();
|
578 |
-
if( $current_currency !== wcml_get_woocommerce_currency_option() ) {
|
579 |
-
$price = $this->woocommerce_wpml->multi_currency->prices->apply_rounding_rules( $price, $current_currency );
|
580 |
-
}
|
581 |
-
}
|
582 |
-
|
583 |
-
return $price;
|
584 |
-
}
|
585 |
-
|
586 |
}
|
1 |
<?php
|
2 |
|
3 |
+
use WCML\Options\WPML;
|
4 |
use WPML\FP\Fns;
|
5 |
use WPML\FP\Obj;
|
6 |
+
use WPML\FP\Str;
|
7 |
|
8 |
+
class WCML_Composite_Products extends WCML_Compatibility_Helper implements \IWPML_Action {
|
|
|
9 |
|
10 |
+
const META_KEY_DATA = '_bto_data';
|
11 |
+
const META_KEY_SCENARIO = '_bto_scenario_data';
|
|
|
12 |
|
13 |
/**
|
14 |
* @var SitePress
|
15 |
*/
|
16 |
private $sitepress;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
17 |
|
18 |
+
public function __construct( SitePress $sitepress ) {
|
19 |
+
$this->sitepress = $sitepress;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
20 |
}
|
21 |
|
22 |
public function add_hooks(){
|
26 |
add_filter( 'woocommerce_composite_component_options_query_args', array($this, 'wpml_composites_transients_cache_per_language'), 10, 3 );
|
27 |
add_action( 'wcml_before_sync_product_data', array( $this, 'sync_composite_data_across_translations' ), 10, 2 );
|
28 |
add_action( 'wpml_translation_job_saved', array( $this, 'save_composite_data_translation' ), 10, 3 );
|
29 |
+
|
30 |
if( is_admin() ){
|
31 |
|
32 |
+
if ( ! WPML::useAte() ) { // Legacy actions/filters for CTE
|
33 |
+
add_action( 'wcml_gui_additional_box_html', [ $this, 'custom_box_html' ], 10, 3 );
|
34 |
+
add_filter( 'wcml_gui_additional_box_data', [ $this, 'custom_box_html_data' ], 10, 4 );
|
35 |
+
add_action( 'wcml_update_extra_fields', [ $this, 'update_component_strings' ], 10, 4 );
|
36 |
+
}
|
37 |
+
|
38 |
add_filter( 'woocommerce_json_search_found_products', array( $this, 'woocommerce_json_search_found_products' ) );
|
39 |
|
40 |
add_filter( 'wpml_tm_translation_job_data', array( $this, 'append_composite_data_translation_package' ), 10, 2 );
|
45 |
add_filter( 'wcml_after_load_lock_fields_js', array( $this, 'localize_lock_fields_js' ) );
|
46 |
add_action( 'init', array( $this, 'load_assets' ) );
|
47 |
|
|
|
|
|
48 |
add_filter( 'wcml_do_not_display_custom_fields_for_product', array( $this, 'replace_tm_editor_custom_fields_with_own_sections' ) );
|
|
|
|
|
|
|
49 |
}
|
50 |
|
51 |
}
|
52 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
53 |
public function woocommerce_composite_component_default_option($selected_value, $component_id, $object) {
|
54 |
|
55 |
if( !empty( $selected_value ) )
|
133 |
|
134 |
}
|
135 |
|
136 |
+
update_post_meta( $product_translation->element_id, self::META_KEY_DATA, $composite_data );
|
137 |
|
138 |
if ( $composite_scenarios_meta ) {
|
139 |
// sync product ids
|
152 |
->map( Obj::over( Obj::lensPath( [ 'scenario_actions', 'conditional_options', 'component_data' ] ), $translate_product_ids ) )
|
153 |
->toArray();
|
154 |
|
155 |
+
update_post_meta( $product_translation->element_id, self::META_KEY_SCENARIO, $composite_scenarios_meta );
|
156 |
}
|
157 |
}
|
158 |
}
|
160 |
}
|
161 |
}
|
162 |
|
163 |
+
/**
|
164 |
+
* @deprecated This method is used by CTE only.
|
165 |
+
*
|
166 |
+
* @param object $obj
|
167 |
+
* @param string|int $product_id
|
168 |
+
* @param mixed $data
|
169 |
+
*/
|
170 |
public function custom_box_html( $obj, $product_id, $data ){
|
171 |
|
172 |
if( $this->get_product_type( $product_id ) == 'composite' ){
|
222 |
|
223 |
}
|
224 |
|
225 |
+
/**
|
226 |
+
* @deprecated This method is used by CTE only.
|
227 |
+
*
|
228 |
+
* @param array $data
|
229 |
+
* @param string|int $bundle_id
|
230 |
+
* @param object $translation
|
231 |
+
* @param string $lang
|
232 |
+
*
|
233 |
+
* @return array
|
234 |
+
*/
|
235 |
public function custom_box_html_data( $data, $product_id, $translation, $lang ){
|
236 |
|
237 |
if( $this->get_product_type( $product_id ) == 'composite' ){
|
294 |
return $data;
|
295 |
}
|
296 |
|
297 |
+
/**
|
298 |
+
* @deprecated This method is used by CTE only.
|
299 |
+
*
|
300 |
+
* @param string|int $original_product_id
|
301 |
+
* @param string|int $product_id
|
302 |
+
* @param array $data
|
303 |
+
* @param string $language
|
304 |
+
*
|
305 |
+
* @return array
|
306 |
+
*/
|
307 |
public function update_component_strings( $original_product_id, $product_id, $data, $language ){
|
308 |
|
309 |
$composite_data = $this->get_composite_data( $product_id );
|
320 |
|
321 |
}
|
322 |
|
323 |
+
update_post_meta( $product_id, self::META_KEY_DATA, $composite_data );
|
324 |
|
325 |
$composite_scenarios_meta = $this->get_composite_scenarios_meta( $product_id );
|
326 |
if( $composite_scenarios_meta ){
|
335 |
}
|
336 |
}
|
337 |
|
338 |
+
update_post_meta( $product_id, self::META_KEY_SCENARIO, $composite_scenarios_meta );
|
339 |
|
340 |
return array(
|
341 |
'components' => $composite_data,
|
343 |
);
|
344 |
}
|
345 |
|
346 |
+
/**
|
347 |
+
* @param array $package
|
348 |
+
* @param \stdClass|\WP_Post $post
|
349 |
+
*
|
350 |
+
* @return array
|
351 |
+
*/
|
352 |
public function append_composite_data_translation_package( $package, $post ){
|
353 |
+
if( 'product' === $post->post_type ) {
|
354 |
+
// $add_titles_and_descriptions :: (array, string, array) -> void
|
355 |
+
$add_fields_to_package = function( $data, $fields, $subtype ) use ( &$package ) {
|
356 |
+
if ( $data ) {
|
357 |
+
foreach( $data as $key => $meta ){
|
358 |
+
foreach( $fields as $field ) {
|
359 |
+
if ( ! empty( $meta[ $field ] ) ) {
|
360 |
+
$package['contents'][ self::get_field_name( $key, $field, $subtype ) ] = [
|
361 |
+
'translate' => 1,
|
362 |
+
'data' => base64_encode( $meta[ $field ] ),
|
363 |
+
'format' => 'base64',
|
364 |
+
];
|
365 |
+
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
366 |
}
|
367 |
}
|
|
|
368 |
}
|
369 |
+
};
|
370 |
|
371 |
+
$add_fields_to_package( $this->get_composite_data( $post->ID ), [ 'title', 'description' ], '' );
|
372 |
+
$add_fields_to_package( $this->get_composite_scenarios_meta( $post->ID ), [ 'title', 'description' ], 'scenario' );
|
373 |
}
|
374 |
|
375 |
return $package;
|
376 |
+
}
|
377 |
|
378 |
+
/**
|
379 |
+
* @param string $component_id
|
380 |
+
* @param string $field
|
381 |
+
* @param string $subtype
|
382 |
+
*
|
383 |
+
* @return string
|
384 |
+
*/
|
385 |
+
private static function get_field_name( $component_id, $field, $subtype ) {
|
386 |
+
$subtype = $subtype ? $subtype . ':' : $subtype;
|
387 |
+
return 'wc_composite:' . $subtype . $component_id . ':' . $field;
|
388 |
}
|
389 |
|
390 |
+
/**
|
391 |
+
* @param string|int $post_id
|
392 |
+
* @param array $data
|
393 |
+
* @param object $job
|
394 |
+
*/
|
395 |
public function save_composite_data_translation( $post_id, $data, $job ){
|
396 |
+
if (
|
397 |
+
Str::startsWith( 'post_', $job->original_post_type )
|
398 |
+
&& 'product' === get_post_type( $job->original_doc_id )
|
399 |
+
) {
|
400 |
+
$composite_data = $this->get_composite_data( $job->original_doc_id );
|
401 |
+
|
402 |
+
if ( $composite_data ) {
|
403 |
+
$get_translation = function ( $name ) use ( $data ) {
|
404 |
+
return Obj::path( [ $name, 'data' ], $data );
|
405 |
+
};
|
406 |
+
|
407 |
+
// $apply_translations :: (array, array, string) -> array
|
408 |
+
$apply_translations = function ( $data, $fields, $subtype ) use ( $get_translation ) {
|
409 |
+
foreach ( $data as $key => $meta ) {
|
410 |
+
foreach ( $fields as $field ) {
|
411 |
+
$translation = $get_translation( self::get_field_name( $key, $field, $subtype ) );
|
412 |
+
|
413 |
+
if ( $translation ) {
|
414 |
+
$data[ $key ][ $field ] = $translation;
|
415 |
+
}
|
416 |
+
}
|
417 |
+
}
|
418 |
|
419 |
+
return $data;
|
420 |
+
};
|
421 |
|
422 |
+
// $adjust_ids :: (array, string) -> array
|
423 |
+
$adjust_ids = function ( $data, $lang ) {
|
424 |
+
foreach ( $data as $key => $meta ) {
|
425 |
+
$ids_key = $cpt = null;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
426 |
|
427 |
+
if ( 'product_ids' === $meta['query_type'] ) {
|
428 |
+
$ids_key = 'assigned_ids';
|
429 |
+
$cpt = 'product';
|
430 |
+
} elseif ( 'category_ids' === $meta['query_type'] ) {
|
431 |
+
$ids_key = 'assigned_category_ids';
|
432 |
+
$cpt = 'product_cat';
|
433 |
+
}
|
434 |
|
435 |
+
if ( $ids_key && $cpt ) {
|
436 |
+
foreach ( $meta[ $ids_key ] as $idx => $assigned_id ) {
|
437 |
+
$data[ $key ][ $ids_key ][ $idx ] = apply_filters( 'wpml_object_id', $assigned_id, $cpt, true, $lang );
|
438 |
+
}
|
439 |
+
}
|
440 |
}
|
441 |
|
442 |
+
return $data;
|
443 |
+
};
|
|
|
|
|
|
|
444 |
|
445 |
+
update_post_meta(
|
446 |
+
$post_id,
|
447 |
+
self::META_KEY_DATA,
|
448 |
+
$adjust_ids( $apply_translations( $composite_data, [ 'title', 'description' ], '' ), $job->language_code )
|
449 |
+
);
|
450 |
|
451 |
+
update_post_meta(
|
452 |
+
$post_id,
|
453 |
+
self::META_KEY_SCENARIO,
|
454 |
+
$apply_translations( $this->get_composite_scenarios_meta( $job->original_doc_id ), [ 'title', 'description' ], 'scenario' )
|
455 |
+
);
|
456 |
}
|
|
|
|
|
457 |
}
|
458 |
}
|
459 |
|
512 |
}
|
513 |
|
514 |
public function get_composite_scenarios_meta( $product_id ){
|
515 |
+
return get_post_meta( $product_id, self::META_KEY_SCENARIO, true );
|
516 |
}
|
517 |
|
518 |
public function get_composite_data( $product_id ){
|
519 |
+
return get_post_meta( $product_id, self::META_KEY_DATA, true ) ?: [];
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
520 |
}
|
521 |
|
522 |
public function replace_tm_editor_custom_fields_with_own_sections( $fields ){
|
523 |
+
$fields[] = self::META_KEY_DATA;
|
524 |
+
$fields[] = self::META_KEY_SCENARIO;
|
525 |
|
526 |
return $fields;
|
527 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
528 |
}
|
compatibility/WcDynamicPricing/Factory.php
ADDED
@@ -0,0 +1,31 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace WCML\Compatibility\WcDynamicPricing;
|
4 |
+
|
5 |
+
use WCML\Compatibility\ComponentFactory;
|
6 |
+
use WCML\StandAlone\IStandAloneAction;
|
7 |
+
use function WCML\functions\getSitePress;
|
8 |
+
use function WCML\functions\isStandAlone;
|
9 |
+
|
10 |
+
/**
|
11 |
+
* @see https://woocommerce.com/products/dynamic-pricing/
|
12 |
+
*/
|
13 |
+
class Factory extends ComponentFactory implements IStandAloneAction {
|
14 |
+
|
15 |
+
/**
|
16 |
+
* @inheritDoc
|
17 |
+
*/
|
18 |
+
public function create() {
|
19 |
+
$hooks = [];
|
20 |
+
|
21 |
+
if ( wcml_is_multi_currency_on() ) {
|
22 |
+
$hooks[] = new MulticurrencyHooks();
|
23 |
+
}
|
24 |
+
|
25 |
+
if ( ! isStandAlone() ) {
|
26 |
+
$hooks[] = new \WCML_Dynamic_Pricing( getSitePress() );
|
27 |
+
}
|
28 |
+
|
29 |
+
return $hooks;
|
30 |
+
}
|
31 |
+
}
|
compatibility/WcDynamicPricing/MulticurrencyHooks.php
ADDED
@@ -0,0 +1,78 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace WCML\Compatibility\WcDynamicPricing;
|
4 |
+
|
5 |
+
class MulticurrencyHooks implements \IWPML_Action {
|
6 |
+
|
7 |
+
public function add_hooks() {
|
8 |
+
add_filter( 'wc_dynamic_pricing_load_modules', [ $this, 'filter_price' ] );
|
9 |
+
add_filter( 'woocommerce_dynamic_pricing_get_rule_amount', [ $this, 'woocommerce_dynamic_pricing_get_rule_amount' ], 10, 2 );
|
10 |
+
add_filter( 'dynamic_pricing_product_rules', [ $this, 'dynamic_pricing_product_rules' ] );
|
11 |
+
}
|
12 |
+
|
13 |
+
/**
|
14 |
+
* @param array $modules
|
15 |
+
*
|
16 |
+
* @return array
|
17 |
+
*/
|
18 |
+
public function filter_price( $modules ) {
|
19 |
+
|
20 |
+
foreach ( $modules as $mod_key => $module ) {
|
21 |
+
if ( isset( $module->available_rulesets ) ) {
|
22 |
+
$available_rulesets = $module->available_rulesets;
|
23 |
+
|
24 |
+
foreach ( $available_rulesets as $rule_key => $available_ruleset ) {
|
25 |
+
|
26 |
+
if ( isset( $available_ruleset['rules'] ) && is_array( $available_ruleset['rules'] ) ) {
|
27 |
+
$rules = $available_ruleset['rules'];
|
28 |
+
foreach ( $rules as $r_key => $rule ) {
|
29 |
+
if ( 'fixed_product' === $rule['type'] ) {
|
30 |
+
$rules[ $r_key ]['amount'] = apply_filters( 'wcml_raw_price_amount', $rule['amount'] );
|
31 |
+
}
|
32 |
+
}
|
33 |
+
$modules[ $mod_key ]->available_rulesets[ $rule_key ]['rules'] = $rules;
|
34 |
+
|
35 |
+
} elseif ( isset( $available_ruleset['type'] ) && 'fixed_product' === $available_ruleset['type'] ) {
|
36 |
+
$modules[ $mod_key ]->available_rulesets[ $rule_key ]['amount'] = apply_filters( 'wcml_raw_price_amount', $available_ruleset['amount'] );
|
37 |
+
}
|
38 |
+
}
|
39 |
+
}
|
40 |
+
}
|
41 |
+
|
42 |
+
return $modules;
|
43 |
+
}
|
44 |
+
|
45 |
+
/**
|
46 |
+
* @param float $amount
|
47 |
+
* @param object $rule
|
48 |
+
*
|
49 |
+
* @return float
|
50 |
+
*/
|
51 |
+
public function woocommerce_dynamic_pricing_get_rule_amount( $amount, $rule ) {
|
52 |
+
|
53 |
+
if ( 'price_discount' === $rule['type'] || 'fixed_price' === $rule['type'] ) {
|
54 |
+
$amount = apply_filters( 'wcml_raw_price_amount', $amount );
|
55 |
+
}
|
56 |
+
|
57 |
+
return $amount;
|
58 |
+
}
|
59 |
+
|
60 |
+
/**
|
61 |
+
* @param array $rules
|
62 |
+
*
|
63 |
+
* @return array
|
64 |
+
*/
|
65 |
+
public function dynamic_pricing_product_rules( $rules ) {
|
66 |
+
if ( is_array( $rules ) ) {
|
67 |
+
foreach ( $rules as $r_key => $rule ) {
|
68 |
+
foreach ( $rule['rules'] as $key => $product_rule ) {
|
69 |
+
if ( 'price_discount' === $product_rule['type'] || 'fixed_price' === $product_rule['type'] ) {
|
70 |
+
$rules[ $r_key ]['rules'][ $key ]['amount'] = apply_filters( 'wcml_raw_price_amount', $product_rule['amount'] );
|
71 |
+
}
|
72 |
+
}
|
73 |
+
}
|
74 |
+
}
|
75 |
+
return $rules;
|
76 |
+
}
|
77 |
+
|
78 |
+
}
|
compatibility/{class-wcml-dynamic-pricing.php → WcDynamicPricing/class-wcml-dynamic-pricing.php}
RENAMED
@@ -5,7 +5,7 @@ use WPML\FP\Obj;
|
|
5 |
/**
|
6 |
* Class WCML_Dynamic_Pricing
|
7 |
*/
|
8 |
-
class WCML_Dynamic_Pricing {
|
9 |
|
10 |
/**
|
11 |
* @var SitePress
|
@@ -22,52 +22,14 @@ class WCML_Dynamic_Pricing {
|
|
22 |
}
|
23 |
|
24 |
public function add_hooks() {
|
25 |
-
|
26 |
if ( ! is_admin() ) {
|
27 |
add_filter( 'woocommerce_dynamic_pricing_is_object_in_terms', [ $this, 'is_object_in_translated_terms' ], 10, 3 );
|
28 |
-
|
29 |
-
add_filter( 'wc_dynamic_pricing_load_modules', [ $this, 'filter_price' ] );
|
30 |
add_filter( 'wc_dynamic_pricing_load_modules', [ $this, 'translate_collector_args' ] );
|
31 |
add_filter( 'woocommerce_dynamic_pricing_is_applied_to', [ $this, 'woocommerce_dynamic_pricing_is_applied_to' ], 10, 5 );
|
32 |
-
add_filter( 'woocommerce_dynamic_pricing_get_rule_amount', [ $this, 'woocommerce_dynamic_pricing_get_rule_amount' ], 10, 2 );
|
33 |
-
add_filter( 'dynamic_pricing_product_rules', [ $this, 'dynamic_pricing_product_rules' ] );
|
34 |
} else {
|
35 |
$this->hide_language_switcher_for_settings_page();
|
36 |
}
|
37 |
add_filter( 'woocommerce_product_get__pricing_rules', [ $this, 'translate_variations_in_rules' ] );
|
38 |
-
|
39 |
-
}
|
40 |
-
|
41 |
-
/**
|
42 |
-
* @param array $modules
|
43 |
-
*
|
44 |
-
* @return array
|
45 |
-
*/
|
46 |
-
public function filter_price( $modules ) {
|
47 |
-
|
48 |
-
foreach ( $modules as $mod_key => $module ) {
|
49 |
-
if ( isset( $module->available_rulesets ) ) {
|
50 |
-
$available_rulesets = $module->available_rulesets;
|
51 |
-
|
52 |
-
foreach ( $available_rulesets as $rule_key => $available_ruleset ) {
|
53 |
-
|
54 |
-
if ( isset( $available_ruleset['rules'] ) && is_array( $available_ruleset['rules'] ) ) {
|
55 |
-
$rules = $available_ruleset['rules'];
|
56 |
-
foreach ( $rules as $r_key => $rule ) {
|
57 |
-
if ( 'fixed_product' === $rule['type'] ) {
|
58 |
-
$rules[ $r_key ]['amount'] = apply_filters( 'wcml_raw_price_amount', $rule['amount'] );
|
59 |
-
}
|
60 |
-
}
|
61 |
-
$modules[ $mod_key ]->available_rulesets[ $rule_key ]['rules'] = $rules;
|
62 |
-
|
63 |
-
} elseif ( isset( $available_ruleset['type'] ) && 'fixed_product' === $available_ruleset['type'] ) {
|
64 |
-
$modules[ $mod_key ]->available_rulesets[ $rule_key ]['amount'] = apply_filters( 'wcml_raw_price_amount', $available_ruleset['amount'] );
|
65 |
-
}
|
66 |
-
}
|
67 |
-
}
|
68 |
-
}
|
69 |
-
|
70 |
-
return $modules;
|
71 |
}
|
72 |
|
73 |
/**
|
@@ -76,7 +38,6 @@ class WCML_Dynamic_Pricing {
|
|
76 |
* @return array
|
77 |
*/
|
78 |
public function translate_collector_args( $modules ) {
|
79 |
-
|
80 |
foreach ( $modules as $mod_key => $module ) {
|
81 |
if ( isset( $module->available_advanced_rulesets ) ) {
|
82 |
foreach ( $module->available_advanced_rulesets as $rule_key => $rule ) {
|
@@ -111,7 +72,6 @@ class WCML_Dynamic_Pricing {
|
|
111 |
return is_object_in_term( $product_id, 'product_cat', $categories );
|
112 |
}
|
113 |
|
114 |
-
|
115 |
/**
|
116 |
* @param bool $process_discounts
|
117 |
* @param WC_Product $_product
|
@@ -190,7 +150,7 @@ class WCML_Dynamic_Pricing {
|
|
190 |
return wpml_collect( $requirements[ $class_name ] )
|
191 |
->filter(
|
192 |
function ( $property ) use ( $dynamic_pricing ) {
|
193 |
-
|
194 |
}
|
195 |
)
|
196 |
->count();
|
@@ -218,40 +178,6 @@ class WCML_Dynamic_Pricing {
|
|
218 |
);
|
219 |
}
|
220 |
|
221 |
-
/**
|
222 |
-
* @param float $amount
|
223 |
-
* @param object $rule
|
224 |
-
*
|
225 |
-
* @return float
|
226 |
-
*/
|
227 |
-
public function woocommerce_dynamic_pricing_get_rule_amount( $amount, $rule ) {
|
228 |
-
|
229 |
-
if ( 'price_discount' === $rule['type'] || 'fixed_price' === $rule['type'] ) {
|
230 |
-
$amount = apply_filters( 'wcml_raw_price_amount', $amount );
|
231 |
-
}
|
232 |
-
|
233 |
-
return $amount;
|
234 |
-
}
|
235 |
-
|
236 |
-
|
237 |
-
/**
|
238 |
-
* @param array $rules
|
239 |
-
*
|
240 |
-
* @return array
|
241 |
-
*/
|
242 |
-
public function dynamic_pricing_product_rules( $rules ) {
|
243 |
-
if ( is_array( $rules ) ) {
|
244 |
-
foreach ( $rules as $r_key => $rule ) {
|
245 |
-
foreach ( $rule['rules'] as $key => $product_rule ) {
|
246 |
-
if ( 'price_discount' === $product_rule['type'] || 'fixed_price' === $product_rule['type'] ) {
|
247 |
-
$rules[ $r_key ]['rules'][ $key ]['amount'] = apply_filters( 'wcml_raw_price_amount', $product_rule['amount'] );
|
248 |
-
}
|
249 |
-
}
|
250 |
-
}
|
251 |
-
}
|
252 |
-
return $rules;
|
253 |
-
}
|
254 |
-
|
255 |
/**
|
256 |
* @param array $rules
|
257 |
*
|
5 |
/**
|
6 |
* Class WCML_Dynamic_Pricing
|
7 |
*/
|
8 |
+
class WCML_Dynamic_Pricing implements \IWPML_Action {
|
9 |
|
10 |
/**
|
11 |
* @var SitePress
|
22 |
}
|
23 |
|
24 |
public function add_hooks() {
|
|
|
25 |
if ( ! is_admin() ) {
|
26 |
add_filter( 'woocommerce_dynamic_pricing_is_object_in_terms', [ $this, 'is_object_in_translated_terms' ], 10, 3 );
|
|
|
|
|
27 |
add_filter( 'wc_dynamic_pricing_load_modules', [ $this, 'translate_collector_args' ] );
|
28 |
add_filter( 'woocommerce_dynamic_pricing_is_applied_to', [ $this, 'woocommerce_dynamic_pricing_is_applied_to' ], 10, 5 );
|
|
|
|
|
29 |
} else {
|
30 |
$this->hide_language_switcher_for_settings_page();
|
31 |
}
|
32 |
add_filter( 'woocommerce_product_get__pricing_rules', [ $this, 'translate_variations_in_rules' ] );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
33 |
}
|
34 |
|
35 |
/**
|
38 |
* @return array
|
39 |
*/
|
40 |
public function translate_collector_args( $modules ) {
|
|
|
41 |
foreach ( $modules as $mod_key => $module ) {
|
42 |
if ( isset( $module->available_advanced_rulesets ) ) {
|
43 |
foreach ( $module->available_advanced_rulesets as $rule_key => $rule ) {
|
72 |
return is_object_in_term( $product_id, 'product_cat', $categories );
|
73 |
}
|
74 |
|
|
|
75 |
/**
|
76 |
* @param bool $process_discounts
|
77 |
* @param WC_Product $_product
|
150 |
return wpml_collect( $requirements[ $class_name ] )
|
151 |
->filter(
|
152 |
function ( $property ) use ( $dynamic_pricing ) {
|
153 |
+
return isset( $dynamic_pricing->$property ) && $dynamic_pricing->$property;
|
154 |
}
|
155 |
)
|
156 |
->count();
|
178 |
);
|
179 |
}
|
180 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
181 |
/**
|
182 |
* @param array $rules
|
183 |
*
|
compatibility/WcExporter/Factory.php
ADDED
@@ -0,0 +1,21 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace WCML\Compatibility\WcExporter;
|
4 |
+
|
5 |
+
use WCML\Compatibility\ComponentFactory;
|
6 |
+
use WCML_wcExporter;
|
7 |
+
use function WCML\functions\getSitePress;
|
8 |
+
use function WCML\functions\getWooCommerceWpml;
|
9 |
+
|
10 |
+
/**
|
11 |
+
* @see https://br.wordpress.org/plugins/woocommerce-exporter/
|
12 |
+
*/
|
13 |
+
class Factory extends ComponentFactory {
|
14 |
+
|
15 |
+
/**
|
16 |
+
* @inheritDoc
|
17 |
+
*/
|
18 |
+
public function create() {
|
19 |
+
return new WCML_wcExporter( getSitePress(), getWooCommerceWpml() );
|
20 |
+
}
|
21 |
+
}
|
compatibility/{class-wcml-wcexporter.php → WcExporter/class-wcml-wcexporter.php}
RENAMED
@@ -1,6 +1,6 @@
|
|
1 |
<?php
|
2 |
|
3 |
-
class WCML_wcExporter {
|
4 |
|
5 |
/**
|
6 |
* @var SitePress
|
1 |
<?php
|
2 |
|
3 |
+
class WCML_wcExporter implements \IWPML_Action {
|
4 |
|
5 |
/**
|
6 |
* @var SitePress
|
compatibility/WcMemberships/Factory.php
ADDED
@@ -0,0 +1,15 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace WCML\Compatibility\WcMemberships;
|
4 |
+
|
5 |
+
use WCML\Compatibility\ComponentFactory;
|
6 |
+
|
7 |
+
class Factory extends ComponentFactory {
|
8 |
+
|
9 |
+
/**
|
10 |
+
* @inheritDoc
|
11 |
+
*/
|
12 |
+
public function create() {
|
13 |
+
return new \WCML_WC_Memberships( new \WPML_WP_API() );
|
14 |
+
}
|
15 |
+
}
|
compatibility/{class-wcml-wc-memberships.php → WcMemberships/class-wcml-wc-memberships.php}
RENAMED
@@ -1,6 +1,6 @@
|
|
1 |
<?php
|
2 |
|
3 |
-
class WCML_WC_Memberships {
|
4 |
|
5 |
/**
|
6 |
* @var WPML_WP_API
|
1 |
<?php
|
2 |
|
3 |
+
class WCML_WC_Memberships implements \IWPML_Action {
|
4 |
|
5 |
/**
|
6 |
* @var WPML_WP_API
|
compatibility/WcMixAndMatch/Factory.php
ADDED
@@ -0,0 +1,30 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace WCML\Compatibility\WcMixAndMatch;
|
4 |
+
|
5 |
+
use WCML\Compatibility\ComponentFactory;
|
6 |
+
use WCML\StandAlone\IStandAloneAction;
|
7 |
+
|
8 |
+
use function WCML\functions\getSitePress;
|
9 |
+
use function WCML\functions\isStandAlone;
|
10 |
+
|
11 |
+
class Factory extends ComponentFactory implements IStandAloneAction {
|
12 |
+
|
13 |
+
/**
|
14 |
+
* @inheritDoc
|
15 |
+
*/
|
16 |
+
public function create() {
|
17 |
+
$hooks = [];
|
18 |
+
|
19 |
+
if ( wcml_is_multi_currency_on() ) {
|
20 |
+
$hooks[] = new MulticurrencyHooks();
|
21 |
+
}
|
22 |
+
|
23 |
+
if ( ! isStandAlone() ) {
|
24 |
+
$hooks[] = new \WCML_Mix_And_Match_Products( getSitePress() );
|
25 |
+
}
|
26 |
+
|
27 |
+
return $hooks;
|
28 |
+
}
|
29 |
+
|
30 |
+
}
|
compatibility/WcMixAndMatch/MulticurrencyHooks.php
ADDED
@@ -0,0 +1,74 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace WCML\Compatibility\WcMixAndMatch;
|
4 |
+
|
5 |
+
class MulticurrencyHooks implements \IWPML_Action {
|
6 |
+
|
7 |
+
public function add_hooks() {
|
8 |
+
add_filter( 'wcml_price_custom_fields_filtered', [ $this, 'get_price_custom_fields' ], 10, 2 );
|
9 |
+
add_filter( 'wcml_update_custom_prices_values', [ $this, 'update_container_custom_prices_values' ], 10, 2 );
|
10 |
+
add_filter( 'wcml_after_save_custom_prices', [ $this, 'update_container_base_price' ], 10, 4 );
|
11 |
+
}
|
12 |
+
|
13 |
+
/**
|
14 |
+
* Add MNM price fields to list to be converted.
|
15 |
+
*
|
16 |
+
* @since 5.0.0
|
17 |
+
*
|
18 |
+
* @param array $custom_fields
|
19 |
+
* @return array
|
20 |
+
*/
|
21 |
+
public function get_price_custom_fields( $custom_fields ) {
|
22 |
+
return array_merge(
|
23 |
+
$custom_fields,
|
24 |
+
[
|
25 |
+
'_mnm_base_regular_price',
|
26 |
+
'_mnm_base_sale_price',
|
27 |
+
'_mnm_base_price',
|
28 |
+
'_mnm_max_price',
|
29 |
+
'_mnm_max_regular_price',
|
30 |
+
]
|
31 |
+
);
|
32 |
+
}
|
33 |
+
|
34 |
+
/**
|
35 |
+
* Swap the base price for the custom price in that currency.
|
36 |
+
*
|
37 |
+
* @since 5.0.0
|
38 |
+
*
|
39 |
+
* @param array $prices
|
40 |
+
* @param string $code
|
41 |
+
* @return array
|
42 |
+
*/
|
43 |
+
public function update_container_custom_prices_values( $prices, $code ) {
|
44 |
+
foreach ( [
|
45 |
+
'_custom_regular_price' => '_mnm_base_regular_price',
|
46 |
+
'_custom_sale_price' => '_mnm_base_sale_price',
|
47 |
+
] as $wc_price => $custom_price ) {
|
48 |
+
if ( isset( $_POST[ $wc_price ][ $code ] ) ) {
|
49 |
+
$prices[ $custom_price ] = wc_format_decimal( $_POST[ $wc_price ][ $code ] );
|
50 |
+
}
|
51 |
+
}
|
52 |
+
|
53 |
+
return $prices;
|
54 |
+
}
|
55 |
+
|
56 |
+
/**
|
57 |
+
* Save base price per currency.
|
58 |
+
*
|
59 |
+
* @since 5.0.0
|
60 |
+
*
|
61 |
+
* @param int $post_id
|
62 |
+
* @param string $product_price
|
63 |
+
* @param array $custom_prices
|
64 |
+
* @param string $code
|
65 |
+
*/
|
66 |
+
public function update_container_base_price( $post_id, $product_price, $custom_prices, $code ) {
|
67 |
+
|
68 |
+
if ( isset( $custom_prices['_mnm_base_regular_price'] ) ) {
|
69 |
+
update_post_meta( $post_id, '_mnm_base_price_' . $code, $product_price );
|
70 |
+
}
|
71 |
+
|
72 |
+
}
|
73 |
+
|
74 |
+
}
|
compatibility/WcMixAndMatch/class-wcml-mix-and-match-products.php
ADDED
@@ -0,0 +1,235 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Mix and Match Products compatibility class.
|
4 |
+
*
|
5 |
+
* @version 5.0.0
|
6 |
+
*/
|
7 |
+
class WCML_Mix_And_Match_Products implements \IWPML_Action {
|
8 |
+
|
9 |
+
/**
|
10 |
+
* @var SitePress
|
11 |
+
*/
|
12 |
+
private $sitepress;
|
13 |
+
|
14 |
+
/**
|
15 |
+
* @param SitePress $sitepress
|
16 |
+
*/
|
17 |
+
public function __construct( SitePress $sitepress ) {
|
18 |
+
$this->sitepress = $sitepress;
|
19 |
+
}
|
20 |
+
|
21 |
+
/**
|
22 |
+
* Attach callbacks.
|
23 |
+
*
|
24 |
+
* @since 5.0.0
|
25 |
+
*/
|
26 |
+
public function add_hooks() {
|
27 |
+
// Support MNM 2.0 custom tables, cart syncing.
|
28 |
+
if ( is_callable( [ 'WC_MNM_Compatibility', 'is_db_version_gte' ] ) && WC_MNM_Compatibility::is_db_version_gte( '2.0' ) ) {
|
29 |
+
add_action( 'wcml_after_sync_product_data', [ $this, 'sync_allowed_contents' ], 10, 2 );
|
30 |
+
add_filter( 'wcml_cart_contents', [ $this, 'sync_cart' ], 10, 4 );
|
31 |
+
} else {
|
32 |
+
add_action( 'updated_post_meta', [ $this, 'sync_mnm_data' ], 10, 4 );
|
33 |
+
}
|
34 |
+
}
|
35 |
+
|
36 |
+
/**
|
37 |
+
* Translate container data with translated values when the product is duplicated.
|
38 |
+
*
|
39 |
+
* Handles translating source products to the MNM custom table.
|
40 |
+
* Handles translating source categories as meta.
|
41 |
+
*
|
42 |
+
* @param int $container_id
|
43 |
+
* @param int $translated_container_id
|
44 |
+
*/
|
45 |
+
public function sync_allowed_contents( $container_id, $translated_container_id ) {
|
46 |
+
|
47 |
+
if ( has_term( 'mix-and-match', 'product_type', $container_id ) ) {
|
48 |
+
|
49 |
+
$translated_child_items = [];
|
50 |
+
$lang = $this->sitepress->get_language_for_element( $translated_container_id, 'post_product' );
|
51 |
+
|
52 |
+
$original_product = wc_get_product( $container_id );
|
53 |
+
$translated_product = wc_get_product( $translated_container_id );
|
54 |
+
|
55 |
+
if ( $original_product ) {
|
56 |
+
|
57 |
+
$original_child_items = $original_product->get_child_items( 'edit' );
|
58 |
+
|
59 |
+
$translated_child_items = [];
|
60 |
+
|
61 |
+
// Translate child items.
|
62 |
+
if ( ! empty( $original_child_items ) ) {
|
63 |
+
|
64 |
+
foreach ( $original_child_items as $item_key => $original_child_item ) {
|
65 |
+
|
66 |
+
$translated_child_items[] = [
|
67 |
+
'product_id' => apply_filters( 'wpml_object_id', $original_child_item->get_product_id(), 'product', false, $lang ),
|
68 |
+
'variation_id' => apply_filters( 'wpml_object_id', $original_child_item->get_variation_id(), 'product_variation', false, $lang ),
|
69 |
+
];
|
70 |
+
|
71 |
+
}
|
72 |
+
}
|
73 |
+
|
74 |
+
if ( $translated_product && ! empty( $translated_child_items ) ) {
|
75 |
+
$translated_product->set_child_items( $translated_child_items );
|
76 |
+
}
|
77 |
+
|
78 |
+
// Translate child source categories.
|
79 |
+
$original_child_cat_ids = $original_product->get_child_category_ids( 'edit' );
|
80 |
+
$translated_child_cat_ids = [];
|
81 |
+
|
82 |
+
foreach ( $original_child_cat_ids as $original_cat_id ) {
|
83 |
+
$translated_child_cat_ids[] = apply_filters( 'wpml_object_id', $original_cat_id, 'product_cat', true, $lang );
|
84 |
+
}
|
85 |
+
|
86 |
+
if ( $translated_product && ! empty( $translated_child_cat_ids ) ) {
|
87 |
+
$translated_product->set_child_category_ids( $translated_child_cat_ids );
|
88 |
+
}
|
89 |
+
|
90 |
+
// Save product.
|
91 |
+
$translated_product->save();
|
92 |
+
|
93 |
+
}
|
94 |
+
}
|
95 |
+
|
96 |
+
}
|
97 |
+
|
98 |
+
/**
|
99 |
+
* Update the cart contents to the new language
|
100 |
+
*
|
101 |
+
* @since 5.0.0
|
102 |
+
*
|
103 |
+
* @param array $new_cart_contents
|
104 |
+
* @param array $cart_contents
|
105 |
+
* @param string $key
|
106 |
+
* @param string $new_key
|
107 |
+
*
|
108 |
+
* @return array
|
109 |
+
*/
|
110 |
+
public function sync_cart( $new_cart_contents, $cart_contents, $key, $new_key ) {
|
111 |
+
if ( ! function_exists( 'wc_mnm_is_container_cart_item' )
|
112 |
+
|| ! function_exists( 'wc_mnm_get_child_cart_items' )
|
113 |
+
|| ! function_exists( 'wc_mnm_maybe_is_child_cart_item' )
|
114 |
+
|| ! function_exists( 'wc_mnm_get_cart_item_container' )
|
115 |
+
) {
|
116 |
+
return $new_cart_contents;
|
117 |
+
}
|
118 |
+
|
119 |
+
$current_language = $this->sitepress->get_current_language();
|
120 |
+
|
121 |
+
// Translate container.
|
122 |
+
if ( wc_mnm_is_container_cart_item( $new_cart_contents[ $new_key ] ) ) {
|
123 |
+
|
124 |
+
$new_config = [];
|
125 |
+
|
126 |
+
// Translate config.
|
127 |
+
foreach ( $new_cart_contents[ $new_key ]['mnm_config'] as $id => $data ) {
|
128 |
+
|
129 |
+
$tr_product_id = apply_filters( 'wpml_object_id', $data['product_id'], 'product', false, $current_language );
|
130 |
+
$tr_variation_id = 0;
|
131 |
+
|
132 |
+
if ( isset( $data['variation_id'] ) && $data['variation_id'] ) {
|
133 |
+
$tr_variation_id = apply_filters( 'wpml_object_id', $data['variation_id'], 'product_variation', false, $current_language );
|
134 |
+
}
|
135 |
+
|
136 |
+
$tr_child_id = $tr_variation_id ? intval( $tr_variation_id ) : intval( $tr_product_id );
|
137 |
+
|
138 |
+
$new_config[ $tr_child_id ] = [
|
139 |
+
'mnm_child_id' => $tr_child_id,
|
140 |
+
'product_id' => intval( $tr_product_id ),
|
141 |
+
'variation_id' => intval( $tr_variation_id ),
|
142 |
+
'quantity' => $data['quantity'],
|
143 |
+
'variation' => $data['variation'], // @todo: translate attributes
|
144 |
+
];
|
145 |
+
|
146 |
+
}
|
147 |
+
|
148 |
+
if ( ! empty( $new_config ) ) {
|
149 |
+
$new_cart_contents[ $new_key ]['mnm_config'] = $new_config;
|
150 |
+
}
|
151 |
+
|
152 |
+
// Find all children and stash new container cart key. Need to direclty manipulate the wc()->cart as $cart_contents isn't persisted.
|
153 |
+
foreach ( wc_mnm_get_child_cart_items( $new_cart_contents[ $new_key ] ) as $child_key => $child_item ) {
|
154 |
+
WC()->cart->cart_contents[ $child_key ]['translated_mnm_container'] = $new_key;
|
155 |
+
}
|
156 |
+
}
|
157 |
+
|
158 |
+
// Translate children.
|
159 |
+
if ( wc_mnm_maybe_is_child_cart_item( $new_cart_contents[ $new_key ] ) ) {
|
160 |
+
|
161 |
+
// Update the child's container and remove the stashed version.
|
162 |
+
$new_cart_contents[ $new_key ]['mnm_container'] = $cart_contents[ $key ]['translated_mnm_container'];
|
163 |
+
unset( $cart_contents[ $key ]['translated_mnm_container'] );
|
164 |
+
|
165 |
+
$container_key = wc_mnm_get_cart_item_container( $new_cart_contents[ $new_key ], $new_cart_contents, true );
|
166 |
+
|
167 |
+
if ( $container_key ) {
|
168 |
+
|
169 |
+
// Swap keys in container's content array.
|
170 |
+
$remove_key = array_search( $key, $new_cart_contents[ $container_key ]['mnm_contents'] );
|
171 |
+
unset( $new_cart_contents[ $container_key ]['mnm_contents'][ $remove_key ] );
|
172 |
+
$new_cart_contents[ $container_key ]['mnm_contents'][] = $new_key;
|
173 |
+
|
174 |
+
}
|
175 |
+
}
|
176 |
+
|
177 |
+
return $new_cart_contents;
|
178 |
+
}
|
179 |
+
|
180 |
+
/**
|
181 |
+
* Translate the _mnm_data meta of child products.
|
182 |
+
*
|
183 |
+
* For Mix and Match 1.x data.
|
184 |
+
*
|
185 |
+
* @param string $meta_id
|
186 |
+
* @param int $post_id
|
187 |
+
* @param string $meta_key
|
188 |
+
* @param mixed $meta_value
|
189 |
+
*/
|
190 |
+
public function sync_mnm_data( $meta_id, $post_id, $meta_key, $meta_value ) {
|
191 |
+
if ( '_mnm_data' !== $meta_key ) {
|
192 |
+
return;
|
193 |
+
}
|
194 |
+
|
195 |
+
global $sitepress, $woocommerce_wpml;
|
196 |
+
|
197 |
+
$post = get_post( $post_id );
|
198 |
+
|
199 |
+
// Skip auto-drafts, skip autosave.
|
200 |
+
if ( 'auto-draft' === $post->post_status || isset( $_POST['autosave'] ) ) {
|
201 |
+
return;
|
202 |
+
}
|
203 |
+
|
204 |
+
if ( 'product' === $post->post_type ) {
|
205 |
+
remove_action( 'updated_post_meta', [ $this, 'sync_mnm_data' ], 10 );
|
206 |
+
|
207 |
+
if ( $woocommerce_wpml->products->is_original_product( $post_id ) ) {
|
208 |
+
$original_product_id = $post_id;
|
209 |
+
} else {
|
210 |
+
$original_product_id = $woocommerce_wpml->products->get_original_product_id( $post_id );
|
211 |
+
}
|
212 |
+
|
213 |
+
$mnm_data = maybe_unserialize( get_post_meta( $original_product_id, '_mnm_data', true ) );
|
214 |
+
$product_trid = $sitepress->get_element_trid( $original_product_id, 'post_product' );
|
215 |
+
$product_translations = $sitepress->get_element_translations( $product_trid, 'post_product' );
|
216 |
+
|
217 |
+
foreach ( $product_translations as $product_translation ) {
|
218 |
+
if ( empty( $product_translation->original ) ) {
|
219 |
+
foreach ( $mnm_data as $key => $mnm_element ) {
|
220 |
+
|
221 |
+
$trnsl_prod = apply_filters( 'translate_object_id', $key, 'product', true, $product_translation->language_code );
|
222 |
+
$mnm_element['product_id'] = $trnsl_prod;
|
223 |
+
$mnm_data[ $trnsl_prod ] = $mnm_element;
|
224 |
+
unset( $mnm_data[ $key ] );
|
225 |
+
}
|
226 |
+
|
227 |
+
update_post_meta( $product_translation->element_id, '_mnm_data', $mnm_data );
|
228 |
+
}
|
229 |
+
}
|
230 |
+
|
231 |
+
add_action( 'updated_post_meta', [ $this, 'sync_mnm_data' ], 10, 4 );
|
232 |
+
}
|
233 |
+
}
|
234 |
+
|
235 |
+
}
|
compatibility/WcNameYourPrice/Factory.php
ADDED
@@ -0,0 +1,26 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace WCML\Compatibility\WcNameYourPrice;
|
4 |
+
|
5 |
+
use WCML\Compatibility\ComponentFactory;
|
6 |
+
use WCML\StandAlone\IStandAloneAction;
|
7 |
+
|
8 |
+
/**
|
9 |
+
* @see https://woocommerce.com/products/name-your-price/
|
10 |
+
*/
|
11 |
+
class Factory extends ComponentFactory implements IStandAloneAction {
|
12 |
+
|
13 |
+
/**
|
14 |
+
* @inheritDoc
|
15 |
+
*/
|
16 |
+
public function create() {
|
17 |
+
$hooks = [];
|
18 |
+
|
19 |
+
if ( wcml_is_multi_currency_on() ) {
|
20 |
+
$hooks[] = new MulticurrencyHooks();
|
21 |
+
}
|
22 |
+
|
23 |
+
return $hooks;
|
24 |
+
}
|
25 |
+
|
26 |
+
}
|
compatibility/WcNameYourPrice/MulticurrencyHooks.php
ADDED
@@ -0,0 +1,110 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace WCML\Compatibility\WcNameYourPrice;
|
4 |
+
|
5 |
+
use WC_Name_Your_Price_Compatibility;
|
6 |
+
|
7 |
+
use function WCML\functions\getClientCurrency;
|
8 |
+
|
9 |
+
/**
|
10 |
+
* WooCommerce Name Your Price compatibility.
|
11 |
+
*
|
12 |
+
* @version 4.12.2
|
13 |
+
*/
|
14 |
+
class MulticurrencyHooks implements \IWPML_Action {
|
15 |
+
|
16 |
+
public function add_hooks() {
|
17 |
+
// Price filters.
|
18 |
+
if ( ! is_admin() ) {
|
19 |
+
if ( is_callable( [ 'WC_Name_Your_Price_Compatibility', 'is_nyp_gte' ] ) && WC_Name_Your_Price_Compatibility::is_nyp_gte( '3.0' ) ) {
|
20 |
+
add_filter( 'wc_nyp_raw_suggested_price', [ $this, 'product_price_filter' ] );
|
21 |
+
add_filter( 'wc_nyp_raw_minimum_price', [ $this, 'product_price_filter' ] );
|
22 |
+
add_filter( 'wc_nyp_raw_maximum_price', [ $this, 'product_price_filter' ] );
|
23 |
+
} else {
|
24 |
+
add_filter( 'woocommerce_raw_suggested_price', [ $this, 'product_price_filter' ] );
|
25 |
+
add_filter( 'woocommerce_raw_minimum_price', [ $this, 'product_price_filter' ] );
|
26 |
+
add_filter( 'woocommerce_raw_maximum_price', [ $this, 'product_price_filter' ] );
|
27 |
+
}
|
28 |
+
}
|
29 |
+
|
30 |
+
// Cart currency switching.
|
31 |
+
add_filter( 'woocommerce_add_cart_item_data', [ $this, 'add_initial_currency' ] );
|
32 |
+
add_filter( 'woocommerce_get_cart_item_from_session', [ $this, 'filter_woocommerce_get_cart_item_from_session' ], 20, 2 );
|
33 |
+
}
|
34 |
+
|
35 |
+
/**
|
36 |
+
* @param float|int $price
|
37 |
+
* @param string|false $currency
|
38 |
+
*
|
39 |
+
* @return float|int
|
40 |
+
*/
|
41 |
+
public function product_price_filter( $price, $currency = false ) {
|
42 |
+
return apply_filters( 'wcml_raw_price_amount', $price, $currency );
|
43 |
+
}
|
44 |
+
|
45 |
+
/**
|
46 |
+
* Store the initial currency when item is added.
|
47 |
+
*
|
48 |
+
* @param array $cart_item_data The Cart Item data.
|
49 |
+
*
|
50 |
+
* @return array
|
51 |
+
* @since 4.12.2
|
52 |
+
*/
|
53 |
+
public function add_initial_currency( $cart_item_data ) {
|
54 |
+
|
55 |
+
if ( isset( $cart_item_data['nyp'] ) ) {
|
56 |
+
$cart_item_data['nyp_currency'] = get_woocommerce_currency();
|
57 |
+
$cart_item_data['nyp_original'] = $cart_item_data['nyp'];
|
58 |
+
}
|
59 |
+
|
60 |
+
return $cart_item_data;
|
61 |
+
}
|
62 |
+
|
63 |
+
/**
|
64 |
+
* Filter Name Your Price Cart prices.
|
65 |
+
*
|
66 |
+
* @param array $session_data The Session data.
|
67 |
+
* @param array $values The values.
|
68 |
+
*
|
69 |
+
* @return array
|
70 |
+
*
|
71 |
+
* @since 4.12.2
|
72 |
+
*
|
73 |
+
* @internal filter.
|
74 |
+
*/
|
75 |
+
public function filter_woocommerce_get_cart_item_from_session( $session_data, $values ) {
|
76 |
+
|
77 |
+
// Preserve original currency.
|
78 |
+
if ( isset( $values['nyp_currency'] ) ) {
|
79 |
+
$session_data['nyp_currency'] = $values['nyp_currency'];
|
80 |
+
}
|
81 |
+
|
82 |
+
// Preserve original entered value.
|
83 |
+
if ( isset( $values['nyp_original'] ) ) {
|
84 |
+
$session_data['nyp_original'] = $values['nyp_original'];
|
85 |
+
}
|
86 |
+
|
87 |
+
$current_currency = getClientCurrency();
|
88 |
+
|
89 |
+
if ( isset( $session_data['nyp_currency'] ) && $session_data['nyp_currency'] !== $current_currency ) {
|
90 |
+
|
91 |
+
// Product is in the 'data'.
|
92 |
+
$product = $session_data['data'];
|
93 |
+
|
94 |
+
$price_in_current_currency = $this->product_price_filter( $session_data['nyp'], $current_currency );
|
95 |
+
|
96 |
+
// Set to price in current currency.
|
97 |
+
$product->set_price( $price_in_current_currency );
|
98 |
+
$product->set_regular_price( $price_in_current_currency );
|
99 |
+
$product->set_sale_price( $price_in_current_currency );
|
100 |
+
|
101 |
+
// Subscription-specific price and variable billing period.
|
102 |
+
if ( $product->is_type( [ 'subscription', 'subscription_variation' ] ) ) {
|
103 |
+
$product->update_meta_data( '_subscription_price', $price_in_current_currency );
|
104 |
+
}
|
105 |
+
}
|
106 |
+
|
107 |
+
return $session_data;
|
108 |
+
}
|
109 |
+
|
110 |
+
}
|
compatibility/WcOrderStatusManager/Factory.php
ADDED
@@ -0,0 +1,17 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace WCML\Compatibility\WcOrderStatusManager;
|
4 |
+
|
5 |
+
use WCML\Compatibility\ComponentFactory;
|
6 |
+
use WCML_Order_Status_Manager;
|
7 |
+
use WP_Query;
|
8 |
+
|
9 |
+
class Factory extends ComponentFactory {
|
10 |
+
|
11 |
+
/**
|
12 |
+
* @inheritDoc
|
13 |
+
*/
|
14 |
+
public function create() {
|
15 |
+
return new WCML_Order_Status_Manager( new WP_Query() );
|
16 |
+
}
|
17 |
+
}
|
compatibility/{class-wcml-order-status-manager.php → WcOrderStatusManager/class-wcml-order-status-manager.php}
RENAMED
@@ -3,7 +3,7 @@
|
|
3 |
* Class WCML_Order_Status_Manager
|
4 |
* compatibility class for WC Order Status Manager plugin.
|
5 |
*/
|
6 |
-
class WCML_Order_Status_Manager {
|
7 |
/**
|
8 |
* WordPress query object.
|
9 |
*
|
3 |
* Class WCML_Order_Status_Manager
|
4 |
* compatibility class for WC Order Status Manager plugin.
|
5 |
*/
|
6 |
+
class WCML_Order_Status_Manager implements \IWPML_Action {
|
7 |
/**
|
8 |
* WordPress query object.
|
9 |
*
|
compatibility/WcPip/Factory.php
ADDED
@@ -0,0 +1,31 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace WCML\Compatibility\WcPip;
|
4 |
+
|
5 |
+
use WCML\Compatibility\ComponentFactory;
|
6 |
+
use WCML\StandAlone\IStandAloneAction;
|
7 |
+
use WCML_Pip;
|
8 |
+
use function WCML\functions\isStandAlone;
|
9 |
+
|
10 |
+
/**
|
11 |
+
* @see https://woocommerce.com/products/print-invoices-packing-lists/
|
12 |
+
*/
|
13 |
+
class Factory extends ComponentFactory implements IStandAloneAction {
|
14 |
+
|
15 |
+
/**
|
16 |
+
* @inheritDoc
|
17 |
+
*/
|
18 |
+
public function create() {
|
19 |
+
$hooks = [];
|
20 |
+
|
21 |
+
if ( wcml_is_multi_currency_on() ) {
|
22 |
+
$hooks[] = new MulticurrencyHooks();
|
23 |
+
}
|
24 |
+
|
25 |
+
if ( ! isStandAlone() ) {
|
26 |
+
$hooks[] = new WCML_Pip();
|
27 |
+
}
|
28 |
+
|
29 |
+
return $hooks;
|
30 |
+
}
|
31 |
+
}
|
compatibility/WcPip/Helper.php
ADDED
@@ -0,0 +1,28 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace WCML\Compatibility\WcPip;
|
4 |
+
|
5 |
+
class Helper {
|
6 |
+
|
7 |
+
/**
|
8 |
+
* @return false|int|string
|
9 |
+
*/
|
10 |
+
public static function getPipOrderId() {
|
11 |
+
$order_id = false;
|
12 |
+
|
13 |
+
if ( isset( $_GET['wc_pip_action'] ) && isset( $_GET['order_id'] ) ) {
|
14 |
+
$order_id = $_GET['order_id'];
|
15 |
+
} elseif (
|
16 |
+
isset( $_POST['action'] ) &&
|
17 |
+
(
|
18 |
+
$_POST['action'] == 'wc_pip_order_send_email' ||
|
19 |
+
$_POST['action'] == 'wc_pip_send_email_packing_list'
|
20 |
+
) &&
|
21 |
+
isset( $_POST['order_id'] )
|
22 |
+
) {
|
23 |
+
$order_id = $_POST['order_id'];
|
24 |
+
}
|
25 |
+
|
26 |
+
return $order_id;
|
27 |
+
}
|
28 |
+
}
|
compatibility/WcPip/MulticurrencyHooks.php
ADDED
@@ -0,0 +1,69 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace WCML\Compatibility\WcPip;
|
4 |
+
|
5 |
+
class MulticurrencyHooks implements \IWPML_Action {
|
6 |
+
|
7 |
+
public function add_hooks() {
|
8 |
+
add_filter( 'woocommerce_currency_symbol', [ $this, 'filter_pip_currency_symbol' ] );
|
9 |
+
add_filter( 'wcml_filter_currency_position', [ $this, 'filter_pip_currency_position' ] );
|
10 |
+
}
|
11 |
+
|
12 |
+
/**
|
13 |
+
* @param string $currencySymbol
|
14 |
+
*
|
15 |
+
* @return string
|
16 |
+
*/
|
17 |
+
public function filter_pip_currency_symbol( $currencySymbol ) {
|
18 |
+
remove_filter( 'woocommerce_currency_symbol', [ $this, 'filter_pip_currency_symbol' ] );
|
19 |
+
|
20 |
+
$currency = self::getPipOrderCurrency();
|
21 |
+
|
22 |
+
if ( $currency ) {
|
23 |
+
$currencySymbol = get_woocommerce_currency_symbol( $currency );
|
24 |
+
}
|
25 |
+
|
26 |
+
add_filter( 'woocommerce_currency_symbol', [ $this, 'filter_pip_currency_symbol' ] );
|
27 |
+
|
28 |
+
return $currencySymbol;
|
29 |
+
}
|
30 |
+
|
31 |
+
/**
|
32 |
+
* @param string $currency
|
33 |
+
*
|
34 |
+
* @return string
|
35 |
+
*/
|
36 |
+
public function filter_pip_currency_position( $currency ) {
|
37 |
+
remove_filter( 'wcml_filter_currency_position', [ $this, 'filter_pip_currency_position' ] );
|
38 |
+
|
39 |
+
$currency = self::getPipOrderCurrency( $currency );
|
40 |
+
|
41 |
+
add_filter( 'wcml_filter_currency_position', [ $this, 'filter_pip_currency_position' ] );
|
42 |
+
|
43 |
+
return $currency;
|
44 |
+
}
|
45 |
+
|
46 |
+
/**
|
47 |
+
* @param string|false $currency
|
48 |
+
*
|
49 |
+
* @return string|false
|
50 |
+
*/
|
51 |
+
private static function getPipOrderCurrency( $currency = false ) {
|
52 |
+
$pip_order_id = Helper::getPipOrderId();
|
53 |
+
|
54 |
+
if ( $pip_order_id && isset( WC()->order_factory ) ) {
|
55 |
+
|
56 |
+
$the_order = WC()->order_factory->get_order( $pip_order_id );
|
57 |
+
|
58 |
+
if ( $the_order ) {
|
59 |
+
$currency = $the_order->get_currency();
|
60 |
+
|
61 |
+
if ( ! $currency && isset( $_COOKIE['_wcml_order_currency'] ) ) {
|
62 |
+
$currency = $_COOKIE['_wcml_order_currency'];
|
63 |
+
}
|
64 |
+
}
|
65 |
+
}
|
66 |
+
|
67 |
+
return $currency;
|
68 |
+
}
|
69 |
+
}
|
compatibility/WcPip/class-wcml-pip.php
ADDED
@@ -0,0 +1,29 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
use WCML\Compatibility\WcPip\Helper;
|
4 |
+
|
5 |
+
class WCML_Pip implements \IWPML_Action {
|
6 |
+
|
7 |
+
public function add_hooks() {
|
8 |
+
add_filter( 'wcml_send_email_order_id', [ $this, 'wcml_send_email_order_id' ] );
|
9 |
+
add_action( 'wc_pip_print', [ $this, 'print_invoice_language' ], 10, 2 );
|
10 |
+
}
|
11 |
+
|
12 |
+
public function wcml_send_email_order_id( $order_id ) {
|
13 |
+
$pip_order_id = Helper::getPipOrderId();
|
14 |
+
|
15 |
+
if ( $pip_order_id ) {
|
16 |
+
$order_id = $pip_order_id;
|
17 |
+
}
|
18 |
+
|
19 |
+
return $order_id;
|
20 |
+
}
|
21 |
+
|
22 |
+
public function print_invoice_language( $type, $order_id ) {
|
23 |
+
$order_language = get_post_meta( $order_id, 'wpml_language', true );
|
24 |
+
|
25 |
+
if ( $order_language ) {
|
26 |
+
do_action( 'wpml_switch_language', $order_language );
|
27 |
+
}
|
28 |
+
}
|
29 |
+
}
|
compatibility/WcProductAddons/Factory.php
ADDED
@@ -0,0 +1,34 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace WCML\Compatibility\WcProductAddons;
|
4 |
+
|
5 |
+
use WCML\Compatibility\ComponentFactory;
|
6 |
+
use WCML\StandAlone\IStandAloneAction;
|
7 |
+
use function WCML\functions\getSitePress;
|
8 |
+
use function WCML\functions\getWooCommerceWpml;
|
9 |
+
use function WCML\functions\isStandAlone;
|
10 |
+
|
11 |
+
/**
|
12 |
+
* @see https://woocommerce.com/products/product-add-ons/
|
13 |
+
*/
|
14 |
+
class Factory extends ComponentFactory implements IStandAloneAction {
|
15 |
+
|
16 |
+
/**
|
17 |
+
* @inheritDoc
|
18 |
+
*/
|
19 |
+
public function create() {
|
20 |
+
$hooks = [
|
21 |
+
new SharedHooks(),
|
22 |
+
];
|
23 |
+
|
24 |
+
if ( wcml_is_multi_currency_on() ) {
|
25 |
+
$hooks[] = new MulticurrencyHooks( getWooCommerceWpml() );
|
26 |
+
}
|
27 |
+
|
28 |
+
if ( ! isStandAlone() ) {
|
29 |
+
$hooks[] = new \WCML_Product_Addons( getSitePress() );
|
30 |
+
}
|
31 |
+
|
32 |
+
return $hooks;
|
33 |
+
}
|
34 |
+
}
|
compatibility/WcProductAddons/MulticurrencyHooks.php
ADDED
@@ -0,0 +1,341 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace WCML\Compatibility\WcProductAddons;
|
4 |
+
|
5 |
+
use WC_Product_Booking;
|
6 |
+
use WCML_Product_Addons;
|
7 |
+
use woocommerce_wpml;
|
8 |
+
use WPML_Twig_Template_Loader;
|
9 |
+
|
10 |
+
class MulticurrencyHooks implements \IWPML_Action {
|
11 |
+
|
12 |
+
const TEMPLATE_FOLDER = '/templates/compatibility/';
|
13 |
+
const DIALOG_TEMPLATE = 'product-addons-prices-dialog.twig';
|
14 |
+
const SETTINGS_TEMPLATE = 'product-addons-prices-settings.twig';
|
15 |
+
const PRICE_OPTION_KEY = '_product_addon_prices';
|
16 |
+
|
17 |
+
/** @var woocommerce_wpml $woocommerce_wpml */
|
18 |
+
private $woocommerce_wpml;
|
19 |
+
|
20 |
+
/**
|
21 |
+
* @param woocommerce_wpml $woocommerce_wpml
|
22 |
+
*/
|
23 |
+
public function __construct( woocommerce_wpml $woocommerce_wpml ) {
|
24 |
+
$this->woocommerce_wpml = $woocommerce_wpml;
|
25 |
+
}
|
26 |
+
|
27 |
+
public function add_hooks() {
|
28 |
+
add_filter( 'get_product_addons_fields', [ $this, 'product_addons_price_filter' ], 10, 2 );
|
29 |
+
add_filter( 'wcml_cart_contents_not_changed', [ $this, 'filter_booking_addon_product_in_cart_contents' ], 20 );
|
30 |
+
add_filter( 'wcml_product_addons_global_updated', [ $this, 'onGlobalAddonsUpdated' ], 10, 2 );
|
31 |
+
|
32 |
+
if ( is_admin() ) {
|
33 |
+
add_action( 'woocommerce_product_addons_panel_start', [ $this, 'load_dialog_resources' ] );
|
34 |
+
add_action( 'woocommerce_product_addons_panel_option_row', [ $this, 'dialog_button_after_option_row' ], 10, 4 );
|
35 |
+
add_action( 'woocommerce_product_addons_panel_before_options', [ $this, 'dialog_button_before_options' ], 10, 3 );
|
36 |
+
add_action( 'wcml_before_sync_product', [ $this, 'update_custom_prices_values' ] );
|
37 |
+
add_action( 'save_post', [ $this, 'maybeUpdateCustomPricesValues' ], 10, 2 );
|
38 |
+
add_action( 'woocommerce_product_addons_global_edit_objects', [ $this, 'custom_prices_settings_block' ] );
|
39 |
+
}
|
40 |
+
}
|
41 |
+
|
42 |
+
public function maybeUpdateCustomPricesValues( $productId, $arg ) {
|
43 |
+
if ( 'product' === get_post_type( $productId ) ) {
|
44 |
+
$this->update_custom_prices_values( $productId );
|
45 |
+
}
|
46 |
+
}
|
47 |
+
|
48 |
+
/**
|
49 |
+
* @param array $addons
|
50 |
+
* @param int $postId
|
51 |
+
*
|
52 |
+
* @return array
|
53 |
+
*/
|
54 |
+
public function product_addons_price_filter( $addons, $postId ) {
|
55 |
+
foreach ( $addons as $addonId => $addon ) {
|
56 |
+
|
57 |
+
$addon_data = wpml_collect( $addon );
|
58 |
+
|
59 |
+
if ( $addon_data->offsetExists( 'price' ) && $addon_data->get( 'price' ) ) {
|
60 |
+
$addons[ $addonId ]['price'] = $this->converted_addon_price( $addon, $postId );
|
61 |
+
}
|
62 |
+
|
63 |
+
if ( $addon_data->offsetExists( 'options' ) ) {
|
64 |
+
foreach ( $addon_data->get( 'options' ) as $key => $option ) {
|
65 |
+
$addons[ $addonId ]['options'][ $key ]['price'] = $this->converted_addon_price( $option, $postId );
|
66 |
+
}
|
67 |
+
}
|
68 |
+
}
|
69 |
+
|
70 |
+
return $addons;
|
71 |
+
}
|
72 |
+
|
73 |
+
/**
|
74 |
+
* Special case for WC Bookings plugin - need add addon cost after re-calculating booking costs.
|
75 |
+
*
|
76 |
+
* @see https://onthegosystems.myjetbrains.com/youtrack/issue/wcml-1877
|
77 |
+
*
|
78 |
+
* @param array $cartItem
|
79 |
+
*
|
80 |
+
* @return array
|
81 |
+
*/
|
82 |
+
public function filter_booking_addon_product_in_cart_contents( $cartItem ) {
|
83 |
+
$isBookingProductWithAddons = $cartItem['data'] instanceof WC_Product_Booking && isset( $cartItem['addons'] );
|
84 |
+
|
85 |
+
if ( $isBookingProductWithAddons ) {
|
86 |
+
$cost = $cartItem['data']->get_price();
|
87 |
+
|
88 |
+
foreach ( $cartItem['addons'] as $addon ) {
|
89 |
+
$cost += $addon['price'];
|
90 |
+
}
|
91 |
+
|
92 |
+
$cartItem['data']->set_price( $cost );
|
93 |
+
}
|
94 |
+
|
95 |
+
return $cartItem;
|
96 |
+
}
|
97 |
+
|
98 |
+
/**
|
99 |
+
* @param array $addon
|
100 |
+
* @param int $postId
|
101 |
+
*
|
102 |
+
* @return string
|
103 |
+
*/
|
104 |
+
private function converted_addon_price( $addon, $postId ) {
|
105 |
+
$addonData = wpml_collect( $addon );
|
106 |
+
|
107 |
+
$isCustomPricesOn = $this->isProductCustomPricesOn( $postId );
|
108 |
+
$field = 'price_' . $this->woocommerce_wpml->multi_currency->get_client_currency();
|
109 |
+
|
110 |
+
if (
|
111 |
+
$isCustomPricesOn &&
|
112 |
+
$addonData->get( $field )
|
113 |
+
) {
|
114 |
+
return $addonData->get( $field );
|
115 |
+
}
|
116 |
+
|
117 |
+
if ( wpml_collect( [ 'flat_fee', 'quantity_based' ] )->contains( $addonData->get( 'price_type' ) ) ) {
|
118 |
+
return apply_filters( 'wcml_raw_price_amount', $addonData->get( 'price' ) );
|
119 |
+
}
|
120 |
+
|
121 |
+
return $addonData->get( 'price' );
|
122 |
+
}
|
123 |
+
|
124 |
+
/**
|
125 |
+
* @param int|false $productId
|
126 |
+
*
|
127 |
+
* @return bool|mixed
|
128 |
+
*/
|
129 |
+
private function isProductCustomPricesOn( $productId ) {
|
130 |
+
if ( $productId ) {
|
131 |
+
return get_post_meta( $productId, '_wcml_custom_prices_status', true );
|
132 |
+
}
|
133 |
+
|
134 |
+
if ( SharedHooks::isGlobalAddonEditPage() ) {
|
135 |
+
return $this->getGlobalAddonPricesStatus();
|
136 |
+
}
|
137 |
+
|
138 |
+
return false;
|
139 |
+
}
|
140 |
+
|
141 |
+
/**
|
142 |
+
* @return bool|mixed
|
143 |
+
*/
|
144 |
+
private function getGlobalAddonPricesStatus() {
|
145 |
+
if ( isset( $_GET['edit'] ) ) {
|
146 |
+
return get_post_meta( $_GET['edit'], '_wcml_custom_prices_status', true );
|
147 |
+
} elseif ( isset( $_POST['_wcml_custom_prices'] ) ) {
|
148 |
+
return $_POST['_wcml_custom_prices'];
|
149 |
+
}
|
150 |
+
|
151 |
+
return false;
|
152 |
+
}
|
153 |
+
|
154 |
+
public function load_dialog_resources() {
|
155 |
+
wp_enqueue_script( 'wcml-dialogs', WCML_PLUGIN_URL . '/res/js/dialogs' . WCML_JS_MIN . '.js', [ 'jquery-ui-dialog', 'underscore' ], WCML_VERSION );
|
156 |
+
}
|
157 |
+
|
158 |
+
/**
|
159 |
+
* @param \WP_Post|null $product
|
160 |
+
* @param array $productAddons
|
161 |
+
* @param int $loop
|
162 |
+
* @param array $option
|
163 |
+
*/
|
164 |
+
public function dialog_button_after_option_row( $product, $productAddons, $loop, $option ) {
|
165 |
+
if ( $option ) {
|
166 |
+
$this->renderEditPriceElement( $this->getPricesDialogModel( $productAddons, $option, $loop, $this->isProductCustomPricesOn( $product ? $product->ID : false ) ) );
|
167 |
+
}
|
168 |
+
}
|
169 |
+
|
170 |
+
/**
|
171 |
+
* @param \WP_Post|null $product
|
172 |
+
* @param array $productAddons
|
173 |
+
* @param int $loop
|
174 |
+
*/
|
175 |
+
public function dialog_button_before_options( $product, $productAddons, $loop ) {
|
176 |
+
$this->renderEditPriceElement( $this->getPricesDialogModel( [], $productAddons, $loop, $this->isProductCustomPricesOn( $product ? $product->ID : false ) ) );
|
177 |
+
}
|
178 |
+
|
179 |
+
/**
|
180 |
+
* @param int $metaId
|
181 |
+
* @param int $id
|
182 |
+
*/
|
183 |
+
public function onGlobalAddonsUpdated( $metaId, $id ) {
|
184 |
+
$this->update_custom_prices_values( $id );
|
185 |
+
}
|
186 |
+
|
187 |
+
/**
|
188 |
+
* @param string|int $productId
|
189 |
+
*/
|
190 |
+
public function update_custom_prices_values( $productId ) {
|
191 |
+
$this->saveGlobalAddonPricesSetting( $productId );
|
192 |
+
$productAddons = SharedHooks::getProductAddons( $productId );
|
193 |
+
|
194 |
+
if ( $productAddons ) {
|
195 |
+
$activeCurrencies = $this->woocommerce_wpml->multi_currency->get_currencies();
|
196 |
+
|
197 |
+
foreach ( $productAddons as $addonKey => $productAddon ) {
|
198 |
+
|
199 |
+
foreach ( $activeCurrencies as $code => $currency ) {
|
200 |
+
$priceOptionKey = self::PRICE_OPTION_KEY;
|
201 |
+
|
202 |
+
if ( in_array( $productAddon['type'], self::getOnePriceTypes(), true ) ) {
|
203 |
+
$productAddons = $this->updateSingleOptionPrices( $productAddons, $priceOptionKey, $addonKey, $code );
|
204 |
+
} else {
|
205 |
+
$productAddons = $this->updateMultipleOptionsPrices( $productAddons, $priceOptionKey, $addonKey, $code );
|
206 |
+
}
|
207 |
+
}
|
208 |
+
}
|
209 |
+
|
210 |
+
update_post_meta( $productId, WCML_Product_Addons::ADDONS_OPTION_KEY, $productAddons );
|
211 |
+
}
|
212 |
+
}
|
213 |
+
|
214 |
+
/**
|
215 |
+
* @param array $productAddons
|
216 |
+
* @param string $priceOptionKey
|
217 |
+
* @param string $addonKey
|
218 |
+
* @param string $code
|
219 |
+
*
|
220 |
+
* @return array
|
221 |
+
*/
|
222 |
+
private function updateSingleOptionPrices( $productAddons, $priceOptionKey, $addonKey, $code ) {
|
223 |
+
if ( isset( $_POST[ $priceOptionKey ][ $addonKey ][ 'price_' . $code ][0] ) ) {
|
224 |
+
$productAddons[ $addonKey ][ 'price_' . $code ] = wc_format_decimal( $_POST[ $priceOptionKey ][ $addonKey ][ 'price_' . $code ][0] );
|
225 |
+
}
|
226 |
+
|
227 |
+
return $productAddons;
|
228 |
+
}
|
229 |
+
|
230 |
+
/**
|
231 |
+
* @param array $productAddons
|
232 |
+
* @param string $priceOptionKey
|
233 |
+
* @param string $addonKey
|
234 |
+
* @param string $code
|
235 |
+
*
|
236 |
+
* @return array
|
237 |
+
*/
|
238 |
+
private function updateMultipleOptionsPrices( $productAddons, $priceOptionKey, $addonKey, $code ) {
|
239 |
+
$addon_data = wpml_collect( $productAddons[ $addonKey ] );
|
240 |
+
|
241 |
+
if ( $addon_data->offsetExists( 'options' ) ) {
|
242 |
+
foreach ( $addon_data->get( 'options' ) as $option_key => $option ) {
|
243 |
+
if ( isset( $_POST[ $priceOptionKey ][ $addonKey ][ 'price_' . $code ][ $option_key ] ) ) {
|
244 |
+
$productAddons[ $addonKey ]['options'][ $option_key ][ 'price_' . $code ] = wc_format_decimal( $_POST[ $priceOptionKey ][ $addonKey ][ 'price_' . $code ][ $option_key ] );
|
245 |
+
}
|
246 |
+
}
|
247 |
+
}
|
248 |
+
|
249 |
+
return $productAddons;
|
250 |
+
}
|
251 |
+
|
252 |
+
public function custom_prices_settings_block() {
|
253 |
+
// phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
254 |
+
echo $this->getTwigLoader()->get_template()->show( $this->getCustomPricesSettingsModel(), self::SETTINGS_TEMPLATE );
|
255 |
+
}
|
256 |
+
|
257 |
+
/**
|
258 |
+
* @param array $model
|
259 |
+
*/
|
260 |
+
private function renderEditPriceElement( $model ) {
|
261 |
+
// phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
262 |
+
echo $this->getTwigLoader()->get_template()->show( $model, self::DIALOG_TEMPLATE );
|
263 |
+
}
|
264 |
+
|
265 |
+
/**
|
266 |
+
* @return WPML_Twig_Template_Loader
|
267 |
+
*/
|
268 |
+
private function getTwigLoader() {
|
269 |
+
return new WPML_Twig_Template_Loader( [ WCML_PLUGIN_PATH . SharedHooks::TEMPLATE_FOLDER ] );
|
270 |
+
}
|
271 |
+
|
272 |
+
/**
|
273 |
+
* @return array
|
274 |
+
*/
|
275 |
+
private function getCustomPricesSettingsModel() {
|
276 |
+
return [
|
277 |
+
'strings' => [
|
278 |
+
'label' => __( 'Multi-currency settings', 'woocommerce-multilingual' ),
|
279 |
+
'auto' => __( 'Calculate prices in other currencies automatically', 'woocommerce-multilingual' ),
|
280 |
+
'manually' => __( 'Set prices in other currencies manually', 'woocommerce-multilingual' ),
|
281 |
+
],
|
282 |
+
'custom_prices_on' => $this->getGlobalAddonPricesStatus(),
|
283 |
+
'nonce' => wp_create_nonce( 'wcml_save_custom_prices' ),
|
284 |
+
];
|
285 |
+
}
|
286 |
+
|
287 |
+
/**
|
288 |
+
* @param array $productAddons
|
289 |
+
* @param array $option
|
290 |
+
* @param int $loop
|
291 |
+
* @param string|bool $customPricesOn
|
292 |
+
*
|
293 |
+
* @return array
|
294 |
+
*/
|
295 |
+
private function getPricesDialogModel( $productAddons, $option, $loop, $customPricesOn ) {
|
296 |
+
|
297 |
+
$label = isset( $option['label'] ) ? $option['label'] : $option['name'];
|
298 |
+
|
299 |
+
return [
|
300 |
+
'strings' => [
|
301 |
+
'dialog_title' => __( 'Multi-currency settings', 'woocommerce-multilingual' ),
|
302 |
+
/* translators: %s is an option label */
|
303 |
+
'description' => sprintf( __( 'Here you can set different prices for the %s in multiple currencies:', 'woocommerce-multilingual' ), '<strong>' . $label . '</strong>' ),
|
304 |
+
'apply' => __( 'Apply', 'woocommerce-multilingual' ),
|
305 |
+
'cancel' => __( 'Cancel', 'woocommerce-multilingual' ),
|
306 |
+
],
|
307 |
+
'custom_prices_on' => $customPricesOn,
|
308 |
+
'dialog_id' => '_product_addon_option_' . md5( uniqid( $loop . $label ) ),
|
309 |
+
'option_id' => isset( $productAddons[ $loop ]['options'] ) ? array_search( $option, $productAddons[ $loop ]['options'] ) : '',
|
310 |
+
'addon_id' => $loop,
|
311 |
+
'option_details' => $option,
|
312 |
+
'default_currency' => wcml_get_woocommerce_currency_option(),
|
313 |
+
'active_currencies' => $this->woocommerce_wpml->multi_currency->get_currencies(),
|
314 |
+
];
|
315 |
+
}
|
316 |
+
|
317 |
+
/**
|
318 |
+
* @param int $productId
|
319 |
+
*/
|
320 |
+
private function saveGlobalAddonPricesSetting( $productId ) {
|
321 |
+
if ( SharedHooks::isGlobalAddon( $productId ) ) {
|
322 |
+
$nonce = filter_var( isset( $_POST['_wcml_custom_prices_nonce'] ) ? $_POST['_wcml_custom_prices_nonce'] : '', FILTER_SANITIZE_FULL_SPECIAL_CHARS );
|
323 |
+
|
324 |
+
if ( isset( $_POST['_wcml_custom_prices'] ) && isset( $nonce ) && wp_verify_nonce( $nonce, 'wcml_save_custom_prices' ) ) {
|
325 |
+
update_post_meta( $productId, '_wcml_custom_prices_status', $_POST['_wcml_custom_prices'] );
|
326 |
+
}
|
327 |
+
}
|
328 |
+
}
|
329 |
+
|
330 |
+
/**
|
331 |
+
* @return array
|
332 |
+
*/
|
333 |
+
private static function getOnePriceTypes() {
|
334 |
+
return [
|
335 |
+
'custom_text',
|
336 |
+
'custom_textarea',
|
337 |
+
'file_upload',
|
338 |
+
'input_multiplier',
|
339 |
+
];
|
340 |
+
}
|
341 |
+
}
|
compatibility/WcProductAddons/SharedHooks.php
ADDED
@@ -0,0 +1,75 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace WCML\Compatibility\WcProductAddons;
|
4 |
+
|
5 |
+
use WPML\FP\Fns;
|
6 |
+
|
7 |
+
class SharedHooks implements \IWPML_Action {
|
8 |
+
|
9 |
+
const TEMPLATE_FOLDER = '/templates/compatibility/';
|
10 |
+
const ADDONS_OPTION_KEY = '_product_addons';
|
11 |
+
|
12 |
+
public function add_hooks() {
|
13 |
+
$withoutRecursion = Fns::withoutRecursion( Fns::noop() );
|
14 |
+
|
15 |
+
add_action( 'init', [ $this, 'loadAssets' ] );
|
16 |
+
add_action( 'updated_post_meta', $withoutRecursion( [ $this, 'triggerGlobalAddonUpdated' ] ), 10, 4 );
|
17 |
+
add_action( 'added_post_meta', $withoutRecursion( [ $this, 'triggerGlobalAddonUpdated' ] ), 10, 4 );
|
18 |
+
}
|
19 |
+
|
20 |
+
public function loadAssets() {
|
21 |
+
global $pagenow;
|
22 |
+
|
23 |
+
$isProductPage = 'post.php' === $pagenow && isset( $_GET['post'] );
|
24 |
+
$isProductNewPage = 'post-new.php' === $pagenow && isset( $_GET['post_type'] ) && 'product' === $_GET['post_type'];
|
25 |
+
|
26 |
+
if ( $isProductPage || $isProductNewPage || self::isGlobalAddonEditPage() ) {
|
27 |
+
wp_enqueue_script( 'wcml-product-addons', WCML_PLUGIN_URL . '/compatibility/res/js/wcml-product-addons' . WCML_JS_MIN . '.js', [ 'jquery' ], WCML_VERSION );
|
28 |
+
wp_enqueue_style( 'wcml-product-addons', WCML_PLUGIN_URL . '/compatibility/res/css/wcml-product-addons.css', [ 'wpml-dialog' ], WCML_VERSION );
|
29 |
+
}
|
30 |
+
}
|
31 |
+
|
32 |
+
/**
|
33 |
+
* @return bool
|
34 |
+
*/
|
35 |
+
public static function isGlobalAddonEditPage() {
|
36 |
+
global $pagenow;
|
37 |
+
|
38 |
+
return 'edit.php' === $pagenow &&
|
39 |
+
isset( $_GET['post_type'] ) &&
|
40 |
+
'product' === $_GET['post_type'] &&
|
41 |
+
isset( $_GET['page'] ) &&
|
42 |
+
( 'global_addons' === $_GET['page'] || 'addons' === $_GET['page'] );
|
43 |
+
}
|
44 |
+
|
45 |
+
/**
|
46 |
+
* @param int $metaId
|
47 |
+
* @param int $id
|
48 |
+
* @param string $metaKey
|
49 |
+
* @param array $addons
|
50 |
+
*/
|
51 |
+
public function triggerGlobalAddonUpdated( $metaId, $id, $metaKey, $addons ) {
|
52 |
+
if ( self::ADDONS_OPTION_KEY === $metaKey && self::isGlobalAddon( $id ) ) {
|
53 |
+
do_action( 'wcml_product_addons_global_updated', $metaId, $id, $metaKey, $addons );
|
54 |
+
}
|
55 |
+
}
|
56 |
+
|
57 |
+
/**
|
58 |
+
* @param int $postId
|
59 |
+
*
|
60 |
+
* @return bool
|
61 |
+
*/
|
62 |
+
public static function isGlobalAddon( $postId ) {
|
63 |
+
return 'global_product_addon' === get_post_type( $postId );
|
64 |
+
}
|
65 |
+
|
66 |
+
/**
|
67 |
+
* @param string $productId
|
68 |
+
*
|
69 |
+
* @return array
|
70 |
+
*/
|
71 |
+
public static function getProductAddons( $productId ) {
|
72 |
+
$data = get_post_meta( $productId, self::ADDONS_OPTION_KEY, true );
|
73 |
+
return $data ? maybe_unserialize( $data ) : [];
|
74 |
+
}
|
75 |
+
}
|
compatibility/WcProductAddons/class-wcml-product-addons.php
ADDED
@@ -0,0 +1,397 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
use WCML\Compatibility\WcProductAddons\SharedHooks;
|
4 |
+
use WCML\Options\WPML;
|
5 |
+
use WPML\FP\Obj;
|
6 |
+
use WPML\FP\Str;
|
7 |
+
|
8 |
+
/**
|
9 |
+
* Class WCML_Product_Addons
|
10 |
+
*/
|
11 |
+
class WCML_Product_Addons implements \IWPML_Action {
|
12 |
+
|
13 |
+
const ADDONS_OPTION_KEY = SharedHooks::ADDONS_OPTION_KEY;
|
14 |
+
|
15 |
+
/**
|
16 |
+
* @var SitePress
|
17 |
+
*/
|
18 |
+
public $sitepress;
|
19 |
+
|
20 |
+
/**
|
21 |
+
* WCML_Product_Addons constructor.
|
22 |
+
*
|
23 |
+
* @param SitePress $sitepress
|
24 |
+
* @param woocommerce_wpml $woocommerce_wpml
|
25 |
+
*/
|
26 |
+
public function __construct( SitePress $sitepress ) {
|
27 |
+
$this->sitepress = $sitepress;
|
28 |
+
}
|
29 |
+
|
30 |
+
public function add_hooks() {
|
31 |
+
add_filter( 'get_product_addons_product_terms', [ $this, 'addons_product_terms' ] );
|
32 |
+
add_action( 'wcml_product_addons_global_updated', [ $this, 'register_addons_strings' ], 10, 4 );
|
33 |
+
add_action( 'woocommerce-product-addons_panel_start', [ $this, 'show_pointer_info' ] );
|
34 |
+
|
35 |
+
if ( WPML::useAte() ) {
|
36 |
+
add_action( 'wpml_pro_translation_completed', [ $this, 'save_addons_to_translation' ], 10, 3 );
|
37 |
+
}
|
38 |
+
|
39 |
+
if ( is_admin() ) {
|
40 |
+
|
41 |
+
if ( SharedHooks::isGlobalAddonEditPage() ) {
|
42 |
+
if ( ! isset( $_GET['edit'] ) ) {
|
43 |
+
add_action( 'admin_notices', [ $this, 'inf_translate_strings' ] );
|
44 |
+
}
|
45 |
+
}
|
46 |
+
|
47 |
+
if ( WPML::useAte() ) {
|
48 |
+
add_filter( 'wpml_tm_translation_job_data', [ $this, 'append_addons_to_translation_package' ], 10, 2 );
|
49 |
+
} else {
|
50 |
+
add_action( 'wcml_gui_additional_box_html', [ $this, 'custom_box_html' ], 10, 3 );
|
51 |
+
add_filter( 'wcml_gui_additional_box_data', [ $this, 'custom_box_html_data' ], 10, 3 );
|
52 |
+
add_action( 'wcml_update_extra_fields', [ $this, 'addons_update' ], 10, 3 );
|
53 |
+
}
|
54 |
+
|
55 |
+
add_action( 'woocommerce_product_data_panels', [ $this, 'show_pointer_info' ] );
|
56 |
+
|
57 |
+
add_filter( 'wcml_do_not_display_custom_fields_for_product', [ $this, 'replace_tm_editor_custom_fields_with_own_sections' ] );
|
58 |
+
} else {
|
59 |
+
add_filter( 'get_post_metadata', [ $this, 'translate_addons_strings' ], 10, 4 );
|
60 |
+
}
|
61 |
+
|
62 |
+
add_filter(
|
63 |
+
'get_product_addons_global_query_args',
|
64 |
+
[
|
65 |
+
$this,
|
66 |
+
'set_global_ids_in_query_args',
|
67 |
+
]
|
68 |
+
);
|
69 |
+
}
|
70 |
+
|
71 |
+
/**
|
72 |
+
* @param $meta_id
|
73 |
+
* @param $id
|
74 |
+
* @param $meta_key
|
75 |
+
* @param $addons
|
76 |
+
*/
|
77 |
+
public function register_addons_strings( $meta_id, $id, $meta_key, $addons ) {
|
78 |
+
if ( self::ADDONS_OPTION_KEY === $meta_key && 'global_product_addon' === get_post_type( $id ) ) {
|
79 |
+
foreach ( $addons as $addon ) {
|
80 |
+
$addon_data = wpml_collect( $addon );
|
81 |
+
$addon_type = $addon_data->get( 'type' );
|
82 |
+
$addon_position = $addon_data->get( 'position' );
|
83 |
+
// register name
|
84 |
+
do_action( 'wpml_register_single_string', 'wc_product_addons_strings', $id . '_addon_' . $addon_type . '_' . $addon_position . '_name', $addon_data->get( 'name' ) );
|
85 |
+
// register description
|
86 |
+
do_action( 'wpml_register_single_string', 'wc_product_addons_strings', $id . '_addon_' . $addon_type . '_' . $addon_position . '_description', $addon_data->get( 'description' ) );
|
87 |
+
// register options labels
|
88 |
+
if ( $addon_data->offsetExists( 'options' ) ) {
|
89 |
+
foreach ( $addon_data->get( 'options' ) as $key => $option ) {
|
90 |
+
do_action( 'wpml_register_single_string', 'wc_product_addons_strings', $id . '_addon_' . $addon_type . '_' . $addon_position . '_option_label_' . $key, wpml_collect( $option )->get( 'label' ) );
|
91 |
+
}
|
92 |
+
}
|
93 |
+
}
|
94 |
+
}
|
95 |
+
}
|
96 |
+
|
97 |
+
/**
|
98 |
+
* @param $null
|
99 |
+
* @param $object_id
|
100 |
+
* @param $meta_key
|
101 |
+
* @param $single
|
102 |
+
*
|
103 |
+
* @return array
|
104 |
+
*/
|
105 |
+
public function translate_addons_strings( $null, $object_id, $meta_key, $single ) {
|
106 |
+
|
107 |
+
if ( self::ADDONS_OPTION_KEY === $meta_key && 'global_product_addon' === get_post_type( $object_id ) ) {
|
108 |
+
|
109 |
+
remove_filter( 'get_post_metadata', [ $this, 'translate_addons_strings' ], 10 );
|
110 |
+
$addons = get_post_meta( $object_id, $meta_key, true );
|
111 |
+
add_filter( 'get_post_metadata', [ $this, 'translate_addons_strings' ], 10, 4 );
|
112 |
+
|
113 |
+
if ( is_array( $addons ) ) {
|
114 |
+
foreach ( $addons as $key => $addon ) {
|
115 |
+
$addon_data = wpml_collect( $addon );
|
116 |
+
$addon_type = $addon_data->get( 'type' );
|
117 |
+
$addon_position = $addon_data->get( 'position' );
|
118 |
+
// register name
|
119 |
+
$addons[ $key ]['name'] = apply_filters( 'wpml_translate_single_string', $addon_data->get( 'name' ), 'wc_product_addons_strings', $object_id . '_addon_' . $addon_type . '_' . $addon_position . '_name' );
|
120 |
+
// register description
|
121 |
+
$addons[ $key ]['description'] = apply_filters( 'wpml_translate_single_string', $addon_data->get( 'description' ), 'wc_product_addons_strings', $object_id . '_addon_' . $addon_type . '_' . $addon_position . '_description' );
|
122 |
+
// register options labels
|
123 |
+
if ( $addon_data->offsetExists( 'options' ) ) {
|
124 |
+
foreach ( $addon['options'] as $opt_key => $option ) {
|
125 |
+
$addons[ $key ]['options'][ $opt_key ]['label'] = apply_filters( 'wpml_translate_single_string', wpml_collect( $option )->get( 'label' ), 'wc_product_addons_strings', $object_id . '_addon_' . $addon_type . '_' . $addon_position . '_option_label_' . $opt_key );
|
126 |
+
}
|
127 |
+
}
|
128 |
+
}
|
129 |
+
}
|
130 |
+
|
131 |
+
return [ 0 => $addons ];
|
132 |
+
}
|
133 |
+
|
134 |
+
return $null;
|
135 |
+
|
136 |
+
}
|
137 |
+
|
138 |
+
/**
|
139 |
+
* @param $product_terms
|
140 |
+
*
|
141 |
+
* @return array
|
142 |
+
*/
|
143 |
+
public function addons_product_terms( $product_terms ) {
|
144 |
+
foreach ( $product_terms as $key => $product_term ) {
|
145 |
+
$product_terms[ $key ] = apply_filters( 'translate_object_id', $product_term, 'product_cat', true, $this->sitepress->get_default_language() );
|
146 |
+
}
|
147 |
+
|
148 |
+
return $product_terms;
|
149 |
+
}
|
150 |
+
|
151 |
+
public function inf_translate_strings() {
|
152 |
+
|
153 |
+
$pointer_ui = new WCML_Pointer_UI(
|
154 |
+
/* translators: %1$s and %2$s are opening and closing HTML link tags */
|
155 |
+
sprintf( __( 'You can translate strings related to global add-ons on the %1$sWPML String Translation page%2$s. Use the search on the top of that page to find the strings.', 'woocommerce-multilingual' ), '<a href="' . admin_url( 'admin.php?page=' . WPML_ST_FOLDER . '/menu/string-translation.php&context=wc_product_addons_strings' ) . '">', '</a>' ),
|
156 |
+
WCML_Tracking_Link::getWcmlProductAddonsDoc(),
|
157 |
+
'wpbody-content .woocommerce>h2'
|
158 |
+
);
|
159 |
+
|
160 |
+
$pointer_ui->show();
|
161 |
+
}
|
162 |
+
|
163 |
+
/**
|
164 |
+
* @param array $package
|
165 |
+
* @param \WP_Post $post
|
166 |
+
*
|
167 |
+
* @return array
|
168 |
+
*/
|
169 |
+
public function append_addons_to_translation_package( $package, $post ) {
|
170 |
+
if ( 'product' === $post->post_type ) {
|
171 |
+
$add_field = function( $name, $value ) use ( &$package ) {
|
172 |
+
if ( $value ) {
|
173 |
+
$package['contents'][ $name ] = [
|
174 |
+
'translate' => 1,
|
175 |
+
'data' => base64_encode( $value ),
|
176 |
+
'format' => 'base64',
|
177 |
+
];
|
178 |
+
}
|
179 |
+
};
|
180 |
+
|
181 |
+
foreach ( SharedHooks::getProductAddons( $post->ID ) as $addon_id => $addon_data ) {
|
182 |
+
$add_field( self::get_job_field_name( $addon_id, 'name' ), Obj::prop( 'name', $addon_data ) );
|
183 |
+
$add_field( self::get_job_field_name( $addon_id, 'description' ), Obj::prop( 'description', $addon_data ) );
|
184 |
+
|
185 |
+
foreach ( (array) Obj::prop( 'options', $addon_data ) as $option_id => $option ) {
|
186 |
+
$add_field( self::get_job_field_name( $addon_id, $option_id ), Obj::prop( 'label', $option ) );
|
187 |
+
}
|
188 |
+
}
|
189 |
+
}
|
190 |
+
|
191 |
+
return $package;
|
192 |
+
}
|
193 |
+
|
194 |
+
/**
|
195 |
+
* @param int $post_id
|
196 |
+
* @param array $fields
|
197 |
+
* @param object $job
|
198 |
+
*/
|
199 |
+
public function save_addons_to_translation( $post_id, $fields, $job ) {
|
200 |
+
if (
|
201 |
+
Str::startsWith( 'post_', $job->original_post_type )
|
202 |
+
&& 'product' === get_post_type( $post_id )
|
203 |
+
) {
|
204 |
+
$get_translation = function( $field_name ) use ( $fields ) {
|
205 |
+
return Obj::path( [ $field_name, 'data' ], $fields );
|
206 |
+
};
|
207 |
+
|
208 |
+
$addons = SharedHooks::getProductAddons( $post_id );
|
209 |
+
|
210 |
+
foreach ( $addons as $addon_id => $addon_data ) {
|
211 |
+
if ( isset( $addons[ $addon_id ]['name'] ) ) {
|
212 |
+
$addons[ $addon_id ]['name'] = $get_translation( self::get_job_field_name( $addon_id, 'name' ) );
|
213 |
+
$addons[ $addon_id ]['description'] = $get_translation( self::get_job_field_name( $addon_id, 'description' ) );
|
214 |
+
}
|
215 |
+
|
216 |
+
foreach ( (array) Obj::prop( 'options', $addon_data ) as $option_id => $option ) {
|
217 |
+
if ( isset( $addons[ $addon_id ]['options'][ $option_id ]['label'] ) ) {
|
218 |
+
$addons[ $addon_id ]['options'][ $option_id ]['label'] = $get_translation( self::get_job_field_name( $addon_id, $option_id ) );
|
219 |
+
}
|
220 |
+
}
|
221 |
+
}
|
222 |
+
|
223 |
+
update_post_meta( $post_id, self::ADDONS_OPTION_KEY, $addons );
|
224 |
+
}
|
225 |
+
}
|
226 |
+
|
227 |
+
/**
|
228 |
+
* @param int $addon_id
|
229 |
+
* @param int|string $name_or_id
|
230 |
+
*
|
231 |
+
* @return string
|
232 |
+
*/
|
233 |
+
private static function get_job_field_name( $addon_id, $name_or_id ) {
|
234 |
+
return is_numeric( $name_or_id )
|
235 |
+
? 'addon_' . $addon_id . '_option_' . $name_or_id . '_label'
|
236 |
+
: 'addon_' . $addon_id . '_' . $name_or_id;
|
237 |
+
}
|
238 |
+
|
239 |
+
/**
|
240 |
+
* @deprecated This method is used by CTE only.
|
241 |
+
*
|
242 |
+
* @param $obj
|
243 |
+
* @param $product_id
|
244 |
+
* @param $data
|
245 |
+
*/
|
246 |
+
public function custom_box_html( $obj, $product_id, $data ) {
|
247 |
+
|
248 |
+
$product_addons = SharedHooks::getProductAddons( $product_id );
|
249 |
+
|
250 |
+
if ( ! empty( $product_addons ) ) {
|
251 |
+
foreach ( $product_addons as $addon_id => $product_addon ) {
|
252 |
+
$addon_data = wpml_collect( $product_addon );
|
253 |
+
|
254 |
+
/* translators: %s is a product addon name */
|
255 |
+
$addons_section = new WPML_Editor_UI_Field_Section( sprintf( __( 'Product Add-ons Group "%s"', 'woocommerce-multilingual' ), $addon_data->get( 'name' ) ) );
|
256 |
+
|
257 |
+
$group = new WPML_Editor_UI_Field_Group( '', true );
|
258 |
+
$addon_field = new WPML_Editor_UI_Single_Line_Field( 'addon_' . $addon_id . '_name', __( 'Name', 'woocommerce-multilingual' ), $data, false );
|
259 |
+
$group->add_field( $addon_field );
|
260 |
+
$addon_field = new WPML_Editor_UI_Single_Line_Field( 'addon_' . $addon_id . '_description', __( 'Description', 'woocommerce-multilingual' ), $data, false );
|
261 |
+
$group->add_field( $addon_field );
|
262 |
+
|
263 |
+
$addons_section->add_field( $group );
|
264 |
+
|
265 |
+
if ( $addon_data->offsetExists( 'options' ) && $addon_data->get( 'options' ) ) {
|
266 |
+
|
267 |
+
$labels_group = new WPML_Editor_UI_Field_Group( __( 'Options', 'woocommerce-multilingual' ), true );
|
268 |
+
|
269 |
+
foreach ( $addon_data->get( 'options' ) as $option_id => $option ) {
|
270 |
+
$option_label_field = new WPML_Editor_UI_Single_Line_Field( 'addon_' . $addon_id . '_option_' . $option_id . '_label', __( 'Label', 'woocommerce-multilingual' ), $data, false );
|
271 |
+
$labels_group->add_field( $option_label_field );
|
272 |
+
}
|
273 |
+
$addons_section->add_field( $labels_group );
|
274 |
+
}
|
275 |
+
$obj->add_field( $addons_section );
|
276 |
+
}
|
277 |
+
}
|
278 |
+
}
|
279 |
+
|
280 |
+
/**
|
281 |
+
* @deprecated This method is used by CTE only.
|
282 |
+
*
|
283 |
+
* @param $data
|
284 |
+
* @param $product_id
|
285 |
+
* @param $translation
|
286 |
+
*
|
287 |
+
* @return mixed
|
288 |
+
*/
|
289 |
+
public function custom_box_html_data( $data, $product_id, $translation ) {
|
290 |
+
|
291 |
+
$product_addons = SharedHooks::getProductAddons( $product_id );
|
292 |
+
|
293 |
+
if ( ! empty( $product_addons ) ) {
|
294 |
+
foreach ( $product_addons as $addon_id => $product_addon ) {
|
295 |
+
$addon_data = wpml_collect( $product_addon );
|
296 |
+
$data[ 'addon_' . $addon_id . '_name' ] = [ 'original' => $addon_data->get( 'name' ) ];
|
297 |
+
$data[ 'addon_' . $addon_id . '_description' ] = [ 'original' => $addon_data->get( 'description' ) ];
|
298 |
+
if ( $addon_data->offsetExists( 'options' ) && $addon_data->get( 'options' ) ) {
|
299 |
+
foreach ( $addon_data->get( 'options' ) as $option_id => $option ) {
|
300 |
+
$data[ 'addon_' . $addon_id . '_option_' . $option_id . '_label' ] = [ 'original' => wpml_collect( $option )->get( 'label' ) ];
|
301 |
+
}
|
302 |
+
}
|
303 |
+
}
|
304 |
+
|
305 |
+
if ( $translation ) {
|
306 |
+
$translated_product_addons = SharedHooks::getProductAddons( $translation->ID );
|
307 |
+
if ( ! empty( $translated_product_addons ) ) {
|
308 |
+
foreach ( $translated_product_addons as $addon_id => $transalted_product_addon ) {
|
309 |
+
$translated_addon_data = wpml_collect( $transalted_product_addon );
|
310 |
+
$data[ 'addon_' . $addon_id . '_name' ]['translation'] = $translated_addon_data->get( 'name' );
|
311 |
+
$data[ 'addon_' . $addon_id . '_description' ]['translation'] = $translated_addon_data->get( 'description' );
|
312 |
+
if ( $translated_addon_data->offsetExists( 'options' ) && $translated_addon_data->get( 'options' ) ) {
|
313 |
+
foreach ( $translated_addon_data->get( 'options' ) as $option_id => $option ) {
|
314 |
+
$data[ 'addon_' . $addon_id . '_option_' . $option_id . '_label' ]['translation'] = wpml_collect( $option )->get( 'label' );
|
315 |
+
}
|
316 |
+
}
|
317 |
+
}
|
318 |
+
}
|
319 |
+
}
|
320 |
+
}
|
321 |
+
|
322 |
+
return $data;
|
323 |
+
}
|
324 |
+
|
325 |
+
/**
|
326 |
+
* @deprecated This method is used by CTE only.
|
327 |
+
*
|
328 |
+
* @param $original_product_id
|
329 |
+
* @param $product_id
|
330 |
+
* @param $data
|
331 |
+
*/
|
332 |
+
public function addons_update( $original_product_id, $product_id, $data ) {
|
333 |
+
|
334 |
+
$product_addons = SharedHooks::getProductAddons( $original_product_id );
|
335 |
+
|
336 |
+
if ( ! empty( $product_addons ) ) {
|
337 |
+
|
338 |
+
foreach ( $product_addons as $addon_id => $product_addon ) {
|
339 |
+
$addon_data = wpml_collect( $product_addon );
|
340 |
+
$product_addons[ $addon_id ]['name'] = $data[ md5( 'addon_' . $addon_id . '_name' ) ];
|
341 |
+
$product_addons[ $addon_id ]['description'] = $data[ md5( 'addon_' . $addon_id . '_description' ) ];
|
342 |
+
|
343 |
+
if ( $addon_data->offsetExists( 'options' ) && $addon_data->get( 'options' ) ) {
|
344 |
+
foreach ( $addon_data->get( 'options' ) as $option_id => $option ) {
|
345 |
+
$product_addons[ $addon_id ]['options'][ $option_id ]['label'] = $data[ md5( 'addon_' . $addon_id . '_option_' . $option_id . '_label' ) ];
|
346 |
+
}
|
347 |
+
}
|
348 |
+
}
|
349 |
+
}
|
350 |
+
|
351 |
+
update_post_meta( $product_id, self::ADDONS_OPTION_KEY, $product_addons );
|
352 |
+
}
|
353 |
+
|
354 |
+
public function show_pointer_info() {
|
355 |
+
|
356 |
+
$pointer_ui = new WCML_Pointer_UI(
|
357 |
+
/* translators: %1$s and %2$s are opening and closing HTML link tags */
|
358 |
+
sprintf( __( 'You can translate the Group Name, Group Description and every Option Label of your product add-on on the %1$sWooCommerce product translation page%2$s', 'woocommerce-multilingual' ), '<a href="' . admin_url( 'admin.php?page=wpml-wcml' ) . '">', '</a>' ),
|
359 |
+
WCML_Tracking_Link::getWcmlProductAddonsDoc(),
|
360 |
+
'product_addons_data>p'
|
361 |
+
);
|
362 |
+
|
363 |
+
$pointer_ui->show();
|
364 |
+
}
|
365 |
+
|
366 |
+
public function replace_tm_editor_custom_fields_with_own_sections( $fields ) {
|
367 |
+
$fields[] = self::ADDONS_OPTION_KEY;
|
368 |
+
|
369 |
+
return $fields;
|
370 |
+
}
|
371 |
+
|
372 |
+
public function set_global_ids_in_query_args( $args ) {
|
373 |
+
|
374 |
+
if ( ! is_archive() ) {
|
375 |
+
|
376 |
+
remove_filter( 'get_terms_args', [ $this->sitepress, 'get_terms_args_filter' ], 10 );
|
377 |
+
remove_filter( 'get_term', [ $this->sitepress, 'get_term_adjust_id' ], 1 );
|
378 |
+
remove_filter( 'terms_clauses', [ $this->sitepress, 'terms_clauses' ], 10 );
|
379 |
+
|
380 |
+
$matched_addons_ids = get_posts( $args );
|
381 |
+
if ( is_object( reset( $matched_addons_ids ) ) ) {
|
382 |
+
$matched_addons_ids = wp_list_pluck( $matched_addons_ids, 'ID' );
|
383 |
+
}
|
384 |
+
|
385 |
+
if ( $matched_addons_ids ) {
|
386 |
+
$args['include'] = $matched_addons_ids;
|
387 |
+
unset( $args['tax_query'] );
|
388 |
+
}
|
389 |
+
|
390 |
+
add_filter( 'get_terms_args', [ $this->sitepress, 'get_terms_args_filter' ], 10, 2 );
|
391 |
+
add_filter( 'get_term', [ $this->sitepress, 'get_term_adjust_id' ], 1 );
|
392 |
+
add_filter( 'terms_clauses', [ $this->sitepress, 'terms_clauses' ], 10, 3 );
|
393 |
+
}
|
394 |
+
|
395 |
+
return $args;
|
396 |
+
}
|
397 |
+
}
|
compatibility/WcProductBundles/Factory.php
ADDED
@@ -0,0 +1,31 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace WCML\Compatibility\WcProductBundles;
|
4 |
+
|
5 |
+
use WCML\Compatibility\ComponentFactory;
|
6 |
+
use WCML\StandAlone\IStandAloneAction;
|
7 |
+
use WCML_Product_Bundles;
|
8 |
+
use WCML_WC_Product_Bundles_Items;
|
9 |
+
use function WCML\functions\getSitePress;
|
10 |
+
use function WCML\functions\getWooCommerceWpml;
|
11 |
+
use function WCML\functions\isStandAlone;
|
12 |
+
|
13 |
+
class Factory extends ComponentFactory implements IStandAloneAction {
|
14 |
+
|
15 |
+
/**
|
16 |
+
* @inheritDoc
|
17 |
+
*/
|
18 |
+
public function create() {
|
19 |
+
$hooks = [];
|
20 |
+
|
21 |
+
if ( wcml_is_multi_currency_on() ) {
|
22 |
+
$hooks[] = new MulticurrencyHooks();
|
23 |
+
}
|
24 |
+
|
25 |
+
if ( ! isStandAlone() ) {
|
26 |
+
$hooks[] = new WCML_Product_Bundles( getSitePress(), getWooCommerceWpml(), new WCML_WC_Product_Bundles_Items(), self::getWpdb() );
|
27 |
+
}
|
28 |
+
|
29 |
+
return $hooks;
|
30 |
+
}
|
31 |
+
}
|
compatibility/WcProductBundles/MulticurrencyHooks.php
ADDED
@@ -0,0 +1,65 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace WCML\Compatibility\WcProductBundles;
|
4 |
+
|
5 |
+
class MulticurrencyHooks implements \IWPML_Action {
|
6 |
+
|
7 |
+
public function add_hooks() {
|
8 |
+
add_filter( 'wcml_price_custom_fields_filtered', [ $this, 'getPriceCustomFields' ], 10, 2 );
|
9 |
+
add_filter( 'wcml_update_custom_prices_values', [ $this, 'updateBundlesCustomPricesValues' ], 10, 2 );
|
10 |
+
add_action( 'wcml_after_save_custom_prices', [ $this, 'updateBundlesBasePrice' ], 10, 4 );
|
11 |
+
}
|
12 |
+
|
13 |
+
/**
|
14 |
+
* @param array $customFields
|
15 |
+
*
|
16 |
+
* @return array
|
17 |
+
*/
|
18 |
+
public function getPriceCustomFields( $customFields ) {
|
19 |
+
return array_merge(
|
20 |
+
$customFields,
|
21 |
+
[
|
22 |
+
'_wc_pb_base_regular_price',
|
23 |
+
'_wc_pb_base_sale_price',
|
24 |
+
'_wc_pb_base_price',
|
25 |
+
'_wc_sw_max_price',
|
26 |
+
'_wc_sw_max_regular_price',
|
27 |
+
]
|
28 |
+
);
|
29 |
+
}
|
30 |
+
|
31 |
+
/**
|
32 |
+
* @param array $prices
|
33 |
+
* @param string $code
|
34 |
+
*
|
35 |
+
* @return array
|
36 |
+
*/
|
37 |
+
public function updateBundlesCustomPricesValues( $prices, $code ) {
|
38 |
+
// phpcs:disable
|
39 |
+
if ( isset( $_POST['_custom_regular_price'][ $code ] ) ) {
|
40 |
+
$prices['_wc_pb_base_regular_price'] = wc_format_decimal( $_POST['_custom_regular_price'][ $code ] );
|
41 |
+
}
|
42 |
+
|
43 |
+
if ( isset( $_POST['_custom_sale_price'][ $code ] ) ) {
|
44 |
+
$prices['_wc_pb_base_sale_price'] = wc_format_decimal( $_POST['_custom_sale_price'][ $code ] );
|
45 |
+
}
|
46 |
+
|
47 |
+
return $prices;
|
48 |
+
// phpcs:enable
|
49 |
+
}
|
50 |
+
|
51 |
+
/**
|
52 |
+
* @param int|string $postId
|
53 |
+
* @param string $productPrice
|
54 |
+
* @param array $customPrices
|
55 |
+
* @param string $code
|
56 |
+
*
|
57 |
+
* @return void
|
58 |
+
*/
|
59 |
+
public function updateBundlesBasePrice( $postId, $productPrice, $customPrices, $code ) {
|
60 |
+
// phpcs:ignore WordPress.Security.NonceVerification.Missing
|
61 |
+
if ( isset( $customPrices['_wc_pb_base_regular_price'] ) ) {
|
62 |
+
update_post_meta( $postId, '_wc_pb_base_price_' . $code, $productPrice );
|
63 |
+
}
|
64 |
+
}
|
65 |
+
}
|
compatibility/{class-wcml-product-bundles.php → WcProductBundles/class-wcml-product-bundles.php}
RENAMED
@@ -1,8 +1,15 @@
|
|
1 |
<?php
|
2 |
|
|
|
|
|
3 |
use WPML\FP\Obj;
|
|
|
4 |
|
5 |
-
class WCML_Product_Bundles {
|
|
|
|
|
|
|
|
|
6 |
|
7 |
/**
|
8 |
* @var WPML_Element_Translation_Package
|
@@ -33,15 +40,21 @@ class WCML_Product_Bundles {
|
|
33 |
* WCML_Product_Bundles constructor.
|
34 |
*/
|
35 |
public function __construct( SitePress $sitepress, woocommerce_wpml $woocommerce_wpml, $product_bundles_items, wpdb $wpdb ) {
|
36 |
-
|
37 |
$this->sitepress = $sitepress;
|
38 |
$this->woocommerce_wpml = $woocommerce_wpml;
|
39 |
$this->product_bundles_items = $product_bundles_items;
|
40 |
$this->wpdb = $wpdb;
|
|
|
41 |
|
|
|
42 |
add_action( 'woocommerce_get_cart_item_from_session', [ $this, 'resync_bundle' ], 5, 3 );
|
43 |
add_filter( 'woocommerce_cart_loaded_from_session', [ $this, 'resync_bundle_clean' ], 10 );
|
44 |
-
|
|
|
|
|
|
|
|
|
|
|
45 |
|
46 |
if ( is_admin() ) {
|
47 |
$this->tp = new WPML_Element_Translation_Package();
|
@@ -56,11 +69,13 @@ class WCML_Product_Bundles {
|
|
56 |
2
|
57 |
);
|
58 |
|
59 |
-
|
60 |
-
|
|
|
|
|
|
|
61 |
|
62 |
add_action( 'wcml_after_duplicate_product_post_meta', [ $this, 'sync_bundled_ids' ], 10, 2 );
|
63 |
-
add_action( 'wcml_update_extra_fields', [ $this, 'bundle_update' ], 10, 4 );
|
64 |
|
65 |
add_action( 'wp_insert_post', [ $this, 'sync_product_bundle_meta_with_translations' ], 10 );
|
66 |
|
@@ -69,17 +84,15 @@ class WCML_Product_Bundles {
|
|
69 |
add_action( 'woocommerce_before_delete_bundled_item', [ $this, 'delete_bundled_item_relationship' ] );
|
70 |
}
|
71 |
|
72 |
-
// product bundle using separate custom fields for prices.
|
73 |
-
if ( wcml_is_multi_currency_on() ) {
|
74 |
-
add_filter( 'wcml_price_custom_fields_filtered', [ $this, 'get_price_custom_fields' ], 10, 2 );
|
75 |
-
add_filter( 'wcml_update_custom_prices_values', [ $this, 'update_bundles_custom_prices_values' ], 10, 2 );
|
76 |
-
add_filter( 'wcml_after_save_custom_prices', [ $this, 'update_bundles_base_price' ], 10, 4 );
|
77 |
-
}
|
78 |
-
|
79 |
add_action( 'init', [ $this, 'upgrade_bundles_items_relationships' ] );
|
80 |
-
|
81 |
}
|
82 |
|
|
|
|
|
|
|
|
|
|
|
83 |
private function get_product_bundle_data( $bundle_id ) {
|
84 |
$product_bundle_data = [];
|
85 |
|
@@ -91,7 +104,12 @@ class WCML_Product_Bundles {
|
|
91 |
return $product_bundle_data;
|
92 |
}
|
93 |
|
|
|
|
|
|
|
|
|
94 |
private function save_product_bundle_data( $bundle_id, $product_bundle_data ) {
|
|
|
95 |
|
96 |
$bundle_items = $this->product_bundles_items->get_items( $bundle_id );
|
97 |
|
@@ -106,6 +124,15 @@ class WCML_Product_Bundles {
|
|
106 |
|
107 |
}
|
108 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
109 |
public function sync_product_bundle_meta( $bundle_id, $translated_bundle_id ) {
|
110 |
|
111 |
$bundle_items = $this->product_bundles_items->get_items( $bundle_id );
|
@@ -179,27 +206,45 @@ class WCML_Product_Bundles {
|
|
179 |
}
|
180 |
|
181 |
public function sync_product_bundle_meta_with_translations( $bundle_id ) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
182 |
|
183 |
-
|
|
|
|
|
|
|
184 |
|
185 |
-
|
186 |
-
|
187 |
-
$original_bundle_id = null;
|
188 |
|
189 |
-
foreach ( $translations as $language => $translation ) {
|
190 |
-
if ( $translation->original ) {
|
191 |
-
$original_bundle_id = $translation->element_id;
|
192 |
-
break;
|
193 |
-
}
|
194 |
-
}
|
195 |
|
196 |
-
|
197 |
-
|
198 |
-
|
199 |
-
|
200 |
-
|
|
|
201 |
}
|
202 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
203 |
}
|
204 |
|
205 |
/**
|
@@ -257,8 +302,8 @@ class WCML_Product_Bundles {
|
|
257 |
}
|
258 |
|
259 |
/**
|
260 |
-
* @param
|
261 |
-
* @param string
|
262 |
*
|
263 |
* @return string
|
264 |
*/
|
@@ -292,7 +337,17 @@ class WCML_Product_Bundles {
|
|
292 |
|
293 |
}
|
294 |
|
295 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
296 |
public function custom_box_html( $obj, $bundle_id, $data ) {
|
297 |
|
298 |
$bundle_items = $this->product_bundles_items->get_items( $bundle_id );
|
@@ -357,6 +412,16 @@ class WCML_Product_Bundles {
|
|
357 |
|
358 |
}
|
359 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
360 |
public function custom_box_html_data( $data, $bundle_id, $translation, $lang ) {
|
361 |
|
362 |
$bundle_data = $this->get_product_bundle_data( $bundle_id );
|
@@ -403,6 +468,17 @@ class WCML_Product_Bundles {
|
|
403 |
return $data;
|
404 |
}
|
405 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
406 |
public function append_bundle_data_translation_package( $package, $post ) {
|
407 |
|
408 |
if ( $post->post_type == 'product' ) {
|
@@ -418,7 +494,7 @@ class WCML_Product_Bundles {
|
|
418 |
$product_id = $this->get_product_id_for_item_id( $item_id );
|
419 |
foreach ( $fields as $field ) {
|
420 |
if ( $product_data[ 'override_' . $field ] == 'yes' && ! empty( $product_data[ $field ] ) ) {
|
421 |
-
$package['contents'][
|
422 |
'translate' => 1,
|
423 |
'data' => $this->tp->encode_field_data( $product_data[ $field ], 'base64' ),
|
424 |
'format' => 'base64',
|
@@ -427,15 +503,99 @@ class WCML_Product_Bundles {
|
|
427 |
}
|
428 |
}
|
429 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
430 |
}
|
431 |
|
432 |
return $package;
|
433 |
|
434 |
}
|
435 |
|
436 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
437 |
public function bundle_update( $bundle_id, $translated_bundle_id, $data, $lang ) {
|
|
|
|
|
|
|
|
|
438 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
439 |
$bundle_data = $this->get_product_bundle_data( $bundle_id );
|
440 |
$translated_bundle_data = $this->get_product_bundle_data( $translated_bundle_id );
|
441 |
|
@@ -453,7 +613,7 @@ class WCML_Product_Bundles {
|
|
453 |
foreach ( $bundle_data as $item_id => $bundle_item_data ) {
|
454 |
|
455 |
$product_id = $this->get_product_id_for_item_id( $item_id );
|
456 |
-
$translated_product_id = apply_filters( 'translate_object_id', $product_id, get_post_type( $product_id ), false, $
|
457 |
|
458 |
if ( $translated_product_id ) {
|
459 |
|
@@ -480,29 +640,28 @@ class WCML_Product_Bundles {
|
|
480 |
);
|
481 |
|
482 |
$translated_item_id = $this->wpdb->insert_id;
|
483 |
-
$this->set_translated_item_id_relationship( $item_id, $translated_item_id, $
|
484 |
}
|
485 |
|
486 |
-
$translated_item_id = $this->get_item_id_for_language( $item_id, $
|
487 |
|
488 |
-
|
489 |
-
|
490 |
-
|
491 |
-
|
492 |
-
|
493 |
|
494 |
-
|
495 |
-
|
496 |
-
|
|
|
497 |
}
|
498 |
|
499 |
if ( isset( $bundle_item_data['allowed_variations'] ) ) {
|
500 |
if ( is_array( $bundle_item_data['allowed_variations'] ) ) {
|
501 |
-
$translated_bundle_data[ $translated_item_id ]['allowed_variations'] =
|
502 |
-
$this->translate_allowed_variations( $bundle_item_data['allowed_variations'], $lang );
|
503 |
} else {
|
504 |
-
$translated_bundle_data[ $translated_item_id ]['allowed_variations'] =
|
505 |
-
$bundle_item_data['allowed_variations'];
|
506 |
}
|
507 |
}
|
508 |
}
|
@@ -692,6 +851,13 @@ class WCML_Product_Bundles {
|
|
692 |
}
|
693 |
}
|
694 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
695 |
public function save_bundle_data_translation( $translated_bundle_id, $data, $job ) {
|
696 |
|
697 |
if ( $this->is_bundle_product( $translated_bundle_id ) ) {
|
@@ -780,50 +946,6 @@ class WCML_Product_Bundles {
|
|
780 |
return $translated_item_id;
|
781 |
}
|
782 |
|
783 |
-
/**
|
784 |
-
* @param array $custom_fields
|
785 |
-
*
|
786 |
-
* @return array
|
787 |
-
*/
|
788 |
-
public function get_price_custom_fields( $custom_fields ) {
|
789 |
-
|
790 |
-
$custom_fields = array_merge(
|
791 |
-
$custom_fields,
|
792 |
-
[
|
793 |
-
'_wc_pb_base_regular_price',
|
794 |
-
'_wc_pb_base_sale_price',
|
795 |
-
'_wc_pb_base_price',
|
796 |
-
'_wc_sw_max_price',
|
797 |
-
'_wc_sw_max_regular_price',
|
798 |
-
]
|
799 |
-
);
|
800 |
-
|
801 |
-
return $custom_fields;
|
802 |
-
}
|
803 |
-
|
804 |
-
|
805 |
-
public function update_bundles_custom_prices_values( $prices, $code ) {
|
806 |
-
|
807 |
-
if ( isset( $_POST['_custom_regular_price'][ $code ] ) ) {
|
808 |
-
$prices['_wc_pb_base_regular_price'] = wc_format_decimal( $_POST['_custom_regular_price'][ $code ] );
|
809 |
-
}
|
810 |
-
|
811 |
-
if ( isset( $_POST['_custom_sale_price'][ $code ] ) ) {
|
812 |
-
$prices['_wc_pb_base_sale_price'] = wc_format_decimal( $_POST['_custom_sale_price'][ $code ] );
|
813 |
-
}
|
814 |
-
|
815 |
-
return $prices;
|
816 |
-
|
817 |
-
}
|
818 |
-
|
819 |
-
public function update_bundles_base_price( $post_id, $product_price, $custom_prices, $code ) {
|
820 |
-
|
821 |
-
if ( isset( $custom_prices['_wc_pb_base_regular_price'] ) ) {
|
822 |
-
update_post_meta( $post_id, '_wc_pb_base_price_' . $code, $product_price );
|
823 |
-
}
|
824 |
-
|
825 |
-
}
|
826 |
-
|
827 |
public function is_bundle_product( $product_id ) {
|
828 |
|
829 |
$product = wc_get_product( $product_id );
|
@@ -904,4 +1026,13 @@ class WCML_Product_Bundles {
|
|
904 |
|
905 |
}
|
906 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
907 |
}
|
1 |
<?php
|
2 |
|
3 |
+
use WCML\Options\WPML;
|
4 |
+
use WPML\FP\Fns;
|
5 |
use WPML\FP\Obj;
|
6 |
+
use WPML\FP\Str;
|
7 |
|
8 |
+
class WCML_Product_Bundles implements \IWPML_Action {
|
9 |
+
|
10 |
+
const META_SELL_IDS = '_wc_pb_bundle_sell_ids';
|
11 |
+
const META_SELLS_TITLE = '_wc_pb_bundle_sells_title';
|
12 |
+
const META_SELLS_DISCOUNT = '_wc_pb_bundle_sells_discount';
|
13 |
|
14 |
/**
|
15 |
* @var WPML_Element_Translation_Package
|
40 |
* WCML_Product_Bundles constructor.
|
41 |
*/
|
42 |
public function __construct( SitePress $sitepress, woocommerce_wpml $woocommerce_wpml, $product_bundles_items, wpdb $wpdb ) {
|
|
|
43 |
$this->sitepress = $sitepress;
|
44 |
$this->woocommerce_wpml = $woocommerce_wpml;
|
45 |
$this->product_bundles_items = $product_bundles_items;
|
46 |
$this->wpdb = $wpdb;
|
47 |
+
}
|
48 |
|
49 |
+
public function add_hooks() {
|
50 |
add_action( 'woocommerce_get_cart_item_from_session', [ $this, 'resync_bundle' ], 5, 3 );
|
51 |
add_filter( 'woocommerce_cart_loaded_from_session', [ $this, 'resync_bundle_clean' ], 10 );
|
52 |
+
|
53 |
+
if ( WPML::useAte() ) {
|
54 |
+
add_action( 'wpml_pro_translation_completed', [ $this, 'save_product_bundles_to_translation' ], 10, 3 );
|
55 |
+
} else { // Legacy action for CTE
|
56 |
+
add_action( 'wpml_translation_job_saved', [ $this, 'save_bundle_data_translation' ], 10, 3 );
|
57 |
+
}
|
58 |
|
59 |
if ( is_admin() ) {
|
60 |
$this->tp = new WPML_Element_Translation_Package();
|
69 |
2
|
70 |
);
|
71 |
|
72 |
+
if ( ! WPML::useAte() ) { // Legacy actions/filters for CTE
|
73 |
+
add_action( 'wcml_gui_additional_box_html', [ $this, 'custom_box_html' ], 10, 3 );
|
74 |
+
add_filter( 'wcml_gui_additional_box_data', [ $this, 'custom_box_html_data' ], 10, 4 );
|
75 |
+
add_action( 'wcml_update_extra_fields', [ $this, 'bundle_update' ], 10, 4 );
|
76 |
+
}
|
77 |
|
78 |
add_action( 'wcml_after_duplicate_product_post_meta', [ $this, 'sync_bundled_ids' ], 10, 2 );
|
|
|
79 |
|
80 |
add_action( 'wp_insert_post', [ $this, 'sync_product_bundle_meta_with_translations' ], 10 );
|
81 |
|
84 |
add_action( 'woocommerce_before_delete_bundled_item', [ $this, 'delete_bundled_item_relationship' ] );
|
85 |
}
|
86 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
87 |
add_action( 'init', [ $this, 'upgrade_bundles_items_relationships' ] );
|
88 |
+
add_filter( 'wpml_custom_field_values_for_post_signature', [ __CLASS__, 'adjust_bundle_sells_product_signature' ], 10, 2 );
|
89 |
}
|
90 |
|
91 |
+
/**
|
92 |
+
* @param string|int $bundle_id
|
93 |
+
*
|
94 |
+
* @return array
|
95 |
+
*/
|
96 |
private function get_product_bundle_data( $bundle_id ) {
|
97 |
$product_bundle_data = [];
|
98 |
|
104 |
return $product_bundle_data;
|
105 |
}
|
106 |
|
107 |
+
/**
|
108 |
+
* @param string|int $bundle_id
|
109 |
+
* @param array $product_bundle_data
|
110 |
+
*/
|
111 |
private function save_product_bundle_data( $bundle_id, $product_bundle_data ) {
|
112 |
+
self::flush_bundle_cache( $bundle_id );
|
113 |
|
114 |
$bundle_items = $this->product_bundles_items->get_items( $bundle_id );
|
115 |
|
124 |
|
125 |
}
|
126 |
|
127 |
+
/**
|
128 |
+
* @see \WC_Product_Bundle::get_bundled_data_items
|
129 |
+
*
|
130 |
+
* @param string|int $bundle_id
|
131 |
+
*/
|
132 |
+
private static function flush_bundle_cache( $bundle_id ) {
|
133 |
+
wp_cache_delete( WC_Cache_Helper::get_cache_prefix( 'bundled_data_items' ) . $bundle_id, 'bundled_data_items' );
|
134 |
+
}
|
135 |
+
|
136 |
public function sync_product_bundle_meta( $bundle_id, $translated_bundle_id ) {
|
137 |
|
138 |
$bundle_items = $this->product_bundles_items->get_items( $bundle_id );
|
206 |
}
|
207 |
|
208 |
public function sync_product_bundle_meta_with_translations( $bundle_id ) {
|
209 |
+
/**
|
210 |
+
* @return array {
|
211 |
+
* @var int $original_bundle_id
|
212 |
+
* @var \WPML\Collect\Support\Collection $translations_only
|
213 |
+
* }
|
214 |
+
*/
|
215 |
+
$get_original_id_and_translations = Fns::memorize( function() use ( $bundle_id ) {
|
216 |
+
$trid = $this->sitepress->get_element_trid( $bundle_id, 'post_product' );
|
217 |
+
$translations = wpml_collect( $this->sitepress->get_element_translations( $trid, 'post_product' ) );
|
218 |
+
$original_bundle_id = (int) $translations->filter( Obj::prop( 'original' ) )
|
219 |
+
->map( Obj::prop( 'element_id' ) )
|
220 |
+
->first();
|
221 |
|
222 |
+
$translations_only = $translations
|
223 |
+
->reject( function( $translation ) use ( $original_bundle_id ) {
|
224 |
+
return (int) $translation->element_id === $original_bundle_id;
|
225 |
+
} );
|
226 |
|
227 |
+
return [ $original_bundle_id, $translations_only ];
|
228 |
+
} );
|
|
|
229 |
|
|
|
|
|
|
|
|
|
|
|
|
|
230 |
|
231 |
+
if ( $this->is_bundle_product( $bundle_id ) ) {
|
232 |
+
list( $original_bundle_id, $translations_only ) = $get_original_id_and_translations();
|
233 |
+
|
234 |
+
$translations_only->each( function( $translation ) use ( $original_bundle_id ) {
|
235 |
+
$this->sync_product_bundle_meta( $original_bundle_id, $translation->element_id );
|
236 |
+
} );
|
237 |
}
|
238 |
|
239 |
+
$bundle_sell_ids = get_post_meta( $bundle_id, self::META_SELL_IDS, true );
|
240 |
+
|
241 |
+
if ( $bundle_sell_ids ) {
|
242 |
+
list( $original_bundle_id, $translations_only ) = $get_original_id_and_translations();
|
243 |
+
|
244 |
+
$translations_only->each( function( $translation ) use ( $original_bundle_id ) {
|
245 |
+
$this->sync_bundle_sells( $original_bundle_id, $translation->element_id, $translation->language_code );
|
246 |
+
} );
|
247 |
+
}
|
248 |
}
|
249 |
|
250 |
/**
|
302 |
}
|
303 |
|
304 |
/**
|
305 |
+
* @param int|string $item_id
|
306 |
+
* @param string $language
|
307 |
*
|
308 |
* @return string
|
309 |
*/
|
337 |
|
338 |
}
|
339 |
|
340 |
+
/**
|
341 |
+
* @deprecated This method is used by CTE only.
|
342 |
+
*
|
343 |
+
* Add Bundles Box to WCML Translation GUI.
|
344 |
+
*
|
345 |
+
* @param object $obj
|
346 |
+
* @param string|int $bundle_id
|
347 |
+
* @param mixed $data
|
348 |
+
*
|
349 |
+
* @return false|void
|
350 |
+
*/
|
351 |
public function custom_box_html( $obj, $bundle_id, $data ) {
|
352 |
|
353 |
$bundle_items = $this->product_bundles_items->get_items( $bundle_id );
|
412 |
|
413 |
}
|
414 |
|
415 |
+
/**
|
416 |
+
* @deprecated This method is used by CTE only.
|
417 |
+
*
|
418 |
+
* @param array $data
|
419 |
+
* @param string|int $bundle_id
|
420 |
+
* @param object $translation
|
421 |
+
* @param string $lang
|
422 |
+
*
|
423 |
+
* @return mixed
|
424 |
+
*/
|
425 |
public function custom_box_html_data( $data, $bundle_id, $translation, $lang ) {
|
426 |
|
427 |
$bundle_data = $this->get_product_bundle_data( $bundle_id );
|
468 |
return $data;
|
469 |
}
|
470 |
|
471 |
+
/**
|
472 |
+
* @param int|string $product_id
|
473 |
+
* @param int|string $item_id
|
474 |
+
* @param string $field
|
475 |
+
*
|
476 |
+
* @return string
|
477 |
+
*/
|
478 |
+
private static function get_job_field_name( $product_id, $item_id, $field ) {
|
479 |
+
return 'product_bundles:' . $product_id . ':' . $item_id . ':' . $field;
|
480 |
+
}
|
481 |
+
|
482 |
public function append_bundle_data_translation_package( $package, $post ) {
|
483 |
|
484 |
if ( $post->post_type == 'product' ) {
|
494 |
$product_id = $this->get_product_id_for_item_id( $item_id );
|
495 |
foreach ( $fields as $field ) {
|
496 |
if ( $product_data[ 'override_' . $field ] == 'yes' && ! empty( $product_data[ $field ] ) ) {
|
497 |
+
$package['contents'][ self::get_job_field_name( $product_id, $item_id, $field ) ] = [
|
498 |
'translate' => 1,
|
499 |
'data' => $this->tp->encode_field_data( $product_data[ $field ], 'base64' ),
|
500 |
'format' => 'base64',
|
503 |
}
|
504 |
}
|
505 |
}
|
506 |
+
|
507 |
+
$bundle_sell = get_post_meta( $post->ID, self::META_SELLS_TITLE, true );
|
508 |
+
|
509 |
+
if ( $bundle_sell ) {
|
510 |
+
$package['contents'][ self::META_SELLS_TITLE ] = [
|
511 |
+
'translate' => 1,
|
512 |
+
'data' => $this->tp->encode_field_data( $bundle_sell ),
|
513 |
+
'format' => 'base64',
|
514 |
+
];
|
515 |
+
}
|
516 |
}
|
517 |
|
518 |
return $package;
|
519 |
|
520 |
}
|
521 |
|
522 |
+
/**
|
523 |
+
* @param string|int $translated_bundle_id
|
524 |
+
* @param array $fields
|
525 |
+
* @param object $job
|
526 |
+
*/
|
527 |
+
public function save_product_bundles_to_translation( $translated_bundle_id, $fields, $job ) {
|
528 |
+
$bundle_id = $job->original_doc_id;
|
529 |
+
|
530 |
+
if (
|
531 |
+
Str::startsWith( 'post_', $job->original_post_type )
|
532 |
+
&& 'product' === get_post_type( $bundle_id )
|
533 |
+
) {
|
534 |
+
// $get_field_translation :: (string, string, string) -> string
|
535 |
+
$get_field_translation = function( $product_id, $item_id, $field ) use ( $fields ) {
|
536 |
+
return Obj::path( [ self::get_job_field_name( $product_id, $item_id, $field ), 'data' ], $fields );
|
537 |
+
};
|
538 |
+
|
539 |
+
$this->apply_translation( $bundle_id, $translated_bundle_id, $get_field_translation, $job->language_code );
|
540 |
+
$this->sync_bundle_sells( $bundle_id, $translated_bundle_id, $job->language_code, Obj::path( [ self::META_SELLS_TITLE, 'data' ], $fields ) );
|
541 |
+
}
|
542 |
+
}
|
543 |
+
|
544 |
+
private function sync_bundle_sells( $bundle_id, $translated_bundle_id, $language_code, $translated_title = null ) {
|
545 |
+
// $transpose_post_meta :: (string, callable) -> void
|
546 |
+
$transpose_post_meta = function( $meta_name, callable $transpose ) use ( $bundle_id, $translated_bundle_id ) {
|
547 |
+
$value = get_post_meta( $bundle_id, $meta_name, true );
|
548 |
+
|
549 |
+
if ( $value ) {
|
550 |
+
update_post_meta( $translated_bundle_id, $meta_name, $transpose( $value ) );
|
551 |
+
} else {
|
552 |
+
delete_post_meta( $translated_bundle_id, $meta_name );
|
553 |
+
}
|
554 |
+
};
|
555 |
+
|
556 |
+
// $convert_product_ids :: array -> array
|
557 |
+
$convert_product_ids = Fns::map( function( $id ) use ( $language_code ) {
|
558 |
+
return $this->sitepress->get_object_id( $id, 'product', true, $language_code );
|
559 |
+
} );
|
560 |
+
|
561 |
+
$transpose_post_meta( self::META_SELL_IDS, $convert_product_ids );
|
562 |
+
$transpose_post_meta( self::META_SELLS_DISCOUNT, Fns::identity() );
|
563 |
+
|
564 |
+
if ( $translated_title ) {
|
565 |
+
$transpose_post_meta( self::META_SELLS_TITLE, Fns::always( $translated_title ) );
|
566 |
+
}
|
567 |
+
}
|
568 |
+
|
569 |
+
/**
|
570 |
+
* @deprecated This method is used by CTE only.
|
571 |
+
*
|
572 |
+
* Update Bundled products title and description after saving the translation.
|
573 |
+
*
|
574 |
+
* @param string|int $bundle_id
|
575 |
+
* @param string|int $translated_bundle_id
|
576 |
+
* @param array $data
|
577 |
+
* @param string $lang
|
578 |
+
*
|
579 |
+
* @return array|void
|
580 |
+
*/
|
581 |
public function bundle_update( $bundle_id, $translated_bundle_id, $data, $lang ) {
|
582 |
+
// $get_field_translation :: (string, string, string, string) -> string
|
583 |
+
$get_field_translation = function( $product_id, $item_id, $field, $field_alias ) use ( $data ) {
|
584 |
+
return Obj::prop( md5( 'bundle_' . $product_id . '_' . $field_alias ), $data );
|
585 |
+
};
|
586 |
|
587 |
+
return $this->apply_translation( $bundle_id, $translated_bundle_id, $get_field_translation, $lang );
|
588 |
+
}
|
589 |
+
|
590 |
+
/**
|
591 |
+
* @param string|int $bundle_id
|
592 |
+
* @param string|int $translated_bundle_id
|
593 |
+
* @param callable $get_field_translation (int, int, string) -> string
|
594 |
+
* @param string $target_lang
|
595 |
+
*
|
596 |
+
* @return array|void
|
597 |
+
*/
|
598 |
+
private function apply_translation( $bundle_id, $translated_bundle_id, callable $get_field_translation, $target_lang ) {
|
599 |
$bundle_data = $this->get_product_bundle_data( $bundle_id );
|
600 |
$translated_bundle_data = $this->get_product_bundle_data( $translated_bundle_id );
|
601 |
|
613 |
foreach ( $bundle_data as $item_id => $bundle_item_data ) {
|
614 |
|
615 |
$product_id = $this->get_product_id_for_item_id( $item_id );
|
616 |
+
$translated_product_id = apply_filters( 'translate_object_id', $product_id, get_post_type( $product_id ), false, $target_lang );
|
617 |
|
618 |
if ( $translated_product_id ) {
|
619 |
|
640 |
);
|
641 |
|
642 |
$translated_item_id = $this->wpdb->insert_id;
|
643 |
+
$this->set_translated_item_id_relationship( $item_id, $translated_item_id, $target_lang );
|
644 |
}
|
645 |
|
646 |
+
$translated_item_id = $this->get_item_id_for_language( $item_id, $target_lang );
|
647 |
|
648 |
+
foreach ( [
|
649 |
+
'title' => 'title',
|
650 |
+
'description' => 'desc',
|
651 |
+
] as $field => $field_alias ) {
|
652 |
+
$field_translation = $get_field_translation( $product_id, $item_id, $field, $field_alias );
|
653 |
|
654 |
+
if ( $field_translation ) {
|
655 |
+
$translated_bundle_data[ $translated_item_id ][ $field ] = $field_translation;
|
656 |
+
$translated_bundle_data[ $translated_item_id ][ "override_$field" ] = $bundle_item_data[ "override_$field" ];
|
657 |
+
}
|
658 |
}
|
659 |
|
660 |
if ( isset( $bundle_item_data['allowed_variations'] ) ) {
|
661 |
if ( is_array( $bundle_item_data['allowed_variations'] ) ) {
|
662 |
+
$translated_bundle_data[ $translated_item_id ]['allowed_variations'] = $this->translate_allowed_variations( $bundle_item_data['allowed_variations'], $target_lang );
|
|
|
663 |
} else {
|
664 |
+
$translated_bundle_data[ $translated_item_id ]['allowed_variations'] = $bundle_item_data['allowed_variations'];
|
|
|
665 |
}
|
666 |
}
|
667 |
}
|
851 |
}
|
852 |
}
|
853 |
|
854 |
+
/**
|
855 |
+
* @deprecated This method is used by CTE only.
|
856 |
+
*
|
857 |
+
* @param string|int $translated_bundle_id
|
858 |
+
* @param array $data
|
859 |
+
* @param object $job
|
860 |
+
*/
|
861 |
public function save_bundle_data_translation( $translated_bundle_id, $data, $job ) {
|
862 |
|
863 |
if ( $this->is_bundle_product( $translated_bundle_id ) ) {
|
946 |
return $translated_item_id;
|
947 |
}
|
948 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
949 |
public function is_bundle_product( $product_id ) {
|
950 |
|
951 |
$product = wc_get_product( $product_id );
|
1026 |
|
1027 |
}
|
1028 |
|
1029 |
+
/**
|
1030 |
+
* @param array $values
|
1031 |
+
* @param int $postId
|
1032 |
+
*
|
1033 |
+
* @return array
|
1034 |
+
*/
|
1035 |
+
public static function adjust_bundle_sells_product_signature( $values, $postId ) {
|
1036 |
+
return Obj::assoc( self::META_SELLS_TITLE, get_post_meta( $postId, self::META_SELLS_TITLE, true ), $values );
|
1037 |
+
}
|
1038 |
}
|
compatibility/{includes → WcProductBundles}/class-wcml-wc-product-bundles-items.php
RENAMED
File without changes
|
compatibility/WcProductTypeColumn/Factory.php
ADDED
@@ -0,0 +1,16 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace WCML\Compatibility\WcProductTypeColumn;
|
4 |
+
|
5 |
+
use WCML\Compatibility\ComponentFactory;
|
6 |
+
use WCML_WC_Product_Type_Column;
|
7 |
+
|
8 |
+
class Factory extends ComponentFactory {
|
9 |
+
|
10 |
+
/**
|
11 |
+
* @inheritDoc
|
12 |
+
*/
|
13 |
+
public function create() {
|
14 |
+
return new WCML_WC_Product_Type_Column();
|
15 |
+
}
|
16 |
+
}
|
compatibility/{class-wcml-wc-product-type-column.php → WcProductTypeColumn/class-wcml-wc-product-type-column.php}
RENAMED
@@ -1,6 +1,6 @@
|
|
1 |
<?php
|
2 |
|
3 |
-
class WCML_WC_Product_Type_Column {
|
4 |
|
5 |
public function add_hooks() {
|
6 |
|
1 |
<?php
|
2 |
|
3 |
+
class WCML_WC_Product_Type_Column implements \IWPML_Action {
|
4 |
|
5 |
public function add_hooks() {
|
6 |
|
compatibility/WcShowSingleVariations/Factory.php
ADDED
@@ -0,0 +1,19 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace WCML\Compatibility\WcShowSingleVariations;
|
4 |
+
|
5 |
+
use WCML\Compatibility\ComponentFactory;
|
6 |
+
use WCML_JCK_WSSV;
|
7 |
+
|
8 |
+
/**
|
9 |
+
* @see https://iconicwp.com/products/woocommerce-show-single-variations/
|
10 |
+
*/
|
11 |
+
class Factory extends ComponentFactory {
|
12 |
+
|
13 |
+
/**
|
14 |
+
* @inheritDoc
|
15 |
+
*/
|
16 |
+
public function create() {
|
17 |
+
return new WCML_JCK_WSSV();
|
18 |
+
}
|
19 |
+
}
|
compatibility/{class-wcml-jck-wssv.php → WcShowSingleVariations/class-wcml-jck-wssv.php}
RENAMED
@@ -1,11 +1,10 @@
|
|
1 |
<?php
|
2 |
|
3 |
-
class WCML_JCK_WSSV {
|
4 |
|
5 |
private $transient_name = 'jck_wssv_term_counts';
|
6 |
|
7 |
-
public function
|
8 |
-
|
9 |
add_filter( 'pre_transient_' . $this->transient_name, [ $this, 'get_language_specific_transient' ] );
|
10 |
add_filter( 'set_transient_' . $this->transient_name, [ $this, 'set_language_specific_transient' ], 10, 2 );
|
11 |
}
|
1 |
<?php
|
2 |
|
3 |
+
class WCML_JCK_WSSV implements \IWPML_Action {
|
4 |
|
5 |
private $transient_name = 'jck_wssv_term_counts';
|
6 |
|
7 |
+
public function add_hooks() {
|
|
|
8 |
add_filter( 'pre_transient_' . $this->transient_name, [ $this, 'get_language_specific_transient' ] );
|
9 |
add_filter( 'set_transient_' . $this->transient_name, [ $this, 'set_language_specific_transient' ], 10, 2 );
|
10 |
}
|
compatibility/WcSubscriptions/Factory.php
ADDED
@@ -0,0 +1,34 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace WCML\Compatibility\WcSubscriptions;
|
4 |
+
|
5 |
+
use WCML\Compatibility\ComponentFactory;
|
6 |
+
use WCML\StandAlone\IStandAloneAction;
|
7 |
+
use WCML_WC_Subscriptions;
|
8 |
+
use function WCML\functions\getWooCommerceWpml;
|
9 |
+
use function WCML\functions\isStandAlone;
|
10 |
+
|
11 |
+
/**
|
12 |
+
* @see https://www.woocommerce.com/products/woocommerce-subscriptions/
|
13 |
+
*/
|
14 |
+
class Factory extends ComponentFactory implements IStandAloneAction {
|
15 |
+
|
16 |
+
/**
|
17 |
+
* @inheritDoc
|
18 |
+
*/
|
19 |
+
public function create() {
|
20 |
+
$hooks = [
|
21 |
+
new SharedHooks(),
|
22 |
+
];
|
23 |
+
|
24 |
+
if ( wcml_is_multi_currency_on() ) {
|
25 |
+
$hooks[] = new MulticurrencyHooks( getWooCommerceWpml(), self::getWpdb() );
|
26 |
+
}
|
27 |
+
|
28 |
+
if ( ! isStandAlone() ) {
|
29 |
+
$hooks[] = new WCML_WC_Subscriptions( getWooCommerceWpml(), self::getWpdb() );
|
30 |
+
}
|
31 |
+
|
32 |
+
return $hooks;
|
33 |
+
}
|
34 |
+
}
|
compatibility/WcSubscriptions/MulticurrencyHooks.php
ADDED
@@ -0,0 +1,265 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace WCML\Compatibility\WcSubscriptions;
|
4 |
+
|
5 |
+
use WC_Product;
|
6 |
+
use WC_Product_Subscription_Variation;
|
7 |
+
use WC_Product_Variable_Subscription;
|
8 |
+
use WCML\Utilities\DB;
|
9 |
+
use WCML_Custom_Prices_UI;
|
10 |
+
use woocommerce_wpml;
|
11 |
+
use wpdb;
|
12 |
+
use function WPML\FP\tap as tap;
|
13 |
+
|
14 |
+
class MulticurrencyHooks implements \IWPML_Action {
|
15 |
+
|
16 |
+
/** @var woocommerce_wpml $woocommerce_wpml */
|
17 |
+
private $woocommerce_wpml;
|
18 |
+
|
19 |
+
/** @var wpdb $wpdb */
|
20 |
+
private $wpdb;
|
21 |
+
|
22 |
+
/** @var bool $newSubscription */
|
23 |
+
private $newSubscription = false;
|
24 |
+
|
25 |
+
/** @var bool $proratingPrice */
|
26 |
+
private $proratingPrice = false;
|
27 |
+
|
28 |
+
public function __construct( woocommerce_wpml $woocommerce_wpml, wpdb $wpdb ) {
|
29 |
+
$this->woocommerce_wpml = $woocommerce_wpml;
|
30 |
+
$this->wpdb = $wpdb;
|
31 |
+
}
|
32 |
+
|
33 |
+
public function add_hooks() {
|
34 |
+
add_action( 'init', [ $this, 'init' ], 9 );
|
35 |
+
|
36 |
+
add_filter( 'wcml_custom_prices_fields', [ $this, 'set_prices_fields' ], 10, 2 );
|
37 |
+
add_filter( 'wcml_custom_prices_strings', [ $this, 'set_labels_for_prices_fields' ], 10, 2 );
|
38 |
+
add_filter( 'wcml_custom_prices_fields_labels', [ $this, 'set_labels_for_prices_fields' ], 10, 2 );
|
39 |
+
add_filter( 'wcml_update_custom_prices_values', [ $this, 'update_custom_prices_values' ], 10, 3 );
|
40 |
+
add_action( 'wcml_after_custom_prices_block', [ $this, 'new_subscription_prices_block' ] );
|
41 |
+
|
42 |
+
add_filter( 'woocommerce_subscriptions_product_price', [ $this, 'woocommerce_subscription_price_from' ], 10, 2 );
|
43 |
+
}
|
44 |
+
|
45 |
+
public function init() {
|
46 |
+
if ( ! is_admin() ) {
|
47 |
+
add_filter( 'woocommerce_subscriptions_product_sign_up_fee', [ $this, 'subscriptions_product_sign_up_fee_filter' ], 10, 2 );
|
48 |
+
$this->maybe_force_client_currency_for_subscription();
|
49 |
+
}
|
50 |
+
|
51 |
+
add_filter( 'wcs_switch_proration_new_price_per_day', tap( [ $this, 'set_prorating_price' ] ) );
|
52 |
+
}
|
53 |
+
|
54 |
+
/**
|
55 |
+
* Set a flag when we are prorating the price (upgrades/downgrades).
|
56 |
+
* We do this to skip currency conversion in the sign_up_fee because
|
57 |
+
* when switching subscription it has already been converted.
|
58 |
+
*/
|
59 |
+
public function set_prorating_price() {
|
60 |
+
$this->proratingPrice = true;
|
61 |
+
}
|
62 |
+
|
63 |
+
/**
|
64 |
+
* Filter Subscription Sign-up fee cost
|
65 |
+
*
|
66 |
+
* @param string $subscriptionSignUpFee
|
67 |
+
* @param WC_Product $product
|
68 |
+
*
|
69 |
+
* @return string
|
70 |
+
*/
|
71 |
+
public function subscriptions_product_sign_up_fee_filter( $subscriptionSignUpFee, $product ) {
|
72 |
+
if ( $product && ! $this->proratingPrice ) {
|
73 |
+
$currency = $this->woocommerce_wpml->multi_currency->get_client_currency();
|
74 |
+
|
75 |
+
if ( wcml_get_woocommerce_currency_option() !== $currency ) {
|
76 |
+
$productId = $product->get_id();
|
77 |
+
|
78 |
+
if ( $product instanceof WC_Product_Variable_Subscription ) {
|
79 |
+
$productId = $product->get_meta( '_min_price_variation_id', true );
|
80 |
+
}
|
81 |
+
|
82 |
+
$originalProductId = $this->woocommerce_wpml->products->get_original_product_id( $productId );
|
83 |
+
|
84 |
+
if ( get_post_meta( $originalProductId, '_wcml_custom_prices_status', true ) ) {
|
85 |
+
$subscriptionSignUpFee = get_post_meta( $originalProductId, '_subscription_sign_up_fee_' . $currency, true );
|
86 |
+
} else {
|
87 |
+
$subscriptionSignUpFee = apply_filters( 'wcml_raw_price_amount', $subscriptionSignUpFee );
|
88 |
+
}
|
89 |
+
}
|
90 |
+
}
|
91 |
+
|
92 |
+
return $subscriptionSignUpFee;
|
93 |
+
}
|
94 |
+
|
95 |
+
/**
|
96 |
+
* Force client currency for resubscribe subscription
|
97 |
+
*/
|
98 |
+
public function maybe_force_client_currency_for_subscription() {
|
99 |
+
$subscriptionId = false;
|
100 |
+
$getData = wpml_collect( $_GET );
|
101 |
+
|
102 |
+
if ( $getData->has( 'resubscribe' ) ) {
|
103 |
+
$subscriptionId = (int) $getData->get( 'resubscribe' );
|
104 |
+
} elseif ( $getData->has( 'subscription_renewal_early' ) ) {
|
105 |
+
$subscriptionId = (int) $getData->get( 'subscription_renewal_early' );
|
106 |
+
} elseif ( is_cart() || is_checkout() ) {
|
107 |
+
$resubscribeCartItem = wcs_cart_contains_resubscribe();
|
108 |
+
if ( $resubscribeCartItem ) {
|
109 |
+
$subscriptionId = $resubscribeCartItem['subscription_resubscribe']['subscription_id'];
|
110 |
+
} else {
|
111 |
+
$earlyRenewalCartItem = wcs_cart_contains_early_renewal();
|
112 |
+
if ( $earlyRenewalCartItem ) {
|
113 |
+
$subscriptionId = $earlyRenewalCartItem['subscription_renewal']['subscription_renewal_early'];
|
114 |
+
}
|
115 |
+
}
|
116 |
+
}
|
117 |
+
|
118 |
+
if ( $subscriptionId ) {
|
119 |
+
$subscriptionCurrency = get_post_meta( $subscriptionId, '_order_currency', true );
|
120 |
+
if ( $subscriptionCurrency && $this->woocommerce_wpml->multi_currency->get_client_currency() !== $subscriptionCurrency ) {
|
121 |
+
$this->woocommerce_wpml->multi_currency->set_client_currency( $subscriptionCurrency );
|
122 |
+
}
|
123 |
+
}
|
124 |
+
}
|
125 |
+
|
126 |
+
/**
|
127 |
+
* @param array $fields
|
128 |
+
* @param int|string $productId
|
129 |
+
*
|
130 |
+
* @return array
|
131 |
+
*/
|
132 |
+
public function set_prices_fields( $fields, $productId ) {
|
133 |
+
if ( $this->isSubscriptionsProduct( $productId ) || $this->newSubscription ) {
|
134 |
+
$fields[] = '_subscription_sign_up_fee';
|
135 |
+
}
|
136 |
+
|
137 |
+
return $fields;
|
138 |
+
}
|
139 |
+
|
140 |
+
/**
|
141 |
+
* @param array $labels
|
142 |
+
* @param int|string $productId
|
143 |
+
*
|
144 |
+
* @return array
|
145 |
+
*/
|
146 |
+
public function set_labels_for_prices_fields( $labels, $productId ) {
|
147 |
+
if ( $this->isSubscriptionsProduct( $productId ) || $this->newSubscription ) {
|
148 |
+
$labels['_regular_price'] = __( 'Subscription Price', 'woocommerce-multilingual' );
|
149 |
+
$labels['_subscription_sign_up_fee'] = __( 'Sign-up Fee', 'woocommerce-multilingual' );
|
150 |
+
}
|
151 |
+
|
152 |
+
return $labels;
|
153 |
+
}
|
154 |
+
|
155 |
+
/**
|
156 |
+
* @param array $prices
|
157 |
+
* @param string $code
|
158 |
+
* @param int|string|false $variationId
|
159 |
+
*
|
160 |
+
* @return array
|
161 |
+
*/
|
162 |
+
public function update_custom_prices_values( $prices, $code, $variationId = false ) {
|
163 |
+
if ( isset( $_POST['_custom_subscription_sign_up_fee'][ $code ] ) ) {
|
164 |
+
$prices['_subscription_sign_up_fee'] = wc_format_decimal( $_POST['_custom_subscription_sign_up_fee'][ $code ] );
|
165 |
+
}
|
166 |
+
|
167 |
+
if ( $variationId && isset( $_POST['_custom_variation_subscription_sign_up_fee'][ $code ][ $variationId ] ) ) {
|
168 |
+
$prices['_subscription_sign_up_fee'] = wc_format_decimal( $_POST['_custom_variation_subscription_sign_up_fee'][ $code ][ $variationId ] );
|
169 |
+
}
|
170 |
+
|
171 |
+
return $prices;
|
172 |
+
}
|
173 |
+
|
174 |
+
/**
|
175 |
+
* @param int|string $productId
|
176 |
+
*
|
177 |
+
* @return void
|
178 |
+
*/
|
179 |
+
public function new_subscription_prices_block( $productId ) {
|
180 |
+
if ( 'new' === $productId ) {
|
181 |
+
$this->newSubscription = true;
|
182 |
+
echo '<div class="wcml_prices_if_subscription" style="display: none">';
|
183 |
+
$custom_prices_ui = new WCML_Custom_Prices_UI( $this->woocommerce_wpml, 'new' );
|
184 |
+
$custom_prices_ui->show();
|
185 |
+
echo '</div>';
|
186 |
+
?>
|
187 |
+
<script>
|
188 |
+
jQuery(function($) {
|
189 |
+
jQuery('.wcml_prices_if_subscription .wcml_custom_prices_input').attr('name', '_wcml_custom_prices[new_subscription]').attr( 'id', '_wcml_custom_prices[new_subscription]');
|
190 |
+
jQuery('.wcml_prices_if_subscription .wcml_custom_prices_options_block>label').attr('for', '_wcml_custom_prices[new_subscription]');
|
191 |
+
jQuery('.wcml_prices_if_subscription .wcml_schedule_input').each( function(){
|
192 |
+
jQuery(this).attr('name', jQuery(this).attr('name')+'_subscription');
|
193 |
+
});
|
194 |
+
|
195 |
+
jQuery('.options_group>.wcml_custom_prices_block .wcml_custom_prices_input:first-child').click();
|
196 |
+
jQuery('.options_group>.wcml_custom_prices_block .wcml_schedule_options .wcml_schedule_input:first-child').click();
|
197 |
+
|
198 |
+
jQuery(document).on('change', 'select#product-type', function () {
|
199 |
+
if (jQuery(this).val() == 'subscription') {
|
200 |
+
jQuery('.wcml_prices_if_subscription').show();
|
201 |
+
jQuery('.options_group>.wcml_custom_prices_block').hide();
|
202 |
+
} else if (jQuery(this).val() != 'variable-subscription') {
|
203 |
+
jQuery('.wcml_prices_if_subscription').hide();
|
204 |
+
jQuery('.options_group>.wcml_custom_prices_block').show();
|
205 |
+
}
|
206 |
+
});
|
207 |
+
|
208 |
+
jQuery(document).on('click', '#publish', function () {
|
209 |
+
if ( jQuery('.wcml_prices_if_subscription').is( ':visible' ) ) {
|
210 |
+
jQuery('.options_group>.wcml_custom_prices_block').remove();
|
211 |
+
jQuery('.wcml_prices_if_subscription .wcml_custom_prices_input').attr('name', '_wcml_custom_prices[new]');
|
212 |
+
jQuery('.wcml_prices_if_subscription .wcml_schedule_input').each( function(){
|
213 |
+
jQuery(this).attr('name', jQuery(this).attr('name').replace('_subscription','') );
|
214 |
+
});
|
215 |
+
}else{
|
216 |
+
jQuery('.wcml_prices_if_subscription').remove();
|
217 |
+
}
|
218 |
+
});
|
219 |
+
});
|
220 |
+
</script>
|
221 |
+
<?php
|
222 |
+
}
|
223 |
+
}
|
224 |
+
|
225 |
+
/**
|
226 |
+
* @param int|string $productId
|
227 |
+
*
|
228 |
+
* @return bool
|
229 |
+
*/
|
230 |
+
private function isSubscriptionsProduct( $productId ) {
|
231 |
+
$variationTermTaxonomyIds = $this->wpdb->get_col( "SELECT tt.term_taxonomy_id FROM {$this->wpdb->terms} AS t LEFT JOIN {$this->wpdb->term_taxonomy} AS tt ON t.term_id = tt.term_id WHERE t.slug IN ( 'subscription', 'variable-subscription' ) AND tt.taxonomy = 'product_type'" );
|
232 |
+
|
233 |
+
if ( get_post_type( $productId ) == 'product_variation' ) {
|
234 |
+
$productId = wp_get_post_parent_id( $productId );
|
235 |
+
}
|
236 |
+
|
237 |
+
return (bool) $this->wpdb->get_var(
|
238 |
+
$this->wpdb->prepare(
|
239 |
+
"SELECT count(object_id) FROM {$this->wpdb->term_relationships}
|
240 |
+
WHERE object_id = %d AND term_taxonomy_id IN (" . DB::prepareIn( $variationTermTaxonomyIds, '%d' ) . ')',
|
241 |
+
$productId
|
242 |
+
)
|
243 |
+
);
|
244 |
+
}
|
245 |
+
|
246 |
+
/**
|
247 |
+
* @param string $price
|
248 |
+
* @param WC_Product|WC_Product_Subscription_Variation $product
|
249 |
+
*
|
250 |
+
* @return string
|
251 |
+
*/
|
252 |
+
public function woocommerce_subscription_price_from( $price, $product ) {
|
253 |
+
if ( $product instanceof WC_Product_Subscription_Variation ) {
|
254 |
+
$customPricesOn = get_post_meta( $product->get_id(), '_wcml_custom_prices_status', true );
|
255 |
+
|
256 |
+
if ( $customPricesOn ) {
|
257 |
+
$price = get_post_meta( $product->get_id(), '_price_' . $this->woocommerce_wpml->multi_currency->get_client_currency(), true );
|
258 |
+
} else {
|
259 |
+
$price = apply_filters( 'wcml_raw_price_amount', $price );
|
260 |
+
}
|
261 |
+
}
|
262 |
+
|
263 |
+
return $price;
|
264 |
+
}
|
265 |
+
}
|
compatibility/WcSubscriptions/SharedHooks.php
ADDED
@@ -0,0 +1,41 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace WCML\Compatibility\WcSubscriptions;
|
4 |
+
|
5 |
+
use WC_Cart;
|
6 |
+
|
7 |
+
class SharedHooks implements \IWPML_Action {
|
8 |
+
|
9 |
+
/** @var WC_Cart[]|null $recurring_carts */
|
10 |
+
private $recurring_carts;
|
11 |
+
|
12 |
+
public function add_hooks() {
|
13 |
+
add_action( 'init', [ $this, 'init' ], 9 );
|
14 |
+
}
|
15 |
+
|
16 |
+
public function init() {
|
17 |
+
if ( ! is_admin() ) {
|
18 |
+
add_action( 'woocommerce_before_calculate_totals', [ $this, 'maybe_backup_recurring_carts' ], 1 );
|
19 |
+
add_action( 'woocommerce_after_calculate_totals', [ $this, 'maybe_restore_recurring_carts' ], 200 );
|
20 |
+
}
|
21 |
+
}
|
22 |
+
|
23 |
+
/**
|
24 |
+
* @param WC_Cart $cart
|
25 |
+
*/
|
26 |
+
public function maybe_backup_recurring_carts( $cart ) {
|
27 |
+
if ( ! empty( $cart->recurring_carts ) ) {
|
28 |
+
$this->recurring_carts = $cart->recurring_carts;
|
29 |
+
}
|
30 |
+
}
|
31 |
+
|
32 |
+
/**
|
33 |
+
* @param WC_Cart $cart
|
34 |
+
*/
|
35 |
+
public function maybe_restore_recurring_carts( $cart ) {
|
36 |
+
if ( ! empty( $this->recurring_carts ) ) {
|
37 |
+
$cart->recurring_carts = $this->recurring_carts;
|
38 |
+
$this->recurring_carts = null;
|
39 |
+
}
|
40 |
+
}
|
41 |
+
}
|
compatibility/WcSubscriptions/class-wcml-wc-subscriptions.php
ADDED
@@ -0,0 +1,198 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
class WCML_WC_Subscriptions implements \IWPML_Action {
|
4 |
+
|
5 |
+
/** @var woocommerce_wpml */
|
6 |
+
private $woocommerce_wpml;
|
7 |
+
|
8 |
+
/** @var wpdb */
|
9 |
+
private $wpdb;
|
10 |
+
|
11 |
+
public function __construct( woocommerce_wpml $woocommerce_wpml, wpdb $wpdb ) {
|
12 |
+
$this->woocommerce_wpml = $woocommerce_wpml;
|
13 |
+
$this->wpdb = $wpdb;
|
14 |
+
}
|
15 |
+
|
16 |
+
public function add_hooks() {
|
17 |
+
add_action( 'init', [ $this, 'init' ], 9 );
|
18 |
+
add_filter( 'wcml_variation_term_taxonomy_ids', [ $this, 'wcml_variation_term_taxonomy_ids' ] );
|
19 |
+
add_filter( 'woocommerce_subscription_lengths', [ $this, 'woocommerce_subscription_lengths' ], 10, 2 );
|
20 |
+
|
21 |
+
add_filter( 'wcml_register_endpoints_query_vars', [ $this, 'register_endpoint' ], 10, 3 );
|
22 |
+
add_filter( 'wcml_endpoint_permalink_filter', [ $this, 'endpoint_permalink_filter' ], 10, 2 );
|
23 |
+
|
24 |
+
add_action( 'woocommerce_subscriptions_product_options_pricing', [ $this, 'show_pointer_info' ] );
|
25 |
+
add_action( 'woocommerce_variable_subscription_pricing', [ $this, 'show_pointer_info' ] );
|
26 |
+
|
27 |
+
add_filter( 'wcml_xliff_allowed_variations_types', [ $this, 'set_allowed_variations_types_in_xliff' ] );
|
28 |
+
|
29 |
+
// Add language links to email settings
|
30 |
+
add_filter( 'wcml_emails_options_to_translate', [ $this, 'translate_email_options' ] );
|
31 |
+
add_filter( 'wcml_emails_section_name_prefix', [ $this, 'email_option_section_prefix' ], 10, 2 );
|
32 |
+
}
|
33 |
+
|
34 |
+
public function init() {
|
35 |
+
if ( ! is_admin() ) {
|
36 |
+
add_filter( 'wcs_get_subscription', [ $this, 'filter_subscription_items' ] );
|
37 |
+
}
|
38 |
+
|
39 |
+
// Translate emails
|
40 |
+
add_filter( 'woocommerce_generated_manual_renewal_order_renewal_notification', [ $this, 'translate_renewal_notification' ], 9 );
|
41 |
+
add_filter( 'woocommerce_order_status_failed_renewal_notification', [ $this, 'translate_renewal_notification' ], 9 );
|
42 |
+
}
|
43 |
+
|
44 |
+
public function wcml_variation_term_taxonomy_ids( $get_variation_term_taxonomy_ids ) {
|
45 |
+
|
46 |
+
$get_variation_term_taxonomy_id = $this->wpdb->get_var( "SELECT tt.term_taxonomy_id FROM {$this->wpdb->terms} AS t LEFT JOIN {$this->wpdb->term_taxonomy} AS tt ON t.term_id = tt.term_id WHERE t.slug = 'variable-subscription'" );
|
47 |
+
|
48 |
+
if ( ! empty( $get_variation_term_taxonomy_id ) ) {
|
49 |
+
$get_variation_term_taxonomy_ids[] = $get_variation_term_taxonomy_id;
|
50 |
+
}
|
51 |
+
|
52 |
+
return $get_variation_term_taxonomy_ids;
|
53 |
+
}
|
54 |
+
|
55 |
+
public function woocommerce_subscription_lengths( $subscription_ranges, $subscription_period ) {
|
56 |
+
|
57 |
+
if ( is_array( $subscription_ranges ) ) {
|
58 |
+
foreach ( $subscription_ranges as $period => $ranges ) {
|
59 |
+
if ( is_array( $ranges ) ) {
|
60 |
+
foreach ( $ranges as $range ) {
|
61 |
+
if ( $range == '9 months' ) {
|
62 |
+
$breakpoint = true;
|
63 |
+
}
|
64 |
+
$new_subscription_ranges[ $period ][] = apply_filters( 'wpml_translate_single_string', $range, 'wc_subscription_ranges', $range );
|
65 |
+
}
|
66 |
+
}
|
67 |
+
}
|
68 |
+
}
|
69 |
+
|
70 |
+
return isset( $new_subscription_ranges ) ? $new_subscription_ranges : $subscription_ranges;
|
71 |
+
}
|
72 |
+
|
73 |
+
public function register_endpoint( $query_vars, $wc_vars, $obj ) {
|
74 |
+
|
75 |
+
$query_vars['view-subscription'] = $obj->get_endpoint_translation( 'view-subscription', isset( $wc_vars['view-subscription'] ) ? $wc_vars['view-subscription'] : 'view-subscription' );
|
76 |
+
$query_vars['subscriptions'] = $obj->get_endpoint_translation( 'subscriptions', isset( $wc_vars['subscriptions'] ) ? $wc_vars['subscriptions'] : 'subscriptions' );
|
77 |
+
return $query_vars;
|
78 |
+
}
|
79 |
+
|
80 |
+
public function endpoint_permalink_filter( $endpoint, $key ) {
|
81 |
+
|
82 |
+
if ( $key == 'view-subscription' ) {
|
83 |
+
return 'view-subscription';
|
84 |
+
}
|
85 |
+
|
86 |
+
return $endpoint;
|
87 |
+
}
|
88 |
+
|
89 |
+
public function show_pointer_info() {
|
90 |
+
|
91 |
+
$pointer_ui = new WCML_Pointer_UI(
|
92 |
+
/* translators: %1$s and %2$s are opening and closing HTML link tags */
|
93 |
+
sprintf( __( 'You can translate strings related to subscription products on the %1$sWPML String Translation page%2$s. Use the search on the top of that page to find the strings.', 'woocommerce-multilingual' ), '<a href="' . admin_url( 'admin.php?page=' . WPML_ST_FOLDER . '/menu/string-translation.php&context=woocommerce_subscriptions' ) . '">', '</a>' ),
|
94 |
+
WCML_Tracking_Link::getWcmlSubscriptionsDoc(),
|
95 |
+
'general_product_data .subscription_pricing',
|
96 |
+
'prepend'
|
97 |
+
);
|
98 |
+
|
99 |
+
$pointer_ui->show();
|
100 |
+
}
|
101 |
+
|
102 |
+
/**
|
103 |
+
* @param array $allowed_types
|
104 |
+
*
|
105 |
+
* @return array
|
106 |
+
*/
|
107 |
+
public function set_allowed_variations_types_in_xliff( $allowed_types ) {
|
108 |
+
|
109 |
+
$allowed_types[] = 'variable-subscription';
|
110 |
+
$allowed_types[] = 'subscription_variation';
|
111 |
+
|
112 |
+
return $allowed_types;
|
113 |
+
}
|
114 |
+
|
115 |
+
/**
|
116 |
+
* Translate strings of renewal notifications
|
117 |
+
*
|
118 |
+
* @param integer $order_id Order ID
|
119 |
+
*/
|
120 |
+
public function translate_renewal_notification( $order_id ) {
|
121 |
+
|
122 |
+
if ( isset( WC()->mailer()->emails['WCS_Email_Customer_Renewal_Invoice'] ) ) {
|
123 |
+
$this->woocommerce_wpml->emails->refresh_email_lang( $order_id );
|
124 |
+
|
125 |
+
$WCS_Email_Customer_Renewal_Invoice = WC()->mailer()->emails['WCS_Email_Customer_Renewal_Invoice'];
|
126 |
+
$WCS_Email_Customer_Renewal_Invoice->heading = __( $WCS_Email_Customer_Renewal_Invoice->heading, 'woocommerce-subscriptions' );
|
127 |
+
$WCS_Email_Customer_Renewal_Invoice->subject = __( $WCS_Email_Customer_Renewal_Invoice->subject, 'woocommerce-subscriptions' );
|
128 |
+
|
129 |
+
add_filter( 'woocommerce_email_get_option', [ $this, 'translate_heading_subject' ], 10, 4 );
|
130 |
+
}
|
131 |
+
}
|
132 |
+
|
133 |
+
/**
|
134 |
+
* Translate custom heading and subject for renewal notification
|
135 |
+
*
|
136 |
+
* @param string $return_value original string
|
137 |
+
* @param WCS_Email_Customer_Renewal_Invoice $obj Object of email class
|
138 |
+
* @param string $value Original value from setting
|
139 |
+
* @param string $key Name of the key
|
140 |
+
* @return string Translated value or original value incase of not translated
|
141 |
+
*/
|
142 |
+
public function translate_heading_subject( $return_value, $obj, $value, $key ) {
|
143 |
+
|
144 |
+
if ( $obj instanceof WCS_Email_Customer_Renewal_Invoice ) {
|
145 |
+
if ( $key == 'subject' || $key == 'heading' ) {
|
146 |
+
$translated_admin_string = $this->woocommerce_wpml->emails->getStringTranslation( 'admin_texts_woocommerce_customer_renewal_invoice_settings', '[woocommerce_customer_renewal_invoice_settings]' . $key );
|
147 |
+
return empty( $translated_admin_string ) ? $return_value : $translated_admin_string;
|
148 |
+
}
|
149 |
+
}
|
150 |
+
|
151 |
+
return $return_value;
|
152 |
+
}
|
153 |
+
|
154 |
+
/**
|
155 |
+
* Add customer renewal invoice option to translate
|
156 |
+
*
|
157 |
+
* @param array $emails_options list of option to translate
|
158 |
+
* @return array $emails_options
|
159 |
+
*/
|
160 |
+
public function translate_email_options( $emails_options ) {
|
161 |
+
|
162 |
+
if ( is_array( $emails_options ) ) {
|
163 |
+
$emails_options[] = 'woocommerce_customer_renewal_invoice_settings';
|
164 |
+
}
|
165 |
+
|
166 |
+
return $emails_options;
|
167 |
+
}
|
168 |
+
|
169 |
+
/**
|
170 |
+
* Change section name prefix to add language links
|
171 |
+
*
|
172 |
+
* @param string $section_prefix section prefix
|
173 |
+
* @param string $emails_option current option name
|
174 |
+
* @return string $section_prefix
|
175 |
+
*/
|
176 |
+
public function email_option_section_prefix( $section_prefix, $emails_option ) {
|
177 |
+
|
178 |
+
if ( $emails_option === 'woocommerce_customer_renewal_invoice_settings' ) {
|
179 |
+
return 'wcs_email_';
|
180 |
+
}
|
181 |
+
|
182 |
+
return $section_prefix;
|
183 |
+
}
|
184 |
+
|
185 |
+
/**
|
186 |
+
* @param mixed $subscription
|
187 |
+
*
|
188 |
+
* @return mixed
|
189 |
+
*/
|
190 |
+
public function filter_subscription_items( $subscription ) {
|
191 |
+
|
192 |
+
if ( $subscription instanceof WC_Subscription ) {
|
193 |
+
$this->woocommerce_wpml->orders->adjust_order_item_in_language( $subscription->get_items() );
|
194 |
+
}
|
195 |
+
|
196 |
+
return $subscription;
|
197 |
+
}
|
198 |
+
}
|
compatibility/WcSwatches/Factory.php
ADDED
@@ -0,0 +1,17 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace WCML\Compatibility\WcSwatches;
|
4 |
+
|
5 |
+
use WCML\Compatibility\ComponentFactory;
|
6 |
+
use WCML_Variation_Swatches_And_Photos;
|
7 |
+
use function WCML\functions\getWooCommerceWpml;
|
8 |
+
|
9 |
+
class Factory extends ComponentFactory {
|
10 |
+
|
11 |
+
/**
|
12 |
+
* @inheritDoc
|
13 |
+
*/
|
14 |
+
public function create() {
|
15 |
+
return new WCML_Variation_Swatches_And_Photos( getWooCommerceWpml() );
|
16 |
+
}
|
17 |
+
}
|
compatibility/{class-wcml-variation-swatches-and-photos.php → WcSwatches/class-wcml-variation-swatches-and-photos.php}
RENAMED
@@ -3,7 +3,7 @@
|
|
3 |
/**
|
4 |
* Compatibility class for Variation Swatches and Photos plugin
|
5 |
*/
|
6 |
-
class WCML_Variation_Swatches_And_Photos {
|
7 |
|
8 |
/** @var woocommerce_wpml */
|
9 |
private $woocommerce_wpml;
|
3 |
/**
|
4 |
* Compatibility class for Variation Swatches and Photos plugin
|
5 |
*/
|
6 |
+
class WCML_Variation_Swatches_And_Photos implements \IWPML_Action {
|
7 |
|
8 |
/** @var woocommerce_wpml */
|
9 |
private $woocommerce_wpml;
|
compatibility/WcTabManager/Factory.php
ADDED
@@ -0,0 +1,18 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace WCML\Compatibility\WcTabManager;
|
4 |
+
|
5 |
+
use WCML\Compatibility\ComponentFactory;
|
6 |
+
use WCML_Tab_Manager;
|
7 |
+
use function WCML\functions\getSitePress;
|
8 |
+
use function WCML\functions\getWooCommerceWpml;
|
9 |
+
|
10 |
+
class Factory extends ComponentFactory {
|
11 |
+
|
12 |
+
/**
|
13 |
+
* @inheritDoc
|
14 |
+
*/
|
15 |
+
public function create() {
|
16 |
+
return new WCML_Tab_Manager( getSitePress(), self::getWooCommerce(), getWooCommerceWpml(), self::getWpdb(), self::getElementTranslationPackage() );
|
17 |
+
}
|
18 |
+
}
|
compatibility/{class-wcml-tab-manager.php → WcTabManager/class-wcml-tab-manager.php}
RENAMED
@@ -3,7 +3,7 @@
|
|
3 |
/**
|
4 |
* Class WCML_Tab_Manager
|
5 |
*/
|
6 |
-
class WCML_Tab_Manager {
|
7 |
/**
|
8 |
* @var WPML_Element_Translation_Package
|
9 |
*/
|
@@ -714,6 +714,7 @@ class WCML_Tab_Manager {
|
|
714 |
public function show_pointer_info() {
|
715 |
|
716 |
$pointer_ui = new WCML_Pointer_UI(
|
|
|
717 |
sprintf( __( 'You can translate your custom product tabs on the %1$sWooCommerce product translation page%2$s', 'woocommerce-multilingual' ), '<a href="' . admin_url( 'admin.php?page=wpml-wcml' ) . '">', '</a>' ),
|
718 |
WCML_Tracking_Link::getWcmlTabManagerDoc(),
|
719 |
'woocommerce_product_tabs>p'
|
3 |
/**
|
4 |
* Class WCML_Tab_Manager
|
5 |
*/
|
6 |
+
class WCML_Tab_Manager implements \IWPML_Action {
|
7 |
/**
|
8 |
* @var WPML_Element_Translation_Package
|
9 |
*/
|
714 |
public function show_pointer_info() {
|
715 |
|
716 |
$pointer_ui = new WCML_Pointer_UI(
|
717 |
+
/* translators: %1$s and %2$s are opening and closing HTML link tags */
|
718 |
sprintf( __( 'You can translate your custom product tabs on the %1$sWooCommerce product translation page%2$s', 'woocommerce-multilingual' ), '<a href="' . admin_url( 'admin.php?page=wpml-wcml' ) . '">', '</a>' ),
|
719 |
WCML_Tracking_Link::getWcmlTabManagerDoc(),
|
720 |
'woocommerce_product_tabs>p'
|
compatibility/WooVariationsTable/Factory.php
ADDED
@@ -0,0 +1,16 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace WCML\Compatibility\WooVariationsTable;
|
4 |
+
|
5 |
+
use WCML\Compatibility\ComponentFactory;
|
6 |
+
use function WCML\functions\getSitePress;
|
7 |
+
|
8 |
+
class Factory extends ComponentFactory {
|
9 |
+
|
10 |
+
/**
|
11 |
+
* @inheritDoc
|
12 |
+
*/
|
13 |
+
public function create() {
|
14 |
+
return new \WCML_Woo_Var_Table( getSitePress()->get_current_language() );
|
15 |
+
}
|
16 |
+
}
|
compatibility/{class-wcml-woo-var-table.php → WooVariationsTable/class-wcml-woo-var-table.php}
RENAMED
@@ -3,7 +3,7 @@
|
|
3 |
* Woo Variations table Compatibility class
|
4 |
*/
|
5 |
|
6 |
-
class WCML_Woo_Var_Table {
|
7 |
|
8 |
/**
|
9 |
* @var string
|
3 |
* Woo Variations table Compatibility class
|
4 |
*/
|
5 |
|
6 |
+
class WCML_Woo_Var_Table implements \IWPML_Action {
|
7 |
|
8 |
/**
|
9 |
* @var string
|
compatibility/WoobeBulkEditor/Factory.php
ADDED
@@ -0,0 +1,17 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace WCML\Compatibility\WoobeBulkEditor;
|
4 |
+
|
5 |
+
use WCML\Compatibility\ComponentFactory;
|
6 |
+
use WCML_Woobe;
|
7 |
+
use function WCML\functions\getSitePress;
|
8 |
+
|
9 |
+
class Factory extends ComponentFactory {
|
10 |
+
|
11 |
+
/**
|
12 |
+
* @inheritDoc
|
13 |
+
*/
|
14 |
+
public function create() {
|
15 |
+
return new WCML_Woobe( getSitePress(), self::getPostTranslations() );
|
16 |
+
}
|
17 |
+
}
|
compatibility/{class-wcml-woobe.php → WoobeBulkEditor/class-wcml-woobe.php}
RENAMED
@@ -1,6 +1,6 @@
|
|
1 |
<?php
|
2 |
|
3 |
-
class WCML_Woobe {
|
4 |
|
5 |
/**
|
6 |
* @var SitePress
|
1 |
<?php
|
2 |
|
3 |
+
class WCML_Woobe implements \IWPML_Action {
|
4 |
|
5 |
/**
|
6 |
* @var SitePress
|
compatibility/WoofWcProductFilter/Factory.php
ADDED
@@ -0,0 +1,26 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace WCML\Compatibility\WoofWcProductFilter;
|
4 |
+
|
5 |
+
use WCML\Compatibility\ComponentFactory;
|
6 |
+
use WCML\StandAlone\IStandAloneAction;
|
7 |
+
|
8 |
+
/**
|
9 |
+
* @see https://wordpress.org/plugins/woocommerce-products-filter/
|
10 |
+
*/
|
11 |
+
class Factory extends ComponentFactory implements IStandAloneAction {
|
12 |
+
|
13 |
+
/**
|
14 |
+
* @inheritDoc
|
15 |
+
*/
|
16 |
+
public function create() {
|
17 |
+
$hooks = [];
|
18 |
+
|
19 |
+
if ( wcml_is_multi_currency_on() ) {
|
20 |
+
$hooks[] = new MulticurrencyHooks();
|
21 |
+
}
|
22 |
+
|
23 |
+
return $hooks;
|
24 |
+
}
|
25 |
+
|
26 |
+
}
|
compatibility/{class-wcml-woof-woocommerce-product-filter.php → WoofWcProductFilter/MulticurrencyHooks.php}
RENAMED
@@ -1,8 +1,8 @@
|
|
1 |
<?php
|
2 |
|
3 |
-
namespace WCML\Compatibility\
|
4 |
|
5 |
-
class
|
6 |
/**
|
7 |
* @var string
|
8 |
*/
|
@@ -19,12 +19,10 @@ class WooCommerceProductFilter {
|
|
19 |
/**
|
20 |
* Registers hooks.
|
21 |
*/
|
22 |
-
public function
|
23 |
-
|
24 |
-
|
25 |
-
|
26 |
-
add_filter( 'wcml_exchange_rates', [ $this, 'storeExchangeRates' ], 10, 1 );
|
27 |
-
}
|
28 |
}
|
29 |
|
30 |
/**
|
@@ -74,15 +72,14 @@ class WooCommerceProductFilter {
|
|
74 |
* @return bool
|
75 |
*/
|
76 |
private function priceIsInSwitchedCurrency() {
|
77 |
-
$
|
78 |
-
return $multicurrencyOn && $this->currentCurrency !== $this->defaultCurrency;
|
79 |
}
|
80 |
|
81 |
/**
|
82 |
* Checks if meta data has a correct format.
|
83 |
*
|
84 |
-
* @param $index
|
85 |
-
* @param $meta
|
86 |
*
|
87 |
* @return bool
|
88 |
*/
|
1 |
<?php
|
2 |
|
3 |
+
namespace WCML\Compatibility\WoofWcProductFilter;
|
4 |
|
5 |
+
class MulticurrencyHooks implements \IWPML_Action {
|
6 |
/**
|
7 |
* @var string
|
8 |
*/
|
19 |
/**
|
20 |
* Registers hooks.
|
21 |
*/
|
22 |
+
public function add_hooks() {
|
23 |
+
add_action( 'init', [ $this, 'setupCurrencies' ] );
|
24 |
+
add_filter( 'woof_get_meta_query', [ $this, 'priceInDefaultCurrency' ], 10, 1 );
|
25 |
+
add_filter( 'wcml_exchange_rates', [ $this, 'storeExchangeRates' ], 10, 1 );
|
|
|
|
|
26 |
}
|
27 |
|
28 |
/**
|
72 |
* @return bool
|
73 |
*/
|
74 |
private function priceIsInSwitchedCurrency() {
|
75 |
+
return $this->currentCurrency !== $this->defaultCurrency;
|
|
|
76 |
}
|
77 |
|
78 |
/**
|
79 |
* Checks if meta data has a correct format.
|
80 |
*
|
81 |
+
* @param int $index
|
82 |
+
* @param array $meta
|
83 |
*
|
84 |
* @return bool
|
85 |
*/
|
compatibility/WpBakery/Factory.php
ADDED
@@ -0,0 +1,16 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace WCML\Compatibility\WpBakery;
|
4 |
+
|
5 |
+
use WCML\Compatibility\ComponentFactory;
|
6 |
+
use WCML_Wpb_Vc;
|
7 |
+
|
8 |
+
class Factory extends ComponentFactory {
|
9 |
+
|
10 |
+
/**
|
11 |
+
* @inheritDoc
|
12 |
+
*/
|
13 |
+
public function create() {
|
14 |
+
return new WCML_Wpb_Vc();
|
15 |
+
}
|
16 |
+
}
|
compatibility/{class-wcml-wpb-vc.php → WpBakery/class-wcml-wpb-vc.php}
RENAMED
@@ -3,7 +3,7 @@
|
|
3 |
* WPBakery Page Builder ( formerly Visual Composer ) Compatibility class
|
4 |
*/
|
5 |
|
6 |
-
class WCML_Wpb_Vc {
|
7 |
|
8 |
public function add_hooks() {
|
9 |
|
3 |
* WPBakery Page Builder ( formerly Visual Composer ) Compatibility class
|
4 |
*/
|
5 |
|
6 |
+
class WCML_Wpb_Vc implements \IWPML_Action {
|
7 |
|
8 |
public function add_hooks() {
|
9 |
|
compatibility/WpFastestCache/Factory.php
ADDED
@@ -0,0 +1,25 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace WCML\Compatibility\WpFastestCache;
|
4 |
+
|
5 |
+
use WCML\Compatibility\ComponentFactory;
|
6 |
+
use WCML\StandAlone\IStandAloneAction;
|
7 |
+
|
8 |
+
/**
|
9 |
+
* @see https://wordpress.org/plugins/wp-fastest-cache/
|
10 |
+
*/
|
11 |
+
class Factory extends ComponentFactory implements IStandAloneAction {
|
12 |
+
|
13 |
+
/**
|
14 |
+
* @inheritDoc
|
15 |
+
*/
|
16 |
+
public function create() {
|
17 |
+
$hooks = [];
|
18 |
+
|
19 |
+
if ( wcml_is_multi_currency_on() ) {
|
20 |
+
$hooks[] = new MulticurrencyHooks();
|
21 |
+
}
|
22 |
+
|
23 |
+
return $hooks;
|
24 |
+
}
|
25 |
+
}
|
compatibility/{class-wcml-wpfastest-cache.php → WpFastestCache/MulticurrencyHooks.php}
RENAMED
@@ -1,6 +1,8 @@
|
|
1 |
<?php
|
2 |
|
3 |
-
|
|
|
|
|
4 |
|
5 |
public function add_hooks() {
|
6 |
add_filter(
|
1 |
<?php
|
2 |
|
3 |
+
namespace WCML\Compatibility\WpFastestCache;
|
4 |
+
|
5 |
+
class MulticurrencyHooks implements \IWPML_Action {
|
6 |
|
7 |
public function add_hooks() {
|
8 |
add_filter(
|
compatibility/WpSeo/Factory.php
ADDED
@@ -0,0 +1,16 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace WCML\Compatibility\WpSeo;
|
4 |
+
|
5 |
+
use WCML\Compatibility\ComponentFactory;
|
6 |
+
use WCML_WPSEO;
|
7 |
+
|
8 |
+
class Factory extends ComponentFactory {
|
9 |
+
|
10 |
+
/**
|
11 |
+
* @inheritDoc
|
12 |
+
*/
|
13 |
+
public function create() {
|
14 |
+
return new WCML_WPSEO();
|
15 |
+
}
|
16 |
+
}
|
compatibility/{class-wcml-wpseo.php → WpSeo/class-wcml-wpseo.php}
RENAMED
@@ -1,10 +1,10 @@
|
|
1 |
<?php
|
2 |
|
3 |
-
class WCML_WPSEO {
|
4 |
|
5 |
private $updated_post_id;
|
6 |
|
7 |
-
public function
|
8 |
|
9 |
add_filter( 'wcml_product_content_label', [ $this, 'wpseo_custom_field_label' ], 10, 2 );
|
10 |
|
1 |
<?php
|
2 |
|
3 |
+
class WCML_WPSEO implements \IWPML_Action {
|
4 |
|
5 |
private $updated_post_id;
|
6 |
|
7 |
+
public function add_hooks() {
|
8 |
|
9 |
add_filter( 'wcml_product_content_label', [ $this, 'wpseo_custom_field_label' ], 10, 2 );
|
10 |
|
compatibility/YikesCustomProductTabs/Factory.php
ADDED
@@ -0,0 +1,17 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace WCML\Compatibility\YikesCustomProductTabs;
|
4 |
+
|
5 |
+
use WCML\Compatibility\ComponentFactory;
|
6 |
+
use function WCML\functions\getSitePress;
|
7 |
+
use function WCML\functions\getWooCommerceWpml;
|
8 |
+
|
9 |
+
class Factory extends ComponentFactory {
|
10 |
+
|
11 |
+
/**
|
12 |
+
* @inheritDoc
|
13 |
+
*/
|
14 |
+
public function create() {
|
15 |
+
return new \WCML_YIKES_Custom_Product_Tabs( getWooCommerceWpml(), getSitePress(), self::getElementTranslationPackage() );
|
16 |
+
}
|
17 |
+
}
|
compatibility/{class-wcml-yikes-custom-product-tabs.php → YikesCustomProductTabs/class-wcml-yikes-custom-product-tabs.php}
RENAMED
@@ -3,7 +3,7 @@
|
|
3 |
/**
|
4 |
* Class WCML_YIKES_Custom_Product_Tabs
|
5 |
*/
|
6 |
-
class WCML_YIKES_Custom_Product_Tabs {
|
7 |
|
8 |
const CUSTOM_TABS_FIELD = 'yikes_woo_products_tabs';
|
9 |
|
@@ -237,6 +237,7 @@ class WCML_YIKES_Custom_Product_Tabs {
|
|
237 |
|
238 |
public function show_pointer_info() {
|
239 |
|
|
|
240 |
$a = __( 'You can translate your custom product tabs on the %s', 'woocommerce-multilingual' );
|
241 |
$b = __( 'WooCommerce product translation page', 'woocommerce-multilingual' );
|
242 |
$link = '<a href="' . admin_url( 'admin.php?page=wpml-wcml' ) . '">' . $b . '</a>';
|
3 |
/**
|
4 |
* Class WCML_YIKES_Custom_Product_Tabs
|
5 |
*/
|
6 |
+
class WCML_YIKES_Custom_Product_Tabs implements \IWPML_Action {
|
7 |
|
8 |
const CUSTOM_TABS_FIELD = 'yikes_woo_products_tabs';
|
9 |
|
237 |
|
238 |
public function show_pointer_info() {
|
239 |
|
240 |
+
/* translators: %s is an HTML link pointing to WooCommerce product translation page */
|
241 |
$a = __( 'You can translate your custom product tabs on the %s', 'woocommerce-multilingual' );
|
242 |
$b = __( 'WooCommerce product translation page', 'woocommerce-multilingual' );
|
243 |
$link = '<a href="' . admin_url( 'admin.php?page=wpml-wcml' ) . '">' . $b . '</a>';
|
compatibility/YithWcQuickView/Factory.php
ADDED
@@ -0,0 +1,25 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace WCML\Compatibility\YithWcQuickView;
|
4 |
+
|
5 |
+
use WCML\Compatibility\ComponentFactory;
|
6 |
+
use WCML\StandAlone\IStandAloneAction;
|
7 |
+
|
8 |
+
/**
|
9 |
+
* @see https://wordpress.org/plugins/yith-woocommerce-quick-view/
|
10 |
+
*/
|
11 |
+
class Factory extends ComponentFactory implements IStandAloneAction {
|
12 |
+
|
13 |
+
/**
|
14 |
+
* @inheritDoc
|
15 |
+
*/
|
16 |
+
public function create() {
|
17 |
+
$hooks = [];
|
18 |
+
|
19 |
+
if ( wcml_is_multi_currency_on() ) {
|
20 |
+
$hooks[] = new MulticurrencyHooks();
|
21 |
+
}
|
22 |
+
|
23 |
+
return $hooks;
|
24 |
+
}
|
25 |
+
}
|
compatibility/{class-wcml-yith-wcqv.php → YithWcQuickView/MulticurrencyHooks.php}
RENAMED
@@ -1,18 +1,21 @@
|
|
1 |
<?php
|
2 |
|
3 |
-
|
4 |
|
5 |
-
|
6 |
|
|
|
7 |
add_filter( 'wcml_multi_currency_ajax_actions', [ $this, 'ajax_action_needs_multi_currency' ] );
|
8 |
-
|
9 |
}
|
10 |
|
|
|
|
|
|
|
|
|
|
|
11 |
public function ajax_action_needs_multi_currency( $actions ) {
|
12 |
-
|
13 |
$actions[] = 'yith_load_product_quick_view';
|
14 |
|
15 |
return $actions;
|
16 |
}
|
17 |
-
|
18 |
}
|
1 |
<?php
|
2 |
|
3 |
+
namespace WCML\Compatibility\YithWcQuickView;
|
4 |
|
5 |
+
class MulticurrencyHooks implements \IWPML_Action {
|
6 |
|
7 |
+
public function add_hooks() {
|
8 |
add_filter( 'wcml_multi_currency_ajax_actions', [ $this, 'ajax_action_needs_multi_currency' ] );
|
|
|
9 |
}
|
10 |
|
11 |
+
/**
|
12 |
+
* @param array $actions
|
13 |
+
*
|
14 |
+
* @return array
|
15 |
+
*/
|
16 |
public function ajax_action_needs_multi_currency( $actions ) {
|
|
|
17 |
$actions[] = 'yith_load_product_quick_view';
|
18 |
|
19 |
return $actions;
|
20 |
}
|
|
|
21 |
}
|
compatibility/class-wcml-checkout-addons.php
DELETED
@@ -1,61 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
/**
|
3 |
-
* Compatibility class for wc_checkout_addons plugin.
|
4 |
-
*
|
5 |
-
* @author konrad
|
6 |
-
*/
|
7 |
-
class WCML_Checkout_Addons {
|
8 |
-
|
9 |
-
public function add_hooks() {
|
10 |
-
add_filter( 'option_wc_checkout_add_ons', [ $this, 'option_wc_checkout_add_ons' ], 10, 2 );
|
11 |
-
}
|
12 |
-
|
13 |
-
public function option_wc_checkout_add_ons( $option_value, $option_name = null ) {
|
14 |
-
if ( is_array( $option_value ) ) {
|
15 |
-
foreach ( $option_value as $addon_id => $addon_conf ) {
|
16 |
-
$addon_conf = $this->handle_option_part( $addon_id, $addon_conf );
|
17 |
-
if ( isset( $addon_conf['options'] ) ) {
|
18 |
-
foreach ( $addon_conf['options'] as $index => $fields ) {
|
19 |
-
$addon_conf['options'][ $index ] = $this->handle_option_part( $index, $fields );
|
20 |
-
}
|
21 |
-
}
|
22 |
-
$option_value[ $addon_id ] = $addon_conf;
|
23 |
-
}
|
24 |
-
}
|
25 |
-
|
26 |
-
return $option_value;
|
27 |
-
}
|
28 |
-
|
29 |
-
private function handle_option_part( $index, $conf ) {
|
30 |
-
$conf = $this->register_or_translate( 'label', $conf, $index );
|
31 |
-
$conf = $this->register_or_translate( 'description', $conf, $index );
|
32 |
-
$conf = $this->adjust_price( $conf );
|
33 |
-
return $conf;
|
34 |
-
}
|
35 |
-
|
36 |
-
private function register_or_translate( $element, $conf, $index ) {
|
37 |
-
if ( isset( $conf[ $element ] ) ) {
|
38 |
-
$string = $conf[ $element ];
|
39 |
-
$key = $index . '_' . $element . '_' . md5( $string );
|
40 |
-
if ( $this->is_default_language() ) {
|
41 |
-
do_action( 'wpml_register_single_string', 'wc_checkout_addons', $key, $string );
|
42 |
-
} else {
|
43 |
-
$conf[ $element ] = apply_filters( 'wpml_translate_single_string', $string, 'wc_checkout_addons', $key );
|
44 |
-
}
|
45 |
-
}
|
46 |
-
return $conf;
|
47 |
-
}
|
48 |
-
|
49 |
-
private function adjust_price( $conf ) {
|
50 |
-
if ( isset( $conf['adjustment'], $conf['adjustment_type'] )
|
51 |
-
&& $conf['adjustment_type'] === 'fixed'
|
52 |
-
&& ! $this->is_default_language() ) {
|
53 |
-
$conf['adjustment'] = apply_filters( 'wcml_raw_price_amount', $conf['adjustment'] );
|
54 |
-
}
|
55 |
-
return $conf;
|
56 |
-
}
|
57 |
-
|
58 |
-
private function is_default_language() {
|
59 |
-
return apply_filters( 'wpml_current_language', null ) === apply_filters( 'wpml_default_language', null );
|
60 |
-
}
|
61 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
compatibility/class-wcml-compatibility-helper.php
CHANGED
@@ -2,7 +2,7 @@
|
|
2 |
|
3 |
class WCML_Compatibility_Helper {
|
4 |
|
5 |
-
public function get_product_type( $product_id ) {
|
6 |
|
7 |
if ( $terms = wp_get_object_terms( $product_id, 'product_type' ) ) {
|
8 |
$product_type = sanitize_title( current( $terms )->name );
|
2 |
|
3 |
class WCML_Compatibility_Helper {
|
4 |
|
5 |
+
public static function get_product_type( $product_id ) {
|
6 |
|
7 |
if ( $terms = wp_get_object_terms( $product_id, 'product_type' ) ) {
|
8 |
$product_type = sanitize_title( current( $terms )->name );
|
compatibility/class-wcml-litespeed-cache.php
DELETED
@@ -1,26 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
class WCML_LiteSpeed_Cache {
|
4 |
-
|
5 |
-
public function add_hooks() {
|
6 |
-
// LiteSpeed_Cache_API::vary is available since 2.6.
|
7 |
-
if ( method_exists( 'LiteSpeed_Cache_API', 'v' ) && LiteSpeed_Cache_API::v( '2.6' ) ) {
|
8 |
-
add_filter( 'wcml_client_currency', [ $this, 'apply_client_currency' ] );
|
9 |
-
add_action( 'wcml_set_client_currency', [ $this, 'set_client_currency' ] );
|
10 |
-
}
|
11 |
-
}
|
12 |
-
|
13 |
-
public function set_client_currency( $currency ) {
|
14 |
-
$this->apply_client_currency( $currency );
|
15 |
-
|
16 |
-
LiteSpeed_Cache_API::force_vary();
|
17 |
-
}
|
18 |
-
|
19 |
-
public function apply_client_currency( $currency ) {
|
20 |
-
LiteSpeed_Cache_API::vary( 'wcml_currency', $currency, wcml_get_woocommerce_currency_option() );
|
21 |
-
|
22 |
-
return $currency;
|
23 |
-
}
|
24 |
-
|
25 |
-
}
|
26 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
compatibility/class-wcml-mix-and-match-products.php
DELETED
@@ -1,53 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
class WCML_Mix_and_Match_Products {
|
4 |
-
|
5 |
-
public function __construct() {
|
6 |
-
add_action( 'updated_post_meta', [ $this, 'sync_mnm_data' ], 10, 4 );
|
7 |
-
}
|
8 |
-
|
9 |
-
public function sync_mnm_data( $meta_id, $post_id, $meta_key, $meta_value ) {
|
10 |
-
if ( '_mnm_data' !== $meta_key ) {
|
11 |
-
return;
|
12 |
-
}
|
13 |
-
|
14 |
-
global $sitepress, $woocommerce_wpml;
|
15 |
-
|
16 |
-
$post = get_post( $post_id );
|
17 |
-
|
18 |
-
// Skip auto-drafts, skip autosave.
|
19 |
-
if ( 'auto-draft' === $post->post_status || isset( $_POST['autosave'] ) ) {
|
20 |
-
return;
|
21 |
-
}
|
22 |
-
|
23 |
-
if ( 'product' === $post->post_type ) {
|
24 |
-
remove_action( 'updated_post_meta', [ $this, 'sync_mnm_data' ], 10 );
|
25 |
-
|
26 |
-
if ( $woocommerce_wpml->products->is_original_product( $post_id ) ) {
|
27 |
-
$original_product_id = $post_id;
|
28 |
-
} else {
|
29 |
-
$original_product_id = $woocommerce_wpml->products->get_original_product_id( $post_id );
|
30 |
-
}
|
31 |
-
|
32 |
-
$mnm_data = maybe_unserialize( get_post_meta( $original_product_id, '_mnm_data', true ) );
|
33 |
-
$product_trid = $sitepress->get_element_trid( $original_product_id, 'post_product' );
|
34 |
-
$product_translations = $sitepress->get_element_translations( $product_trid, 'post_product' );
|
35 |
-
|
36 |
-
foreach ( $product_translations as $product_translation ) {
|
37 |
-
if ( empty( $product_translation->original ) ) {
|
38 |
-
foreach ( $mnm_data as $key => $mnm_element ) {
|
39 |
-
|
40 |
-
$trnsl_prod = apply_filters( 'translate_object_id', $key, 'product', true, $product_translation->language_code );
|
41 |
-
$mnm_element['product_id'] = $trnsl_prod;
|
42 |
-
$mnm_data[ $trnsl_prod ] = $mnm_element;
|
43 |
-
unset( $mnm_data[ $key ] );
|
44 |
-
}
|
45 |
-
|
46 |
-
update_post_meta( $product_translation->element_id, '_mnm_data', $mnm_data );
|
47 |
-
}
|
48 |
-
}
|
49 |
-
|
50 |
-
add_action( 'updated_post_meta', [ $this, 'sync_mnm_data' ], 10, 4 );
|
51 |
-
}
|
52 |
-
}
|
53 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
compatibility/class-wcml-pip.php
DELETED
@@ -1,104 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
class WCML_Pip {
|
4 |
-
|
5 |
-
public function __construct() {
|
6 |
-
|
7 |
-
add_filter( 'wcml_send_email_order_id', [ $this, 'wcml_send_email_order_id' ] );
|
8 |
-
add_filter( 'woocommerce_currency_symbol', [ $this, 'filter_pip_currency_symbol' ] );
|
9 |
-
add_filter( 'wcml_filter_currency_position', [ $this, 'filter_pip_currency_position' ] );
|
10 |
-
add_action( 'wc_pip_print', [ $this, 'print_invoice_language' ], 10, 3 );
|
11 |
-
|
12 |
-
}
|
13 |
-
|
14 |
-
public function wcml_send_email_order_id( $order_id ) {
|
15 |
-
|
16 |
-
$pip_order_id = $this->get_pip_order_id();
|
17 |
-
|
18 |
-
if ( $pip_order_id ) {
|
19 |
-
$order_id = $pip_order_id;
|
20 |
-
}
|
21 |
-
|
22 |
-
return $order_id;
|
23 |
-
|
24 |
-
}
|
25 |
-
|
26 |
-
public function filter_pip_currency_symbol( $currency_symbol ) {
|
27 |
-
|
28 |
-
remove_filter( 'woocommerce_currency_symbol', [ $this, 'filter_pip_currency_symbol' ] );
|
29 |
-
|
30 |
-
$currency = $this->get_pip_order_currency();
|
31 |
-
|
32 |
-
if ( $currency ) {
|
33 |
-
$currency_symbol = get_woocommerce_currency_symbol( $currency );
|
34 |
-
}
|
35 |
-
|
36 |
-
add_filter( 'woocommerce_currency_symbol', [ $this, 'filter_pip_currency_symbol' ] );
|
37 |
-
|
38 |
-
return $currency_symbol;
|
39 |
-
}
|
40 |
-
|
41 |
-
public function filter_pip_currency_position( $currency ) {
|
42 |
-
|
43 |
-
remove_filter( 'wcml_filter_currency_position', [ $this, 'filter_pip_currency_position' ] );
|
44 |
-
|
45 |
-
$currency = $this->get_pip_order_currency( $currency );
|
46 |
-
|
47 |
-
add_filter( 'wcml_filter_currency_position', [ $this, 'filter_pip_currency_position' ] );
|
48 |
-
|
49 |
-
return $currency;
|
50 |
-
|
51 |
-
}
|
52 |
-
|
53 |
-
public function get_pip_order_id() {
|
54 |
-
|
55 |
-
$order_id = false;
|
56 |
-
|
57 |
-
if ( isset( $_GET['wc_pip_action'] ) && isset( $_GET['order_id'] ) ) {
|
58 |
-
$order_id = $_GET['order_id'];
|
59 |
-
} elseif (
|
60 |
-
isset( $_POST['action'] ) &&
|
61 |
-
(
|
62 |
-
$_POST['action'] == 'wc_pip_order_send_email' ||
|
63 |
-
$_POST['action'] == 'wc_pip_send_email_packing_list'
|
64 |
-
) &&
|
65 |
-
isset( $_POST['order_id'] )
|
66 |
-
) {
|
67 |
-
$order_id = $_POST['order_id'];
|
68 |
-
}
|
69 |
-
|
70 |
-
return $order_id;
|
71 |
-
}
|
72 |
-
|
73 |
-
public function get_pip_order_currency( $currency = false ) {
|
74 |
-
|
75 |
-
$pip_order_id = $this->get_pip_order_id();
|
76 |
-
|
77 |
-
if ( $pip_order_id && isset( WC()->order_factory ) ) {
|
78 |
-
|
79 |
-
$the_order = WC()->order_factory->get_order( $pip_order_id );
|
80 |
-
|
81 |
-
if ( $the_order ) {
|
82 |
-
$currency = $the_order->get_currency();
|
83 |
-
|
84 |
-
if ( ! $currency && isset( $_COOKIE['_wcml_order_currency'] ) ) {
|
85 |
-
$currency = $_COOKIE['_wcml_order_currency'];
|
86 |
-
}
|
87 |
-
}
|
88 |
-
}
|
89 |
-
|
90 |
-
return $currency;
|
91 |
-
|
92 |
-
}
|
93 |
-
|
94 |
-
public function print_invoice_language( $type, $order_id, $order_ids ) {
|
95 |
-
|
96 |
-
$order_language = get_post_meta( $order_id, 'wpml_language', true );
|
97 |
-
|
98 |
-
if ( $order_language ) {
|
99 |
-
do_action( 'wpml_switch_language', $order_language );
|
100 |
-
}
|
101 |
-
|
102 |
-
}
|
103 |
-
|
104 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
compatibility/class-wcml-product-addons.php
DELETED
@@ -1,664 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
/**
|
4 |
-
* Class WCML_Product_Addons
|
5 |
-
*/
|
6 |
-
class WCML_Product_Addons {
|
7 |
-
|
8 |
-
const TEMPLATE_FOLDER = '/templates/compatibility/';
|
9 |
-
const DIALOG_TEMPLATE = 'product-addons-prices-dialog.twig';
|
10 |
-
const SETTINGS_TEMPLATE = 'product-addons-prices-settings.twig';
|
11 |
-
const PRICE_OPTION_KEY = '_product_addon_prices';
|
12 |
-
|
13 |
-
/**
|
14 |
-
* @var SitePress
|
15 |
-
*/
|
16 |
-
public $sitepress;
|
17 |
-
/**
|
18 |
-
* @var woocommerce_wpml
|
19 |
-
*/
|
20 |
-
private $woocommerce_wpml;
|
21 |
-
/**
|
22 |
-
* @var int
|
23 |
-
*/
|
24 |
-
private $multi_currency_mode;
|
25 |
-
|
26 |
-
/**
|
27 |
-
* WCML_Product_Addons constructor.
|
28 |
-
*
|
29 |
-
* @param SitePress $sitepress
|
30 |
-
* @param woocommerce_wpml $woocommerce_wpml
|
31 |
-
*/
|
32 |
-
public function __construct( SitePress $sitepress, woocommerce_wpml $woocommerce_wpml ) {
|
33 |
-
$this->sitepress = $sitepress;
|
34 |
-
$this->woocommerce_wpml = $woocommerce_wpml;
|
35 |
-
$this->multi_currency_mode = $woocommerce_wpml->settings['enable_multi_currency'];
|
36 |
-
}
|
37 |
-
|
38 |
-
public function add_hooks() {
|
39 |
-
|
40 |
-
add_action( 'init', [ $this, 'load_assets' ] );
|
41 |
-
add_filter( 'get_product_addons_product_terms', [ $this, 'addons_product_terms' ] );
|
42 |
-
add_filter( 'get_product_addons_fields', [ $this, 'product_addons_price_filter' ], 10, 2 );
|
43 |
-
|
44 |
-
add_action( 'updated_post_meta', [ $this, 'register_addons_strings' ], 10, 4 );
|
45 |
-
add_action( 'added_post_meta', [ $this, 'register_addons_strings' ], 10, 4 );
|
46 |
-
|
47 |
-
add_action( 'woocommerce-product-addons_panel_start', [ $this, 'show_pointer_info' ] );
|
48 |
-
|
49 |
-
if ( is_admin() ) {
|
50 |
-
|
51 |
-
if ( $this->is_global_addon_edit_page() ) {
|
52 |
-
if ( ! isset( $_GET['edit'] ) ) {
|
53 |
-
add_action( 'admin_notices', [ $this, 'inf_translate_strings' ] );
|
54 |
-
}
|
55 |
-
}
|
56 |
-
|
57 |
-
add_action( 'wcml_gui_additional_box_html', [ $this, 'custom_box_html' ], 10, 3 );
|
58 |
-
add_filter( 'wcml_gui_additional_box_data', [ $this, 'custom_box_html_data' ], 10, 3 );
|
59 |
-
add_action( 'wcml_update_extra_fields', [ $this, 'addons_update' ], 10, 3 );
|
60 |
-
|
61 |
-
add_action( 'woocommerce_product_data_panels', [ $this, 'show_pointer_info' ] );
|
62 |
-
|
63 |
-
add_filter( 'wcml_do_not_display_custom_fields_for_product', [ $this, 'replace_tm_editor_custom_fields_with_own_sections' ] );
|
64 |
-
|
65 |
-
if ( $this->is_multi_currency_on() ) {
|
66 |
-
add_action( 'woocommerce_product_addons_panel_start', [ $this, 'load_dialog_resources' ] );
|
67 |
-
add_action( 'woocommerce_product_addons_panel_option_row', [ $this, 'dialog_button_after_option_row' ], 10, 4 );
|
68 |
-
add_action( 'woocommerce_product_addons_panel_before_options', [ $this, 'dialog_button_before_options' ], 10, 3 );
|
69 |
-
add_action( 'wcml_before_sync_product', [ $this, 'update_custom_prices_values' ] );
|
70 |
-
add_action( 'woocommerce_product_addons_global_edit_objects', [ $this, 'custom_prices_settings_block' ] );
|
71 |
-
}
|
72 |
-
} else {
|
73 |
-
add_filter( 'get_post_metadata', [ $this, 'translate_addons_strings' ], 10, 4 );
|
74 |
-
}
|
75 |
-
|
76 |
-
add_filter(
|
77 |
-
'wcml_cart_contents_not_changed',
|
78 |
-
[
|
79 |
-
$this,
|
80 |
-
'filter_booking_addon_product_in_cart_contents',
|
81 |
-
],
|
82 |
-
20
|
83 |
-
);
|
84 |
-
|
85 |
-
add_filter(
|
86 |
-
'get_product_addons_global_query_args',
|
87 |
-
[
|
88 |
-
$this,
|
89 |
-
'set_global_ids_in_query_args',
|
90 |
-
]
|
91 |
-
);
|
92 |
-
}
|
93 |
-
|
94 |
-
|
95 |
-
private function is_global_addon_edit_page() {
|
96 |
-
global $pagenow;
|
97 |
-
|
98 |
-
return 'edit.php' === $pagenow &&
|
99 |
-
isset( $_GET['post_type'] ) &&
|
100 |
-
'product' === $_GET['post_type'] &&
|
101 |
-
isset( $_GET['page'] ) &&
|
102 |
-
( 'global_addons' === $_GET['page'] || 'addons' === $_GET['page'] );
|
103 |
-
}
|
104 |
-
|
105 |
-
/**
|
106 |
-
* @param string $product_id
|
107 |
-
*
|
108 |
-
* @return array
|
109 |
-
*/
|
110 |
-
private function get_product_addons( $product_id ) {
|
111 |
-
return maybe_unserialize( get_post_meta( $product_id, '_product_addons', true ) );
|
112 |
-
}
|
113 |
-
|
114 |
-
/**
|
115 |
-
* @param $meta_id
|
116 |
-
* @param $id
|
117 |
-
* @param $meta_key
|
118 |
-
* @param $addons
|
119 |
-
*/
|
120 |
-
public function register_addons_strings( $meta_id, $id, $meta_key, $addons ) {
|
121 |
-
if ( '_product_addons' === $meta_key && 'global_product_addon' === get_post_type( $id ) ) {
|
122 |
-
$this->update_custom_prices_values( $id );
|
123 |
-
foreach ( $addons as $addon ) {
|
124 |
-
$addon_data = wpml_collect( $addon );
|
125 |
-
$addon_type = $addon_data->get( 'type' );
|
126 |
-
$addon_position = $addon_data->get( 'position' );
|
127 |
-
// register name
|
128 |
-
do_action( 'wpml_register_single_string', 'wc_product_addons_strings', $id . '_addon_' . $addon_type . '_' . $addon_position . '_name', $addon_data->get( 'name' ) );
|
129 |
-
// register description
|
130 |
-
do_action( 'wpml_register_single_string', 'wc_product_addons_strings', $id . '_addon_' . $addon_type . '_' . $addon_position . '_description', $addon_data->get( 'description' ) );
|
131 |
-
// register options labels
|
132 |
-
if ( $addon_data->offsetExists( 'options' ) ) {
|
133 |
-
foreach ( $addon_data->get( 'options' ) as $key => $option ) {
|
134 |
-
do_action( 'wpml_register_single_string', 'wc_product_addons_strings', $id . '_addon_' . $addon_type . '_' . $addon_position . '_option_label_' . $key, wpml_collect( $option )->get( 'label' ) );
|
135 |
-
}
|
136 |
-
}
|
137 |
-
}
|
138 |
-
}
|
139 |
-
}
|
140 |
-
|
141 |
-
/**
|
142 |
-
* @param $null
|
143 |
-
* @param $object_id
|
144 |
-
* @param $meta_key
|
145 |
-
* @param $single
|
146 |
-
*
|
147 |
-
* @return array
|
148 |
-
*/
|
149 |
-
public function translate_addons_strings( $null, $object_id, $meta_key, $single ) {
|
150 |
-
|
151 |
-
if ( '_product_addons' === $meta_key && 'global_product_addon' === get_post_type( $object_id ) ) {
|
152 |
-
|
153 |
-
remove_filter( 'get_post_metadata', [ $this, 'translate_addons_strings' ], 10 );
|
154 |
-
$addons = get_post_meta( $object_id, $meta_key, true );
|
155 |
-
add_filter( 'get_post_metadata', [ $this, 'translate_addons_strings' ], 10, 4 );
|
156 |
-
|
157 |
-
if ( is_array( $addons ) ) {
|
158 |
-
foreach ( $addons as $key => $addon ) {
|
159 |
-
$addon_data = wpml_collect( $addon );
|
160 |
-
$addon_type = $addon_data->get( 'type' );
|
161 |
-
$addon_position = $addon_data->get( 'position' );
|
162 |
-
// register name
|
163 |
-
$addons[ $key ]['name'] = apply_filters( 'wpml_translate_single_string', $addon_data->get( 'name' ), 'wc_product_addons_strings', $object_id . '_addon_' . $addon_type . '_' . $addon_position . '_name' );
|
164 |
-
// register description
|
165 |
-
$addons[ $key ]['description'] = apply_filters( 'wpml_translate_single_string', $addon_data->get( 'description' ), 'wc_product_addons_strings', $object_id . '_addon_' . $addon_type . '_' . $addon_position . '_description' );
|
166 |
-
// register options labels
|
167 |
-
if ( $addon_data->offsetExists( 'options' ) ) {
|
168 |
-
foreach ( $addon['options'] as $opt_key => $option ) {
|
169 |
-
$addons[ $key ]['options'][ $opt_key ]['label'] = apply_filters( 'wpml_translate_single_string', wpml_collect( $option )->get( 'label' ), 'wc_product_addons_strings', $object_id . '_addon_' . $addon_type . '_' . $addon_position . '_option_label_' . $opt_key );
|
170 |
-
}
|
171 |
-
}
|
172 |
-
}
|
173 |
-
}
|
174 |
-
|
175 |
-
return [ 0 => $addons ];
|
176 |
-
}
|
177 |
-
|
178 |
-
return $null;
|
179 |
-
|
180 |
-
}
|
181 |
-
|
182 |
-
/**
|
183 |
-
* @param $addons
|
184 |
-
* @param $post_id
|
185 |
-
*
|
186 |
-
* @return mixed
|
187 |
-
*/
|
188 |
-
public function product_addons_price_filter( $addons, $post_id ) {
|
189 |
-
|
190 |
-
if ( $this->is_multi_currency_on() ) {
|
191 |
-
|
192 |
-
foreach ( $addons as $add_id => $addon ) {
|
193 |
-
|
194 |
-
$addon_data = wpml_collect( $addon );
|
195 |
-
|
196 |
-
if ( $addon_data->offsetExists( 'price' ) && $addon_data->get( 'price' ) ) {
|
197 |
-
$addons[ $add_id ]['price'] = $this->converted_addon_price( $addon, $post_id );
|
198 |
-
}
|
199 |
-
|
200 |
-
if ( $addon_data->offsetExists( 'options' ) ) {
|
201 |
-
foreach ( $addon_data->get( 'options' ) as $key => $option ) {
|
202 |
-
$addons[ $add_id ]['options'][ $key ]['price'] = $this->converted_addon_price( $option, $post_id );
|
203 |
-
}
|
204 |
-
}
|
205 |
-
}
|
206 |
-
}
|
207 |
-
|
208 |
-
return $addons;
|
209 |
-
}
|
210 |
-
|
211 |
-
/**
|
212 |
-
* @param array $addon
|
213 |
-
* @param int $post_id
|
214 |
-
*
|
215 |
-
* @return string
|
216 |
-
*/
|
217 |
-
private function converted_addon_price( $addon, $post_id ) {
|
218 |
-
|
219 |
-
$addonData = wpml_collect( $addon );
|
220 |
-
|
221 |
-
$is_custom_prices_on = $this->is_product_custom_prices_on( $post_id );
|
222 |
-
$field = 'price_' . $this->woocommerce_wpml->multi_currency->get_client_currency();
|
223 |
-
|
224 |
-
if (
|
225 |
-
$is_custom_prices_on &&
|
226 |
-
$addonData->get( $field )
|
227 |
-
) {
|
228 |
-
return $addonData->get( $field );
|
229 |
-
}
|
230 |
-
|
231 |
-
if ( wpml_collect( [ 'flat_fee', 'quantity_based' ] )->contains( $addonData->get( 'price_type' ) ) ) {
|
232 |
-
return apply_filters( 'wcml_raw_price_amount', $addonData->get( 'price' ) );
|
233 |
-
}
|
234 |
-
|
235 |
-
return $addonData->get( 'price' );
|
236 |
-
}
|
237 |
-
|
238 |
-
/**
|
239 |
-
* @param $product_terms
|
240 |
-
*
|
241 |
-
* @return array
|
242 |
-
*/
|
243 |
-
public function addons_product_terms( $product_terms ) {
|
244 |
-
foreach ( $product_terms as $key => $product_term ) {
|
245 |
-
$product_terms[ $key ] = apply_filters( 'translate_object_id', $product_term, 'product_cat', true, $this->sitepress->get_default_language() );
|
246 |
-
}
|
247 |
-
|
248 |
-
return $product_terms;
|
249 |
-
}
|
250 |
-
|
251 |
-
public function inf_translate_strings() {
|
252 |
-
|
253 |
-
$pointer_ui = new WCML_Pointer_UI(
|
254 |
-
sprintf( __( 'You can translate strings related to global add-ons on the %1$sWPML String Translation page%2$s. Use the search on the top of that page to find the strings.', 'woocommerce-multilingual' ), '<a href="' . admin_url( 'admin.php?page=' . WPML_ST_FOLDER . '/menu/string-translation.php&context=wc_product_addons_strings' ) . '">', '</a>' ),
|
255 |
-
WCML_Tracking_Link::getWcmlProductAddonsDoc(),
|
256 |
-
'wpbody-content .woocommerce>h2'
|
257 |
-
);
|
258 |
-
|
259 |
-
$pointer_ui->show();
|
260 |
-
}
|
261 |
-
|
262 |
-
/**
|
263 |
-
* @param $obj
|
264 |
-
* @param $product_id
|
265 |
-
* @param $data
|
266 |
-
*/
|
267 |
-
public function custom_box_html( $obj, $product_id, $data ) {
|
268 |
-
|
269 |
-
$product_addons = $this->get_product_addons( $product_id );
|
270 |
-
|
271 |
-
if ( ! empty( $product_addons ) ) {
|
272 |
-
foreach ( $product_addons as $addon_id => $product_addon ) {
|
273 |
-
$addon_data = wpml_collect( $product_addon );
|
274 |
-
|
275 |
-
$addons_section = new WPML_Editor_UI_Field_Section( sprintf( __( 'Product Add-ons Group "%s"', 'woocommerce-multilingual' ), $addon_data->get( 'name' ) ) );
|
276 |
-
|
277 |
-
$group = new WPML_Editor_UI_Field_Group( '', true );
|
278 |
-
$addon_field = new WPML_Editor_UI_Single_Line_Field( 'addon_' . $addon_id . '_name', __( 'Name', 'woocommerce-multilingual' ), $data, false );
|
279 |
-
$group->add_field( $addon_field );
|
280 |
-
$addon_field = new WPML_Editor_UI_Single_Line_Field( 'addon_' . $addon_id . '_description', __( 'Description', 'woocommerce-multilingual' ), $data, false );
|
281 |
-
$group->add_field( $addon_field );
|
282 |
-
|
283 |
-
$addons_section->add_field( $group );
|
284 |
-
|
285 |
-
if ( $addon_data->offsetExists( 'options' ) && $addon_data->get( 'options' ) ) {
|
286 |
-
|
287 |
-
$labels_group = new WPML_Editor_UI_Field_Group( __( 'Options', 'woocommerce-multilingual' ), true );
|
288 |
-
|
289 |
-
foreach ( $addon_data->get( 'options' ) as $option_id => $option ) {
|
290 |
-
$option_label_field = new WPML_Editor_UI_Single_Line_Field( 'addon_' . $addon_id . '_option_' . $option_id . '_label', __( 'Label', 'woocommerce-multilingual' ), $data, false );
|
291 |
-
$labels_group->add_field( $option_label_field );
|
292 |
-
}
|
293 |
-
$addons_section->add_field( $labels_group );
|
294 |
-
}
|
295 |
-
$obj->add_field( $addons_section );
|
296 |
-
}
|
297 |
-
}
|
298 |
-
}
|
299 |
-
|
300 |
-
/**
|
301 |
-
* @param $data
|
302 |
-
* @param $product_id
|
303 |
-
* @param $translation
|
304 |
-
*
|
305 |
-
* @return mixed
|
306 |
-
*/
|
307 |
-
public function custom_box_html_data( $data, $product_id, $translation ) {
|
308 |
-
|
309 |
-
$product_addons = $this->get_product_addons( $product_id );
|
310 |
-
|
311 |
-
if ( ! empty( $product_addons ) ) {
|
312 |
-
foreach ( $product_addons as $addon_id => $product_addon ) {
|
313 |
-
$addon_data = wpml_collect( $product_addon );
|
314 |
-
$data[ 'addon_' . $addon_id . '_name' ] = [ 'original' => $addon_data->get( 'name' ) ];
|
315 |
-
$data[ 'addon_' . $addon_id . '_description' ] = [ 'original' => $addon_data->get( 'description' ) ];
|
316 |
-
if ( $addon_data->offsetExists( 'options' ) && $addon_data->get( 'options' ) ) {
|
317 |
-
foreach ( $addon_data->get( 'options' ) as $option_id => $option ) {
|
318 |
-
$data[ 'addon_' . $addon_id . '_option_' . $option_id . '_label' ] = [ 'original' => wpml_collect( $option )->get( 'label' ) ];
|
319 |
-
}
|
320 |
-
}
|
321 |
-
}
|
322 |
-
|
323 |
-
if ( $translation ) {
|
324 |
-
$translated_product_addons = $this->get_product_addons( $translation->ID );
|
325 |
-
if ( ! empty( $translated_product_addons ) ) {
|
326 |
-
foreach ( $translated_product_addons as $addon_id => $transalted_product_addon ) {
|
327 |
-
$translated_addon_data = wpml_collect( $transalted_product_addon );
|
328 |
-
$data[ 'addon_' . $addon_id . '_name' ]['translation'] = $translated_addon_data->get( 'name' );
|
329 |
-
$data[ 'addon_' . $addon_id . '_description' ]['translation'] = $translated_addon_data->get( 'description' );
|
330 |
-
if ( $translated_addon_data->offsetExists( 'options' ) && $translated_addon_data->get( 'options' ) ) {
|
331 |
-
foreach ( $translated_addon_data->get( 'options' ) as $option_id => $option ) {
|
332 |
-
$data[ 'addon_' . $addon_id . '_option_' . $option_id . '_label' ]['translation'] = wpml_collect( $option )->get( 'label' );
|
333 |
-
}
|
334 |
-
}
|
335 |
-
}
|
336 |
-
}
|
337 |
-
}
|
338 |
-
}
|
339 |
-
|
340 |
-
return $data;
|
341 |
-
}
|
342 |
-
|
343 |
-
/**
|
344 |
-
* @param $original_product_id
|
345 |
-
* @param $product_id
|
346 |
-
* @param $data
|
347 |
-
*/
|
348 |
-
public function addons_update( $original_product_id, $product_id, $data ) {
|
349 |
-
|
350 |
-
$product_addons = $this->get_product_addons( $original_product_id );
|
351 |
-
|
352 |
-
if ( ! empty( $product_addons ) ) {
|
353 |
-
|
354 |
-
foreach ( $product_addons as $addon_id => $product_addon ) {
|
355 |
-
$addon_data = wpml_collect( $product_addon );
|
356 |
-
$product_addons[ $addon_id ]['name'] = $data[ md5( 'addon_' . $addon_id . '_name' ) ];
|
357 |
-
$product_addons[ $addon_id ]['description'] = $data[ md5( 'addon_' . $addon_id . '_description' ) ];
|
358 |
-
|
359 |
-
if ( $addon_data->offsetExists( 'options' ) && $addon_data->get( 'options' ) ) {
|
360 |
-
foreach ( $addon_data->get( 'options' ) as $option_id => $option ) {
|
361 |
-
$product_addons[ $addon_id ]['options'][ $option_id ]['label'] = $data[ md5( 'addon_' . $addon_id . '_option_' . $option_id . '_label' ) ];
|
362 |
-
}
|
363 |
-
}
|
364 |
-
}
|
365 |
-
}
|
366 |
-
|
367 |
-
update_post_meta( $product_id, '_product_addons', $product_addons );
|
368 |
-
}
|
369 |
-
|
370 |
-
public function show_pointer_info() {
|
371 |
-
|
372 |
-
$pointer_ui = new WCML_Pointer_UI(
|
373 |
-
sprintf( __( 'You can translate the Group Name, Group Description and every Option Label of your product add-on on the %1$sWooCommerce product translation page%2$s', 'woocommerce-multilingual' ), '<a href="' . admin_url( 'admin.php?page=wpml-wcml' ) . '">', '</a>' ),
|
374 |
-
WCML_Tracking_Link::getWcmlProductAddonsDoc(),
|
375 |
-
'product_addons_data>p'
|
376 |
-
);
|
377 |
-
|
378 |
-
$pointer_ui->show();
|
379 |
-
}
|
380 |
-
|
381 |
-
public function replace_tm_editor_custom_fields_with_own_sections( $fields ) {
|
382 |
-
$fields[] = '_product_addons';
|
383 |
-
|
384 |
-
return $fields;
|
385 |
-
}
|
386 |
-
|
387 |
-
// special case for WC Bookings plugin - need add addon cost after re-calculating booking costs #wcml-1877
|
388 |
-
public function filter_booking_addon_product_in_cart_contents( $cart_item ) {
|
389 |
-
|
390 |
-
$is_booking_product_with_addons = $cart_item['data'] instanceof WC_Product_Booking && isset( $cart_item['addons'] );
|
391 |
-
|
392 |
-
if ( $this->is_multi_currency_on() && $is_booking_product_with_addons ) {
|
393 |
-
$cost = $cart_item['data']->get_price();
|
394 |
-
|
395 |
-
foreach ( $cart_item['addons'] as $addon ) {
|
396 |
-
$cost += $addon['price'];
|
397 |
-
}
|
398 |
-
|
399 |
-
$cart_item['data']->set_price( $cost );
|
400 |
-
}
|
401 |
-
|
402 |
-
return $cart_item;
|
403 |
-
}
|
404 |
-
|
405 |
-
public function set_global_ids_in_query_args( $args ) {
|
406 |
-
|
407 |
-
if ( ! is_archive() ) {
|
408 |
-
|
409 |
-
remove_filter( 'get_terms_args', [ $this->sitepress, 'get_terms_args_filter' ], 10 );
|
410 |
-
remove_filter( 'get_term', [ $this->sitepress, 'get_term_adjust_id' ], 1 );
|
411 |
-
remove_filter( 'terms_clauses', [ $this->sitepress, 'terms_clauses' ], 10 );
|
412 |
-
|
413 |
-
$matched_addons_ids = wp_list_pluck( get_posts( $args ), 'ID' );
|
414 |
-
|
415 |
-
if ( $matched_addons_ids ) {
|
416 |
-
$args['include'] = $matched_addons_ids;
|
417 |
-
unset( $args['tax_query'] );
|
418 |
-
}
|
419 |
-
|
420 |
-
add_filter( 'get_terms_args', [ $this->sitepress, 'get_terms_args_filter' ], 10, 2 );
|
421 |
-
add_filter( 'get_term', [ $this->sitepress, 'get_term_adjust_id' ], 1 );
|
422 |
-
add_filter( 'terms_clauses', [ $this->sitepress, 'terms_clauses' ], 10, 3 );
|
423 |
-
}
|
424 |
-
|
425 |
-
return $args;
|
426 |
-
}
|
427 |
-
|
428 |
-
/**
|
429 |
-
* @return bool
|
430 |
-
*/
|
431 |
-
private function is_multi_currency_on() {
|
432 |
-
return $this->multi_currency_mode === $this->sitepress->get_wp_api()->constant( 'WCML_MULTI_CURRENCIES_INDEPENDENT' );
|
433 |
-
}
|
434 |
-
|
435 |
-
public function load_dialog_resources() {
|
436 |
-
wp_enqueue_script( 'wcml-dialogs', WCML_PLUGIN_URL . '/res/js/dialogs' . WCML_JS_MIN . '.js', [ 'jquery-ui-dialog', 'underscore' ], WCML_VERSION );
|
437 |
-
}
|
438 |
-
|
439 |
-
/**
|
440 |
-
* @param WP_Post|null $product
|
441 |
-
* @param array $product_addons
|
442 |
-
* @param int $loop
|
443 |
-
* @param array $option
|
444 |
-
*/
|
445 |
-
public function dialog_button_after_option_row( $product, $product_addons, $loop, $option ) {
|
446 |
-
if ( $option ) {
|
447 |
-
$this->render_edit_price_element( $this->get_prices_dialog_model( $product_addons, $option, $loop, $this->is_product_custom_prices_on( $product ? $product->ID : false ) ) );
|
448 |
-
}
|
449 |
-
|
450 |
-
}
|
451 |
-
|
452 |
-
/**
|
453 |
-
* @param WP_Post|null $product
|
454 |
-
* @param array $product_addons
|
455 |
-
* @param int $loop
|
456 |
-
*/
|
457 |
-
public function dialog_button_before_options( $product, $product_addons, $loop ) {
|
458 |
-
$this->render_edit_price_element( $this->get_prices_dialog_model( [], $product_addons, $loop, $this->is_product_custom_prices_on( $product ? $product->ID : false ) ) );
|
459 |
-
}
|
460 |
-
|
461 |
-
/**
|
462 |
-
* @param array $model
|
463 |
-
*/
|
464 |
-
private function render_edit_price_element( $model ) {
|
465 |
-
$twig_loader = $this->get_twig_loader();
|
466 |
-
// phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
467 |
-
echo $twig_loader->get_template()->show( $model, self::DIALOG_TEMPLATE );
|
468 |
-
}
|
469 |
-
|
470 |
-
/**
|
471 |
-
* @return array
|
472 |
-
*/
|
473 |
-
private function get_one_price_types() {
|
474 |
-
|
475 |
-
return [
|
476 |
-
'custom_text',
|
477 |
-
'custom_textarea',
|
478 |
-
'file_upload',
|
479 |
-
'input_multiplier',
|
480 |
-
];
|
481 |
-
}
|
482 |
-
|
483 |
-
/**
|
484 |
-
* @return WPML_Twig_Template_Loader
|
485 |
-
*/
|
486 |
-
private function get_twig_loader() {
|
487 |
-
return new WPML_Twig_Template_Loader( [ $this->sitepress->get_wp_api()->constant( 'WCML_PLUGIN_PATH' ) . self::TEMPLATE_FOLDER ] );
|
488 |
-
}
|
489 |
-
|
490 |
-
/**
|
491 |
-
* @param int|false $product
|
492 |
-
*
|
493 |
-
* @return mixed
|
494 |
-
*/
|
495 |
-
private function is_product_custom_prices_on( $product_id ) {
|
496 |
-
|
497 |
-
if ( $product_id ) {
|
498 |
-
return get_post_meta( $product_id, '_wcml_custom_prices_status', true );
|
499 |
-
}
|
500 |
-
|
501 |
-
if ( $this->is_global_addon_edit_page() ) {
|
502 |
-
return $this->get_global_addon_prices_status();
|
503 |
-
}
|
504 |
-
|
505 |
-
return false;
|
506 |
-
}
|
507 |
-
|
508 |
-
/**
|
509 |
-
* @return bool|mixed
|
510 |
-
*/
|
511 |
-
private function get_global_addon_prices_status() {
|
512 |
-
|
513 |
-
if ( isset( $_GET['edit'] ) ) {
|
514 |
-
return get_post_meta( $_GET['edit'], '_wcml_custom_prices_status', true );
|
515 |
-
} elseif ( isset( $_POST['_wcml_custom_prices'] ) ) {
|
516 |
-
return $_POST['_wcml_custom_prices'];
|
517 |
-
}
|
518 |
-
|
519 |
-
return false;
|
520 |
-
}
|
521 |
-
|
522 |
-
public function load_assets() {
|
523 |
-
global $pagenow;
|
524 |
-
|
525 |
-
$is_product_page = 'post.php' === $pagenow && isset( $_GET['post'] );
|
526 |
-
$is_product_new_page = 'post-new.php' === $pagenow && isset( $_GET['post_type'] ) && 'product' === $_GET['post_type'];
|
527 |
-
|
528 |
-
if ( $is_product_page || $is_product_new_page || $this->is_global_addon_edit_page() ) {
|
529 |
-
wp_enqueue_script( 'wcml-product-addons', WCML_PLUGIN_URL . '/compatibility/res/js/wcml-product-addons' . WCML_JS_MIN . '.js', [ 'jquery' ], WCML_VERSION );
|
530 |
-
wp_enqueue_style( 'wcml-product-addons', WCML_PLUGIN_URL . '/compatibility/res/css/wcml-product-addons.css', '', WCML_VERSION );
|
531 |
-
}
|
532 |
-
|
533 |
-
}
|
534 |
-
|
535 |
-
/**
|
536 |
-
* @param string $product_id
|
537 |
-
*/
|
538 |
-
public function update_custom_prices_values( $product_id ) {
|
539 |
-
|
540 |
-
if ( $this->is_multi_currency_on() ) {
|
541 |
-
$this->save_global_addon_prices_setting( $product_id );
|
542 |
-
$product_addons = $this->get_product_addons( $product_id );
|
543 |
-
|
544 |
-
if ( $product_addons ) {
|
545 |
-
$active_currencies = $this->woocommerce_wpml->multi_currency->get_currencies();
|
546 |
-
|
547 |
-
foreach ( $product_addons as $addon_key => $product_addon ) {
|
548 |
-
|
549 |
-
foreach ( $active_currencies as $code => $currency ) {
|
550 |
-
$price_option_key = self::PRICE_OPTION_KEY;
|
551 |
-
|
552 |
-
if ( in_array( $product_addon['type'], $this->get_one_price_types() ) ) {
|
553 |
-
$product_addons = $this->update_single_option_prices( $product_addons, $price_option_key, $addon_key, $code );
|
554 |
-
} else {
|
555 |
-
$product_addons = $this->update_multiple_options_prices( $product_addons, $price_option_key, $addon_key, $code );
|
556 |
-
}
|
557 |
-
}
|
558 |
-
}
|
559 |
-
|
560 |
-
update_post_meta( $product_id, '_product_addons', $product_addons );
|
561 |
-
}
|
562 |
-
}
|
563 |
-
}
|
564 |
-
|
565 |
-
/**
|
566 |
-
* @param array $product_addons
|
567 |
-
* @param string $price_option_key
|
568 |
-
* @param string $addon_key
|
569 |
-
* @param string $code
|
570 |
-
*
|
571 |
-
* @return array
|
572 |
-
*/
|
573 |
-
private function update_single_option_prices( $product_addons, $price_option_key, $addon_key, $code ) {
|
574 |
-
if ( isset( $_POST[ $price_option_key ][ $addon_key ][ 'price_' . $code ][0] ) ) {
|
575 |
-
$product_addons[ $addon_key ][ 'price_' . $code ] = wc_format_decimal( $_POST[ $price_option_key ][ $addon_key ][ 'price_' . $code ][0] );
|
576 |
-
}
|
577 |
-
|
578 |
-
return $product_addons;
|
579 |
-
}
|
580 |
-
|
581 |
-
/**
|
582 |
-
* @param array $product_addons
|
583 |
-
* @param string $price_option_key
|
584 |
-
* @param string $addon_key
|
585 |
-
* @param string $code
|
586 |
-
*
|
587 |
-
* @return array
|
588 |
-
*/
|
589 |
-
private function update_multiple_options_prices( $product_addons, $price_option_key, $addon_key, $code ) {
|
590 |
-
|
591 |
-
$addon_data = wpml_collect( $product_addons[ $addon_key ] );
|
592 |
-
|
593 |
-
if ( $addon_data->offsetExists( 'options' ) ) {
|
594 |
-
foreach ( $addon_data->get( 'options' ) as $option_key => $option ) {
|
595 |
-
if ( isset( $_POST[ $price_option_key ][ $addon_key ][ 'price_' . $code ][ $option_key ] ) ) {
|
596 |
-
$product_addons[ $addon_key ]['options'][ $option_key ][ 'price_' . $code ] = wc_format_decimal( $_POST[ $price_option_key ][ $addon_key ][ 'price_' . $code ][ $option_key ] );
|
597 |
-
}
|
598 |
-
}
|
599 |
-
}
|
600 |
-
|
601 |
-
return $product_addons;
|
602 |
-
}
|
603 |
-
|
604 |
-
/**
|
605 |
-
* @param array $product_addons
|
606 |
-
* @param array $option
|
607 |
-
* @param int $loop
|
608 |
-
* @param string|bool $custom_prices_on
|
609 |
-
*
|
610 |
-
* @return array
|
611 |
-
*/
|
612 |
-
private function get_prices_dialog_model( $product_addons, $option, $loop, $custom_prices_on ) {
|
613 |
-
|
614 |
-
$label = isset( $option['label'] ) ? $option['label'] : $option['name'];
|
615 |
-
|
616 |
-
return [
|
617 |
-
'strings' => [
|
618 |
-
'dialog_title' => __( 'Multi-currency settings', 'woocommerce-multilingual' ),
|
619 |
-
'description' => sprintf( __( 'Here you can set different prices for the %s in multiple currencies:', 'woocommerce-multilingual' ), '<strong>' . $label . '</strong>' ),
|
620 |
-
'apply' => __( 'Apply', 'woocommerce-multilingual' ),
|
621 |
-
'cancel' => __( 'Cancel', 'woocommerce-multilingual' ),
|
622 |
-
],
|
623 |
-
'custom_prices_on' => $custom_prices_on,
|
624 |
-
'dialog_id' => '_product_addon_option_' . md5( uniqid( $loop . $label ) ),
|
625 |
-
'option_id' => isset( $product_addons[ $loop ]['options'] ) ? array_search( $option, $product_addons[ $loop ]['options'] ) : '',
|
626 |
-
'addon_id' => $loop,
|
627 |
-
'option_details' => $option,
|
628 |
-
'default_currency' => wcml_get_woocommerce_currency_option(),
|
629 |
-
'active_currencies' => $this->woocommerce_wpml->multi_currency->get_currencies(),
|
630 |
-
];
|
631 |
-
}
|
632 |
-
|
633 |
-
public function custom_prices_settings_block() {
|
634 |
-
$twig_loader = $this->get_twig_loader();
|
635 |
-
// phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
636 |
-
echo $twig_loader->get_template()->show( $this->get_custom_prices_settings_model(), self::SETTINGS_TEMPLATE );
|
637 |
-
}
|
638 |
-
|
639 |
-
private function get_custom_prices_settings_model() {
|
640 |
-
return [
|
641 |
-
'strings' => [
|
642 |
-
'label' => __( 'Multi-currency settings', 'woocommerce-multilingual' ),
|
643 |
-
'auto' => __( 'Calculate prices in other currencies automatically', 'woocommerce-multilingual' ),
|
644 |
-
'manually' => __( 'Set prices in other currencies manually', 'woocommerce-multilingual' ),
|
645 |
-
],
|
646 |
-
'custom_prices_on' => $this->get_global_addon_prices_status(),
|
647 |
-
'nonce' => wp_create_nonce( 'wcml_save_custom_prices' ),
|
648 |
-
];
|
649 |
-
}
|
650 |
-
|
651 |
-
/**
|
652 |
-
* @param int $global_addon_id
|
653 |
-
*/
|
654 |
-
private function save_global_addon_prices_setting( $global_addon_id ) {
|
655 |
-
|
656 |
-
$nonce = filter_var( isset( $_POST['_wcml_custom_prices_nonce'] ) ? $_POST['_wcml_custom_prices_nonce'] : '', FILTER_SANITIZE_FULL_SPECIAL_CHARS );
|
657 |
-
|
658 |
-
if ( isset( $_POST['_wcml_custom_prices'] ) && isset( $nonce ) && wp_verify_nonce( $nonce, 'wcml_save_custom_prices' ) ) {
|
659 |
-
update_post_meta( $global_addon_id, '_wcml_custom_prices_status', $_POST['_wcml_custom_prices'] );
|
660 |
-
}
|
661 |
-
|
662 |
-
}
|
663 |
-
|
664 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
compatibility/class-wcml-wc-name-your-price.php
DELETED
@@ -1,29 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
class WCML_WC_Name_Your_Price {
|
4 |
-
|
5 |
-
public function __construct() {
|
6 |
-
|
7 |
-
add_action( 'init', [ $this, 'init' ], 9 );
|
8 |
-
|
9 |
-
}
|
10 |
-
|
11 |
-
public function init() {
|
12 |
-
if ( ! is_admin() ) {
|
13 |
-
if ( is_callable( [ 'WC_Name_Your_Price_Compatibility', 'is_nyp_gte' ] ) && WC_Name_Your_Price_Compatibility::is_nyp_gte( '3.0' ) ) {
|
14 |
-
add_filter( 'wc_nyp_raw_suggested_price', [ $this, 'product_price_filter' ], 10, 2 );
|
15 |
-
add_filter( 'wc_nyp_raw_minimum_price', [ $this, 'product_price_filter' ], 10, 2 );
|
16 |
-
add_filter( 'wc_nyp_raw_maximum_price', [ $this, 'product_price_filter' ], 10, 2 );
|
17 |
-
} else {
|
18 |
-
add_filter( 'woocommerce_raw_suggested_price', [ $this, 'product_price_filter' ], 10, 2 );
|
19 |
-
add_filter( 'woocommerce_raw_minimum_price', [ $this, 'product_price_filter' ], 10, 2 );
|
20 |
-
add_filter( 'woocommerce_raw_maximum_price', [ $this, 'product_price_filter' ], 10, 2 );
|
21 |
-
}
|
22 |
-
}
|
23 |
-
}
|
24 |
-
|
25 |
-
public function product_price_filter( $price, $product ) {
|
26 |
-
return apply_filters( 'wcml_raw_price_amount', $price );
|
27 |
-
}
|
28 |
-
|
29 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
compatibility/class-wcml-wc-subscriptions.php
DELETED
@@ -1,460 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
use function WPML\FP\tap as tap;
|
4 |
-
|
5 |
-
class WCML_WC_Subscriptions {
|
6 |
-
|
7 |
-
/** @var bool */
|
8 |
-
private $new_subscription = false;
|
9 |
-
|
10 |
-
/** @var bool */
|
11 |
-
private $prorating_price = false;
|
12 |
-
|
13 |
-
/** @var woocommerce_wpml */
|
14 |
-
private $woocommerce_wpml;
|
15 |
-
|
16 |
-
/** @var wpdb */
|
17 |
-
private $wpdb;
|
18 |
-
|
19 |
-
/** @var WC_Cart[]|null $recurring_carts */
|
20 |
-
private $recurring_carts;
|
21 |
-
|
22 |
-
public function __construct( woocommerce_wpml $woocommerce_wpml, wpdb $wpdb ) {
|
23 |
-
$this->woocommerce_wpml = $woocommerce_wpml;
|
24 |
-
$this->wpdb = $wpdb;
|
25 |
-
}
|
26 |
-
|
27 |
-
public function add_hooks() {
|
28 |
-
|
29 |
-
add_action( 'init', [ $this, 'init' ], 9 );
|
30 |
-
add_filter( 'wcml_variation_term_taxonomy_ids', [ $this, 'wcml_variation_term_taxonomy_ids' ] );
|
31 |
-
add_filter( 'woocommerce_subscription_lengths', [ $this, 'woocommerce_subscription_lengths' ], 10, 2 );
|
32 |
-
|
33 |
-
add_filter( 'wcml_register_endpoints_query_vars', [ $this, 'register_endpoint' ], 10, 3 );
|
34 |
-
add_filter( 'wcml_endpoint_permalink_filter', [ $this, 'endpoint_permalink_filter' ], 10, 2 );
|
35 |
-
|
36 |
-
// Custom prices
|
37 |
-
add_filter( 'wcml_custom_prices_fields', [ $this, 'set_prices_fields' ], 10, 2 );
|
38 |
-
add_filter( 'wcml_custom_prices_strings', [ $this, 'set_labels_for_prices_fields' ], 10, 2 );
|
39 |
-
add_filter( 'wcml_custom_prices_fields_labels', [ $this, 'set_labels_for_prices_fields' ], 10, 2 );
|
40 |
-
add_filter( 'wcml_update_custom_prices_values', [ $this, 'update_custom_prices_values' ], 10, 3 );
|
41 |
-
add_action( 'wcml_after_custom_prices_block', [ $this, 'new_subscription_prices_block' ] );
|
42 |
-
|
43 |
-
add_action( 'woocommerce_subscriptions_product_options_pricing', [ $this, 'show_pointer_info' ] );
|
44 |
-
add_action( 'woocommerce_variable_subscription_pricing', [ $this, 'show_pointer_info' ] );
|
45 |
-
|
46 |
-
add_filter(
|
47 |
-
'woocommerce_subscriptions_product_price',
|
48 |
-
[
|
49 |
-
$this,
|
50 |
-
'woocommerce_subscription_price_from',
|
51 |
-
],
|
52 |
-
10,
|
53 |
-
2
|
54 |
-
);
|
55 |
-
|
56 |
-
add_filter( 'wcml_xliff_allowed_variations_types', [ $this, 'set_allowed_variations_types_in_xliff' ] );
|
57 |
-
|
58 |
-
// Add language links to email settings
|
59 |
-
add_filter( 'wcml_emails_options_to_translate', [ $this, 'translate_email_options' ] );
|
60 |
-
add_filter( 'wcml_emails_section_name_prefix', [ $this, 'email_option_section_prefix' ], 10, 2 );
|
61 |
-
}
|
62 |
-
|
63 |
-
public function init() {
|
64 |
-
if ( ! is_admin() ) {
|
65 |
-
add_filter(
|
66 |
-
'woocommerce_subscriptions_product_sign_up_fee',
|
67 |
-
[
|
68 |
-
$this,
|
69 |
-
'subscriptions_product_sign_up_fee_filter',
|
70 |
-
],
|
71 |
-
10,
|
72 |
-
2
|
73 |
-
);
|
74 |
-
|
75 |
-
add_action( 'woocommerce_before_calculate_totals', [ $this, 'maybe_backup_recurring_carts' ], 1 );
|
76 |
-
add_action( 'woocommerce_after_calculate_totals', [ $this, 'maybe_restore_recurring_carts' ], 200 );
|
77 |
-
|
78 |
-
$this->maybe_force_client_currency_for_subscription();
|
79 |
-
|
80 |
-
add_filter( 'wcs_get_subscription', [ $this, 'filter_subscription_items' ] );
|
81 |
-
}
|
82 |
-
|
83 |
-
// Translate emails
|
84 |
-
add_filter( 'woocommerce_generated_manual_renewal_order_renewal_notification', [ $this, 'translate_renewal_notification' ], 9 );
|
85 |
-
add_filter( 'woocommerce_order_status_failed_renewal_notification', [ $this, 'translate_renewal_notification' ], 9 );
|
86 |
-
|
87 |
-
add_filter( 'wcs_switch_proration_new_price_per_day', tap( [ $this, 'set_prorating_price' ] ) );
|
88 |
-
}
|
89 |
-
|
90 |
-
/**
|
91 |
-
* Set a flag when we are prorating the price (upgrades/downgrades).
|
92 |
-
* We do this to skip currency conversion in the sign_up_fee because
|
93 |
-
* when switching subscription it has already been converted.
|
94 |
-
*/
|
95 |
-
public function set_prorating_price() {
|
96 |
-
$this->prorating_price = true;
|
97 |
-
}
|
98 |
-
|
99 |
-
/**
|
100 |
-
* Filter Subscription Sign-up fee cost
|
101 |
-
*
|
102 |
-
* @param string $subscription_sign_up_fee
|
103 |
-
* @param WC_Product $product
|
104 |
-
* @return string
|
105 |
-
*/
|
106 |
-
public function subscriptions_product_sign_up_fee_filter( $subscription_sign_up_fee, $product ) {
|
107 |
-
|
108 |
-
if ( $product && wcml_is_multi_currency_on() && ! $this->prorating_price ) {
|
109 |
-
$currency = $this->woocommerce_wpml->multi_currency->get_client_currency();
|
110 |
-
|
111 |
-
if ( $currency !== wcml_get_woocommerce_currency_option() ) {
|
112 |
-
|
113 |
-
$product_id = $product->get_id();
|
114 |
-
if( $product instanceof WC_Product_Variable_Subscription ){
|
115 |
-
$product_id = $product->get_meta( '_min_price_variation_id', true );
|
116 |
-
}
|
117 |
-
|
118 |
-
$original_product_id = $this->woocommerce_wpml->products->get_original_product_id( $product_id );
|
119 |
-
|
120 |
-
if ( get_post_meta( $original_product_id, '_wcml_custom_prices_status', true ) ) {
|
121 |
-
$subscription_sign_up_fee = get_post_meta( $original_product_id, '_subscription_sign_up_fee_' . $currency, true );
|
122 |
-
} else {
|
123 |
-
$subscription_sign_up_fee = apply_filters( 'wcml_raw_price_amount', $subscription_sign_up_fee );
|
124 |
-
}
|
125 |
-
}
|
126 |
-
}
|
127 |
-
|
128 |
-
return $subscription_sign_up_fee;
|
129 |
-
}
|
130 |
-
|
131 |
-
public function wcml_variation_term_taxonomy_ids( $get_variation_term_taxonomy_ids ) {
|
132 |
-
|
133 |
-
$get_variation_term_taxonomy_id = $this->wpdb->get_var( "SELECT tt.term_taxonomy_id FROM {$this->wpdb->terms} AS t LEFT JOIN {$this->wpdb->term_taxonomy} AS tt ON t.term_id = tt.term_id WHERE t.slug = 'variable-subscription'" );
|
134 |
-
|
135 |
-
if ( ! empty( $get_variation_term_taxonomy_id ) ) {
|
136 |
-
$get_variation_term_taxonomy_ids[] = $get_variation_term_taxonomy_id;
|
137 |
-
}
|
138 |
-
|
139 |
-
return $get_variation_term_taxonomy_ids;
|
140 |
-
}
|
141 |
-
|
142 |
-
public function woocommerce_subscription_lengths( $subscription_ranges, $subscription_period ) {
|
143 |
-
|
144 |
-
if ( is_array( $subscription_ranges ) ) {
|
145 |
-
foreach ( $subscription_ranges as $period => $ranges ) {
|
146 |
-
if ( is_array( $ranges ) ) {
|
147 |
-
foreach ( $ranges as $range ) {
|
148 |
-
if ( $range == '9 months' ) {
|
149 |
-
$breakpoint = true;
|
150 |
-
}
|
151 |
-
$new_subscription_ranges[ $period ][] = apply_filters( 'wpml_translate_single_string', $range, 'wc_subscription_ranges', $range );
|
152 |
-
}
|
153 |
-
}
|
154 |
-
}
|
155 |
-
}
|
156 |
-
|
157 |
-
return isset( $new_subscription_ranges ) ? $new_subscription_ranges : $subscription_ranges;
|
158 |
-
}
|
159 |
-
|
160 |
-
public function set_prices_fields( $fields, $product_id ) {
|
161 |
-
if ( $this->is_subscriptions_product( $product_id ) || $this->new_subscription ) {
|
162 |
-
$fields[] = '_subscription_sign_up_fee';
|
163 |
-
}
|
164 |
-
|
165 |
-
return $fields;
|
166 |
-
|
167 |
-
}
|
168 |
-
|
169 |
-
public function set_labels_for_prices_fields( $labels, $product_id ) {
|
170 |
-
|
171 |
-
if ( $this->is_subscriptions_product( $product_id ) || $this->new_subscription ) {
|
172 |
-
$labels['_regular_price'] = __( 'Subscription Price', 'woocommerce-multilingual' );
|
173 |
-
$labels['_subscription_sign_up_fee'] = __( 'Sign-up Fee', 'woocommerce-multilingual' );
|
174 |
-
}
|
175 |
-
|
176 |
-
return $labels;
|
177 |
-
|
178 |
-
}
|
179 |
-
|
180 |
-
public function update_custom_prices_values( $prices, $code, $variation_id = false ) {
|
181 |
-
|
182 |
-
if ( isset( $_POST['_custom_subscription_sign_up_fee'][ $code ] ) ) {
|
183 |
-
$prices['_subscription_sign_up_fee'] = wc_format_decimal( $_POST['_custom_subscription_sign_up_fee'][ $code ] );
|
184 |
-
}
|
185 |
-
|
186 |
-
if ( $variation_id && isset( $_POST['_custom_variation_subscription_sign_up_fee'][ $code ][ $variation_id ] ) ) {
|
187 |
-
$prices['_subscription_sign_up_fee'] = wc_format_decimal( $_POST['_custom_variation_subscription_sign_up_fee'][ $code ][ $variation_id ] );
|
188 |
-
}
|
189 |
-
|
190 |
-
return $prices;
|
191 |
-
|
192 |
-
}
|
193 |
-
|
194 |
-
public function is_subscriptions_product( $product_id ) {
|
195 |
-
|
196 |
-
$get_variation_term_taxonomy_ids = $this->wpdb->get_col( "SELECT tt.term_taxonomy_id FROM {$this->wpdb->terms} AS t LEFT JOIN {$this->wpdb->term_taxonomy} AS tt ON t.term_id = tt.term_id WHERE t.slug IN ( 'subscription', 'variable-subscription' ) AND tt.taxonomy = 'product_type'" );
|
197 |
-
|
198 |
-
if ( get_post_type( $product_id ) == 'product_variation' ) {
|
199 |
-
$product_id = wp_get_post_parent_id( $product_id );
|
200 |
-
}
|
201 |
-
|
202 |
-
$is_subscriptions_product = $this->wpdb->get_var(
|
203 |
-
$this->wpdb->prepare(
|
204 |
-
"SELECT count(object_id) FROM {$this->wpdb->term_relationships}
|
205 |
-
WHERE object_id = %d AND term_taxonomy_id IN (" . wpml_prepare_in( $get_variation_term_taxonomy_ids, '%d' ) . ')',
|
206 |
-
$product_id
|
207 |
-
)
|
208 |
-
);
|
209 |
-
return $is_subscriptions_product;
|
210 |
-
}
|
211 |
-
|
212 |
-
public function new_subscription_prices_block( $product_id ) {
|
213 |
-
|
214 |
-
if ( $product_id == 'new' ) {
|
215 |
-
$this->new_subscription = true;
|
216 |
-
echo '<div class="wcml_prices_if_subscription" style="display: none">';
|
217 |
-
$custom_prices_ui = new WCML_Custom_Prices_UI( $this->woocommerce_wpml, 'new' );
|
218 |
-
$custom_prices_ui->show();
|
219 |
-
echo '</div>';
|
220 |
-
?>
|
221 |
-
<script>
|
222 |
-
jQuery(function($) {
|
223 |
-
jQuery('.wcml_prices_if_subscription .wcml_custom_prices_input').attr('name', '_wcml_custom_prices[new_subscription]').attr( 'id', '_wcml_custom_prices[new_subscription]');
|
224 |
-
jQuery('.wcml_prices_if_subscription .wcml_custom_prices_options_block>label').attr('for', '_wcml_custom_prices[new_subscription]');
|
225 |
-
jQuery('.wcml_prices_if_subscription .wcml_schedule_input').each( function(){
|
226 |
-
jQuery(this).attr('name', jQuery(this).attr('name')+'_subscription');
|
227 |
-
});
|
228 |
-
|
229 |
-
jQuery('.options_group>.wcml_custom_prices_block .wcml_custom_prices_input:first-child').click();
|
230 |
-
jQuery('.options_group>.wcml_custom_prices_block .wcml_schedule_options .wcml_schedule_input:first-child').click();
|
231 |
-
|
232 |
-
jQuery(document).on('change', 'select#product-type', function () {
|
233 |
-
if (jQuery(this).val() == 'subscription') {
|
234 |
-
jQuery('.wcml_prices_if_subscription').show();
|
235 |
-
jQuery('.options_group>.wcml_custom_prices_block').hide();
|
236 |
-
} else if (jQuery(this).val() != 'variable-subscription') {
|
237 |
-
jQuery('.wcml_prices_if_subscription').hide();
|
238 |
-
jQuery('.options_group>.wcml_custom_prices_block').show();
|
239 |
-
}
|
240 |
-
});
|
241 |
-
|
242 |
-
jQuery(document).on('click', '#publish', function () {
|
243 |
-
if ( jQuery('.wcml_prices_if_subscription').is( ':visible' ) ) {
|
244 |
-
jQuery('.options_group>.wcml_custom_prices_block').remove();
|
245 |
-
jQuery('.wcml_prices_if_subscription .wcml_custom_prices_input').attr('name', '_wcml_custom_prices[new]');
|
246 |
-
jQuery('.wcml_prices_if_subscription .wcml_schedule_input').each( function(){
|
247 |
-
jQuery(this).attr('name', jQuery(this).attr('name').replace('_subscription','') );
|
248 |
-
});
|
249 |
-
}else{
|
250 |
-
jQuery('.wcml_prices_if_subscription').remove();
|
251 |
-
}
|
252 |
-
});
|
253 |
-
});
|
254 |
-
</script>
|
255 |
-
<?php
|
256 |
-
}
|
257 |
-
}
|
258 |
-
|
259 |
-
public function register_endpoint( $query_vars, $wc_vars, $obj ) {
|
260 |
-
|
261 |
-
$query_vars['view-subscription'] = $obj->get_endpoint_translation( 'view-subscription', isset( $wc_vars['view-subscription'] ) ? $wc_vars['view-subscription'] : 'view-subscription' );
|
262 |
-
$query_vars['subscriptions'] = $obj->get_endpoint_translation( 'subscriptions', isset( $wc_vars['subscriptions'] ) ? $wc_vars['subscriptions'] : 'subscriptions' );
|
263 |
-
return $query_vars;
|
264 |
-
}
|
265 |
-
|
266 |
-
public function endpoint_permalink_filter( $endpoint, $key ) {
|
267 |
-
|
268 |
-
if ( $key == 'view-subscription' ) {
|
269 |
-
return 'view-subscription';
|
270 |
-
}
|
271 |
-
|
272 |
-
return $endpoint;
|
273 |
-
}
|
274 |
-
|
275 |
-
public function show_pointer_info() {
|
276 |
-
|
277 |
-
$pointer_ui = new WCML_Pointer_UI(
|
278 |
-
sprintf( __( 'You can translate strings related to subscription products on the %1$sWPML String Translation page%2$s. Use the search on the top of that page to find the strings.', 'woocommerce-multilingual' ), '<a href="' . admin_url( 'admin.php?page=' . WPML_ST_FOLDER . '/menu/string-translation.php&context=woocommerce_subscriptions' ) . '">', '</a>' ),
|
279 |
-
WCML_Tracking_Link::getWcmlSubscriptionsDoc(),
|
280 |
-
'general_product_data .subscription_pricing',
|
281 |
-
'prepend'
|
282 |
-
);
|
283 |
-
|
284 |
-
$pointer_ui->show();
|
285 |
-
}
|
286 |
-
|
287 |
-
/**
|
288 |
-
* @param WC_Cart $cart
|
289 |
-
*/
|
290 |
-
public function maybe_backup_recurring_carts( $cart ) {
|
291 |
-
if ( ! empty( $cart->recurring_carts ) ) {
|
292 |
-
$this->recurring_carts = $cart->recurring_carts;
|
293 |
-
}
|
294 |
-
}
|
295 |
-
|
296 |
-
/**
|
297 |
-
* @param WC_Cart $cart
|
298 |
-
*/
|
299 |
-
public function maybe_restore_recurring_carts( $cart ) {
|
300 |
-
if ( ! empty( $this->recurring_carts ) ) {
|
301 |
-
$cart->recurring_carts = $this->recurring_carts;
|
302 |
-
$this->recurring_carts = null;
|
303 |
-
}
|
304 |
-
}
|
305 |
-
|
306 |
-
/**
|
307 |
-
* @param string $price
|
308 |
-
* @param WC_Product|WC_Product_Subscription_Variation $product
|
309 |
-
*
|
310 |
-
* @return string
|
311 |
-
*/
|
312 |
-
public function woocommerce_subscription_price_from( $price, $product ) {
|
313 |
-
|
314 |
-
if ( $product && $product instanceof WC_Product_Subscription_Variation ) {
|
315 |
-
|
316 |
-
$custom_prices_on = get_post_meta( $product->get_id(), '_wcml_custom_prices_status', true );
|
317 |
-
if ( $custom_prices_on ) {
|
318 |
-
$client_currency = $this->woocommerce_wpml->multi_currency->get_client_currency();
|
319 |
-
|
320 |
-
$price = get_post_meta( $product->get_id(), '_price_' . $client_currency, true );
|
321 |
-
} else {
|
322 |
-
$price = apply_filters( 'wcml_raw_price_amount', $price );
|
323 |
-
}
|
324 |
-
}
|
325 |
-
|
326 |
-
return $price;
|
327 |
-
}
|
328 |
-
|
329 |
-
/**
|
330 |
-
* Force client currency for resubscribe subscription
|
331 |
-
*/
|
332 |
-
public function maybe_force_client_currency_for_subscription() {
|
333 |
-
|
334 |
-
if ( wcml_is_multi_currency_on() ) {
|
335 |
-
|
336 |
-
$subscription_id = false;
|
337 |
-
$getData = wpml_collect( $_GET );
|
338 |
-
|
339 |
-
if ( $getData->has( 'resubscribe' ) ) {
|
340 |
-
$subscription_id = (int) $getData->get( 'resubscribe' );
|
341 |
-
} elseif ( $getData->has( 'subscription_renewal_early' ) ) {
|
342 |
-
$subscription_id = (int) $getData->get( 'subscription_renewal_early' );
|
343 |
-
} elseif ( is_cart() || is_checkout() ) {
|
344 |
-
$resubscribe_cart_item = wcs_cart_contains_resubscribe();
|
345 |
-
if ( $resubscribe_cart_item ) {
|
346 |
-
$subscription_id = $resubscribe_cart_item['subscription_resubscribe']['subscription_id'];
|
347 |
-
} else {
|
348 |
-
$early_renewal_cart_item = wcs_cart_contains_early_renewal();
|
349 |
-
if ( $early_renewal_cart_item ) {
|
350 |
-
$subscription_id = $early_renewal_cart_item['subscription_renewal']['subscription_renewal_early'];
|
351 |
-
}
|
352 |
-
}
|
353 |
-
}
|
354 |
-
|
355 |
-
if ( $subscription_id ) {
|
356 |
-
$subscription_currency = get_post_meta( $subscription_id, '_order_currency', true );
|
357 |
-
if ( $subscription_currency && $this->woocommerce_wpml->multi_currency->get_client_currency() !== $subscription_currency ) {
|
358 |
-
$this->woocommerce_wpml->multi_currency->set_client_currency( $subscription_currency );
|
359 |
-
}
|
360 |
-
}
|
361 |
-
}
|
362 |
-
}
|
363 |
-
|
364 |
-
/**
|
365 |
-
* @param array $allowed_types
|
366 |
-
*
|
367 |
-
* @return array
|
368 |
-
*/
|
369 |
-
public function set_allowed_variations_types_in_xliff( $allowed_types ) {
|
370 |
-
|
371 |
-
$allowed_types[] = 'variable-subscription';
|
372 |
-
$allowed_types[] = 'subscription_variation';
|
373 |
-
|
374 |
-
return $allowed_types;
|
375 |
-
}
|
376 |
-
|
377 |
-
/**
|
378 |
-
* Translate strings of renewal notifications
|
379 |
-
*
|
380 |
-
* @param integer $order_id Order ID
|
381 |
-
*/
|
382 |
-
public function translate_renewal_notification( $order_id ) {
|
383 |
-
|
384 |
-
if ( isset( WC()->mailer()->emails['WCS_Email_Customer_Renewal_Invoice'] ) ) {
|
385 |
-
$this->woocommerce_wpml->emails->refresh_email_lang( $order_id );
|
386 |
-
|
387 |
-
$WCS_Email_Customer_Renewal_Invoice = WC()->mailer()->emails['WCS_Email_Customer_Renewal_Invoice'];
|
388 |
-
$WCS_Email_Customer_Renewal_Invoice->heading = __( $WCS_Email_Customer_Renewal_Invoice->heading, 'woocommerce-subscriptions' );
|
389 |
-
$WCS_Email_Customer_Renewal_Invoice->subject = __( $WCS_Email_Customer_Renewal_Invoice->subject, 'woocommerce-subscriptions' );
|
390 |
-
|
391 |
-
add_filter( 'woocommerce_email_get_option', [ $this, 'translate_heading_subject' ], 10, 4 );
|
392 |
-
}
|
393 |
-
}
|
394 |
-
|
395 |
-
/**
|
396 |
-
* Translate custom heading and subject for renewal notification
|
397 |
-
*
|
398 |
-
* @param string $return_value original string
|
399 |
-
* @param WCS_Email_Customer_Renewal_Invoice $obj Object of email class
|
400 |
-
* @param string $value Original value from setting
|
401 |
-
* @param string $key Name of the key
|
402 |
-
* @return string Translated value or original value incase of not translated
|
403 |
-
*/
|
404 |
-
public function translate_heading_subject( $return_value, $obj, $value, $key ) {
|
405 |
-
|
406 |
-
if ( $obj instanceof WCS_Email_Customer_Renewal_Invoice ) {
|
407 |
-
if ( $key == 'subject' || $key == 'heading' ) {
|
408 |
-
$translated_admin_string = $this->woocommerce_wpml->emails->getStringTranslation( 'admin_texts_woocommerce_customer_renewal_invoice_settings', '[woocommerce_customer_renewal_invoice_settings]' . $key );
|
409 |
-
return empty( $translated_admin_string ) ? $return_value : $translated_admin_string;
|
410 |
-
}
|
411 |
-
}
|
412 |
-
|
413 |
-
return $return_value;
|
414 |
-
}
|
415 |
-
|
416 |
-
/**
|
417 |
-
* Add customer renewal invoice option to translate
|
418 |
-
*
|
419 |
-
* @param array $emails_options list of option to translate
|
420 |
-
* @return array $emails_options
|
421 |
-
*/
|
422 |
-
public function translate_email_options( $emails_options ) {
|
423 |
-
|
424 |
-
if ( is_array( $emails_options ) ) {
|
425 |
-
$emails_options[] = 'woocommerce_customer_renewal_invoice_settings';
|
426 |
-
}
|
427 |
-
|
428 |
-
return $emails_options;
|
429 |
-
}
|
430 |
-
|
431 |
-
/**
|
432 |
-
* Change section name prefix to add language links
|
433 |
-
*
|
434 |
-
* @param string $section_prefix section prefix
|
435 |
-
* @param string $emails_option current option name
|
436 |
-
* @return string $section_prefix
|
437 |
-
*/
|
438 |
-
public function email_option_section_prefix( $section_prefix, $emails_option ) {
|
439 |
-
|
440 |
-
if ( $emails_option === 'woocommerce_customer_renewal_invoice_settings' ) {
|
441 |
-
return 'wcs_email_';
|
442 |
-
}
|
443 |
-
|
444 |
-
return $section_prefix;
|
445 |
-
}
|
446 |
-
|
447 |
-
/**
|
448 |
-
* @param mixed $subscription
|
449 |
-
*
|
450 |
-
* @return mixed
|
451 |
-
*/
|
452 |
-
public function filter_subscription_items( $subscription ) {
|
453 |
-
|
454 |
-
if ( $subscription instanceof WC_Subscription ) {
|
455 |
-
$this->woocommerce_wpml->orders->adjust_order_item_in_language( $subscription->get_items() );
|
456 |
-
}
|
457 |
-
|
458 |
-
return $subscription;
|
459 |
-
}
|
460 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
dist/css/homeScreen/styles.css
ADDED
@@ -0,0 +1 @@
|
|
|
1 |
+
.fade-enter,.fade-appear{-webkit-animation-duration:0.2s;animation-duration:0.2s;-webkit-animation-fill-mode:both;animation-fill-mode:both;-webkit-animation-play-state:paused;animation-play-state:paused}.fade-leave{-webkit-animation-duration:0.2s;animation-duration:0.2s;-webkit-animation-fill-mode:both;animation-fill-mode:both;-webkit-animation-play-state:paused;animation-play-state:paused}.fade-enter.fade-enter-active,.fade-appear.fade-appear-active{-webkit-animation-name:antFadeIn;animation-name:antFadeIn;-webkit-animation-play-state:running;animation-play-state:running}.fade-leave.fade-leave-active{-webkit-animation-name:antFadeOut;animation-name:antFadeOut;-webkit-animation-play-state:running;animation-play-state:running;pointer-events:none}.fade-enter,.fade-appear{opacity:0;-webkit-animation-timing-function:linear;animation-timing-function:linear}.fade-leave{-webkit-animation-timing-function:linear;animation-timing-function:linear}@-webkit-keyframes antFadeIn{0%{opacity:0}100%{opacity:1}}@keyframes antFadeIn{0%{opacity:0}100%{opacity:1}}@-webkit-keyframes antFadeOut{0%{opacity:1}100%{opacity:0}}@keyframes antFadeOut{0%{opacity:1}100%{opacity:0}}.move-up-enter,.move-up-appear{-webkit-animation-duration:0.2s;animation-duration:0.2s;-webkit-animation-fill-mode:both;animation-fill-mode:both;-webkit-animation-play-state:paused;animation-play-state:paused}.move-up-leave{-webkit-animation-duration:0.2s;animation-duration:0.2s;-webkit-animation-fill-mode:both;animation-fill-mode:both;-webkit-animation-play-state:paused;animation-play-state:paused}.move-up-enter.move-up-enter-active,.move-up-appear.move-up-appear-active{-webkit-animation-name:antMoveUpIn;animation-name:antMoveUpIn;-webkit-animation-play-state:running;animation-play-state:running}.move-up-leave.move-up-leave-active{-webkit-animation-name:antMoveUpOut;animation-name:antMoveUpOut;-webkit-animation-play-state:running;animation-play-state:running;pointer-events:none}.move-up-enter,.move-up-appear{opacity:0;-webkit-animation-timing-function:cubic-bezier(0.08, 0.82, 0.17, 1);animation-timing-function:cubic-bezier(0.08, 0.82, 0.17, 1)}.move-up-leave{-webkit-animation-timing-function:cubic-bezier(0.6, 0.04, 0.98, 0.34);animation-timing-function:cubic-bezier(0.6, 0.04, 0.98, 0.34)}.move-down-enter,.move-down-appear{-webkit-animation-duration:0.2s;animation-duration:0.2s;-webkit-animation-fill-mode:both;animation-fill-mode:both;-webkit-animation-play-state:paused;animation-play-state:paused}.move-down-leave{-webkit-animation-duration:0.2s;animation-duration:0.2s;-webkit-animation-fill-mode:both;animation-fill-mode:both;-webkit-animation-play-state:paused;animation-play-state:paused}.move-down-enter.move-down-enter-active,.move-down-appear.move-down-appear-active{-webkit-animation-name:antMoveDownIn;animation-name:antMoveDownIn;-webkit-animation-play-state:running;animation-play-state:running}.move-down-leave.move-down-leave-active{-webkit-animation-name:antMoveDownOut;animation-name:antMoveDownOut;-webkit-animation-play-state:running;animation-play-state:running;pointer-events:none}.move-down-enter,.move-down-appear{opacity:0;-webkit-animation-timing-function:cubic-bezier(0.08, 0.82, 0.17, 1);animation-timing-function:cubic-bezier(0.08, 0.82, 0.17, 1)}.move-down-leave{-webkit-animation-timing-function:cubic-bezier(0.6, 0.04, 0.98, 0.34);animation-timing-function:cubic-bezier(0.6, 0.04, 0.98, 0.34)}.move-left-enter,.move-left-appear{-webkit-animation-duration:0.2s;animation-duration:0.2s;-webkit-animation-fill-mode:both;animation-fill-mode:both;-webkit-animation-play-state:paused;animation-play-state:paused}.move-left-leave{-webkit-animation-duration:0.2s;animation-duration:0.2s;-webkit-animation-fill-mode:both;animation-fill-mode:both;-webkit-animation-play-state:paused;animation-play-state:paused}.move-left-enter.move-left-enter-active,.move-left-appear.move-left-appear-active{-webkit-animation-name:antMoveLeftIn;animation-name:antMoveLeftIn;-webkit-animation-play-state:running;animation-play-state:running}.move-left-leave.move-left-leave-active{-webkit-animation-name:antMoveLeftOut;animation-name:antMoveLeftOut;-webkit-animation-play-state:running;animation-play-state:running;pointer-events:none}.move-left-enter,.move-left-appear{opacity:0;-webkit-animation-timing-function:cubic-bezier(0.08, 0.82, 0.17, 1);animation-timing-function:cubic-bezier(0.08, 0.82, 0.17, 1)}.move-left-leave{-webkit-animation-timing-function:cubic-bezier(0.6, 0.04, 0.98, 0.34);animation-timing-function:cubic-bezier(0.6, 0.04, 0.98, 0.34)}.move-right-enter,.move-right-appear{-webkit-animation-duration:0.2s;animation-duration:0.2s;-webkit-animation-fill-mode:both;animation-fill-mode:both;-webkit-animation-play-state:paused;animation-play-state:paused}.move-right-leave{-webkit-animation-duration:0.2s;animation-duration:0.2s;-webkit-animation-fill-mode:both;animation-fill-mode:both;-webkit-animation-play-state:paused;animation-play-state:paused}.move-right-enter.move-right-enter-active,.move-right-appear.move-right-appear-active{-webkit-animation-name:antMoveRightIn;animation-name:antMoveRightIn;-webkit-animation-play-state:running;animation-play-state:running}.move-right-leave.move-right-leave-active{-webkit-animation-name:antMoveRightOut;animation-name:antMoveRightOut;-webkit-animation-play-state:running;animation-play-state:running;pointer-events:none}.move-right-enter,.move-right-appear{opacity:0;-webkit-animation-timing-function:cubic-bezier(0.08, 0.82, 0.17, 1);animation-timing-function:cubic-bezier(0.08, 0.82, 0.17, 1)}.move-right-leave{-webkit-animation-timing-function:cubic-bezier(0.6, 0.04, 0.98, 0.34);animation-timing-function:cubic-bezier(0.6, 0.04, 0.98, 0.34)}@-webkit-keyframes antMoveDownIn{0%{-webkit-transform:translateY(100%);transform:translateY(100%);-webkit-transform-origin:0 0;transform-origin:0 0;opacity:0}100%{-webkit-transform:translateY(0%);transform:translateY(0%);-webkit-transform-origin:0 0;transform-origin:0 0;opacity:1}}@keyframes antMoveDownIn{0%{-webkit-transform:translateY(100%);transform:translateY(100%);-webkit-transform-origin:0 0;transform-origin:0 0;opacity:0}100%{-webkit-transform:translateY(0%);transform:translateY(0%);-webkit-transform-origin:0 0;transform-origin:0 0;opacity:1}}@-webkit-keyframes antMoveDownOut{0%{-webkit-transform:translateY(0%);transform:translateY(0%);-webkit-transform-origin:0 0;transform-origin:0 0;opacity:1}100%{-webkit-transform:translateY(100%);transform:translateY(100%);-webkit-transform-origin:0 0;transform-origin:0 0;opacity:0}}@keyframes antMoveDownOut{0%{-webkit-transform:translateY(0%);transform:translateY(0%);-webkit-transform-origin:0 0;transform-origin:0 0;opacity:1}100%{-webkit-transform:translateY(100%);transform:translateY(100%);-webkit-transform-origin:0 0;transform-origin:0 0;opacity:0}}@-webkit-keyframes antMoveLeftIn{0%{-webkit-transform:translateX(-100%);transform:translateX(-100%);-webkit-transform-origin:0 0;transform-origin:0 0;opacity:0}100%{-webkit-transform:translateX(0%);transform:translateX(0%);-webkit-transform-origin:0 0;transform-origin:0 0;opacity:1}}@keyframes antMoveLeftIn{0%{-webkit-transform:translateX(-100%);transform:translateX(-100%);-webkit-transform-origin:0 0;transform-origin:0 0;opacity:0}100%{-webkit-transform:translateX(0%);transform:translateX(0%);-webkit-transform-origin:0 0;transform-origin:0 0;opacity:1}}@-webkit-keyframes antMoveLeftOut{0%{-webkit-transform:translateX(0%);transform:translateX(0%);-webkit-transform-origin:0 0;transform-origin:0 0;opacity:1}100%{-webkit-transform:translateX(-100%);transform:translateX(-100%);-webkit-transform-origin:0 0;transform-origin:0 0;opacity:0}}@keyframes antMoveLeftOut{0%{-webkit-transform:translateX(0%);transform:translateX(0%);-webkit-transform-origin:0 0;transform-origin:0 0;opacity:1}100%{-webkit-transform:translateX(-100%);transform:translateX(-100%);-webkit-transform-origin:0 0;transform-origin:0 0;opacity:0}}@-webkit-keyframes antMoveRightIn{0%{-webkit-transform:translateX(100%);transform:translateX(100%);-webkit-transform-origin:0 0;transform-origin:0 0;opacity:0}100%{-webkit-transform:translateX(0%);transform:translateX(0%);-webkit-transform-origin:0 0;transform-origin:0 0;opacity:1}}@keyframes antMoveRightIn{0%{-webkit-transform:translateX(100%);transform:translateX(100%);-webkit-transform-origin:0 0;transform-origin:0 0;opacity:0}100%{-webkit-transform:translateX(0%);transform:translateX(0%);-webkit-transform-origin:0 0;transform-origin:0 0;opacity:1}}@-webkit-keyframes antMoveRightOut{0%{-webkit-transform:translateX(0%);transform:translateX(0%);-webkit-transform-origin:0 0;transform-origin:0 0;opacity:1}100%{-webkit-transform:translateX(100%);transform:translateX(100%);-webkit-transform-origin:0 0;transform-origin:0 0;opacity:0}}@keyframes antMoveRightOut{0%{-webkit-transform:translateX(0%);transform:translateX(0%);-webkit-transform-origin:0 0;transform-origin:0 0;opacity:1}100%{-webkit-transform:translateX(100%);transform:translateX(100%);-webkit-transform-origin:0 0;transform-origin:0 0;opacity:0}}@-webkit-keyframes antMoveUpIn{0%{-webkit-transform:translateY(-100%);transform:translateY(-100%);-webkit-transform-origin:0 0;transform-origin:0 0;opacity:0}100%{-webkit-transform:translateY(0%);transform:translateY(0%);-webkit-transform-origin:0 0;transform-origin:0 0;opacity:1}}@keyframes antMoveUpIn{0%{-webkit-transform:translateY(-100%);transform:translateY(-100%);-webkit-transform-origin:0 0;transform-origin:0 0;opacity:0}100%{-webkit-transform:translateY(0%);transform:translateY(0%);-webkit-transform-origin:0 0;transform-origin:0 0;opacity:1}}@-webkit-keyframes antMoveUpOut{0%{-webkit-transform:translateY(0%);transform:translateY(0%);-webkit-transform-origin:0 0;transform-origin:0 0;opacity:1}100%{-webkit-transform:translateY(-100%);transform:translateY(-100%);-webkit-transform-origin:0 0;transform-origin:0 0;opacity:0}}@keyframes antMoveUpOut{0%{-webkit-transform:translateY(0%);transform:translateY(0%);-webkit-transform-origin:0 0;transform-origin:0 0;opacity:1}100%{-webkit-transform:translateY(-100%);transform:translateY(-100%);-webkit-transform-origin:0 0;transform-origin:0 0;opacity:0}}@-webkit-keyframes loadingCircle{100%{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}@keyframes loadingCircle{100%{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}[ant-click-animating='true'],[ant-click-animating-without-extra-node='true']{position:relative}html{--antd-wave-shadow-color: #1890ff;--scroll-bar: 0}[ant-click-animating-without-extra-node='true']::after,.ant-click-animating-node{position:absolute;top:0;right:0;bottom:0;left:0;display:block;border-radius:inherit;box-shadow:0 0 0 0 #1890ff;box-shadow:0 0 0 0 var(--antd-wave-shadow-color);opacity:0.2;-webkit-animation:fadeEffect 2s cubic-bezier(0.08, 0.82, 0.17, 1),waveEffect 0.4s cubic-bezier(0.08, 0.82, 0.17, 1);animation:fadeEffect 2s cubic-bezier(0.08, 0.82, 0.17, 1),waveEffect 0.4s cubic-bezier(0.08, 0.82, 0.17, 1);-webkit-animation-fill-mode:forwards;animation-fill-mode:forwards;content:'';pointer-events:none}@-webkit-keyframes waveEffect{100%{box-shadow:0 0 0 #1890ff;box-shadow:0 0 0 6px var(--antd-wave-shadow-color)}}@keyframes waveEffect{100%{box-shadow:0 0 0 #1890ff;box-shadow:0 0 0 6px var(--antd-wave-shadow-color)}}@-webkit-keyframes fadeEffect{100%{opacity:0}}@keyframes fadeEffect{100%{opacity:0}}.slide-up-enter,.slide-up-appear{-webkit-animation-duration:0.2s;animation-duration:0.2s;-webkit-animation-fill-mode:both;animation-fill-mode:both;-webkit-animation-play-state:paused;animation-play-state:paused}.slide-up-leave{-webkit-animation-duration:0.2s;animation-duration:0.2s;-webkit-animation-fill-mode:both;animation-fill-mode:both;-webkit-animation-play-state:paused;animation-play-state:paused}.slide-up-enter.slide-up-enter-active,.slide-up-appear.slide-up-appear-active{-webkit-animation-name:antSlideUpIn;animation-name:antSlideUpIn;-webkit-animation-play-state:running;animation-play-state:running}.slide-up-leave.slide-up-leave-active{-webkit-animation-name:antSlideUpOut;animation-name:antSlideUpOut;-webkit-animation-play-state:running;animation-play-state:running;pointer-events:none}.slide-up-enter,.slide-up-appear{opacity:0;-webkit-animation-timing-function:cubic-bezier(0.23, 1, 0.32, 1);animation-timing-function:cubic-bezier(0.23, 1, 0.32, 1)}.slide-up-leave{-webkit-animation-timing-function:cubic-bezier(0.755, 0.05, 0.855, 0.06);animation-timing-function:cubic-bezier(0.755, 0.05, 0.855, 0.06)}.slide-down-enter,.slide-down-appear{-webkit-animation-duration:0.2s;animation-duration:0.2s;-webkit-animation-fill-mode:both;animation-fill-mode:both;-webkit-animation-play-state:paused;animation-play-state:paused}.slide-down-leave{-webkit-animation-duration:0.2s;animation-duration:0.2s;-webkit-animation-fill-mode:both;animation-fill-mode:both;-webkit-animation-play-state:paused;animation-play-state:paused}.slide-down-enter.slide-down-enter-active,.slide-down-appear.slide-down-appear-active{-webkit-animation-name:antSlideDownIn;animation-name:antSlideDownIn;-webkit-animation-play-state:running;animation-play-state:running}.slide-down-leave.slide-down-leave-active{-webkit-animation-name:antSlideDownOut;animation-name:antSlideDownOut;-webkit-animation-play-state:running;animation-play-state:running;pointer-events:none}.slide-down-enter,.slide-down-appear{opacity:0;-webkit-animation-timing-function:cubic-bezier(0.23, 1, 0.32, 1);animation-timing-function:cubic-bezier(0.23, 1, 0.32, 1)}.slide-down-leave{-webkit-animation-timing-function:cubic-bezier(0.755, 0.05, 0.855, 0.06);animation-timing-function:cubic-bezier(0.755, 0.05, 0.855, 0.06)}.slide-left-enter,.slide-left-appear{-webkit-animation-duration:0.2s;animation-duration:0.2s;-webkit-animation-fill-mode:both;animation-fill-mode:both;-webkit-animation-play-state:paused;animation-play-state:paused}.slide-left-leave{-webkit-animation-duration:0.2s;animation-duration:0.2s;-webkit-animation-fill-mode:both;animation-fill-mode:both;-webkit-animation-play-state:paused;animation-play-state:paused}.slide-left-enter.slide-left-enter-active,.slide-left-appear.slide-left-appear-active{-webkit-animation-name:antSlideLeftIn;animation-name:antSlideLeftIn;-webkit-animation-play-state:running;animation-play-state:running}.slide-left-leave.slide-left-leave-active{-webkit-animation-name:antSlideLeftOut;animation-name:antSlideLeftOut;-webkit-animation-play-state:running;animation-play-state:running;pointer-events:none}.slide-left-enter,.slide-left-appear{opacity:0;-webkit-animation-timing-function:cubic-bezier(0.23, 1, 0.32, 1);animation-timing-function:cubic-bezier(0.23, 1, 0.32, 1)}.slide-left-leave{-webkit-animation-timing-function:cubic-bezier(0.755, 0.05, 0.855, 0.06);animation-timing-function:cubic-bezier(0.755, 0.05, 0.855, 0.06)}.slide-right-enter,.slide-right-appear{-webkit-animation-duration:0.2s;animation-duration:0.2s;-webkit-animation-fill-mode:both;animation-fill-mode:both;-webkit-animation-play-state:paused;animation-play-state:paused}.slide-right-leave{-webkit-animation-duration:0.2s;animation-duration:0.2s;-webkit-animation-fill-mode:both;animation-fill-mode:both;-webkit-animation-play-state:paused;animation-play-state:paused}.slide-right-enter.slide-right-enter-active,.slide-right-appear.slide-right-appear-active{-webkit-animation-name:antSlideRightIn;animation-name:antSlideRightIn;-webkit-animation-play-state:running;animation-play-state:running}.slide-right-leave.slide-right-leave-active{-webkit-animation-name:antSlideRightOut;animation-name:antSlideRightOut;-webkit-animation-play-state:running;animation-play-state:running;pointer-events:none}.slide-right-enter,.slide-right-appear{opacity:0;-webkit-animation-timing-function:cubic-bezier(0.23, 1, 0.32, 1);animation-timing-function:cubic-bezier(0.23, 1, 0.32, 1)}.slide-right-leave{-webkit-animation-timing-function:cubic-bezier(0.755, 0.05, 0.855, 0.06);animation-timing-function:cubic-bezier(0.755, 0.05, 0.855, 0.06)}@-webkit-keyframes antSlideUpIn{0%{-webkit-transform:scaleY(0.8);transform:scaleY(0.8);-webkit-transform-origin:0% 0%;transform-origin:0% 0%;opacity:0}100%{-webkit-transform:scaleY(1);transform:scaleY(1);-webkit-transform-origin:0% 0%;transform-origin:0% 0%;opacity:1}}@keyframes antSlideUpIn{0%{-webkit-transform:scaleY(0.8);transform:scaleY(0.8);-webkit-transform-origin:0% 0%;transform-origin:0% 0%;opacity:0}100%{-webkit-transform:scaleY(1);transform:scaleY(1);-webkit-transform-origin:0% 0%;transform-origin:0% 0%;opacity:1}}@-webkit-keyframes antSlideUpOut{0%{-webkit-transform:scaleY(1);transform:scaleY(1);-webkit-transform-origin:0% 0%;transform-origin:0% 0%;opacity:1}100%{-webkit-transform:scaleY(0.8);transform:scaleY(0.8);-webkit-transform-origin:0% 0%;transform-origin:0% 0%;opacity:0}}@keyframes antSlideUpOut{0%{-webkit-transform:scaleY(1);transform:scaleY(1);-webkit-transform-origin:0% 0%;transform-origin:0% 0%;opacity:1}100%{-webkit-transform:scaleY(0.8);transform:scaleY(0.8);-webkit-transform-origin:0% 0%;transform-origin:0% 0%;opacity:0}}@-webkit-keyframes antSlideDownIn{0%{-webkit-transform:scaleY(0.8);transform:scaleY(0.8);-webkit-transform-origin:100% 100%;transform-origin:100% 100%;opacity:0}100%{-webkit-transform:scaleY(1);transform:scaleY(1);-webkit-transform-origin:100% 100%;transform-origin:100% 100%;opacity:1}}@keyframes antSlideDownIn{0%{-webkit-transform:scaleY(0.8);transform:scaleY(0.8);-webkit-transform-origin:100% 100%;transform-origin:100% 100%;opacity:0}100%{-webkit-transform:scaleY(1);transform:scaleY(1);-webkit-transform-origin:100% 100%;transform-origin:100% 100%;opacity:1}}@-webkit-keyframes antSlideDownOut{0%{-webkit-transform:scaleY(1);transform:scaleY(1);-webkit-transform-origin:100% 100%;transform-origin:100% 100%;opacity:1}100%{-webkit-transform:scaleY(0.8);transform:scaleY(0.8);-webkit-transform-origin:100% 100%;transform-origin:100% 100%;opacity:0}}@keyframes antSlideDownOut{0%{-webkit-transform:scaleY(1);transform:scaleY(1);-webkit-transform-origin:100% 100%;transform-origin:100% 100%;opacity:1}100%{-webkit-transform:scaleY(0.8);transform:scaleY(0.8);-webkit-transform-origin:100% 100%;transform-origin:100% 100%;opacity:0}}@-webkit-keyframes antSlideLeftIn{0%{-webkit-transform:scaleX(0.8);transform:scaleX(0.8);-webkit-transform-origin:0% 0%;transform-origin:0% 0%;opacity:0}100%{-webkit-transform:scaleX(1);transform:scaleX(1);-webkit-transform-origin:0% 0%;transform-origin:0% 0%;opacity:1}}@keyframes antSlideLeftIn{0%{-webkit-transform:scaleX(0.8);transform:scaleX(0.8);-webkit-transform-origin:0% 0%;transform-origin:0% 0%;opacity:0}100%{-webkit-transform:scaleX(1);transform:scaleX(1);-webkit-transform-origin:0% 0%;transform-origin:0% 0%;opacity:1}}@-webkit-keyframes antSlideLeftOut{0%{-webkit-transform:scaleX(1);transform:scaleX(1);-webkit-transform-origin:0% 0%;transform-origin:0% 0%;opacity:1}100%{-webkit-transform:scaleX(0.8);transform:scaleX(0.8);-webkit-transform-origin:0% 0%;transform-origin:0% 0%;opacity:0}}@keyframes antSlideLeftOut{0%{-webkit-transform:scaleX(1);transform:scaleX(1);-webkit-transform-origin:0% 0%;transform-origin:0% 0%;opacity:1}100%{-webkit-transform:scaleX(0.8);transform:scaleX(0.8);-webkit-transform-origin:0% 0%;transform-origin:0% 0%;opacity:0}}@-webkit-keyframes antSlideRightIn{0%{-webkit-transform:scaleX(0.8);transform:scaleX(0.8);-webkit-transform-origin:100% 0%;transform-origin:100% 0%;opacity:0}100%{-webkit-transform:scaleX(1);transform:scaleX(1);-webkit-transform-origin:100% 0%;transform-origin:100% 0%;opacity:1}}@keyframes antSlideRightIn{0%{-webkit-transform:scaleX(0.8);transform:scaleX(0.8);-webkit-transform-origin:100% 0%;transform-origin:100% 0%;opacity:0}100%{-webkit-transform:scaleX(1);transform:scaleX(1);-webkit-transform-origin:100% 0%;transform-origin:100% 0%;opacity:1}}@-webkit-keyframes antSlideRightOut{0%{-webkit-transform:scaleX(1);transform:scaleX(1);-webkit-transform-origin:100% 0%;transform-origin:100% 0%;opacity:1}100%{-webkit-transform:scaleX(0.8);transform:scaleX(0.8);-webkit-transform-origin:100% 0%;transform-origin:100% 0%;opacity:0}}@keyframes antSlideRightOut{0%{-webkit-transform:scaleX(1);transform:scaleX(1);-webkit-transform-origin:100% 0%;transform-origin:100% 0%;opacity:1}100%{-webkit-transform:scaleX(0.8);transform:scaleX(0.8);-webkit-transform-origin:100% 0%;transform-origin:100% 0%;opacity:0}}.zoom-enter,.zoom-appear{-webkit-animation-duration:0.2s;animation-duration:0.2s;-webkit-animation-fill-mode:both;animation-fill-mode:both;-webkit-animation-play-state:paused;animation-play-state:paused}.zoom-leave{-webkit-animation-duration:0.2s;animation-duration:0.2s;-webkit-animation-fill-mode:both;animation-fill-mode:both;-webkit-animation-play-state:paused;animation-play-state:paused}.zoom-enter.zoom-enter-active,.zoom-appear.zoom-appear-active{-webkit-animation-name:antZoomIn;animation-name:antZoomIn;-webkit-animation-play-state:running;animation-play-state:running}.zoom-leave.zoom-leave-active{-webkit-animation-name:antZoomOut;animation-name:antZoomOut;-webkit-animation-play-state:running;animation-play-state:running;pointer-events:none}.zoom-enter,.zoom-appear{-webkit-transform:scale(0);transform:scale(0);opacity:0;-webkit-animation-timing-function:cubic-bezier(0.08, 0.82, 0.17, 1);animation-timing-function:cubic-bezier(0.08, 0.82, 0.17, 1)}.zoom-leave{-webkit-animation-timing-function:cubic-bezier(0.78, 0.14, 0.15, 0.86);animation-timing-function:cubic-bezier(0.78, 0.14, 0.15, 0.86)}.zoom-big-enter,.zoom-big-appear{-webkit-animation-duration:0.2s;animation-duration:0.2s;-webkit-animation-fill-mode:both;animation-fill-mode:both;-webkit-animation-play-state:paused;animation-play-state:paused}.zoom-big-leave{-webkit-animation-duration:0.2s;animation-duration:0.2s;-webkit-animation-fill-mode:both;animation-fill-mode:both;-webkit-animation-play-state:paused;animation-play-state:paused}.zoom-big-enter.zoom-big-enter-active,.zoom-big-appear.zoom-big-appear-active{-webkit-animation-name:antZoomBigIn;animation-name:antZoomBigIn;-webkit-animation-play-state:running;animation-play-state:running}.zoom-big-leave.zoom-big-leave-active{-webkit-animation-name:antZoomBigOut;animation-name:antZoomBigOut;-webkit-animation-play-state:running;animation-play-state:running;pointer-events:none}.zoom-big-enter,.zoom-big-appear{-webkit-transform:scale(0);transform:scale(0);opacity:0;-webkit-animation-timing-function:cubic-bezier(0.08, 0.82, 0.17, 1);animation-timing-function:cubic-bezier(0.08, 0.82, 0.17, 1)}.zoom-big-leave{-webkit-animation-timing-function:cubic-bezier(0.78, 0.14, 0.15, 0.86);animation-timing-function:cubic-bezier(0.78, 0.14, 0.15, 0.86)}.zoom-big-fast-enter,.zoom-big-fast-appear{-webkit-animation-duration:0.1s;animation-duration:0.1s;-webkit-animation-fill-mode:both;animation-fill-mode:both;-webkit-animation-play-state:paused;animation-play-state:paused}.zoom-big-fast-leave{-webkit-animation-duration:0.1s;animation-duration:0.1s;-webkit-animation-fill-mode:both;animation-fill-mode:both;-webkit-animation-play-state:paused;animation-play-state:paused}.zoom-big-fast-enter.zoom-big-fast-enter-active,.zoom-big-fast-appear.zoom-big-fast-appear-active{-webkit-animation-name:antZoomBigIn;animation-name:antZoomBigIn;-webkit-animation-play-state:running;animation-play-state:running}.zoom-big-fast-leave.zoom-big-fast-leave-active{-webkit-animation-name:antZoomBigOut;animation-name:antZoomBigOut;-webkit-animation-play-state:running;animation-play-state:running;pointer-events:none}.zoom-big-fast-enter,.zoom-big-fast-appear{-webkit-transform:scale(0);transform:scale(0);opacity:0;-webkit-animation-timing-function:cubic-bezier(0.08, 0.82, 0.17, 1);animation-timing-function:cubic-bezier(0.08, 0.82, 0.17, 1)}.zoom-big-fast-leave{-webkit-animation-timing-function:cubic-bezier(0.78, 0.14, 0.15, 0.86);animation-timing-function:cubic-bezier(0.78, 0.14, 0.15, 0.86)}.zoom-up-enter,.zoom-up-appear{-webkit-animation-duration:0.2s;animation-duration:0.2s;-webkit-animation-fill-mode:both;animation-fill-mode:both;-webkit-animation-play-state:paused;animation-play-state:paused}.zoom-up-leave{-webkit-animation-duration:0.2s;animation-duration:0.2s;-webkit-animation-fill-mode:both;animation-fill-mode:both;-webkit-animation-play-state:paused;animation-play-state:paused}.zoom-up-enter.zoom-up-enter-active,.zoom-up-appear.zoom-up-appear-active{-webkit-animation-name:antZoomUpIn;animation-name:antZoomUpIn;-webkit-animation-play-state:running;animation-play-state:running}.zoom-up-leave.zoom-up-leave-active{-webkit-animation-name:antZoomUpOut;animation-name:antZoomUpOut;-webkit-animation-play-state:running;animation-play-state:running;pointer-events:none}.zoom-up-enter,.zoom-up-appear{-webkit-transform:scale(0);transform:scale(0);opacity:0;-webkit-animation-timing-function:cubic-bezier(0.08, 0.82, 0.17, 1);animation-timing-function:cubic-bezier(0.08, 0.82, 0.17, 1)}.zoom-up-leave{-webkit-animation-timing-function:cubic-bezier(0.78, 0.14, 0.15, 0.86);animation-timing-function:cubic-bezier(0.78, 0.14, 0.15, 0.86)}.zoom-down-enter,.zoom-down-appear{-webkit-animation-duration:0.2s;animation-duration:0.2s;-webkit-animation-fill-mode:both;animation-fill-mode:both;-webkit-animation-play-state:paused;animation-play-state:paused}.zoom-down-leave{-webkit-animation-duration:0.2s;animation-duration:0.2s;-webkit-animation-fill-mode:both;animation-fill-mode:both;-webkit-animation-play-state:paused;animation-play-state:paused}.zoom-down-enter.zoom-down-enter-active,.zoom-down-appear.zoom-down-appear-active{-webkit-animation-name:antZoomDownIn;animation-name:antZoomDownIn;-webkit-animation-play-state:running;animation-play-state:running}.zoom-down-leave.zoom-down-leave-active{-webkit-animation-name:antZoomDownOut;animation-name:antZoomDownOut;-webkit-animation-play-state:running;animation-play-state:running;pointer-events:none}.zoom-down-enter,.zoom-down-appear{-webkit-transform:scale(0);transform:scale(0);opacity:0;-webkit-animation-timing-function:cubic-bezier(0.08, 0.82, 0.17, 1);animation-timing-function:cubic-bezier(0.08, 0.82, 0.17, 1)}.zoom-down-leave{-webkit-animation-timing-function:cubic-bezier(0.78, 0.14, 0.15, 0.86);animation-timing-function:cubic-bezier(0.78, 0.14, 0.15, 0.86)}.zoom-left-enter,.zoom-left-appear{-webkit-animation-duration:0.2s;animation-duration:0.2s;-webkit-animation-fill-mode:both;animation-fill-mode:both;-webkit-animation-play-state:paused;animation-play-state:paused}.zoom-left-leave{-webkit-animation-duration:0.2s;animation-duration:0.2s;-webkit-animation-fill-mode:both;animation-fill-mode:both;-webkit-animation-play-state:paused;animation-play-state:paused}.zoom-left-enter.zoom-left-enter-active,.zoom-left-appear.zoom-left-appear-active{-webkit-animation-name:antZoomLeftIn;animation-name:antZoomLeftIn;-webkit-animation-play-state:running;animation-play-state:running}.zoom-left-leave.zoom-left-leave-active{-webkit-animation-name:antZoomLeftOut;animation-name:antZoomLeftOut;-webkit-animation-play-state:running;animation-play-state:running;pointer-events:none}.zoom-left-enter,.zoom-left-appear{-webkit-transform:scale(0);transform:scale(0);opacity:0;-webkit-animation-timing-function:cubic-bezier(0.08, 0.82, 0.17, 1);animation-timing-function:cubic-bezier(0.08, 0.82, 0.17, 1)}.zoom-left-leave{-webkit-animation-timing-function:cubic-bezier(0.78, 0.14, 0.15, 0.86);animation-timing-function:cubic-bezier(0.78, 0.14, 0.15, 0.86)}.zoom-right-enter,.zoom-right-appear{-webkit-animation-duration:0.2s;animation-duration:0.2s;-webkit-animation-fill-mode:both;animation-fill-mode:both;-webkit-animation-play-state:paused;animation-play-state:paused}.zoom-right-leave{-webkit-animation-duration:0.2s;animation-duration:0.2s;-webkit-animation-fill-mode:both;animation-fill-mode:both;-webkit-animation-play-state:paused;animation-play-state:paused}.zoom-right-enter.zoom-right-enter-active,.zoom-right-appear.zoom-right-appear-active{-webkit-animation-name:antZoomRightIn;animation-name:antZoomRightIn;-webkit-animation-play-state:running;animation-play-state:running}.zoom-right-leave.zoom-right-leave-active{-webkit-animation-name:antZoomRightOut;animation-name:antZoomRightOut;-webkit-animation-play-state:running;animation-play-state:running;pointer-events:none}.zoom-right-enter,.zoom-right-appear{-webkit-transform:scale(0);transform:scale(0);opacity:0;-webkit-animation-timing-function:cubic-bezier(0.08, 0.82, 0.17, 1);animation-timing-function:cubic-bezier(0.08, 0.82, 0.17, 1)}.zoom-right-leave{-webkit-animation-timing-function:cubic-bezier(0.78, 0.14, 0.15, 0.86);animation-timing-function:cubic-bezier(0.78, 0.14, 0.15, 0.86)}@-webkit-keyframes antZoomIn{0%{-webkit-transform:scale(0.2);transform:scale(0.2);opacity:0}100%{-webkit-transform:scale(1);transform:scale(1);opacity:1}}@keyframes antZoomIn{0%{-webkit-transform:scale(0.2);transform:scale(0.2);opacity:0}100%{-webkit-transform:scale(1);transform:scale(1);opacity:1}}@-webkit-keyframes antZoomOut{0%{-webkit-transform:scale(1);transform:scale(1)}100%{-webkit-transform:scale(0.2);transform:scale(0.2);opacity:0}}@keyframes antZoomOut{0%{-webkit-transform:scale(1);transform:scale(1)}100%{-webkit-transform:scale(0.2);transform:scale(0.2);opacity:0}}@-webkit-keyframes antZoomBigIn{0%{-webkit-transform:scale(0.8);transform:scale(0.8);opacity:0}100%{-webkit-transform:scale(1);transform:scale(1);opacity:1}}@keyframes antZoomBigIn{0%{-webkit-transform:scale(0.8);transform:scale(0.8);opacity:0}100%{-webkit-transform:scale(1);transform:scale(1);opacity:1}}@-webkit-keyframes antZoomBigOut{0%{-webkit-transform:scale(1);transform:scale(1)}100%{-webkit-transform:scale(0.8);transform:scale(0.8);opacity:0}}@keyframes antZoomBigOut{0%{-webkit-transform:scale(1);transform:scale(1)}100%{-webkit-transform:scale(0.8);transform:scale(0.8);opacity:0}}@-webkit-keyframes antZoomUpIn{0%{-webkit-transform:scale(0.8);transform:scale(0.8);-webkit-transform-origin:50% 0%;transform-origin:50% 0%;opacity:0}100%{-webkit-transform:scale(1);transform:scale(1);-webkit-transform-origin:50% 0%;transform-origin:50% 0%}}@keyframes antZoomUpIn{0%{-webkit-transform:scale(0.8);transform:scale(0.8);-webkit-transform-origin:50% 0%;transform-origin:50% 0%;opacity:0}100%{-webkit-transform:scale(1);transform:scale(1);-webkit-transform-origin:50% 0%;transform-origin:50% 0%}}@-webkit-keyframes antZoomUpOut{0%{-webkit-transform:scale(1);transform:scale(1);-webkit-transform-origin:50% 0%;transform-origin:50% 0%}100%{-webkit-transform:scale(0.8);transform:scale(0.8);-webkit-transform-origin:50% 0%;transform-origin:50% 0%;opacity:0}}@keyframes antZoomUpOut{0%{-webkit-transform:scale(1);transform:scale(1);-webkit-transform-origin:50% 0%;transform-origin:50% 0%}100%{-webkit-transform:scale(0.8);transform:scale(0.8);-webkit-transform-origin:50% 0%;transform-origin:50% 0%;opacity:0}}@-webkit-keyframes antZoomLeftIn{0%{-webkit-transform:scale(0.8);transform:scale(0.8);-webkit-transform-origin:0% 50%;transform-origin:0% 50%;opacity:0}100%{-webkit-transform:scale(1);transform:scale(1);-webkit-transform-origin:0% 50%;transform-origin:0% 50%}}@keyframes antZoomLeftIn{0%{-webkit-transform:scale(0.8);transform:scale(0.8);-webkit-transform-origin:0% 50%;transform-origin:0% 50%;opacity:0}100%{-webkit-transform:scale(1);transform:scale(1);-webkit-transform-origin:0% 50%;transform-origin:0% 50%}}@-webkit-keyframes antZoomLeftOut{0%{-webkit-transform:scale(1);transform:scale(1);-webkit-transform-origin:0% 50%;transform-origin:0% 50%}100%{-webkit-transform:scale(0.8);transform:scale(0.8);-webkit-transform-origin:0% 50%;transform-origin:0% 50%;opacity:0}}@keyframes antZoomLeftOut{0%{-webkit-transform:scale(1);transform:scale(1);-webkit-transform-origin:0% 50%;transform-origin:0% 50%}100%{-webkit-transform:scale(0.8);transform:scale(0.8);-webkit-transform-origin:0% 50%;transform-origin:0% 50%;opacity:0}}@-webkit-keyframes antZoomRightIn{0%{-webkit-transform:scale(0.8);transform:scale(0.8);-webkit-transform-origin:100% 50%;transform-origin:100% 50%;opacity:0}100%{-webkit-transform:scale(1);transform:scale(1);-webkit-transform-origin:100% 50%;transform-origin:100% 50%}}@keyframes antZoomRightIn{0%{-webkit-transform:scale(0.8);transform:scale(0.8);-webkit-transform-origin:100% 50%;transform-origin:100% 50%;opacity:0}100%{-webkit-transform:scale(1);transform:scale(1);-webkit-transform-origin:100% 50%;transform-origin:100% 50%}}@-webkit-keyframes antZoomRightOut{0%{-webkit-transform:scale(1);transform:scale(1);-webkit-transform-origin:100% 50%;transform-origin:100% 50%}100%{-webkit-transform:scale(0.8);transform:scale(0.8);-webkit-transform-origin:100% 50%;transform-origin:100% 50%;opacity:0}}@keyframes antZoomRightOut{0%{-webkit-transform:scale(1);transform:scale(1);-webkit-transform-origin:100% 50%;transform-origin:100% 50%}100%{-webkit-transform:scale(0.8);transform:scale(0.8);-webkit-transform-origin:100% 50%;transform-origin:100% 50%;opacity:0}}@-webkit-keyframes antZoomDownIn{0%{-webkit-transform:scale(0.8);transform:scale(0.8);-webkit-transform-origin:50% 100%;transform-origin:50% 100%;opacity:0}100%{-webkit-transform:scale(1);transform:scale(1);-webkit-transform-origin:50% 100%;transform-origin:50% 100%}}@keyframes antZoomDownIn{0%{-webkit-transform:scale(0.8);transform:scale(0.8);-webkit-transform-origin:50% 100%;transform-origin:50% 100%;opacity:0}100%{-webkit-transform:scale(1);transform:scale(1);-webkit-transform-origin:50% 100%;transform-origin:50% 100%}}@-webkit-keyframes antZoomDownOut{0%{-webkit-transform:scale(1);transform:scale(1);-webkit-transform-origin:50% 100%;transform-origin:50% 100%}100%{-webkit-transform:scale(0.8);transform:scale(0.8);-webkit-transform-origin:50% 100%;transform-origin:50% 100%;opacity:0}}@keyframes antZoomDownOut{0%{-webkit-transform:scale(1);transform:scale(1);-webkit-transform-origin:50% 100%;transform-origin:50% 100%}100%{-webkit-transform:scale(0.8);transform:scale(0.8);-webkit-transform-origin:50% 100%;transform-origin:50% 100%;opacity:0}}.ant-motion-collapse-legacy{overflow:hidden}.ant-motion-collapse-legacy-active{transition:height 0.15s cubic-bezier(0.645, 0.045, 0.355, 1),opacity 0.15s cubic-bezier(0.645, 0.045, 0.355, 1) !important}.ant-motion-collapse{overflow:hidden;transition:height 0.15s cubic-bezier(0.645, 0.045, 0.355, 1),opacity 0.15s cubic-bezier(0.645, 0.045, 0.355, 1) !important}
|
dist/css/multicurrencyOptions/styles.css
CHANGED
@@ -1,4 +1,6 @@
|
|
|
|
1 |
.fade-enter,.fade-appear{-webkit-animation-duration:0.2s;animation-duration:0.2s;-webkit-animation-fill-mode:both;animation-fill-mode:both;-webkit-animation-play-state:paused;animation-play-state:paused}.fade-leave{-webkit-animation-duration:0.2s;animation-duration:0.2s;-webkit-animation-fill-mode:both;animation-fill-mode:both;-webkit-animation-play-state:paused;animation-play-state:paused}.fade-enter.fade-enter-active,.fade-appear.fade-appear-active{-webkit-animation-name:antFadeIn;animation-name:antFadeIn;-webkit-animation-play-state:running;animation-play-state:running}.fade-leave.fade-leave-active{-webkit-animation-name:antFadeOut;animation-name:antFadeOut;-webkit-animation-play-state:running;animation-play-state:running;pointer-events:none}.fade-enter,.fade-appear{opacity:0;-webkit-animation-timing-function:linear;animation-timing-function:linear}.fade-leave{-webkit-animation-timing-function:linear;animation-timing-function:linear}@-webkit-keyframes antFadeIn{0%{opacity:0}100%{opacity:1}}@keyframes antFadeIn{0%{opacity:0}100%{opacity:1}}@-webkit-keyframes antFadeOut{0%{opacity:1}100%{opacity:0}}@keyframes antFadeOut{0%{opacity:1}100%{opacity:0}}.move-up-enter,.move-up-appear{-webkit-animation-duration:0.2s;animation-duration:0.2s;-webkit-animation-fill-mode:both;animation-fill-mode:both;-webkit-animation-play-state:paused;animation-play-state:paused}.move-up-leave{-webkit-animation-duration:0.2s;animation-duration:0.2s;-webkit-animation-fill-mode:both;animation-fill-mode:both;-webkit-animation-play-state:paused;animation-play-state:paused}.move-up-enter.move-up-enter-active,.move-up-appear.move-up-appear-active{-webkit-animation-name:antMoveUpIn;animation-name:antMoveUpIn;-webkit-animation-play-state:running;animation-play-state:running}.move-up-leave.move-up-leave-active{-webkit-animation-name:antMoveUpOut;animation-name:antMoveUpOut;-webkit-animation-play-state:running;animation-play-state:running;pointer-events:none}.move-up-enter,.move-up-appear{opacity:0;-webkit-animation-timing-function:cubic-bezier(0.08, 0.82, 0.17, 1);animation-timing-function:cubic-bezier(0.08, 0.82, 0.17, 1)}.move-up-leave{-webkit-animation-timing-function:cubic-bezier(0.6, 0.04, 0.98, 0.34);animation-timing-function:cubic-bezier(0.6, 0.04, 0.98, 0.34)}.move-down-enter,.move-down-appear{-webkit-animation-duration:0.2s;animation-duration:0.2s;-webkit-animation-fill-mode:both;animation-fill-mode:both;-webkit-animation-play-state:paused;animation-play-state:paused}.move-down-leave{-webkit-animation-duration:0.2s;animation-duration:0.2s;-webkit-animation-fill-mode:both;animation-fill-mode:both;-webkit-animation-play-state:paused;animation-play-state:paused}.move-down-enter.move-down-enter-active,.move-down-appear.move-down-appear-active{-webkit-animation-name:antMoveDownIn;animation-name:antMoveDownIn;-webkit-animation-play-state:running;animation-play-state:running}.move-down-leave.move-down-leave-active{-webkit-animation-name:antMoveDownOut;animation-name:antMoveDownOut;-webkit-animation-play-state:running;animation-play-state:running;pointer-events:none}.move-down-enter,.move-down-appear{opacity:0;-webkit-animation-timing-function:cubic-bezier(0.08, 0.82, 0.17, 1);animation-timing-function:cubic-bezier(0.08, 0.82, 0.17, 1)}.move-down-leave{-webkit-animation-timing-function:cubic-bezier(0.6, 0.04, 0.98, 0.34);animation-timing-function:cubic-bezier(0.6, 0.04, 0.98, 0.34)}.move-left-enter,.move-left-appear{-webkit-animation-duration:0.2s;animation-duration:0.2s;-webkit-animation-fill-mode:both;animation-fill-mode:both;-webkit-animation-play-state:paused;animation-play-state:paused}.move-left-leave{-webkit-animation-duration:0.2s;animation-duration:0.2s;-webkit-animation-fill-mode:both;animation-fill-mode:both;-webkit-animation-play-state:paused;animation-play-state:paused}.move-left-enter.move-left-enter-active,.move-left-appear.move-left-appear-active{-webkit-animation-name:antMoveLeftIn;animation-name:antMoveLeftIn;-webkit-animation-play-state:running;animation-play-state:running}.move-left-leave.move-left-leave-active{-webkit-animation-name:antMoveLeftOut;animation-name:antMoveLeftOut;-webkit-animation-play-state:running;animation-play-state:running;pointer-events:none}.move-left-enter,.move-left-appear{opacity:0;-webkit-animation-timing-function:cubic-bezier(0.08, 0.82, 0.17, 1);animation-timing-function:cubic-bezier(0.08, 0.82, 0.17, 1)}.move-left-leave{-webkit-animation-timing-function:cubic-bezier(0.6, 0.04, 0.98, 0.34);animation-timing-function:cubic-bezier(0.6, 0.04, 0.98, 0.34)}.move-right-enter,.move-right-appear{-webkit-animation-duration:0.2s;animation-duration:0.2s;-webkit-animation-fill-mode:both;animation-fill-mode:both;-webkit-animation-play-state:paused;animation-play-state:paused}.move-right-leave{-webkit-animation-duration:0.2s;animation-duration:0.2s;-webkit-animation-fill-mode:both;animation-fill-mode:both;-webkit-animation-play-state:paused;animation-play-state:paused}.move-right-enter.move-right-enter-active,.move-right-appear.move-right-appear-active{-webkit-animation-name:antMoveRightIn;animation-name:antMoveRightIn;-webkit-animation-play-state:running;animation-play-state:running}.move-right-leave.move-right-leave-active{-webkit-animation-name:antMoveRightOut;animation-name:antMoveRightOut;-webkit-animation-play-state:running;animation-play-state:running;pointer-events:none}.move-right-enter,.move-right-appear{opacity:0;-webkit-animation-timing-function:cubic-bezier(0.08, 0.82, 0.17, 1);animation-timing-function:cubic-bezier(0.08, 0.82, 0.17, 1)}.move-right-leave{-webkit-animation-timing-function:cubic-bezier(0.6, 0.04, 0.98, 0.34);animation-timing-function:cubic-bezier(0.6, 0.04, 0.98, 0.34)}@-webkit-keyframes antMoveDownIn{0%{-webkit-transform:translateY(100%);transform:translateY(100%);-webkit-transform-origin:0 0;transform-origin:0 0;opacity:0}100%{-webkit-transform:translateY(0%);transform:translateY(0%);-webkit-transform-origin:0 0;transform-origin:0 0;opacity:1}}@keyframes antMoveDownIn{0%{-webkit-transform:translateY(100%);transform:translateY(100%);-webkit-transform-origin:0 0;transform-origin:0 0;opacity:0}100%{-webkit-transform:translateY(0%);transform:translateY(0%);-webkit-transform-origin:0 0;transform-origin:0 0;opacity:1}}@-webkit-keyframes antMoveDownOut{0%{-webkit-transform:translateY(0%);transform:translateY(0%);-webkit-transform-origin:0 0;transform-origin:0 0;opacity:1}100%{-webkit-transform:translateY(100%);transform:translateY(100%);-webkit-transform-origin:0 0;transform-origin:0 0;opacity:0}}@keyframes antMoveDownOut{0%{-webkit-transform:translateY(0%);transform:translateY(0%);-webkit-transform-origin:0 0;transform-origin:0 0;opacity:1}100%{-webkit-transform:translateY(100%);transform:translateY(100%);-webkit-transform-origin:0 0;transform-origin:0 0;opacity:0}}@-webkit-keyframes antMoveLeftIn{0%{-webkit-transform:translateX(-100%);transform:translateX(-100%);-webkit-transform-origin:0 0;transform-origin:0 0;opacity:0}100%{-webkit-transform:translateX(0%);transform:translateX(0%);-webkit-transform-origin:0 0;transform-origin:0 0;opacity:1}}@keyframes antMoveLeftIn{0%{-webkit-transform:translateX(-100%);transform:translateX(-100%);-webkit-transform-origin:0 0;transform-origin:0 0;opacity:0}100%{-webkit-transform:translateX(0%);transform:translateX(0%);-webkit-transform-origin:0 0;transform-origin:0 0;opacity:1}}@-webkit-keyframes antMoveLeftOut{0%{-webkit-transform:translateX(0%);transform:translateX(0%);-webkit-transform-origin:0 0;transform-origin:0 0;opacity:1}100%{-webkit-transform:translateX(-100%);transform:translateX(-100%);-webkit-transform-origin:0 0;transform-origin:0 0;opacity:0}}@keyframes antMoveLeftOut{0%{-webkit-transform:translateX(0%);transform:translateX(0%);-webkit-transform-origin:0 0;transform-origin:0 0;opacity:1}100%{-webkit-transform:translateX(-100%);transform:translateX(-100%);-webkit-transform-origin:0 0;transform-origin:0 0;opacity:0}}@-webkit-keyframes antMoveRightIn{0%{-webkit-transform:translateX(100%);transform:translateX(100%);-webkit-transform-origin:0 0;transform-origin:0 0;opacity:0}100%{-webkit-transform:translateX(0%);transform:translateX(0%);-webkit-transform-origin:0 0;transform-origin:0 0;opacity:1}}@keyframes antMoveRightIn{0%{-webkit-transform:translateX(100%);transform:translateX(100%);-webkit-transform-origin:0 0;transform-origin:0 0;opacity:0}100%{-webkit-transform:translateX(0%);transform:translateX(0%);-webkit-transform-origin:0 0;transform-origin:0 0;opacity:1}}@-webkit-keyframes antMoveRightOut{0%{-webkit-transform:translateX(0%);transform:translateX(0%);-webkit-transform-origin:0 0;transform-origin:0 0;opacity:1}100%{-webkit-transform:translateX(100%);transform:translateX(100%);-webkit-transform-origin:0 0;transform-origin:0 0;opacity:0}}@keyframes antMoveRightOut{0%{-webkit-transform:translateX(0%);transform:translateX(0%);-webkit-transform-origin:0 0;transform-origin:0 0;opacity:1}100%{-webkit-transform:translateX(100%);transform:translateX(100%);-webkit-transform-origin:0 0;transform-origin:0 0;opacity:0}}@-webkit-keyframes antMoveUpIn{0%{-webkit-transform:translateY(-100%);transform:translateY(-100%);-webkit-transform-origin:0 0;transform-origin:0 0;opacity:0}100%{-webkit-transform:translateY(0%);transform:translateY(0%);-webkit-transform-origin:0 0;transform-origin:0 0;opacity:1}}@keyframes antMoveUpIn{0%{-webkit-transform:translateY(-100%);transform:translateY(-100%);-webkit-transform-origin:0 0;transform-origin:0 0;opacity:0}100%{-webkit-transform:translateY(0%);transform:translateY(0%);-webkit-transform-origin:0 0;transform-origin:0 0;opacity:1}}@-webkit-keyframes antMoveUpOut{0%{-webkit-transform:translateY(0%);transform:translateY(0%);-webkit-transform-origin:0 0;transform-origin:0 0;opacity:1}100%{-webkit-transform:translateY(-100%);transform:translateY(-100%);-webkit-transform-origin:0 0;transform-origin:0 0;opacity:0}}@keyframes antMoveUpOut{0%{-webkit-transform:translateY(0%);transform:translateY(0%);-webkit-transform-origin:0 0;transform-origin:0 0;opacity:1}100%{-webkit-transform:translateY(-100%);transform:translateY(-100%);-webkit-transform-origin:0 0;transform-origin:0 0;opacity:0}}@-webkit-keyframes loadingCircle{100%{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}@keyframes loadingCircle{100%{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}[ant-click-animating='true'],[ant-click-animating-without-extra-node='true']{position:relative}html{--antd-wave-shadow-color: #1890ff;--scroll-bar: 0}[ant-click-animating-without-extra-node='true']::after,.ant-click-animating-node{position:absolute;top:0;right:0;bottom:0;left:0;display:block;border-radius:inherit;box-shadow:0 0 0 0 #1890ff;box-shadow:0 0 0 0 var(--antd-wave-shadow-color);opacity:0.2;-webkit-animation:fadeEffect 2s cubic-bezier(0.08, 0.82, 0.17, 1),waveEffect 0.4s cubic-bezier(0.08, 0.82, 0.17, 1);animation:fadeEffect 2s cubic-bezier(0.08, 0.82, 0.17, 1),waveEffect 0.4s cubic-bezier(0.08, 0.82, 0.17, 1);-webkit-animation-fill-mode:forwards;animation-fill-mode:forwards;content:'';pointer-events:none}@-webkit-keyframes waveEffect{100%{box-shadow:0 0 0 #1890ff;box-shadow:0 0 0 6px var(--antd-wave-shadow-color)}}@keyframes waveEffect{100%{box-shadow:0 0 0 #1890ff;box-shadow:0 0 0 6px var(--antd-wave-shadow-color)}}@-webkit-keyframes fadeEffect{100%{opacity:0}}@keyframes fadeEffect{100%{opacity:0}}.slide-up-enter,.slide-up-appear{-webkit-animation-duration:0.2s;animation-duration:0.2s;-webkit-animation-fill-mode:both;animation-fill-mode:both;-webkit-animation-play-state:paused;animation-play-state:paused}.slide-up-leave{-webkit-animation-duration:0.2s;animation-duration:0.2s;-webkit-animation-fill-mode:both;animation-fill-mode:both;-webkit-animation-play-state:paused;animation-play-state:paused}.slide-up-enter.slide-up-enter-active,.slide-up-appear.slide-up-appear-active{-webkit-animation-name:antSlideUpIn;animation-name:antSlideUpIn;-webkit-animation-play-state:running;animation-play-state:running}.slide-up-leave.slide-up-leave-active{-webkit-animation-name:antSlideUpOut;animation-name:antSlideUpOut;-webkit-animation-play-state:running;animation-play-state:running;pointer-events:none}.slide-up-enter,.slide-up-appear{opacity:0;-webkit-animation-timing-function:cubic-bezier(0.23, 1, 0.32, 1);animation-timing-function:cubic-bezier(0.23, 1, 0.32, 1)}.slide-up-leave{-webkit-animation-timing-function:cubic-bezier(0.755, 0.05, 0.855, 0.06);animation-timing-function:cubic-bezier(0.755, 0.05, 0.855, 0.06)}.slide-down-enter,.slide-down-appear{-webkit-animation-duration:0.2s;animation-duration:0.2s;-webkit-animation-fill-mode:both;animation-fill-mode:both;-webkit-animation-play-state:paused;animation-play-state:paused}.slide-down-leave{-webkit-animation-duration:0.2s;animation-duration:0.2s;-webkit-animation-fill-mode:both;animation-fill-mode:both;-webkit-animation-play-state:paused;animation-play-state:paused}.slide-down-enter.slide-down-enter-active,.slide-down-appear.slide-down-appear-active{-webkit-animation-name:antSlideDownIn;animation-name:antSlideDownIn;-webkit-animation-play-state:running;animation-play-state:running}.slide-down-leave.slide-down-leave-active{-webkit-animation-name:antSlideDownOut;animation-name:antSlideDownOut;-webkit-animation-play-state:running;animation-play-state:running;pointer-events:none}.slide-down-enter,.slide-down-appear{opacity:0;-webkit-animation-timing-function:cubic-bezier(0.23, 1, 0.32, 1);animation-timing-function:cubic-bezier(0.23, 1, 0.32, 1)}.slide-down-leave{-webkit-animation-timing-function:cubic-bezier(0.755, 0.05, 0.855, 0.06);animation-timing-function:cubic-bezier(0.755, 0.05, 0.855, 0.06)}.slide-left-enter,.slide-left-appear{-webkit-animation-duration:0.2s;animation-duration:0.2s;-webkit-animation-fill-mode:both;animation-fill-mode:both;-webkit-animation-play-state:paused;animation-play-state:paused}.slide-left-leave{-webkit-animation-duration:0.2s;animation-duration:0.2s;-webkit-animation-fill-mode:both;animation-fill-mode:both;-webkit-animation-play-state:paused;animation-play-state:paused}.slide-left-enter.slide-left-enter-active,.slide-left-appear.slide-left-appear-active{-webkit-animation-name:antSlideLeftIn;animation-name:antSlideLeftIn;-webkit-animation-play-state:running;animation-play-state:running}.slide-left-leave.slide-left-leave-active{-webkit-animation-name:antSlideLeftOut;animation-name:antSlideLeftOut;-webkit-animation-play-state:running;animation-play-state:running;pointer-events:none}.slide-left-enter,.slide-left-appear{opacity:0;-webkit-animation-timing-function:cubic-bezier(0.23, 1, 0.32, 1);animation-timing-function:cubic-bezier(0.23, 1, 0.32, 1)}.slide-left-leave{-webkit-animation-timing-function:cubic-bezier(0.755, 0.05, 0.855, 0.06);animation-timing-function:cubic-bezier(0.755, 0.05, 0.855, 0.06)}.slide-right-enter,.slide-right-appear{-webkit-animation-duration:0.2s;animation-duration:0.2s;-webkit-animation-fill-mode:both;animation-fill-mode:both;-webkit-animation-play-state:paused;animation-play-state:paused}.slide-right-leave{-webkit-animation-duration:0.2s;animation-duration:0.2s;-webkit-animation-fill-mode:both;animation-fill-mode:both;-webkit-animation-play-state:paused;animation-play-state:paused}.slide-right-enter.slide-right-enter-active,.slide-right-appear.slide-right-appear-active{-webkit-animation-name:antSlideRightIn;animation-name:antSlideRightIn;-webkit-animation-play-state:running;animation-play-state:running}.slide-right-leave.slide-right-leave-active{-webkit-animation-name:antSlideRightOut;animation-name:antSlideRightOut;-webkit-animation-play-state:running;animation-play-state:running;pointer-events:none}.slide-right-enter,.slide-right-appear{opacity:0;-webkit-animation-timing-function:cubic-bezier(0.23, 1, 0.32, 1);animation-timing-function:cubic-bezier(0.23, 1, 0.32, 1)}.slide-right-leave{-webkit-animation-timing-function:cubic-bezier(0.755, 0.05, 0.855, 0.06);animation-timing-function:cubic-bezier(0.755, 0.05, 0.855, 0.06)}@-webkit-keyframes antSlideUpIn{0%{-webkit-transform:scaleY(0.8);transform:scaleY(0.8);-webkit-transform-origin:0% 0%;transform-origin:0% 0%;opacity:0}100%{-webkit-transform:scaleY(1);transform:scaleY(1);-webkit-transform-origin:0% 0%;transform-origin:0% 0%;opacity:1}}@keyframes antSlideUpIn{0%{-webkit-transform:scaleY(0.8);transform:scaleY(0.8);-webkit-transform-origin:0% 0%;transform-origin:0% 0%;opacity:0}100%{-webkit-transform:scaleY(1);transform:scaleY(1);-webkit-transform-origin:0% 0%;transform-origin:0% 0%;opacity:1}}@-webkit-keyframes antSlideUpOut{0%{-webkit-transform:scaleY(1);transform:scaleY(1);-webkit-transform-origin:0% 0%;transform-origin:0% 0%;opacity:1}100%{-webkit-transform:scaleY(0.8);transform:scaleY(0.8);-webkit-transform-origin:0% 0%;transform-origin:0% 0%;opacity:0}}@keyframes antSlideUpOut{0%{-webkit-transform:scaleY(1);transform:scaleY(1);-webkit-transform-origin:0% 0%;transform-origin:0% 0%;opacity:1}100%{-webkit-transform:scaleY(0.8);transform:scaleY(0.8);-webkit-transform-origin:0% 0%;transform-origin:0% 0%;opacity:0}}@-webkit-keyframes antSlideDownIn{0%{-webkit-transform:scaleY(0.8);transform:scaleY(0.8);-webkit-transform-origin:100% 100%;transform-origin:100% 100%;opacity:0}100%{-webkit-transform:scaleY(1);transform:scaleY(1);-webkit-transform-origin:100% 100%;transform-origin:100% 100%;opacity:1}}@keyframes antSlideDownIn{0%{-webkit-transform:scaleY(0.8);transform:scaleY(0.8);-webkit-transform-origin:100% 100%;transform-origin:100% 100%;opacity:0}100%{-webkit-transform:scaleY(1);transform:scaleY(1);-webkit-transform-origin:100% 100%;transform-origin:100% 100%;opacity:1}}@-webkit-keyframes antSlideDownOut{0%{-webkit-transform:scaleY(1);transform:scaleY(1);-webkit-transform-origin:100% 100%;transform-origin:100% 100%;opacity:1}100%{-webkit-transform:scaleY(0.8);transform:scaleY(0.8);-webkit-transform-origin:100% 100%;transform-origin:100% 100%;opacity:0}}@keyframes antSlideDownOut{0%{-webkit-transform:scaleY(1);transform:scaleY(1);-webkit-transform-origin:100% 100%;transform-origin:100% 100%;opacity:1}100%{-webkit-transform:scaleY(0.8);transform:scaleY(0.8);-webkit-transform-origin:100% 100%;transform-origin:100% 100%;opacity:0}}@-webkit-keyframes antSlideLeftIn{0%{-webkit-transform:scaleX(0.8);transform:scaleX(0.8);-webkit-transform-origin:0% 0%;transform-origin:0% 0%;opacity:0}100%{-webkit-transform:scaleX(1);transform:scaleX(1);-webkit-transform-origin:0% 0%;transform-origin:0% 0%;opacity:1}}@keyframes antSlideLeftIn{0%{-webkit-transform:scaleX(0.8);transform:scaleX(0.8);-webkit-transform-origin:0% 0%;transform-origin:0% 0%;opacity:0}100%{-webkit-transform:scaleX(1);transform:scaleX(1);-webkit-transform-origin:0% 0%;transform-origin:0% 0%;opacity:1}}@-webkit-keyframes antSlideLeftOut{0%{-webkit-transform:scaleX(1);transform:scaleX(1);-webkit-transform-origin:0% 0%;transform-origin:0% 0%;opacity:1}100%{-webkit-transform:scaleX(0.8);transform:scaleX(0.8);-webkit-transform-origin:0% 0%;transform-origin:0% 0%;opacity:0}}@keyframes antSlideLeftOut{0%{-webkit-transform:scaleX(1);transform:scaleX(1);-webkit-transform-origin:0% 0%;transform-origin:0% 0%;opacity:1}100%{-webkit-transform:scaleX(0.8);transform:scaleX(0.8);-webkit-transform-origin:0% 0%;transform-origin:0% 0%;opacity:0}}@-webkit-keyframes antSlideRightIn{0%{-webkit-transform:scaleX(0.8);transform:scaleX(0.8);-webkit-transform-origin:100% 0%;transform-origin:100% 0%;opacity:0}100%{-webkit-transform:scaleX(1);transform:scaleX(1);-webkit-transform-origin:100% 0%;transform-origin:100% 0%;opacity:1}}@keyframes antSlideRightIn{0%{-webkit-transform:scaleX(0.8);transform:scaleX(0.8);-webkit-transform-origin:100% 0%;transform-origin:100% 0%;opacity:0}100%{-webkit-transform:scaleX(1);transform:scaleX(1);-webkit-transform-origin:100% 0%;transform-origin:100% 0%;opacity:1}}@-webkit-keyframes antSlideRightOut{0%{-webkit-transform:scaleX(1);transform:scaleX(1);-webkit-transform-origin:100% 0%;transform-origin:100% 0%;opacity:1}100%{-webkit-transform:scaleX(0.8);transform:scaleX(0.8);-webkit-transform-origin:100% 0%;transform-origin:100% 0%;opacity:0}}@keyframes antSlideRightOut{0%{-webkit-transform:scaleX(1);transform:scaleX(1);-webkit-transform-origin:100% 0%;transform-origin:100% 0%;opacity:1}100%{-webkit-transform:scaleX(0.8);transform:scaleX(0.8);-webkit-transform-origin:100% 0%;transform-origin:100% 0%;opacity:0}}.zoom-enter,.zoom-appear{-webkit-animation-duration:0.2s;animation-duration:0.2s;-webkit-animation-fill-mode:both;animation-fill-mode:both;-webkit-animation-play-state:paused;animation-play-state:paused}.zoom-leave{-webkit-animation-duration:0.2s;animation-duration:0.2s;-webkit-animation-fill-mode:both;animation-fill-mode:both;-webkit-animation-play-state:paused;animation-play-state:paused}.zoom-enter.zoom-enter-active,.zoom-appear.zoom-appear-active{-webkit-animation-name:antZoomIn;animation-name:antZoomIn;-webkit-animation-play-state:running;animation-play-state:running}.zoom-leave.zoom-leave-active{-webkit-animation-name:antZoomOut;animation-name:antZoomOut;-webkit-animation-play-state:running;animation-play-state:running;pointer-events:none}.zoom-enter,.zoom-appear{-webkit-transform:scale(0);transform:scale(0);opacity:0;-webkit-animation-timing-function:cubic-bezier(0.08, 0.82, 0.17, 1);animation-timing-function:cubic-bezier(0.08, 0.82, 0.17, 1)}.zoom-leave{-webkit-animation-timing-function:cubic-bezier(0.78, 0.14, 0.15, 0.86);animation-timing-function:cubic-bezier(0.78, 0.14, 0.15, 0.86)}.zoom-big-enter,.zoom-big-appear{-webkit-animation-duration:0.2s;animation-duration:0.2s;-webkit-animation-fill-mode:both;animation-fill-mode:both;-webkit-animation-play-state:paused;animation-play-state:paused}.zoom-big-leave{-webkit-animation-duration:0.2s;animation-duration:0.2s;-webkit-animation-fill-mode:both;animation-fill-mode:both;-webkit-animation-play-state:paused;animation-play-state:paused}.zoom-big-enter.zoom-big-enter-active,.zoom-big-appear.zoom-big-appear-active{-webkit-animation-name:antZoomBigIn;animation-name:antZoomBigIn;-webkit-animation-play-state:running;animation-play-state:running}.zoom-big-leave.zoom-big-leave-active{-webkit-animation-name:antZoomBigOut;animation-name:antZoomBigOut;-webkit-animation-play-state:running;animation-play-state:running;pointer-events:none}.zoom-big-enter,.zoom-big-appear{-webkit-transform:scale(0);transform:scale(0);opacity:0;-webkit-animation-timing-function:cubic-bezier(0.08, 0.82, 0.17, 1);animation-timing-function:cubic-bezier(0.08, 0.82, 0.17, 1)}.zoom-big-leave{-webkit-animation-timing-function:cubic-bezier(0.78, 0.14, 0.15, 0.86);animation-timing-function:cubic-bezier(0.78, 0.14, 0.15, 0.86)}.zoom-big-fast-enter,.zoom-big-fast-appear{-webkit-animation-duration:0.1s;animation-duration:0.1s;-webkit-animation-fill-mode:both;animation-fill-mode:both;-webkit-animation-play-state:paused;animation-play-state:paused}.zoom-big-fast-leave{-webkit-animation-duration:0.1s;animation-duration:0.1s;-webkit-animation-fill-mode:both;animation-fill-mode:both;-webkit-animation-play-state:paused;animation-play-state:paused}.zoom-big-fast-enter.zoom-big-fast-enter-active,.zoom-big-fast-appear.zoom-big-fast-appear-active{-webkit-animation-name:antZoomBigIn;animation-name:antZoomBigIn;-webkit-animation-play-state:running;animation-play-state:running}.zoom-big-fast-leave.zoom-big-fast-leave-active{-webkit-animation-name:antZoomBigOut;animation-name:antZoomBigOut;-webkit-animation-play-state:running;animation-play-state:running;pointer-events:none}.zoom-big-fast-enter,.zoom-big-fast-appear{-webkit-transform:scale(0);transform:scale(0);opacity:0;-webkit-animation-timing-function:cubic-bezier(0.08, 0.82, 0.17, 1);animation-timing-function:cubic-bezier(0.08, 0.82, 0.17, 1)}.zoom-big-fast-leave{-webkit-animation-timing-function:cubic-bezier(0.78, 0.14, 0.15, 0.86);animation-timing-function:cubic-bezier(0.78, 0.14, 0.15, 0.86)}.zoom-up-enter,.zoom-up-appear{-webkit-animation-duration:0.2s;animation-duration:0.2s;-webkit-animation-fill-mode:both;animation-fill-mode:both;-webkit-animation-play-state:paused;animation-play-state:paused}.zoom-up-leave{-webkit-animation-duration:0.2s;animation-duration:0.2s;-webkit-animation-fill-mode:both;animation-fill-mode:both;-webkit-animation-play-state:paused;animation-play-state:paused}.zoom-up-enter.zoom-up-enter-active,.zoom-up-appear.zoom-up-appear-active{-webkit-animation-name:antZoomUpIn;animation-name:antZoomUpIn;-webkit-animation-play-state:running;animation-play-state:running}.zoom-up-leave.zoom-up-leave-active{-webkit-animation-name:antZoomUpOut;animation-name:antZoomUpOut;-webkit-animation-play-state:running;animation-play-state:running;pointer-events:none}.zoom-up-enter,.zoom-up-appear{-webkit-transform:scale(0);transform:scale(0);opacity:0;-webkit-animation-timing-function:cubic-bezier(0.08, 0.82, 0.17, 1);animation-timing-function:cubic-bezier(0.08, 0.82, 0.17, 1)}.zoom-up-leave{-webkit-animation-timing-function:cubic-bezier(0.78, 0.14, 0.15, 0.86);animation-timing-function:cubic-bezier(0.78, 0.14, 0.15, 0.86)}.zoom-down-enter,.zoom-down-appear{-webkit-animation-duration:0.2s;animation-duration:0.2s;-webkit-animation-fill-mode:both;animation-fill-mode:both;-webkit-animation-play-state:paused;animation-play-state:paused}.zoom-down-leave{-webkit-animation-duration:0.2s;animation-duration:0.2s;-webkit-animation-fill-mode:both;animation-fill-mode:both;-webkit-animation-play-state:paused;animation-play-state:paused}.zoom-down-enter.zoom-down-enter-active,.zoom-down-appear.zoom-down-appear-active{-webkit-animation-name:antZoomDownIn;animation-name:antZoomDownIn;-webkit-animation-play-state:running;animation-play-state:running}.zoom-down-leave.zoom-down-leave-active{-webkit-animation-name:antZoomDownOut;animation-name:antZoomDownOut;-webkit-animation-play-state:running;animation-play-state:running;pointer-events:none}.zoom-down-enter,.zoom-down-appear{-webkit-transform:scale(0);transform:scale(0);opacity:0;-webkit-animation-timing-function:cubic-bezier(0.08, 0.82, 0.17, 1);animation-timing-function:cubic-bezier(0.08, 0.82, 0.17, 1)}.zoom-down-leave{-webkit-animation-timing-function:cubic-bezier(0.78, 0.14, 0.15, 0.86);animation-timing-function:cubic-bezier(0.78, 0.14, 0.15, 0.86)}.zoom-left-enter,.zoom-left-appear{-webkit-animation-duration:0.2s;animation-duration:0.2s;-webkit-animation-fill-mode:both;animation-fill-mode:both;-webkit-animation-play-state:paused;animation-play-state:paused}.zoom-left-leave{-webkit-animation-duration:0.2s;animation-duration:0.2s;-webkit-animation-fill-mode:both;animation-fill-mode:both;-webkit-animation-play-state:paused;animation-play-state:paused}.zoom-left-enter.zoom-left-enter-active,.zoom-left-appear.zoom-left-appear-active{-webkit-animation-name:antZoomLeftIn;animation-name:antZoomLeftIn;-webkit-animation-play-state:running;animation-play-state:running}.zoom-left-leave.zoom-left-leave-active{-webkit-animation-name:antZoomLeftOut;animation-name:antZoomLeftOut;-webkit-animation-play-state:running;animation-play-state:running;pointer-events:none}.zoom-left-enter,.zoom-left-appear{-webkit-transform:scale(0);transform:scale(0);opacity:0;-webkit-animation-timing-function:cubic-bezier(0.08, 0.82, 0.17, 1);animation-timing-function:cubic-bezier(0.08, 0.82, 0.17, 1)}.zoom-left-leave{-webkit-animation-timing-function:cubic-bezier(0.78, 0.14, 0.15, 0.86);animation-timing-function:cubic-bezier(0.78, 0.14, 0.15, 0.86)}.zoom-right-enter,.zoom-right-appear{-webkit-animation-duration:0.2s;animation-duration:0.2s;-webkit-animation-fill-mode:both;animation-fill-mode:both;-webkit-animation-play-state:paused;animation-play-state:paused}.zoom-right-leave{-webkit-animation-duration:0.2s;animation-duration:0.2s;-webkit-animation-fill-mode:both;animation-fill-mode:both;-webkit-animation-play-state:paused;animation-play-state:paused}.zoom-right-enter.zoom-right-enter-active,.zoom-right-appear.zoom-right-appear-active{-webkit-animation-name:antZoomRightIn;animation-name:antZoomRightIn;-webkit-animation-play-state:running;animation-play-state:running}.zoom-right-leave.zoom-right-leave-active{-webkit-animation-name:antZoomRightOut;animation-name:antZoomRightOut;-webkit-animation-play-state:running;animation-play-state:running;pointer-events:none}.zoom-right-enter,.zoom-right-appear{-webkit-transform:scale(0);transform:scale(0);opacity:0;-webkit-animation-timing-function:cubic-bezier(0.08, 0.82, 0.17, 1);animation-timing-function:cubic-bezier(0.08, 0.82, 0.17, 1)}.zoom-right-leave{-webkit-animation-timing-function:cubic-bezier(0.78, 0.14, 0.15, 0.86);animation-timing-function:cubic-bezier(0.78, 0.14, 0.15, 0.86)}@-webkit-keyframes antZoomIn{0%{-webkit-transform:scale(0.2);transform:scale(0.2);opacity:0}100%{-webkit-transform:scale(1);transform:scale(1);opacity:1}}@keyframes antZoomIn{0%{-webkit-transform:scale(0.2);transform:scale(0.2);opacity:0}100%{-webkit-transform:scale(1);transform:scale(1);opacity:1}}@-webkit-keyframes antZoomOut{0%{-webkit-transform:scale(1);transform:scale(1)}100%{-webkit-transform:scale(0.2);transform:scale(0.2);opacity:0}}@keyframes antZoomOut{0%{-webkit-transform:scale(1);transform:scale(1)}100%{-webkit-transform:scale(0.2);transform:scale(0.2);opacity:0}}@-webkit-keyframes antZoomBigIn{0%{-webkit-transform:scale(0.8);transform:scale(0.8);opacity:0}100%{-webkit-transform:scale(1);transform:scale(1);opacity:1}}@keyframes antZoomBigIn{0%{-webkit-transform:scale(0.8);transform:scale(0.8);opacity:0}100%{-webkit-transform:scale(1);transform:scale(1);opacity:1}}@-webkit-keyframes antZoomBigOut{0%{-webkit-transform:scale(1);transform:scale(1)}100%{-webkit-transform:scale(0.8);transform:scale(0.8);opacity:0}}@keyframes antZoomBigOut{0%{-webkit-transform:scale(1);transform:scale(1)}100%{-webkit-transform:scale(0.8);transform:scale(0.8);opacity:0}}@-webkit-keyframes antZoomUpIn{0%{-webkit-transform:scale(0.8);transform:scale(0.8);-webkit-transform-origin:50% 0%;transform-origin:50% 0%;opacity:0}100%{-webkit-transform:scale(1);transform:scale(1);-webkit-transform-origin:50% 0%;transform-origin:50% 0%}}@keyframes antZoomUpIn{0%{-webkit-transform:scale(0.8);transform:scale(0.8);-webkit-transform-origin:50% 0%;transform-origin:50% 0%;opacity:0}100%{-webkit-transform:scale(1);transform:scale(1);-webkit-transform-origin:50% 0%;transform-origin:50% 0%}}@-webkit-keyframes antZoomUpOut{0%{-webkit-transform:scale(1);transform:scale(1);-webkit-transform-origin:50% 0%;transform-origin:50% 0%}100%{-webkit-transform:scale(0.8);transform:scale(0.8);-webkit-transform-origin:50% 0%;transform-origin:50% 0%;opacity:0}}@keyframes antZoomUpOut{0%{-webkit-transform:scale(1);transform:scale(1);-webkit-transform-origin:50% 0%;transform-origin:50% 0%}100%{-webkit-transform:scale(0.8);transform:scale(0.8);-webkit-transform-origin:50% 0%;transform-origin:50% 0%;opacity:0}}@-webkit-keyframes antZoomLeftIn{0%{-webkit-transform:scale(0.8);transform:scale(0.8);-webkit-transform-origin:0% 50%;transform-origin:0% 50%;opacity:0}100%{-webkit-transform:scale(1);transform:scale(1);-webkit-transform-origin:0% 50%;transform-origin:0% 50%}}@keyframes antZoomLeftIn{0%{-webkit-transform:scale(0.8);transform:scale(0.8);-webkit-transform-origin:0% 50%;transform-origin:0% 50%;opacity:0}100%{-webkit-transform:scale(1);transform:scale(1);-webkit-transform-origin:0% 50%;transform-origin:0% 50%}}@-webkit-keyframes antZoomLeftOut{0%{-webkit-transform:scale(1);transform:scale(1);-webkit-transform-origin:0% 50%;transform-origin:0% 50%}100%{-webkit-transform:scale(0.8);transform:scale(0.8);-webkit-transform-origin:0% 50%;transform-origin:0% 50%;opacity:0}}@keyframes antZoomLeftOut{0%{-webkit-transform:scale(1);transform:scale(1);-webkit-transform-origin:0% 50%;transform-origin:0% 50%}100%{-webkit-transform:scale(0.8);transform:scale(0.8);-webkit-transform-origin:0% 50%;transform-origin:0% 50%;opacity:0}}@-webkit-keyframes antZoomRightIn{0%{-webkit-transform:scale(0.8);transform:scale(0.8);-webkit-transform-origin:100% 50%;transform-origin:100% 50%;opacity:0}100%{-webkit-transform:scale(1);transform:scale(1);-webkit-transform-origin:100% 50%;transform-origin:100% 50%}}@keyframes antZoomRightIn{0%{-webkit-transform:scale(0.8);transform:scale(0.8);-webkit-transform-origin:100% 50%;transform-origin:100% 50%;opacity:0}100%{-webkit-transform:scale(1);transform:scale(1);-webkit-transform-origin:100% 50%;transform-origin:100% 50%}}@-webkit-keyframes antZoomRightOut{0%{-webkit-transform:scale(1);transform:scale(1);-webkit-transform-origin:100% 50%;transform-origin:100% 50%}100%{-webkit-transform:scale(0.8);transform:scale(0.8);-webkit-transform-origin:100% 50%;transform-origin:100% 50%;opacity:0}}@keyframes antZoomRightOut{0%{-webkit-transform:scale(1);transform:scale(1);-webkit-transform-origin:100% 50%;transform-origin:100% 50%}100%{-webkit-transform:scale(0.8);transform:scale(0.8);-webkit-transform-origin:100% 50%;transform-origin:100% 50%;opacity:0}}@-webkit-keyframes antZoomDownIn{0%{-webkit-transform:scale(0.8);transform:scale(0.8);-webkit-transform-origin:50% 100%;transform-origin:50% 100%;opacity:0}100%{-webkit-transform:scale(1);transform:scale(1);-webkit-transform-origin:50% 100%;transform-origin:50% 100%}}@keyframes antZoomDownIn{0%{-webkit-transform:scale(0.8);transform:scale(0.8);-webkit-transform-origin:50% 100%;transform-origin:50% 100%;opacity:0}100%{-webkit-transform:scale(1);transform:scale(1);-webkit-transform-origin:50% 100%;transform-origin:50% 100%}}@-webkit-keyframes antZoomDownOut{0%{-webkit-transform:scale(1);transform:scale(1);-webkit-transform-origin:50% 100%;transform-origin:50% 100%}100%{-webkit-transform:scale(0.8);transform:scale(0.8);-webkit-transform-origin:50% 100%;transform-origin:50% 100%;opacity:0}}@keyframes antZoomDownOut{0%{-webkit-transform:scale(1);transform:scale(1);-webkit-transform-origin:50% 100%;transform-origin:50% 100%}100%{-webkit-transform:scale(0.8);transform:scale(0.8);-webkit-transform-origin:50% 100%;transform-origin:50% 100%;opacity:0}}.ant-motion-collapse-legacy{overflow:hidden}.ant-motion-collapse-legacy-active{transition:height 0.15s cubic-bezier(0.645, 0.045, 0.355, 1),opacity 0.15s cubic-bezier(0.645, 0.045, 0.355, 1) !important}.ant-motion-collapse{overflow:hidden;transition:height 0.15s cubic-bezier(0.645, 0.045, 0.355, 1),opacity 0.15s cubic-bezier(0.645, 0.045, 0.355, 1) !important}
|
2 |
.ant-modal{-webkit-box-sizing:border-box;box-sizing:border-box;margin:0;padding:0;color:rgba(0,0,0,0.65);font-size:14px;font-variant:tabular-nums;line-height:1.5715;list-style:none;-webkit-font-feature-settings:'tnum';font-feature-settings:'tnum';position:relative;top:100px;width:auto;margin:0 auto;padding-bottom:24px;pointer-events:none}.ant-modal-wrap{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1000;overflow:auto;outline:0;-webkit-overflow-scrolling:touch}.ant-modal-title{margin:0;color:rgba(0,0,0,0.85);font-weight:500;font-size:16px;line-height:22px;word-wrap:break-word}.ant-modal-content{position:relative;background-color:#fff;background-clip:padding-box;border:0;border-radius:2px;-webkit-box-shadow:0 3px 6px -4px rgba(0,0,0,0.12),0 6px 16px 0 rgba(0,0,0,0.08),0 9px 28px 8px rgba(0,0,0,0.05);box-shadow:0 3px 6px -4px rgba(0,0,0,0.12),0 6px 16px 0 rgba(0,0,0,0.08),0 9px 28px 8px rgba(0,0,0,0.05);pointer-events:auto}.ant-modal-close{position:absolute;top:0;right:0;z-index:10;padding:0;color:rgba(0,0,0,0.45);font-weight:700;line-height:1;text-decoration:none;background:transparent;border:0;outline:0;cursor:pointer;-webkit-transition:color 0.3s;transition:color 0.3s}.ant-modal-close-x{display:block;width:56px;height:56px;font-size:16px;font-style:normal;line-height:56px;text-align:center;text-transform:none;text-rendering:auto}.ant-modal-close:focus,.ant-modal-close:hover{color:rgba(0,0,0,0.75);text-decoration:none}.ant-modal-header{padding:16px 24px;color:rgba(0,0,0,0.65);background:#fff;border-bottom:1px solid #f0f0f0;border-radius:2px 2px 0 0}.ant-modal-body{padding:24px;font-size:14px;line-height:1.5715;word-wrap:break-word}.ant-modal-footer{padding:10px 16px;text-align:right;background:transparent;border-top:1px solid #f0f0f0;border-radius:0 0 2px 2px}.ant-modal-footer button+button{margin-bottom:0;margin-left:8px}.ant-modal.zoom-enter,.ant-modal.zoom-appear{-webkit-transform:none;transform:none;opacity:0;-webkit-animation-duration:0.3s;animation-duration:0.3s;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.ant-modal-mask{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1000;height:100%;background-color:rgba(0,0,0,0.45);filter:alpha(opacity=50)}.ant-modal-mask-hidden{display:none}.ant-modal-open{overflow:hidden}.ant-modal-centered{text-align:center}.ant-modal-centered::before{display:inline-block;width:0;height:100%;vertical-align:middle;content:''}.ant-modal-centered .ant-modal{top:0;display:inline-block;text-align:left;vertical-align:middle}@media (max-width: 767px){.ant-modal{max-width:calc(100vw - 16px);margin:8px auto}.ant-modal-centered .ant-modal{-webkit-box-flex:1;-ms-flex:1;flex:1}}.ant-modal-confirm .ant-modal-header{display:none}.ant-modal-confirm .ant-modal-close{display:none}.ant-modal-confirm .ant-modal-body{padding:32px 32px 24px}.ant-modal-confirm-body-wrapper::before{display:table;content:''}.ant-modal-confirm-body-wrapper::after{display:table;clear:both;content:''}.ant-modal-confirm-body .ant-modal-confirm-title{display:block;overflow:hidden;color:rgba(0,0,0,0.85);font-weight:500;font-size:16px;line-height:1.4}.ant-modal-confirm-body .ant-modal-confirm-content{margin-top:8px;color:rgba(0,0,0,0.65);font-size:14px}.ant-modal-confirm-body>.anticon{float:left;margin-right:16px;font-size:22px}.ant-modal-confirm-body>.anticon+.ant-modal-confirm-title+.ant-modal-confirm-content{margin-left:38px}.ant-modal-confirm .ant-modal-confirm-btns{float:right;margin-top:24px}.ant-modal-confirm .ant-modal-confirm-btns button+button{margin-bottom:0;margin-left:8px}.ant-modal-confirm-error .ant-modal-confirm-body>.anticon{color:#ff4d4f}.ant-modal-confirm-warning .ant-modal-confirm-body>.anticon,.ant-modal-confirm-confirm .ant-modal-confirm-body>.anticon{color:#faad14}.ant-modal-confirm-info .ant-modal-confirm-body>.anticon{color:#1890ff}.ant-modal-confirm-success .ant-modal-confirm-body>.anticon{color:#52c41a}.ant-modal-wrap-rtl{direction:rtl}.ant-modal-wrap-rtl .ant-modal-close{right:initial;left:0}.ant-modal-wrap-rtl .ant-modal-footer{text-align:left}.ant-modal-wrap-rtl .ant-modal-footer button+button{margin-right:8px;margin-left:0}.ant-modal-wrap-rtl.ant-modal-centered .ant-modal{text-align:right}
|
3 |
-
.ant-tooltip{-webkit-box-sizing:border-box;box-sizing:border-box;margin:0;padding:0;color:rgba(0,0,0,0.65);font-size:14px;font-variant:tabular-nums;line-height:1.5715;list-style:none;-webkit-font-feature-settings:'tnum';font-feature-settings:'tnum';position:absolute;z-index:1060;display:block;max-width:250px;visibility:visible}.ant-tooltip-hidden{display:none}.ant-tooltip-placement-top,.ant-tooltip-placement-topLeft,.ant-tooltip-placement-topRight{padding-bottom:8px}.ant-tooltip-placement-right,.ant-tooltip-placement-rightTop,.ant-tooltip-placement-rightBottom{padding-left:8px}.ant-tooltip-placement-bottom,.ant-tooltip-placement-bottomLeft,.ant-tooltip-placement-bottomRight{padding-top:8px}.ant-tooltip-placement-left,.ant-tooltip-placement-leftTop,.ant-tooltip-placement-leftBottom{padding-right:8px}.ant-tooltip-inner{min-width:30px;min-height:32px;padding:6px 8px;color:#fff;text-align:left;text-decoration:none;word-wrap:break-word;background-color:rgba(0,0,0,0.75);border-radius:2px;-webkit-box-shadow:0 3px 6px -4px rgba(0,0,0,0.12),0 6px 16px 0 rgba(0,0,0,0.08),0 9px 28px 8px rgba(0,0,0,0.05);box-shadow:0 3px 6px -4px rgba(0,0,0,0.12),0 6px 16px 0 rgba(0,0,0,0.08),0 9px 28px 8px rgba(0,0,0,0.05)}.ant-tooltip-arrow{position:absolute;display:block;width:13.07106781px;height:13.07106781px;overflow:hidden;background:transparent;pointer-events:none}.ant-tooltip-arrow::before{position:absolute;top:0;right:0;bottom:0;left:0;display:block;width:5px;height:5px;margin:auto;background-color:rgba(0,0,0,0.75);content:'';pointer-events:auto}.ant-tooltip-placement-top .ant-tooltip-arrow,.ant-tooltip-placement-topLeft .ant-tooltip-arrow,.ant-tooltip-placement-topRight .ant-tooltip-arrow{bottom:-5.07106781px}.ant-tooltip-placement-top .ant-tooltip-arrow::before,.ant-tooltip-placement-topLeft .ant-tooltip-arrow::before,.ant-tooltip-placement-topRight .ant-tooltip-arrow::before{-webkit-box-shadow:3px 3px 7px rgba(0,0,0,0.07);box-shadow:3px 3px 7px rgba(0,0,0,0.07);-webkit-transform:translateY(-6.53553px) rotate(45deg);transform:translateY(-6.53553px) rotate(45deg)}.ant-tooltip-placement-top .ant-tooltip-arrow{left:50%;-webkit-transform:translateX(-50%);transform:translateX(-50%)}.ant-tooltip-placement-topLeft .ant-tooltip-arrow{left:13px}.ant-tooltip-placement-topRight .ant-tooltip-arrow{right:13px}.ant-tooltip-placement-right .ant-tooltip-arrow,.ant-tooltip-placement-rightTop .ant-tooltip-arrow,.ant-tooltip-placement-rightBottom .ant-tooltip-arrow{left:-5.07106781px}.ant-tooltip-placement-right .ant-tooltip-arrow::before,.ant-tooltip-placement-rightTop .ant-tooltip-arrow::before,.ant-tooltip-placement-rightBottom .ant-tooltip-arrow::before{-webkit-box-shadow:-3px 3px 7px rgba(0,0,0,0.07);box-shadow:-3px 3px 7px rgba(0,0,0,0.07);-webkit-transform:translateX(6.53553px) rotate(45deg);transform:translateX(6.53553px) rotate(45deg)}.ant-tooltip-placement-right .ant-tooltip-arrow{top:50%;-webkit-transform:translateY(-50%);transform:translateY(-50%)}.ant-tooltip-placement-rightTop .ant-tooltip-arrow{top:5px}.ant-tooltip-placement-rightBottom .ant-tooltip-arrow{bottom:5px}.ant-tooltip-placement-left .ant-tooltip-arrow,.ant-tooltip-placement-leftTop .ant-tooltip-arrow,.ant-tooltip-placement-leftBottom .ant-tooltip-arrow{right:-5.07106781px}.ant-tooltip-placement-left .ant-tooltip-arrow::before,.ant-tooltip-placement-leftTop .ant-tooltip-arrow::before,.ant-tooltip-placement-leftBottom .ant-tooltip-arrow::before{-webkit-box-shadow:3px -3px 7px rgba(0,0,0,0.07);box-shadow:3px -3px 7px rgba(0,0,0,0.07);-webkit-transform:translateX(-6.53553px) rotate(45deg);transform:translateX(-6.53553px) rotate(45deg)}.ant-tooltip-placement-left .ant-tooltip-arrow{top:50%;-webkit-transform:translateY(-50%);transform:translateY(-50%)}.ant-tooltip-placement-leftTop .ant-tooltip-arrow{top:5px}.ant-tooltip-placement-leftBottom .ant-tooltip-arrow{bottom:5px}.ant-tooltip-placement-bottom .ant-tooltip-arrow,.ant-tooltip-placement-bottomLeft .ant-tooltip-arrow,.ant-tooltip-placement-bottomRight .ant-tooltip-arrow{top:-5.07106781px}.ant-tooltip-placement-bottom .ant-tooltip-arrow::before,.ant-tooltip-placement-bottomLeft .ant-tooltip-arrow::before,.ant-tooltip-placement-bottomRight .ant-tooltip-arrow::before{-webkit-box-shadow:-3px -3px 7px rgba(0,0,0,0.07);box-shadow:-3px -3px 7px rgba(0,0,0,0.07);-webkit-transform:translateY(6.53553px) rotate(45deg);transform:translateY(6.53553px) rotate(45deg)}.ant-tooltip-placement-bottom .ant-tooltip-arrow{left:50%;-webkit-transform:translateX(-50%);transform:translateX(-50%)}.ant-tooltip-placement-bottomLeft .ant-tooltip-arrow{left:13px}.ant-tooltip-placement-bottomRight .ant-tooltip-arrow{right:13px}.ant-tooltip-rtl{direction:rtl}.ant-tooltip-rtl .ant-tooltip-inner{text-align:right}
|
4 |
.ant-select-single .ant-select-selector{display:-webkit-box;display:-ms-flexbox;display:flex}.ant-select-single .ant-select-selector .ant-select-selection-search{position:absolute;top:0;right:11px;bottom:0;left:11px}.ant-select-single .ant-select-selector .ant-select-selection-search-input{width:100%}.ant-select-single .ant-select-selector .ant-select-selection-item,.ant-select-single .ant-select-selector .ant-select-selection-placeholder{padding:0;line-height:30px;-webkit-transition:all 0.3s;transition:all 0.3s}@supports (-moz-appearance: meterbar){.ant-select-single .ant-select-selector .ant-select-selection-item,.ant-select-single .ant-select-selector .ant-select-selection-placeholder{line-height:30px}}.ant-select-single .ant-select-selector .ant-select-selection-item{position:relative;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.ant-select-single .ant-select-selector .ant-select-selection-placeholder{pointer-events:none}.ant-select-single .ant-select-selector::after,.ant-select-single .ant-select-selector .ant-select-selection-item::after,.ant-select-single .ant-select-selector .ant-select-selection-placeholder::after{display:inline-block;width:0;visibility:hidden;content:'\a0'}.ant-select-single.ant-select-show-arrow .ant-select-selection-search{right:25px}.ant-select-single.ant-select-show-arrow .ant-select-selection-item,.ant-select-single.ant-select-show-arrow .ant-select-selection-placeholder{padding-right:18px}.ant-select-single.ant-select-open .ant-select-selection-item{opacity:0.4}.ant-select-single:not(.ant-select-customize-input) .ant-select-selector{position:relative;background-color:#fff;border:1px solid #d9d9d9;border-radius:2px;-webkit-transition:all 0.3s cubic-bezier(0.645, 0.045, 0.355, 1);transition:all 0.3s cubic-bezier(0.645, 0.045, 0.355, 1);width:100%;height:32px;padding:0 11px}.ant-select-single:not(.ant-select-customize-input) .ant-select-selector input{cursor:pointer}.ant-select-show-search.ant-select-single:not(.ant-select-customize-input) .ant-select-selector{cursor:text}.ant-select-show-search.ant-select-single:not(.ant-select-customize-input) .ant-select-selector input{cursor:auto}.ant-select-focused.ant-select-single:not(.ant-select-customize-input) .ant-select-selector{border-color:#40a9ff;border-right-width:1px !important;outline:0;-webkit-box-shadow:0 0 0 2px rgba(24,144,255,0.2);box-shadow:0 0 0 2px rgba(24,144,255,0.2)}.ant-select-disabled.ant-select-single:not(.ant-select-customize-input) .ant-select-selector{color:rgba(0,0,0,0.25);background:#f5f5f5;cursor:not-allowed}.ant-select-disabled.ant-select-single:not(.ant-select-customize-input) .ant-select-selector input{cursor:not-allowed}.ant-select-single:not(.ant-select-customize-input) .ant-select-selector .ant-select-selection-search-input{background:transparent;border:none;outline:none}.ant-select-single:not(.ant-select-customize-input) .ant-select-selector .ant-select-selection-search-input{height:30px}.ant-select-single.ant-select-customize-input .ant-select-selector::after{display:none}.ant-select-single.ant-select-customize-input .ant-select-selector .ant-select-selection-search{position:static;width:100%}.ant-select-single.ant-select-customize-input .ant-select-selector .ant-select-selection-placeholder{position:absolute;right:0;left:0;padding:0 11px}.ant-select-single.ant-select-customize-input .ant-select-selector .ant-select-selection-placeholder::after{display:none}.ant-select-single.ant-select-lg:not(.ant-select-customize-input) .ant-select-selector{height:40px}.ant-select-single.ant-select-lg:not(.ant-select-customize-input) .ant-select-selector .ant-select-selection-item,.ant-select-single.ant-select-lg:not(.ant-select-customize-input) .ant-select-selector .ant-select-selection-placeholder{line-height:38px}.ant-select-single.ant-select-lg:not(.ant-select-customize-input):not(.ant-select-customize-input) .ant-select-selection-search-input{height:38px}.ant-select-single.ant-select-sm:not(.ant-select-customize-input) .ant-select-selector{height:24px}.ant-select-single.ant-select-sm:not(.ant-select-customize-input) .ant-select-selector .ant-select-selection-item,.ant-select-single.ant-select-sm:not(.ant-select-customize-input) .ant-select-selector .ant-select-selection-placeholder{line-height:22px}.ant-select-single.ant-select-sm:not(.ant-select-customize-input):not(.ant-select-customize-input) .ant-select-selection-search-input{height:22px}.ant-select-single.ant-select-sm:not(.ant-select-customize-input) .ant-select-selection-search{right:7px;left:7px}.ant-select-single.ant-select-sm:not(.ant-select-customize-input) .ant-select-selector{padding:0 7px}.ant-select-single.ant-select-sm:not(.ant-select-customize-input).ant-select-show-arrow .ant-select-selection-search{right:28px}.ant-select-single.ant-select-sm:not(.ant-select-customize-input).ant-select-show-arrow .ant-select-selection-item,.ant-select-single.ant-select-sm:not(.ant-select-customize-input).ant-select-show-arrow .ant-select-selection-placeholder{padding-right:21px}.ant-select-single.ant-select-lg:not(.ant-select-customize-input) .ant-select-selector{padding:0 11px}.ant-select-multiple .ant-select-selector{position:relative;background-color:#fff;border:1px solid #d9d9d9;border-radius:2px;-webkit-transition:all 0.3s cubic-bezier(0.645, 0.045, 0.355, 1);transition:all 0.3s cubic-bezier(0.645, 0.045, 0.355, 1);display:-webkit-box;display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;-webkit-box-align:center;-ms-flex-align:center;align-items:center;padding:1px 4px}.ant-select-multiple .ant-select-selector input{cursor:pointer}.ant-select-show-search.ant-select-multiple .ant-select-selector{cursor:text}.ant-select-show-search.ant-select-multiple .ant-select-selector input{cursor:auto}.ant-select-focused.ant-select-multiple .ant-select-selector{border-color:#40a9ff;border-right-width:1px !important;outline:0;-webkit-box-shadow:0 0 0 2px rgba(24,144,255,0.2);box-shadow:0 0 0 2px rgba(24,144,255,0.2)}.ant-select-disabled.ant-select-multiple .ant-select-selector{color:rgba(0,0,0,0.25);background:#f5f5f5;cursor:not-allowed}.ant-select-disabled.ant-select-multiple .ant-select-selector input{cursor:not-allowed}.ant-select-multiple .ant-select-selector .ant-select-selection-search-input{background:transparent;border:none;outline:none}.ant-select-show-search.ant-select-multiple .ant-select-selector{cursor:text}.ant-select-multiple .ant-select-selector::after{display:inline-block;width:0;margin:2px 0;line-height:24px;content:'\a0'}.ant-select-multiple.ant-select-allow-clear .ant-select-selector{padding-right:24px}.ant-select-multiple .ant-select-selection-item{position:relative;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-flex:0;-ms-flex:none;flex:none;-webkit-box-sizing:border-box;box-sizing:border-box;max-width:100%;height:24px;margin-top:2px;margin-right:4px;margin-bottom:2px;padding:0 4px 0 8px;line-height:22px;background:#f5f5f5;border:1px solid #f0f0f0;border-radius:2px;cursor:default;-webkit-transition:font-size 0.3s, line-height 0.3s, height 0.3s;transition:font-size 0.3s, line-height 0.3s, height 0.3s;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.ant-select-multiple .ant-select-selection-item-content{display:inline-block;margin-right:4px;overflow:hidden;white-space:nowrap;text-overflow:ellipsis}.ant-select-multiple .ant-select-selection-item-remove{color:inherit;font-style:normal;line-height:0;text-align:center;text-transform:none;vertical-align:-0.125em;text-rendering:optimizeLegibility;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;color:rgba(0,0,0,0.45);font-weight:bold;font-size:12px;line-height:inherit;cursor:pointer;display:inline-block;font-size:10px}.ant-select-multiple .ant-select-selection-item-remove>*{line-height:1}.ant-select-multiple .ant-select-selection-item-remove svg{display:inline-block}.ant-select-multiple .ant-select-selection-item-remove::before{display:none}.ant-select-multiple .ant-select-selection-item-remove .ant-select-multiple .ant-select-selection-item-remove-icon{display:block}.ant-select-multiple .ant-select-selection-item-remove>.anticon{vertical-align:-0.2em}.ant-select-multiple .ant-select-selection-item-remove:hover{color:rgba(0,0,0,0.75)}.ant-select-multiple .ant-select-selection-search{position:relative;margin-left:0.5px}.ant-select-multiple .ant-select-selection-search-input,.ant-select-multiple .ant-select-selection-search-mirror{font-family:-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, 'Noto Sans', sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol', 'Noto Color Emoji';line-height:1.5715;-webkit-transition:all 0.3s;transition:all 0.3s}.ant-select-multiple .ant-select-selection-search-input{width:100%;min-width:3px}.ant-select-multiple .ant-select-selection-search-mirror{position:absolute;top:0;left:0;z-index:999;white-space:nowrap;visibility:hidden}.ant-select-multiple .ant-select-selection-search:first-child .ant-select-selection-search-input{margin-left:6.5px}.ant-select-multiple .ant-select-selection-placeholder{position:absolute;top:50%;right:11px;left:11px;-webkit-transform:translateY(-50%);transform:translateY(-50%);-webkit-transition:all 0.3s;transition:all 0.3s}.ant-select-multiple.ant-select-lg .ant-select-selector::after{line-height:32px}.ant-select-multiple.ant-select-lg .ant-select-selection-item{height:32px;line-height:30px}.ant-select-multiple.ant-select-lg .ant-select-selection-search{height:33px;line-height:33px}.ant-select-multiple.ant-select-lg .ant-select-selection-search-input,.ant-select-multiple.ant-select-lg .ant-select-selection-search-mirror{height:32px;line-height:30px}.ant-select-multiple.ant-select-sm .ant-select-selector::after{line-height:16px}.ant-select-multiple.ant-select-sm .ant-select-selection-item{height:16px;line-height:14px}.ant-select-multiple.ant-select-sm .ant-select-selection-search{height:17px;line-height:17px}.ant-select-multiple.ant-select-sm .ant-select-selection-search-input,.ant-select-multiple.ant-select-sm .ant-select-selection-search-mirror{height:16px;line-height:14px}.ant-select-multiple.ant-select-sm .ant-select-selection-placeholder{left:7px}.ant-select-multiple.ant-select-sm .ant-select-selection-search:first-child .ant-select-selection-search-input{margin-left:3px}.ant-select-multiple.ant-select-lg .ant-select-selection-item{height:32px;line-height:32px}.ant-select-disabled .ant-select-selection-item-remove{display:none}.ant-select{-webkit-box-sizing:border-box;box-sizing:border-box;margin:0;padding:0;color:rgba(0,0,0,0.65);font-size:14px;font-variant:tabular-nums;line-height:1.5715;list-style:none;-webkit-font-feature-settings:'tnum';font-feature-settings:'tnum';position:relative;display:inline-block;cursor:pointer}.ant-select:not(.ant-select-disabled):hover .ant-select-selector{border-color:#40a9ff;border-right-width:1px !important}.ant-select-selection-item{-webkit-box-flex:1;-ms-flex:1;flex:1;overflow:hidden;white-space:nowrap;text-overflow:ellipsis}@media all and (-ms-high-contrast: none){.ant-select-selection-item *::-ms-backdrop,.ant-select-selection-item{-ms-flex:auto;flex:auto}}.ant-select-selection-placeholder{-webkit-box-flex:1;-ms-flex:1;flex:1;overflow:hidden;white-space:nowrap;text-overflow:ellipsis;opacity:0.4}@media all and (-ms-high-contrast: none){.ant-select-selection-placeholder *::-ms-backdrop,.ant-select-selection-placeholder{-ms-flex:auto;flex:auto}}.ant-select-arrow{display:inline-block;color:inherit;font-style:normal;line-height:0;text-transform:none;vertical-align:-0.125em;text-rendering:optimizeLegibility;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;position:absolute;top:53%;right:11px;width:12px;height:12px;margin-top:-6px;color:rgba(0,0,0,0.25);font-size:12px;line-height:1;text-align:center;pointer-events:none}.ant-select-arrow>*{line-height:1}.ant-select-arrow svg{display:inline-block}.ant-select-arrow::before{display:none}.ant-select-arrow .ant-select-arrow-icon{display:block}.ant-select-arrow .anticon{vertical-align:top;-webkit-transition:-webkit-transform 0.3s;transition:-webkit-transform 0.3s;transition:transform 0.3s;transition:transform 0.3s, -webkit-transform 0.3s}.ant-select-arrow .anticon>svg{vertical-align:top}.ant-select-arrow .anticon:not(.anticon-down){pointer-events:auto}.ant-select-clear{position:absolute;top:50%;right:11px;z-index:1;display:inline-block;width:12px;height:12px;margin-top:-6px;color:rgba(0,0,0,0.25);font-size:12px;font-style:normal;line-height:1;text-align:center;text-transform:none;background:#fff;cursor:pointer;opacity:0;-webkit-transition:color 0.3s ease, opacity 0.15s ease;transition:color 0.3s ease, opacity 0.15s ease;text-rendering:auto}.ant-select-clear::before{display:block}.ant-select-clear:hover{color:rgba(0,0,0,0.45)}.ant-select:hover .ant-select-clear{opacity:1}.ant-select-dropdown{margin:0;padding:0;color:rgba(0,0,0,0.65);font-variant:tabular-nums;line-height:1.5715;list-style:none;-webkit-font-feature-settings:'tnum';font-feature-settings:'tnum';position:absolute;top:-9999px;left:-9999px;z-index:1050;-webkit-box-sizing:border-box;box-sizing:border-box;padding:4px 0;overflow:hidden;font-size:14px;font-variant:initial;background-color:#fff;border-radius:2px;outline:none;-webkit-box-shadow:0 3px 6px -4px rgba(0,0,0,0.12),0 6px 16px 0 rgba(0,0,0,0.08),0 9px 28px 8px rgba(0,0,0,0.05);box-shadow:0 3px 6px -4px rgba(0,0,0,0.12),0 6px 16px 0 rgba(0,0,0,0.08),0 9px 28px 8px rgba(0,0,0,0.05)}.ant-select-dropdown.slide-up-enter.slide-up-enter-active.ant-select-dropdown-placement-bottomLeft,.ant-select-dropdown.slide-up-appear.slide-up-appear-active.ant-select-dropdown-placement-bottomLeft{-webkit-animation-name:antSlideUpIn;animation-name:antSlideUpIn}.ant-select-dropdown.slide-up-enter.slide-up-enter-active.ant-select-dropdown-placement-topLeft,.ant-select-dropdown.slide-up-appear.slide-up-appear-active.ant-select-dropdown-placement-topLeft{-webkit-animation-name:antSlideDownIn;animation-name:antSlideDownIn}.ant-select-dropdown.slide-up-leave.slide-up-leave-active.ant-select-dropdown-placement-bottomLeft{-webkit-animation-name:antSlideUpOut;animation-name:antSlideUpOut}.ant-select-dropdown.slide-up-leave.slide-up-leave-active.ant-select-dropdown-placement-topLeft{-webkit-animation-name:antSlideDownOut;animation-name:antSlideDownOut}.ant-select-dropdown-hidden{display:none}.ant-select-item-empty{position:relative;display:block;min-height:32px;padding:5px 12px;color:rgba(0,0,0,0.65);font-weight:normal;font-size:14px;line-height:22px}.ant-select-item{position:relative;display:block;min-height:32px;padding:5px 12px;color:rgba(0,0,0,0.65);font-weight:normal;font-size:14px;line-height:22px;cursor:pointer;-webkit-transition:background 0.3s ease;transition:background 0.3s ease}.ant-select-item-group{color:rgba(0,0,0,0.45);font-size:12px;cursor:default}.ant-select-item-option{display:-webkit-box;display:-ms-flexbox;display:flex}.ant-select-item-option-content{-webkit-box-flex:1;-ms-flex:auto;flex:auto;overflow:hidden;white-space:nowrap;text-overflow:ellipsis}.ant-select-item-option-state{-webkit-box-flex:0;-ms-flex:none;flex:none}.ant-select-item-option-active:not(.ant-select-item-option-disabled){background-color:#f5f5f5}.ant-select-item-option-selected:not(.ant-select-item-option-disabled){color:rgba(0,0,0,0.65);font-weight:600;background-color:#e6f7ff}.ant-select-item-option-selected:not(.ant-select-item-option-disabled) .ant-select-item-option-state{color:#1890ff}.ant-select-item-option-disabled{color:rgba(0,0,0,0.25);cursor:not-allowed}.ant-select-item-option-grouped{padding-left:24px}.ant-select-lg{font-size:16px}.ant-select-borderless .ant-select-selector{background-color:transparent !important;border-color:transparent !important;-webkit-box-shadow:none !important;box-shadow:none !important}.ant-select-rtl{direction:rtl}.ant-select-rtl .ant-select-arrow{right:initial;left:11px}.ant-select-rtl .ant-select-clear{right:initial;left:11px}.ant-select-dropdown-rtl{direction:rtl}.ant-select-dropdown-rtl .ant-select-item-option-grouped{padding-right:24px;padding-left:12px}.ant-select-rtl.ant-select-multiple.ant-select-allow-clear .ant-select-selector{padding-right:4px;padding-left:24px}.ant-select-rtl.ant-select-multiple .ant-select-selection-item{margin-right:0;margin-left:4px;padding:0 8px 0 4px;text-align:right}.ant-select-rtl.ant-select-multiple .ant-select-selection-item-content{margin-right:0;margin-left:4px;text-align:right}.ant-select-rtl.ant-select-multiple .ant-select-selection-search{margin-right:0.5px;margin-left:4px}.ant-select-rtl.ant-select-multiple .ant-select-selection-search-mirror{right:0;left:auto}.ant-select-rtl.ant-select-multiple .ant-select-selection-placeholder{right:11px;left:auto}.ant-select-rtl.ant-select-multiple.ant-select-sm .ant-select-selection-placeholder{right:7px}.ant-select-rtl.ant-select-single .ant-select-selector .ant-select-selection-item,.ant-select-rtl.ant-select-single .ant-select-selector .ant-select-selection-placeholder{right:0;left:9px;text-align:right}.ant-select-rtl.ant-select-single.ant-select-show-arrow .ant-select-selection-search{right:11px;left:25px}.ant-select-rtl.ant-select-single.ant-select-show-arrow .ant-select-selection-item,.ant-select-rtl.ant-select-single.ant-select-show-arrow .ant-select-selection-placeholder{padding-right:0;padding-left:18px}.ant-select-rtl.ant-select-single:not(.ant-select-customize-input) .ant-select-selector{padding:0 11px}.ant-select-rtl.ant-select-single.ant-select-sm:not(.ant-select-customize-input).ant-select-show-arrow .ant-select-selection-search{right:0}.ant-select-rtl.ant-select-single.ant-select-sm:not(.ant-select-customize-input).ant-select-show-arrow .ant-select-selection-item,.ant-select-rtl.ant-select-single.ant-select-sm:not(.ant-select-customize-input).ant-select-show-arrow .ant-select-selection-placeholder{padding-right:0;padding-left:21px}
|
|
|
|
1 |
+
#wcml-by-language-tooltip{text-align:center}#wcml-by-language-tooltip a{color:#ffffff}
|
2 |
.fade-enter,.fade-appear{-webkit-animation-duration:0.2s;animation-duration:0.2s;-webkit-animation-fill-mode:both;animation-fill-mode:both;-webkit-animation-play-state:paused;animation-play-state:paused}.fade-leave{-webkit-animation-duration:0.2s;animation-duration:0.2s;-webkit-animation-fill-mode:both;animation-fill-mode:both;-webkit-animation-play-state:paused;animation-play-state:paused}.fade-enter.fade-enter-active,.fade-appear.fade-appear-active{-webkit-animation-name:antFadeIn;animation-name:antFadeIn;-webkit-animation-play-state:running;animation-play-state:running}.fade-leave.fade-leave-active{-webkit-animation-name:antFadeOut;animation-name:antFadeOut;-webkit-animation-play-state:running;animation-play-state:running;pointer-events:none}.fade-enter,.fade-appear{opacity:0;-webkit-animation-timing-function:linear;animation-timing-function:linear}.fade-leave{-webkit-animation-timing-function:linear;animation-timing-function:linear}@-webkit-keyframes antFadeIn{0%{opacity:0}100%{opacity:1}}@keyframes antFadeIn{0%{opacity:0}100%{opacity:1}}@-webkit-keyframes antFadeOut{0%{opacity:1}100%{opacity:0}}@keyframes antFadeOut{0%{opacity:1}100%{opacity:0}}.move-up-enter,.move-up-appear{-webkit-animation-duration:0.2s;animation-duration:0.2s;-webkit-animation-fill-mode:both;animation-fill-mode:both;-webkit-animation-play-state:paused;animation-play-state:paused}.move-up-leave{-webkit-animation-duration:0.2s;animation-duration:0.2s;-webkit-animation-fill-mode:both;animation-fill-mode:both;-webkit-animation-play-state:paused;animation-play-state:paused}.move-up-enter.move-up-enter-active,.move-up-appear.move-up-appear-active{-webkit-animation-name:antMoveUpIn;animation-name:antMoveUpIn;-webkit-animation-play-state:running;animation-play-state:running}.move-up-leave.move-up-leave-active{-webkit-animation-name:antMoveUpOut;animation-name:antMoveUpOut;-webkit-animation-play-state:running;animation-play-state:running;pointer-events:none}.move-up-enter,.move-up-appear{opacity:0;-webkit-animation-timing-function:cubic-bezier(0.08, 0.82, 0.17, 1);animation-timing-function:cubic-bezier(0.08, 0.82, 0.17, 1)}.move-up-leave{-webkit-animation-timing-function:cubic-bezier(0.6, 0.04, 0.98, 0.34);animation-timing-function:cubic-bezier(0.6, 0.04, 0.98, 0.34)}.move-down-enter,.move-down-appear{-webkit-animation-duration:0.2s;animation-duration:0.2s;-webkit-animation-fill-mode:both;animation-fill-mode:both;-webkit-animation-play-state:paused;animation-play-state:paused}.move-down-leave{-webkit-animation-duration:0.2s;animation-duration:0.2s;-webkit-animation-fill-mode:both;animation-fill-mode:both;-webkit-animation-play-state:paused;animation-play-state:paused}.move-down-enter.move-down-enter-active,.move-down-appear.move-down-appear-active{-webkit-animation-name:antMoveDownIn;animation-name:antMoveDownIn;-webkit-animation-play-state:running;animation-play-state:running}.move-down-leave.move-down-leave-active{-webkit-animation-name:antMoveDownOut;animation-name:antMoveDownOut;-webkit-animation-play-state:running;animation-play-state:running;pointer-events:none}.move-down-enter,.move-down-appear{opacity:0;-webkit-animation-timing-function:cubic-bezier(0.08, 0.82, 0.17, 1);animation-timing-function:cubic-bezier(0.08, 0.82, 0.17, 1)}.move-down-leave{-webkit-animation-timing-function:cubic-bezier(0.6, 0.04, 0.98, 0.34);animation-timing-function:cubic-bezier(0.6, 0.04, 0.98, 0.34)}.move-left-enter,.move-left-appear{-webkit-animation-duration:0.2s;animation-duration:0.2s;-webkit-animation-fill-mode:both;animation-fill-mode:both;-webkit-animation-play-state:paused;animation-play-state:paused}.move-left-leave{-webkit-animation-duration:0.2s;animation-duration:0.2s;-webkit-animation-fill-mode:both;animation-fill-mode:both;-webkit-animation-play-state:paused;animation-play-state:paused}.move-left-enter.move-left-enter-active,.move-left-appear.move-left-appear-active{-webkit-animation-name:antMoveLeftIn;animation-name:antMoveLeftIn;-webkit-animation-play-state:running;animation-play-state:running}.move-left-leave.move-left-leave-active{-webkit-animation-name:antMoveLeftOut;animation-name:antMoveLeftOut;-webkit-animation-play-state:running;animation-play-state:running;pointer-events:none}.move-left-enter,.move-left-appear{opacity:0;-webkit-animation-timing-function:cubic-bezier(0.08, 0.82, 0.17, 1);animation-timing-function:cubic-bezier(0.08, 0.82, 0.17, 1)}.move-left-leave{-webkit-animation-timing-function:cubic-bezier(0.6, 0.04, 0.98, 0.34);animation-timing-function:cubic-bezier(0.6, 0.04, 0.98, 0.34)}.move-right-enter,.move-right-appear{-webkit-animation-duration:0.2s;animation-duration:0.2s;-webkit-animation-fill-mode:both;animation-fill-mode:both;-webkit-animation-play-state:paused;animation-play-state:paused}.move-right-leave{-webkit-animation-duration:0.2s;animation-duration:0.2s;-webkit-animation-fill-mode:both;animation-fill-mode:both;-webkit-animation-play-state:paused;animation-play-state:paused}.move-right-enter.move-right-enter-active,.move-right-appear.move-right-appear-active{-webkit-animation-name:antMoveRightIn;animation-name:antMoveRightIn;-webkit-animation-play-state:running;animation-play-state:running}.move-right-leave.move-right-leave-active{-webkit-animation-name:antMoveRightOut;animation-name:antMoveRightOut;-webkit-animation-play-state:running;animation-play-state:running;pointer-events:none}.move-right-enter,.move-right-appear{opacity:0;-webkit-animation-timing-function:cubic-bezier(0.08, 0.82, 0.17, 1);animation-timing-function:cubic-bezier(0.08, 0.82, 0.17, 1)}.move-right-leave{-webkit-animation-timing-function:cubic-bezier(0.6, 0.04, 0.98, 0.34);animation-timing-function:cubic-bezier(0.6, 0.04, 0.98, 0.34)}@-webkit-keyframes antMoveDownIn{0%{-webkit-transform:translateY(100%);transform:translateY(100%);-webkit-transform-origin:0 0;transform-origin:0 0;opacity:0}100%{-webkit-transform:translateY(0%);transform:translateY(0%);-webkit-transform-origin:0 0;transform-origin:0 0;opacity:1}}@keyframes antMoveDownIn{0%{-webkit-transform:translateY(100%);transform:translateY(100%);-webkit-transform-origin:0 0;transform-origin:0 0;opacity:0}100%{-webkit-transform:translateY(0%);transform:translateY(0%);-webkit-transform-origin:0 0;transform-origin:0 0;opacity:1}}@-webkit-keyframes antMoveDownOut{0%{-webkit-transform:translateY(0%);transform:translateY(0%);-webkit-transform-origin:0 0;transform-origin:0 0;opacity:1}100%{-webkit-transform:translateY(100%);transform:translateY(100%);-webkit-transform-origin:0 0;transform-origin:0 0;opacity:0}}@keyframes antMoveDownOut{0%{-webkit-transform:translateY(0%);transform:translateY(0%);-webkit-transform-origin:0 0;transform-origin:0 0;opacity:1}100%{-webkit-transform:translateY(100%);transform:translateY(100%);-webkit-transform-origin:0 0;transform-origin:0 0;opacity:0}}@-webkit-keyframes antMoveLeftIn{0%{-webkit-transform:translateX(-100%);transform:translateX(-100%);-webkit-transform-origin:0 0;transform-origin:0 0;opacity:0}100%{-webkit-transform:translateX(0%);transform:translateX(0%);-webkit-transform-origin:0 0;transform-origin:0 0;opacity:1}}@keyframes antMoveLeftIn{0%{-webkit-transform:translateX(-100%);transform:translateX(-100%);-webkit-transform-origin:0 0;transform-origin:0 0;opacity:0}100%{-webkit-transform:translateX(0%);transform:translateX(0%);-webkit-transform-origin:0 0;transform-origin:0 0;opacity:1}}@-webkit-keyframes antMoveLeftOut{0%{-webkit-transform:translateX(0%);transform:translateX(0%);-webkit-transform-origin:0 0;transform-origin:0 0;opacity:1}100%{-webkit-transform:translateX(-100%);transform:translateX(-100%);-webkit-transform-origin:0 0;transform-origin:0 0;opacity:0}}@keyframes antMoveLeftOut{0%{-webkit-transform:translateX(0%);transform:translateX(0%);-webkit-transform-origin:0 0;transform-origin:0 0;opacity:1}100%{-webkit-transform:translateX(-100%);transform:translateX(-100%);-webkit-transform-origin:0 0;transform-origin:0 0;opacity:0}}@-webkit-keyframes antMoveRightIn{0%{-webkit-transform:translateX(100%);transform:translateX(100%);-webkit-transform-origin:0 0;transform-origin:0 0;opacity:0}100%{-webkit-transform:translateX(0%);transform:translateX(0%);-webkit-transform-origin:0 0;transform-origin:0 0;opacity:1}}@keyframes antMoveRightIn{0%{-webkit-transform:translateX(100%);transform:translateX(100%);-webkit-transform-origin:0 0;transform-origin:0 0;opacity:0}100%{-webkit-transform:translateX(0%);transform:translateX(0%);-webkit-transform-origin:0 0;transform-origin:0 0;opacity:1}}@-webkit-keyframes antMoveRightOut{0%{-webkit-transform:translateX(0%);transform:translateX(0%);-webkit-transform-origin:0 0;transform-origin:0 0;opacity:1}100%{-webkit-transform:translateX(100%);transform:translateX(100%);-webkit-transform-origin:0 0;transform-origin:0 0;opacity:0}}@keyframes antMoveRightOut{0%{-webkit-transform:translateX(0%);transform:translateX(0%);-webkit-transform-origin:0 0;transform-origin:0 0;opacity:1}100%{-webkit-transform:translateX(100%);transform:translateX(100%);-webkit-transform-origin:0 0;transform-origin:0 0;opacity:0}}@-webkit-keyframes antMoveUpIn{0%{-webkit-transform:translateY(-100%);transform:translateY(-100%);-webkit-transform-origin:0 0;transform-origin:0 0;opacity:0}100%{-webkit-transform:translateY(0%);transform:translateY(0%);-webkit-transform-origin:0 0;transform-origin:0 0;opacity:1}}@keyframes antMoveUpIn{0%{-webkit-transform:translateY(-100%);transform:translateY(-100%);-webkit-transform-origin:0 0;transform-origin:0 0;opacity:0}100%{-webkit-transform:translateY(0%);transform:translateY(0%);-webkit-transform-origin:0 0;transform-origin:0 0;opacity:1}}@-webkit-keyframes antMoveUpOut{0%{-webkit-transform:translateY(0%);transform:translateY(0%);-webkit-transform-origin:0 0;transform-origin:0 0;opacity:1}100%{-webkit-transform:translateY(-100%);transform:translateY(-100%);-webkit-transform-origin:0 0;transform-origin:0 0;opacity:0}}@keyframes antMoveUpOut{0%{-webkit-transform:translateY(0%);transform:translateY(0%);-webkit-transform-origin:0 0;transform-origin:0 0;opacity:1}100%{-webkit-transform:translateY(-100%);transform:translateY(-100%);-webkit-transform-origin:0 0;transform-origin:0 0;opacity:0}}@-webkit-keyframes loadingCircle{100%{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}@keyframes loadingCircle{100%{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}[ant-click-animating='true'],[ant-click-animating-without-extra-node='true']{position:relative}html{--antd-wave-shadow-color: #1890ff;--scroll-bar: 0}[ant-click-animating-without-extra-node='true']::after,.ant-click-animating-node{position:absolute;top:0;right:0;bottom:0;left:0;display:block;border-radius:inherit;box-shadow:0 0 0 0 #1890ff;box-shadow:0 0 0 0 var(--antd-wave-shadow-color);opacity:0.2;-webkit-animation:fadeEffect 2s cubic-bezier(0.08, 0.82, 0.17, 1),waveEffect 0.4s cubic-bezier(0.08, 0.82, 0.17, 1);animation:fadeEffect 2s cubic-bezier(0.08, 0.82, 0.17, 1),waveEffect 0.4s cubic-bezier(0.08, 0.82, 0.17, 1);-webkit-animation-fill-mode:forwards;animation-fill-mode:forwards;content:'';pointer-events:none}@-webkit-keyframes waveEffect{100%{box-shadow:0 0 0 #1890ff;box-shadow:0 0 0 6px var(--antd-wave-shadow-color)}}@keyframes waveEffect{100%{box-shadow:0 0 0 #1890ff;box-shadow:0 0 0 6px var(--antd-wave-shadow-color)}}@-webkit-keyframes fadeEffect{100%{opacity:0}}@keyframes fadeEffect{100%{opacity:0}}.slide-up-enter,.slide-up-appear{-webkit-animation-duration:0.2s;animation-duration:0.2s;-webkit-animation-fill-mode:both;animation-fill-mode:both;-webkit-animation-play-state:paused;animation-play-state:paused}.slide-up-leave{-webkit-animation-duration:0.2s;animation-duration:0.2s;-webkit-animation-fill-mode:both;animation-fill-mode:both;-webkit-animation-play-state:paused;animation-play-state:paused}.slide-up-enter.slide-up-enter-active,.slide-up-appear.slide-up-appear-active{-webkit-animation-name:antSlideUpIn;animation-name:antSlideUpIn;-webkit-animation-play-state:running;animation-play-state:running}.slide-up-leave.slide-up-leave-active{-webkit-animation-name:antSlideUpOut;animation-name:antSlideUpOut;-webkit-animation-play-state:running;animation-play-state:running;pointer-events:none}.slide-up-enter,.slide-up-appear{opacity:0;-webkit-animation-timing-function:cubic-bezier(0.23, 1, 0.32, 1);animation-timing-function:cubic-bezier(0.23, 1, 0.32, 1)}.slide-up-leave{-webkit-animation-timing-function:cubic-bezier(0.755, 0.05, 0.855, 0.06);animation-timing-function:cubic-bezier(0.755, 0.05, 0.855, 0.06)}.slide-down-enter,.slide-down-appear{-webkit-animation-duration:0.2s;animation-duration:0.2s;-webkit-animation-fill-mode:both;animation-fill-mode:both;-webkit-animation-play-state:paused;animation-play-state:paused}.slide-down-leave{-webkit-animation-duration:0.2s;animation-duration:0.2s;-webkit-animation-fill-mode:both;animation-fill-mode:both;-webkit-animation-play-state:paused;animation-play-state:paused}.slide-down-enter.slide-down-enter-active,.slide-down-appear.slide-down-appear-active{-webkit-animation-name:antSlideDownIn;animation-name:antSlideDownIn;-webkit-animation-play-state:running;animation-play-state:running}.slide-down-leave.slide-down-leave-active{-webkit-animation-name:antSlideDownOut;animation-name:antSlideDownOut;-webkit-animation-play-state:running;animation-play-state:running;pointer-events:none}.slide-down-enter,.slide-down-appear{opacity:0;-webkit-animation-timing-function:cubic-bezier(0.23, 1, 0.32, 1);animation-timing-function:cubic-bezier(0.23, 1, 0.32, 1)}.slide-down-leave{-webkit-animation-timing-function:cubic-bezier(0.755, 0.05, 0.855, 0.06);animation-timing-function:cubic-bezier(0.755, 0.05, 0.855, 0.06)}.slide-left-enter,.slide-left-appear{-webkit-animation-duration:0.2s;animation-duration:0.2s;-webkit-animation-fill-mode:both;animation-fill-mode:both;-webkit-animation-play-state:paused;animation-play-state:paused}.slide-left-leave{-webkit-animation-duration:0.2s;animation-duration:0.2s;-webkit-animation-fill-mode:both;animation-fill-mode:both;-webkit-animation-play-state:paused;animation-play-state:paused}.slide-left-enter.slide-left-enter-active,.slide-left-appear.slide-left-appear-active{-webkit-animation-name:antSlideLeftIn;animation-name:antSlideLeftIn;-webkit-animation-play-state:running;animation-play-state:running}.slide-left-leave.slide-left-leave-active{-webkit-animation-name:antSlideLeftOut;animation-name:antSlideLeftOut;-webkit-animation-play-state:running;animation-play-state:running;pointer-events:none}.slide-left-enter,.slide-left-appear{opacity:0;-webkit-animation-timing-function:cubic-bezier(0.23, 1, 0.32, 1);animation-timing-function:cubic-bezier(0.23, 1, 0.32, 1)}.slide-left-leave{-webkit-animation-timing-function:cubic-bezier(0.755, 0.05, 0.855, 0.06);animation-timing-function:cubic-bezier(0.755, 0.05, 0.855, 0.06)}.slide-right-enter,.slide-right-appear{-webkit-animation-duration:0.2s;animation-duration:0.2s;-webkit-animation-fill-mode:both;animation-fill-mode:both;-webkit-animation-play-state:paused;animation-play-state:paused}.slide-right-leave{-webkit-animation-duration:0.2s;animation-duration:0.2s;-webkit-animation-fill-mode:both;animation-fill-mode:both;-webkit-animation-play-state:paused;animation-play-state:paused}.slide-right-enter.slide-right-enter-active,.slide-right-appear.slide-right-appear-active{-webkit-animation-name:antSlideRightIn;animation-name:antSlideRightIn;-webkit-animation-play-state:running;animation-play-state:running}.slide-right-leave.slide-right-leave-active{-webkit-animation-name:antSlideRightOut;animation-name:antSlideRightOut;-webkit-animation-play-state:running;animation-play-state:running;pointer-events:none}.slide-right-enter,.slide-right-appear{opacity:0;-webkit-animation-timing-function:cubic-bezier(0.23, 1, 0.32, 1);animation-timing-function:cubic-bezier(0.23, 1, 0.32, 1)}.slide-right-leave{-webkit-animation-timing-function:cubic-bezier(0.755, 0.05, 0.855, 0.06);animation-timing-function:cubic-bezier(0.755, 0.05, 0.855, 0.06)}@-webkit-keyframes antSlideUpIn{0%{-webkit-transform:scaleY(0.8);transform:scaleY(0.8);-webkit-transform-origin:0% 0%;transform-origin:0% 0%;opacity:0}100%{-webkit-transform:scaleY(1);transform:scaleY(1);-webkit-transform-origin:0% 0%;transform-origin:0% 0%;opacity:1}}@keyframes antSlideUpIn{0%{-webkit-transform:scaleY(0.8);transform:scaleY(0.8);-webkit-transform-origin:0% 0%;transform-origin:0% 0%;opacity:0}100%{-webkit-transform:scaleY(1);transform:scaleY(1);-webkit-transform-origin:0% 0%;transform-origin:0% 0%;opacity:1}}@-webkit-keyframes antSlideUpOut{0%{-webkit-transform:scaleY(1);transform:scaleY(1);-webkit-transform-origin:0% 0%;transform-origin:0% 0%;opacity:1}100%{-webkit-transform:scaleY(0.8);transform:scaleY(0.8);-webkit-transform-origin:0% 0%;transform-origin:0% 0%;opacity:0}}@keyframes antSlideUpOut{0%{-webkit-transform:scaleY(1);transform:scaleY(1);-webkit-transform-origin:0% 0%;transform-origin:0% 0%;opacity:1}100%{-webkit-transform:scaleY(0.8);transform:scaleY(0.8);-webkit-transform-origin:0% 0%;transform-origin:0% 0%;opacity:0}}@-webkit-keyframes antSlideDownIn{0%{-webkit-transform:scaleY(0.8);transform:scaleY(0.8);-webkit-transform-origin:100% 100%;transform-origin:100% 100%;opacity:0}100%{-webkit-transform:scaleY(1);transform:scaleY(1);-webkit-transform-origin:100% 100%;transform-origin:100% 100%;opacity:1}}@keyframes antSlideDownIn{0%{-webkit-transform:scaleY(0.8);transform:scaleY(0.8);-webkit-transform-origin:100% 100%;transform-origin:100% 100%;opacity:0}100%{-webkit-transform:scaleY(1);transform:scaleY(1);-webkit-transform-origin:100% 100%;transform-origin:100% 100%;opacity:1}}@-webkit-keyframes antSlideDownOut{0%{-webkit-transform:scaleY(1);transform:scaleY(1);-webkit-transform-origin:100% 100%;transform-origin:100% 100%;opacity:1}100%{-webkit-transform:scaleY(0.8);transform:scaleY(0.8);-webkit-transform-origin:100% 100%;transform-origin:100% 100%;opacity:0}}@keyframes antSlideDownOut{0%{-webkit-transform:scaleY(1);transform:scaleY(1);-webkit-transform-origin:100% 100%;transform-origin:100% 100%;opacity:1}100%{-webkit-transform:scaleY(0.8);transform:scaleY(0.8);-webkit-transform-origin:100% 100%;transform-origin:100% 100%;opacity:0}}@-webkit-keyframes antSlideLeftIn{0%{-webkit-transform:scaleX(0.8);transform:scaleX(0.8);-webkit-transform-origin:0% 0%;transform-origin:0% 0%;opacity:0}100%{-webkit-transform:scaleX(1);transform:scaleX(1);-webkit-transform-origin:0% 0%;transform-origin:0% 0%;opacity:1}}@keyframes antSlideLeftIn{0%{-webkit-transform:scaleX(0.8);transform:scaleX(0.8);-webkit-transform-origin:0% 0%;transform-origin:0% 0%;opacity:0}100%{-webkit-transform:scaleX(1);transform:scaleX(1);-webkit-transform-origin:0% 0%;transform-origin:0% 0%;opacity:1}}@-webkit-keyframes antSlideLeftOut{0%{-webkit-transform:scaleX(1);transform:scaleX(1);-webkit-transform-origin:0% 0%;transform-origin:0% 0%;opacity:1}100%{-webkit-transform:scaleX(0.8);transform:scaleX(0.8);-webkit-transform-origin:0% 0%;transform-origin:0% 0%;opacity:0}}@keyframes antSlideLeftOut{0%{-webkit-transform:scaleX(1);transform:scaleX(1);-webkit-transform-origin:0% 0%;transform-origin:0% 0%;opacity:1}100%{-webkit-transform:scaleX(0.8);transform:scaleX(0.8);-webkit-transform-origin:0% 0%;transform-origin:0% 0%;opacity:0}}@-webkit-keyframes antSlideRightIn{0%{-webkit-transform:scaleX(0.8);transform:scaleX(0.8);-webkit-transform-origin:100% 0%;transform-origin:100% 0%;opacity:0}100%{-webkit-transform:scaleX(1);transform:scaleX(1);-webkit-transform-origin:100% 0%;transform-origin:100% 0%;opacity:1}}@keyframes antSlideRightIn{0%{-webkit-transform:scaleX(0.8);transform:scaleX(0.8);-webkit-transform-origin:100% 0%;transform-origin:100% 0%;opacity:0}100%{-webkit-transform:scaleX(1);transform:scaleX(1);-webkit-transform-origin:100% 0%;transform-origin:100% 0%;opacity:1}}@-webkit-keyframes antSlideRightOut{0%{-webkit-transform:scaleX(1);transform:scaleX(1);-webkit-transform-origin:100% 0%;transform-origin:100% 0%;opacity:1}100%{-webkit-transform:scaleX(0.8);transform:scaleX(0.8);-webkit-transform-origin:100% 0%;transform-origin:100% 0%;opacity:0}}@keyframes antSlideRightOut{0%{-webkit-transform:scaleX(1);transform:scaleX(1);-webkit-transform-origin:100% 0%;transform-origin:100% 0%;opacity:1}100%{-webkit-transform:scaleX(0.8);transform:scaleX(0.8);-webkit-transform-origin:100% 0%;transform-origin:100% 0%;opacity:0}}.zoom-enter,.zoom-appear{-webkit-animation-duration:0.2s;animation-duration:0.2s;-webkit-animation-fill-mode:both;animation-fill-mode:both;-webkit-animation-play-state:paused;animation-play-state:paused}.zoom-leave{-webkit-animation-duration:0.2s;animation-duration:0.2s;-webkit-animation-fill-mode:both;animation-fill-mode:both;-webkit-animation-play-state:paused;animation-play-state:paused}.zoom-enter.zoom-enter-active,.zoom-appear.zoom-appear-active{-webkit-animation-name:antZoomIn;animation-name:antZoomIn;-webkit-animation-play-state:running;animation-play-state:running}.zoom-leave.zoom-leave-active{-webkit-animation-name:antZoomOut;animation-name:antZoomOut;-webkit-animation-play-state:running;animation-play-state:running;pointer-events:none}.zoom-enter,.zoom-appear{-webkit-transform:scale(0);transform:scale(0);opacity:0;-webkit-animation-timing-function:cubic-bezier(0.08, 0.82, 0.17, 1);animation-timing-function:cubic-bezier(0.08, 0.82, 0.17, 1)}.zoom-leave{-webkit-animation-timing-function:cubic-bezier(0.78, 0.14, 0.15, 0.86);animation-timing-function:cubic-bezier(0.78, 0.14, 0.15, 0.86)}.zoom-big-enter,.zoom-big-appear{-webkit-animation-duration:0.2s;animation-duration:0.2s;-webkit-animation-fill-mode:both;animation-fill-mode:both;-webkit-animation-play-state:paused;animation-play-state:paused}.zoom-big-leave{-webkit-animation-duration:0.2s;animation-duration:0.2s;-webkit-animation-fill-mode:both;animation-fill-mode:both;-webkit-animation-play-state:paused;animation-play-state:paused}.zoom-big-enter.zoom-big-enter-active,.zoom-big-appear.zoom-big-appear-active{-webkit-animation-name:antZoomBigIn;animation-name:antZoomBigIn;-webkit-animation-play-state:running;animation-play-state:running}.zoom-big-leave.zoom-big-leave-active{-webkit-animation-name:antZoomBigOut;animation-name:antZoomBigOut;-webkit-animation-play-state:running;animation-play-state:running;pointer-events:none}.zoom-big-enter,.zoom-big-appear{-webkit-transform:scale(0);transform:scale(0);opacity:0;-webkit-animation-timing-function:cubic-bezier(0.08, 0.82, 0.17, 1);animation-timing-function:cubic-bezier(0.08, 0.82, 0.17, 1)}.zoom-big-leave{-webkit-animation-timing-function:cubic-bezier(0.78, 0.14, 0.15, 0.86);animation-timing-function:cubic-bezier(0.78, 0.14, 0.15, 0.86)}.zoom-big-fast-enter,.zoom-big-fast-appear{-webkit-animation-duration:0.1s;animation-duration:0.1s;-webkit-animation-fill-mode:both;animation-fill-mode:both;-webkit-animation-play-state:paused;animation-play-state:paused}.zoom-big-fast-leave{-webkit-animation-duration:0.1s;animation-duration:0.1s;-webkit-animation-fill-mode:both;animation-fill-mode:both;-webkit-animation-play-state:paused;animation-play-state:paused}.zoom-big-fast-enter.zoom-big-fast-enter-active,.zoom-big-fast-appear.zoom-big-fast-appear-active{-webkit-animation-name:antZoomBigIn;animation-name:antZoomBigIn;-webkit-animation-play-state:running;animation-play-state:running}.zoom-big-fast-leave.zoom-big-fast-leave-active{-webkit-animation-name:antZoomBigOut;animation-name:antZoomBigOut;-webkit-animation-play-state:running;animation-play-state:running;pointer-events:none}.zoom-big-fast-enter,.zoom-big-fast-appear{-webkit-transform:scale(0);transform:scale(0);opacity:0;-webkit-animation-timing-function:cubic-bezier(0.08, 0.82, 0.17, 1);animation-timing-function:cubic-bezier(0.08, 0.82, 0.17, 1)}.zoom-big-fast-leave{-webkit-animation-timing-function:cubic-bezier(0.78, 0.14, 0.15, 0.86);animation-timing-function:cubic-bezier(0.78, 0.14, 0.15, 0.86)}.zoom-up-enter,.zoom-up-appear{-webkit-animation-duration:0.2s;animation-duration:0.2s;-webkit-animation-fill-mode:both;animation-fill-mode:both;-webkit-animation-play-state:paused;animation-play-state:paused}.zoom-up-leave{-webkit-animation-duration:0.2s;animation-duration:0.2s;-webkit-animation-fill-mode:both;animation-fill-mode:both;-webkit-animation-play-state:paused;animation-play-state:paused}.zoom-up-enter.zoom-up-enter-active,.zoom-up-appear.zoom-up-appear-active{-webkit-animation-name:antZoomUpIn;animation-name:antZoomUpIn;-webkit-animation-play-state:running;animation-play-state:running}.zoom-up-leave.zoom-up-leave-active{-webkit-animation-name:antZoomUpOut;animation-name:antZoomUpOut;-webkit-animation-play-state:running;animation-play-state:running;pointer-events:none}.zoom-up-enter,.zoom-up-appear{-webkit-transform:scale(0);transform:scale(0);opacity:0;-webkit-animation-timing-function:cubic-bezier(0.08, 0.82, 0.17, 1);animation-timing-function:cubic-bezier(0.08, 0.82, 0.17, 1)}.zoom-up-leave{-webkit-animation-timing-function:cubic-bezier(0.78, 0.14, 0.15, 0.86);animation-timing-function:cubic-bezier(0.78, 0.14, 0.15, 0.86)}.zoom-down-enter,.zoom-down-appear{-webkit-animation-duration:0.2s;animation-duration:0.2s;-webkit-animation-fill-mode:both;animation-fill-mode:both;-webkit-animation-play-state:paused;animation-play-state:paused}.zoom-down-leave{-webkit-animation-duration:0.2s;animation-duration:0.2s;-webkit-animation-fill-mode:both;animation-fill-mode:both;-webkit-animation-play-state:paused;animation-play-state:paused}.zoom-down-enter.zoom-down-enter-active,.zoom-down-appear.zoom-down-appear-active{-webkit-animation-name:antZoomDownIn;animation-name:antZoomDownIn;-webkit-animation-play-state:running;animation-play-state:running}.zoom-down-leave.zoom-down-leave-active{-webkit-animation-name:antZoomDownOut;animation-name:antZoomDownOut;-webkit-animation-play-state:running;animation-play-state:running;pointer-events:none}.zoom-down-enter,.zoom-down-appear{-webkit-transform:scale(0);transform:scale(0);opacity:0;-webkit-animation-timing-function:cubic-bezier(0.08, 0.82, 0.17, 1);animation-timing-function:cubic-bezier(0.08, 0.82, 0.17, 1)}.zoom-down-leave{-webkit-animation-timing-function:cubic-bezier(0.78, 0.14, 0.15, 0.86);animation-timing-function:cubic-bezier(0.78, 0.14, 0.15, 0.86)}.zoom-left-enter,.zoom-left-appear{-webkit-animation-duration:0.2s;animation-duration:0.2s;-webkit-animation-fill-mode:both;animation-fill-mode:both;-webkit-animation-play-state:paused;animation-play-state:paused}.zoom-left-leave{-webkit-animation-duration:0.2s;animation-duration:0.2s;-webkit-animation-fill-mode:both;animation-fill-mode:both;-webkit-animation-play-state:paused;animation-play-state:paused}.zoom-left-enter.zoom-left-enter-active,.zoom-left-appear.zoom-left-appear-active{-webkit-animation-name:antZoomLeftIn;animation-name:antZoomLeftIn;-webkit-animation-play-state:running;animation-play-state:running}.zoom-left-leave.zoom-left-leave-active{-webkit-animation-name:antZoomLeftOut;animation-name:antZoomLeftOut;-webkit-animation-play-state:running;animation-play-state:running;pointer-events:none}.zoom-left-enter,.zoom-left-appear{-webkit-transform:scale(0);transform:scale(0);opacity:0;-webkit-animation-timing-function:cubic-bezier(0.08, 0.82, 0.17, 1);animation-timing-function:cubic-bezier(0.08, 0.82, 0.17, 1)}.zoom-left-leave{-webkit-animation-timing-function:cubic-bezier(0.78, 0.14, 0.15, 0.86);animation-timing-function:cubic-bezier(0.78, 0.14, 0.15, 0.86)}.zoom-right-enter,.zoom-right-appear{-webkit-animation-duration:0.2s;animation-duration:0.2s;-webkit-animation-fill-mode:both;animation-fill-mode:both;-webkit-animation-play-state:paused;animation-play-state:paused}.zoom-right-leave{-webkit-animation-duration:0.2s;animation-duration:0.2s;-webkit-animation-fill-mode:both;animation-fill-mode:both;-webkit-animation-play-state:paused;animation-play-state:paused}.zoom-right-enter.zoom-right-enter-active,.zoom-right-appear.zoom-right-appear-active{-webkit-animation-name:antZoomRightIn;animation-name:antZoomRightIn;-webkit-animation-play-state:running;animation-play-state:running}.zoom-right-leave.zoom-right-leave-active{-webkit-animation-name:antZoomRightOut;animation-name:antZoomRightOut;-webkit-animation-play-state:running;animation-play-state:running;pointer-events:none}.zoom-right-enter,.zoom-right-appear{-webkit-transform:scale(0);transform:scale(0);opacity:0;-webkit-animation-timing-function:cubic-bezier(0.08, 0.82, 0.17, 1);animation-timing-function:cubic-bezier(0.08, 0.82, 0.17, 1)}.zoom-right-leave{-webkit-animation-timing-function:cubic-bezier(0.78, 0.14, 0.15, 0.86);animation-timing-function:cubic-bezier(0.78, 0.14, 0.15, 0.86)}@-webkit-keyframes antZoomIn{0%{-webkit-transform:scale(0.2);transform:scale(0.2);opacity:0}100%{-webkit-transform:scale(1);transform:scale(1);opacity:1}}@keyframes antZoomIn{0%{-webkit-transform:scale(0.2);transform:scale(0.2);opacity:0}100%{-webkit-transform:scale(1);transform:scale(1);opacity:1}}@-webkit-keyframes antZoomOut{0%{-webkit-transform:scale(1);transform:scale(1)}100%{-webkit-transform:scale(0.2);transform:scale(0.2);opacity:0}}@keyframes antZoomOut{0%{-webkit-transform:scale(1);transform:scale(1)}100%{-webkit-transform:scale(0.2);transform:scale(0.2);opacity:0}}@-webkit-keyframes antZoomBigIn{0%{-webkit-transform:scale(0.8);transform:scale(0.8);opacity:0}100%{-webkit-transform:scale(1);transform:scale(1);opacity:1}}@keyframes antZoomBigIn{0%{-webkit-transform:scale(0.8);transform:scale(0.8);opacity:0}100%{-webkit-transform:scale(1);transform:scale(1);opacity:1}}@-webkit-keyframes antZoomBigOut{0%{-webkit-transform:scale(1);transform:scale(1)}100%{-webkit-transform:scale(0.8);transform:scale(0.8);opacity:0}}@keyframes antZoomBigOut{0%{-webkit-transform:scale(1);transform:scale(1)}100%{-webkit-transform:scale(0.8);transform:scale(0.8);opacity:0}}@-webkit-keyframes antZoomUpIn{0%{-webkit-transform:scale(0.8);transform:scale(0.8);-webkit-transform-origin:50% 0%;transform-origin:50% 0%;opacity:0}100%{-webkit-transform:scale(1);transform:scale(1);-webkit-transform-origin:50% 0%;transform-origin:50% 0%}}@keyframes antZoomUpIn{0%{-webkit-transform:scale(0.8);transform:scale(0.8);-webkit-transform-origin:50% 0%;transform-origin:50% 0%;opacity:0}100%{-webkit-transform:scale(1);transform:scale(1);-webkit-transform-origin:50% 0%;transform-origin:50% 0%}}@-webkit-keyframes antZoomUpOut{0%{-webkit-transform:scale(1);transform:scale(1);-webkit-transform-origin:50% 0%;transform-origin:50% 0%}100%{-webkit-transform:scale(0.8);transform:scale(0.8);-webkit-transform-origin:50% 0%;transform-origin:50% 0%;opacity:0}}@keyframes antZoomUpOut{0%{-webkit-transform:scale(1);transform:scale(1);-webkit-transform-origin:50% 0%;transform-origin:50% 0%}100%{-webkit-transform:scale(0.8);transform:scale(0.8);-webkit-transform-origin:50% 0%;transform-origin:50% 0%;opacity:0}}@-webkit-keyframes antZoomLeftIn{0%{-webkit-transform:scale(0.8);transform:scale(0.8);-webkit-transform-origin:0% 50%;transform-origin:0% 50%;opacity:0}100%{-webkit-transform:scale(1);transform:scale(1);-webkit-transform-origin:0% 50%;transform-origin:0% 50%}}@keyframes antZoomLeftIn{0%{-webkit-transform:scale(0.8);transform:scale(0.8);-webkit-transform-origin:0% 50%;transform-origin:0% 50%;opacity:0}100%{-webkit-transform:scale(1);transform:scale(1);-webkit-transform-origin:0% 50%;transform-origin:0% 50%}}@-webkit-keyframes antZoomLeftOut{0%{-webkit-transform:scale(1);transform:scale(1);-webkit-transform-origin:0% 50%;transform-origin:0% 50%}100%{-webkit-transform:scale(0.8);transform:scale(0.8);-webkit-transform-origin:0% 50%;transform-origin:0% 50%;opacity:0}}@keyframes antZoomLeftOut{0%{-webkit-transform:scale(1);transform:scale(1);-webkit-transform-origin:0% 50%;transform-origin:0% 50%}100%{-webkit-transform:scale(0.8);transform:scale(0.8);-webkit-transform-origin:0% 50%;transform-origin:0% 50%;opacity:0}}@-webkit-keyframes antZoomRightIn{0%{-webkit-transform:scale(0.8);transform:scale(0.8);-webkit-transform-origin:100% 50%;transform-origin:100% 50%;opacity:0}100%{-webkit-transform:scale(1);transform:scale(1);-webkit-transform-origin:100% 50%;transform-origin:100% 50%}}@keyframes antZoomRightIn{0%{-webkit-transform:scale(0.8);transform:scale(0.8);-webkit-transform-origin:100% 50%;transform-origin:100% 50%;opacity:0}100%{-webkit-transform:scale(1);transform:scale(1);-webkit-transform-origin:100% 50%;transform-origin:100% 50%}}@-webkit-keyframes antZoomRightOut{0%{-webkit-transform:scale(1);transform:scale(1);-webkit-transform-origin:100% 50%;transform-origin:100% 50%}100%{-webkit-transform:scale(0.8);transform:scale(0.8);-webkit-transform-origin:100% 50%;transform-origin:100% 50%;opacity:0}}@keyframes antZoomRightOut{0%{-webkit-transform:scale(1);transform:scale(1);-webkit-transform-origin:100% 50%;transform-origin:100% 50%}100%{-webkit-transform:scale(0.8);transform:scale(0.8);-webkit-transform-origin:100% 50%;transform-origin:100% 50%;opacity:0}}@-webkit-keyframes antZoomDownIn{0%{-webkit-transform:scale(0.8);transform:scale(0.8);-webkit-transform-origin:50% 100%;transform-origin:50% 100%;opacity:0}100%{-webkit-transform:scale(1);transform:scale(1);-webkit-transform-origin:50% 100%;transform-origin:50% 100%}}@keyframes antZoomDownIn{0%{-webkit-transform:scale(0.8);transform:scale(0.8);-webkit-transform-origin:50% 100%;transform-origin:50% 100%;opacity:0}100%{-webkit-transform:scale(1);transform:scale(1);-webkit-transform-origin:50% 100%;transform-origin:50% 100%}}@-webkit-keyframes antZoomDownOut{0%{-webkit-transform:scale(1);transform:scale(1);-webkit-transform-origin:50% 100%;transform-origin:50% 100%}100%{-webkit-transform:scale(0.8);transform:scale(0.8);-webkit-transform-origin:50% 100%;transform-origin:50% 100%;opacity:0}}@keyframes antZoomDownOut{0%{-webkit-transform:scale(1);transform:scale(1);-webkit-transform-origin:50% 100%;transform-origin:50% 100%}100%{-webkit-transform:scale(0.8);transform:scale(0.8);-webkit-transform-origin:50% 100%;transform-origin:50% 100%;opacity:0}}.ant-motion-collapse-legacy{overflow:hidden}.ant-motion-collapse-legacy-active{transition:height 0.15s cubic-bezier(0.645, 0.045, 0.355, 1),opacity 0.15s cubic-bezier(0.645, 0.045, 0.355, 1) !important}.ant-motion-collapse{overflow:hidden;transition:height 0.15s cubic-bezier(0.645, 0.045, 0.355, 1),opacity 0.15s cubic-bezier(0.645, 0.045, 0.355, 1) !important}
|
3 |
.ant-modal{-webkit-box-sizing:border-box;box-sizing:border-box;margin:0;padding:0;color:rgba(0,0,0,0.65);font-size:14px;font-variant:tabular-nums;line-height:1.5715;list-style:none;-webkit-font-feature-settings:'tnum';font-feature-settings:'tnum';position:relative;top:100px;width:auto;margin:0 auto;padding-bottom:24px;pointer-events:none}.ant-modal-wrap{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1000;overflow:auto;outline:0;-webkit-overflow-scrolling:touch}.ant-modal-title{margin:0;color:rgba(0,0,0,0.85);font-weight:500;font-size:16px;line-height:22px;word-wrap:break-word}.ant-modal-content{position:relative;background-color:#fff;background-clip:padding-box;border:0;border-radius:2px;-webkit-box-shadow:0 3px 6px -4px rgba(0,0,0,0.12),0 6px 16px 0 rgba(0,0,0,0.08),0 9px 28px 8px rgba(0,0,0,0.05);box-shadow:0 3px 6px -4px rgba(0,0,0,0.12),0 6px 16px 0 rgba(0,0,0,0.08),0 9px 28px 8px rgba(0,0,0,0.05);pointer-events:auto}.ant-modal-close{position:absolute;top:0;right:0;z-index:10;padding:0;color:rgba(0,0,0,0.45);font-weight:700;line-height:1;text-decoration:none;background:transparent;border:0;outline:0;cursor:pointer;-webkit-transition:color 0.3s;transition:color 0.3s}.ant-modal-close-x{display:block;width:56px;height:56px;font-size:16px;font-style:normal;line-height:56px;text-align:center;text-transform:none;text-rendering:auto}.ant-modal-close:focus,.ant-modal-close:hover{color:rgba(0,0,0,0.75);text-decoration:none}.ant-modal-header{padding:16px 24px;color:rgba(0,0,0,0.65);background:#fff;border-bottom:1px solid #f0f0f0;border-radius:2px 2px 0 0}.ant-modal-body{padding:24px;font-size:14px;line-height:1.5715;word-wrap:break-word}.ant-modal-footer{padding:10px 16px;text-align:right;background:transparent;border-top:1px solid #f0f0f0;border-radius:0 0 2px 2px}.ant-modal-footer button+button{margin-bottom:0;margin-left:8px}.ant-modal.zoom-enter,.ant-modal.zoom-appear{-webkit-transform:none;transform:none;opacity:0;-webkit-animation-duration:0.3s;animation-duration:0.3s;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.ant-modal-mask{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1000;height:100%;background-color:rgba(0,0,0,0.45);filter:alpha(opacity=50)}.ant-modal-mask-hidden{display:none}.ant-modal-open{overflow:hidden}.ant-modal-centered{text-align:center}.ant-modal-centered::before{display:inline-block;width:0;height:100%;vertical-align:middle;content:''}.ant-modal-centered .ant-modal{top:0;display:inline-block;text-align:left;vertical-align:middle}@media (max-width: 767px){.ant-modal{max-width:calc(100vw - 16px);margin:8px auto}.ant-modal-centered .ant-modal{-webkit-box-flex:1;-ms-flex:1;flex:1}}.ant-modal-confirm .ant-modal-header{display:none}.ant-modal-confirm .ant-modal-close{display:none}.ant-modal-confirm .ant-modal-body{padding:32px 32px 24px}.ant-modal-confirm-body-wrapper::before{display:table;content:''}.ant-modal-confirm-body-wrapper::after{display:table;clear:both;content:''}.ant-modal-confirm-body .ant-modal-confirm-title{display:block;overflow:hidden;color:rgba(0,0,0,0.85);font-weight:500;font-size:16px;line-height:1.4}.ant-modal-confirm-body .ant-modal-confirm-content{margin-top:8px;color:rgba(0,0,0,0.65);font-size:14px}.ant-modal-confirm-body>.anticon{float:left;margin-right:16px;font-size:22px}.ant-modal-confirm-body>.anticon+.ant-modal-confirm-title+.ant-modal-confirm-content{margin-left:38px}.ant-modal-confirm .ant-modal-confirm-btns{float:right;margin-top:24px}.ant-modal-confirm .ant-modal-confirm-btns button+button{margin-bottom:0;margin-left:8px}.ant-modal-confirm-error .ant-modal-confirm-body>.anticon{color:#ff4d4f}.ant-modal-confirm-warning .ant-modal-confirm-body>.anticon,.ant-modal-confirm-confirm .ant-modal-confirm-body>.anticon{color:#faad14}.ant-modal-confirm-info .ant-modal-confirm-body>.anticon{color:#1890ff}.ant-modal-confirm-success .ant-modal-confirm-body>.anticon{color:#52c41a}.ant-modal-wrap-rtl{direction:rtl}.ant-modal-wrap-rtl .ant-modal-close{right:initial;left:0}.ant-modal-wrap-rtl .ant-modal-footer{text-align:left}.ant-modal-wrap-rtl .ant-modal-footer button+button{margin-right:8px;margin-left:0}.ant-modal-wrap-rtl.ant-modal-centered .ant-modal{text-align:right}
|
|
|
4 |
.ant-select-single .ant-select-selector{display:-webkit-box;display:-ms-flexbox;display:flex}.ant-select-single .ant-select-selector .ant-select-selection-search{position:absolute;top:0;right:11px;bottom:0;left:11px}.ant-select-single .ant-select-selector .ant-select-selection-search-input{width:100%}.ant-select-single .ant-select-selector .ant-select-selection-item,.ant-select-single .ant-select-selector .ant-select-selection-placeholder{padding:0;line-height:30px;-webkit-transition:all 0.3s;transition:all 0.3s}@supports (-moz-appearance: meterbar){.ant-select-single .ant-select-selector .ant-select-selection-item,.ant-select-single .ant-select-selector .ant-select-selection-placeholder{line-height:30px}}.ant-select-single .ant-select-selector .ant-select-selection-item{position:relative;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.ant-select-single .ant-select-selector .ant-select-selection-placeholder{pointer-events:none}.ant-select-single .ant-select-selector::after,.ant-select-single .ant-select-selector .ant-select-selection-item::after,.ant-select-single .ant-select-selector .ant-select-selection-placeholder::after{display:inline-block;width:0;visibility:hidden;content:'\a0'}.ant-select-single.ant-select-show-arrow .ant-select-selection-search{right:25px}.ant-select-single.ant-select-show-arrow .ant-select-selection-item,.ant-select-single.ant-select-show-arrow .ant-select-selection-placeholder{padding-right:18px}.ant-select-single.ant-select-open .ant-select-selection-item{opacity:0.4}.ant-select-single:not(.ant-select-customize-input) .ant-select-selector{position:relative;background-color:#fff;border:1px solid #d9d9d9;border-radius:2px;-webkit-transition:all 0.3s cubic-bezier(0.645, 0.045, 0.355, 1);transition:all 0.3s cubic-bezier(0.645, 0.045, 0.355, 1);width:100%;height:32px;padding:0 11px}.ant-select-single:not(.ant-select-customize-input) .ant-select-selector input{cursor:pointer}.ant-select-show-search.ant-select-single:not(.ant-select-customize-input) .ant-select-selector{cursor:text}.ant-select-show-search.ant-select-single:not(.ant-select-customize-input) .ant-select-selector input{cursor:auto}.ant-select-focused.ant-select-single:not(.ant-select-customize-input) .ant-select-selector{border-color:#40a9ff;border-right-width:1px !important;outline:0;-webkit-box-shadow:0 0 0 2px rgba(24,144,255,0.2);box-shadow:0 0 0 2px rgba(24,144,255,0.2)}.ant-select-disabled.ant-select-single:not(.ant-select-customize-input) .ant-select-selector{color:rgba(0,0,0,0.25);background:#f5f5f5;cursor:not-allowed}.ant-select-disabled.ant-select-single:not(.ant-select-customize-input) .ant-select-selector input{cursor:not-allowed}.ant-select-single:not(.ant-select-customize-input) .ant-select-selector .ant-select-selection-search-input{background:transparent;border:none;outline:none}.ant-select-single:not(.ant-select-customize-input) .ant-select-selector .ant-select-selection-search-input{height:30px}.ant-select-single.ant-select-customize-input .ant-select-selector::after{display:none}.ant-select-single.ant-select-customize-input .ant-select-selector .ant-select-selection-search{position:static;width:100%}.ant-select-single.ant-select-customize-input .ant-select-selector .ant-select-selection-placeholder{position:absolute;right:0;left:0;padding:0 11px}.ant-select-single.ant-select-customize-input .ant-select-selector .ant-select-selection-placeholder::after{display:none}.ant-select-single.ant-select-lg:not(.ant-select-customize-input) .ant-select-selector{height:40px}.ant-select-single.ant-select-lg:not(.ant-select-customize-input) .ant-select-selector .ant-select-selection-item,.ant-select-single.ant-select-lg:not(.ant-select-customize-input) .ant-select-selector .ant-select-selection-placeholder{line-height:38px}.ant-select-single.ant-select-lg:not(.ant-select-customize-input):not(.ant-select-customize-input) .ant-select-selection-search-input{height:38px}.ant-select-single.ant-select-sm:not(.ant-select-customize-input) .ant-select-selector{height:24px}.ant-select-single.ant-select-sm:not(.ant-select-customize-input) .ant-select-selector .ant-select-selection-item,.ant-select-single.ant-select-sm:not(.ant-select-customize-input) .ant-select-selector .ant-select-selection-placeholder{line-height:22px}.ant-select-single.ant-select-sm:not(.ant-select-customize-input):not(.ant-select-customize-input) .ant-select-selection-search-input{height:22px}.ant-select-single.ant-select-sm:not(.ant-select-customize-input) .ant-select-selection-search{right:7px;left:7px}.ant-select-single.ant-select-sm:not(.ant-select-customize-input) .ant-select-selector{padding:0 7px}.ant-select-single.ant-select-sm:not(.ant-select-customize-input).ant-select-show-arrow .ant-select-selection-search{right:28px}.ant-select-single.ant-select-sm:not(.ant-select-customize-input).ant-select-show-arrow .ant-select-selection-item,.ant-select-single.ant-select-sm:not(.ant-select-customize-input).ant-select-show-arrow .ant-select-selection-placeholder{padding-right:21px}.ant-select-single.ant-select-lg:not(.ant-select-customize-input) .ant-select-selector{padding:0 11px}.ant-select-multiple .ant-select-selector{position:relative;background-color:#fff;border:1px solid #d9d9d9;border-radius:2px;-webkit-transition:all 0.3s cubic-bezier(0.645, 0.045, 0.355, 1);transition:all 0.3s cubic-bezier(0.645, 0.045, 0.355, 1);display:-webkit-box;display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;-webkit-box-align:center;-ms-flex-align:center;align-items:center;padding:1px 4px}.ant-select-multiple .ant-select-selector input{cursor:pointer}.ant-select-show-search.ant-select-multiple .ant-select-selector{cursor:text}.ant-select-show-search.ant-select-multiple .ant-select-selector input{cursor:auto}.ant-select-focused.ant-select-multiple .ant-select-selector{border-color:#40a9ff;border-right-width:1px !important;outline:0;-webkit-box-shadow:0 0 0 2px rgba(24,144,255,0.2);box-shadow:0 0 0 2px rgba(24,144,255,0.2)}.ant-select-disabled.ant-select-multiple .ant-select-selector{color:rgba(0,0,0,0.25);background:#f5f5f5;cursor:not-allowed}.ant-select-disabled.ant-select-multiple .ant-select-selector input{cursor:not-allowed}.ant-select-multiple .ant-select-selector .ant-select-selection-search-input{background:transparent;border:none;outline:none}.ant-select-show-search.ant-select-multiple .ant-select-selector{cursor:text}.ant-select-multiple .ant-select-selector::after{display:inline-block;width:0;margin:2px 0;line-height:24px;content:'\a0'}.ant-select-multiple.ant-select-allow-clear .ant-select-selector{padding-right:24px}.ant-select-multiple .ant-select-selection-item{position:relative;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-flex:0;-ms-flex:none;flex:none;-webkit-box-sizing:border-box;box-sizing:border-box;max-width:100%;height:24px;margin-top:2px;margin-right:4px;margin-bottom:2px;padding:0 4px 0 8px;line-height:22px;background:#f5f5f5;border:1px solid #f0f0f0;border-radius:2px;cursor:default;-webkit-transition:font-size 0.3s, line-height 0.3s, height 0.3s;transition:font-size 0.3s, line-height 0.3s, height 0.3s;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.ant-select-multiple .ant-select-selection-item-content{display:inline-block;margin-right:4px;overflow:hidden;white-space:nowrap;text-overflow:ellipsis}.ant-select-multiple .ant-select-selection-item-remove{color:inherit;font-style:normal;line-height:0;text-align:center;text-transform:none;vertical-align:-0.125em;text-rendering:optimizeLegibility;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;color:rgba(0,0,0,0.45);font-weight:bold;font-size:12px;line-height:inherit;cursor:pointer;display:inline-block;font-size:10px}.ant-select-multiple .ant-select-selection-item-remove>*{line-height:1}.ant-select-multiple .ant-select-selection-item-remove svg{display:inline-block}.ant-select-multiple .ant-select-selection-item-remove::before{display:none}.ant-select-multiple .ant-select-selection-item-remove .ant-select-multiple .ant-select-selection-item-remove-icon{display:block}.ant-select-multiple .ant-select-selection-item-remove>.anticon{vertical-align:-0.2em}.ant-select-multiple .ant-select-selection-item-remove:hover{color:rgba(0,0,0,0.75)}.ant-select-multiple .ant-select-selection-search{position:relative;margin-left:0.5px}.ant-select-multiple .ant-select-selection-search-input,.ant-select-multiple .ant-select-selection-search-mirror{font-family:-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, 'Noto Sans', sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol', 'Noto Color Emoji';line-height:1.5715;-webkit-transition:all 0.3s;transition:all 0.3s}.ant-select-multiple .ant-select-selection-search-input{width:100%;min-width:3px}.ant-select-multiple .ant-select-selection-search-mirror{position:absolute;top:0;left:0;z-index:999;white-space:nowrap;visibility:hidden}.ant-select-multiple .ant-select-selection-search:first-child .ant-select-selection-search-input{margin-left:6.5px}.ant-select-multiple .ant-select-selection-placeholder{position:absolute;top:50%;right:11px;left:11px;-webkit-transform:translateY(-50%);transform:translateY(-50%);-webkit-transition:all 0.3s;transition:all 0.3s}.ant-select-multiple.ant-select-lg .ant-select-selector::after{line-height:32px}.ant-select-multiple.ant-select-lg .ant-select-selection-item{height:32px;line-height:30px}.ant-select-multiple.ant-select-lg .ant-select-selection-search{height:33px;line-height:33px}.ant-select-multiple.ant-select-lg .ant-select-selection-search-input,.ant-select-multiple.ant-select-lg .ant-select-selection-search-mirror{height:32px;line-height:30px}.ant-select-multiple.ant-select-sm .ant-select-selector::after{line-height:16px}.ant-select-multiple.ant-select-sm .ant-select-selection-item{height:16px;line-height:14px}.ant-select-multiple.ant-select-sm .ant-select-selection-search{height:17px;line-height:17px}.ant-select-multiple.ant-select-sm .ant-select-selection-search-input,.ant-select-multiple.ant-select-sm .ant-select-selection-search-mirror{height:16px;line-height:14px}.ant-select-multiple.ant-select-sm .ant-select-selection-placeholder{left:7px}.ant-select-multiple.ant-select-sm .ant-select-selection-search:first-child .ant-select-selection-search-input{margin-left:3px}.ant-select-multiple.ant-select-lg .ant-select-selection-item{height:32px;line-height:32px}.ant-select-disabled .ant-select-selection-item-remove{display:none}.ant-select{-webkit-box-sizing:border-box;box-sizing:border-box;margin:0;padding:0;color:rgba(0,0,0,0.65);font-size:14px;font-variant:tabular-nums;line-height:1.5715;list-style:none;-webkit-font-feature-settings:'tnum';font-feature-settings:'tnum';position:relative;display:inline-block;cursor:pointer}.ant-select:not(.ant-select-disabled):hover .ant-select-selector{border-color:#40a9ff;border-right-width:1px !important}.ant-select-selection-item{-webkit-box-flex:1;-ms-flex:1;flex:1;overflow:hidden;white-space:nowrap;text-overflow:ellipsis}@media all and (-ms-high-contrast: none){.ant-select-selection-item *::-ms-backdrop,.ant-select-selection-item{-ms-flex:auto;flex:auto}}.ant-select-selection-placeholder{-webkit-box-flex:1;-ms-flex:1;flex:1;overflow:hidden;white-space:nowrap;text-overflow:ellipsis;opacity:0.4}@media all and (-ms-high-contrast: none){.ant-select-selection-placeholder *::-ms-backdrop,.ant-select-selection-placeholder{-ms-flex:auto;flex:auto}}.ant-select-arrow{display:inline-block;color:inherit;font-style:normal;line-height:0;text-transform:none;vertical-align:-0.125em;text-rendering:optimizeLegibility;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;position:absolute;top:53%;right:11px;width:12px;height:12px;margin-top:-6px;color:rgba(0,0,0,0.25);font-size:12px;line-height:1;text-align:center;pointer-events:none}.ant-select-arrow>*{line-height:1}.ant-select-arrow svg{display:inline-block}.ant-select-arrow::before{display:none}.ant-select-arrow .ant-select-arrow-icon{display:block}.ant-select-arrow .anticon{vertical-align:top;-webkit-transition:-webkit-transform 0.3s;transition:-webkit-transform 0.3s;transition:transform 0.3s;transition:transform 0.3s, -webkit-transform 0.3s}.ant-select-arrow .anticon>svg{vertical-align:top}.ant-select-arrow .anticon:not(.anticon-down){pointer-events:auto}.ant-select-clear{position:absolute;top:50%;right:11px;z-index:1;display:inline-block;width:12px;height:12px;margin-top:-6px;color:rgba(0,0,0,0.25);font-size:12px;font-style:normal;line-height:1;text-align:center;text-transform:none;background:#fff;cursor:pointer;opacity:0;-webkit-transition:color 0.3s ease, opacity 0.15s ease;transition:color 0.3s ease, opacity 0.15s ease;text-rendering:auto}.ant-select-clear::before{display:block}.ant-select-clear:hover{color:rgba(0,0,0,0.45)}.ant-select:hover .ant-select-clear{opacity:1}.ant-select-dropdown{margin:0;padding:0;color:rgba(0,0,0,0.65);font-variant:tabular-nums;line-height:1.5715;list-style:none;-webkit-font-feature-settings:'tnum';font-feature-settings:'tnum';position:absolute;top:-9999px;left:-9999px;z-index:1050;-webkit-box-sizing:border-box;box-sizing:border-box;padding:4px 0;overflow:hidden;font-size:14px;font-variant:initial;background-color:#fff;border-radius:2px;outline:none;-webkit-box-shadow:0 3px 6px -4px rgba(0,0,0,0.12),0 6px 16px 0 rgba(0,0,0,0.08),0 9px 28px 8px rgba(0,0,0,0.05);box-shadow:0 3px 6px -4px rgba(0,0,0,0.12),0 6px 16px 0 rgba(0,0,0,0.08),0 9px 28px 8px rgba(0,0,0,0.05)}.ant-select-dropdown.slide-up-enter.slide-up-enter-active.ant-select-dropdown-placement-bottomLeft,.ant-select-dropdown.slide-up-appear.slide-up-appear-active.ant-select-dropdown-placement-bottomLeft{-webkit-animation-name:antSlideUpIn;animation-name:antSlideUpIn}.ant-select-dropdown.slide-up-enter.slide-up-enter-active.ant-select-dropdown-placement-topLeft,.ant-select-dropdown.slide-up-appear.slide-up-appear-active.ant-select-dropdown-placement-topLeft{-webkit-animation-name:antSlideDownIn;animation-name:antSlideDownIn}.ant-select-dropdown.slide-up-leave.slide-up-leave-active.ant-select-dropdown-placement-bottomLeft{-webkit-animation-name:antSlideUpOut;animation-name:antSlideUpOut}.ant-select-dropdown.slide-up-leave.slide-up-leave-active.ant-select-dropdown-placement-topLeft{-webkit-animation-name:antSlideDownOut;animation-name:antSlideDownOut}.ant-select-dropdown-hidden{display:none}.ant-select-item-empty{position:relative;display:block;min-height:32px;padding:5px 12px;color:rgba(0,0,0,0.65);font-weight:normal;font-size:14px;line-height:22px}.ant-select-item{position:relative;display:block;min-height:32px;padding:5px 12px;color:rgba(0,0,0,0.65);font-weight:normal;font-size:14px;line-height:22px;cursor:pointer;-webkit-transition:background 0.3s ease;transition:background 0.3s ease}.ant-select-item-group{color:rgba(0,0,0,0.45);font-size:12px;cursor:default}.ant-select-item-option{display:-webkit-box;display:-ms-flexbox;display:flex}.ant-select-item-option-content{-webkit-box-flex:1;-ms-flex:auto;flex:auto;overflow:hidden;white-space:nowrap;text-overflow:ellipsis}.ant-select-item-option-state{-webkit-box-flex:0;-ms-flex:none;flex:none}.ant-select-item-option-active:not(.ant-select-item-option-disabled){background-color:#f5f5f5}.ant-select-item-option-selected:not(.ant-select-item-option-disabled){color:rgba(0,0,0,0.65);font-weight:600;background-color:#e6f7ff}.ant-select-item-option-selected:not(.ant-select-item-option-disabled) .ant-select-item-option-state{color:#1890ff}.ant-select-item-option-disabled{color:rgba(0,0,0,0.25);cursor:not-allowed}.ant-select-item-option-grouped{padding-left:24px}.ant-select-lg{font-size:16px}.ant-select-borderless .ant-select-selector{background-color:transparent !important;border-color:transparent !important;-webkit-box-shadow:none !important;box-shadow:none !important}.ant-select-rtl{direction:rtl}.ant-select-rtl .ant-select-arrow{right:initial;left:11px}.ant-select-rtl .ant-select-clear{right:initial;left:11px}.ant-select-dropdown-rtl{direction:rtl}.ant-select-dropdown-rtl .ant-select-item-option-grouped{padding-right:24px;padding-left:12px}.ant-select-rtl.ant-select-multiple.ant-select-allow-clear .ant-select-selector{padding-right:4px;padding-left:24px}.ant-select-rtl.ant-select-multiple .ant-select-selection-item{margin-right:0;margin-left:4px;padding:0 8px 0 4px;text-align:right}.ant-select-rtl.ant-select-multiple .ant-select-selection-item-content{margin-right:0;margin-left:4px;text-align:right}.ant-select-rtl.ant-select-multiple .ant-select-selection-search{margin-right:0.5px;margin-left:4px}.ant-select-rtl.ant-select-multiple .ant-select-selection-search-mirror{right:0;left:auto}.ant-select-rtl.ant-select-multiple .ant-select-selection-placeholder{right:11px;left:auto}.ant-select-rtl.ant-select-multiple.ant-select-sm .ant-select-selection-placeholder{right:7px}.ant-select-rtl.ant-select-single .ant-select-selector .ant-select-selection-item,.ant-select-rtl.ant-select-single .ant-select-selector .ant-select-selection-placeholder{right:0;left:9px;text-align:right}.ant-select-rtl.ant-select-single.ant-select-show-arrow .ant-select-selection-search{right:11px;left:25px}.ant-select-rtl.ant-select-single.ant-select-show-arrow .ant-select-selection-item,.ant-select-rtl.ant-select-single.ant-select-show-arrow .ant-select-selection-placeholder{padding-right:0;padding-left:18px}.ant-select-rtl.ant-select-single:not(.ant-select-customize-input) .ant-select-selector{padding:0 11px}.ant-select-rtl.ant-select-single.ant-select-sm:not(.ant-select-customize-input).ant-select-show-arrow .ant-select-selection-search{right:0}.ant-select-rtl.ant-select-single.ant-select-sm:not(.ant-select-customize-input).ant-select-show-arrow .ant-select-selection-item,.ant-select-rtl.ant-select-single.ant-select-sm:not(.ant-select-customize-input).ant-select-show-arrow .ant-select-selection-placeholder{padding-right:0;padding-left:21px}
|
5 |
+
.ant-tooltip{-webkit-box-sizing:border-box;box-sizing:border-box;margin:0;padding:0;color:rgba(0,0,0,0.65);font-size:14px;font-variant:tabular-nums;line-height:1.5715;list-style:none;-webkit-font-feature-settings:'tnum';font-feature-settings:'tnum';position:absolute;z-index:1060;display:block;max-width:250px;visibility:visible}.ant-tooltip-hidden{display:none}.ant-tooltip-placement-top,.ant-tooltip-placement-topLeft,.ant-tooltip-placement-topRight{padding-bottom:8px}.ant-tooltip-placement-right,.ant-tooltip-placement-rightTop,.ant-tooltip-placement-rightBottom{padding-left:8px}.ant-tooltip-placement-bottom,.ant-tooltip-placement-bottomLeft,.ant-tooltip-placement-bottomRight{padding-top:8px}.ant-tooltip-placement-left,.ant-tooltip-placement-leftTop,.ant-tooltip-placement-leftBottom{padding-right:8px}.ant-tooltip-inner{min-width:30px;min-height:32px;padding:6px 8px;color:#fff;text-align:left;text-decoration:none;word-wrap:break-word;background-color:rgba(0,0,0,0.75);border-radius:2px;-webkit-box-shadow:0 3px 6px -4px rgba(0,0,0,0.12),0 6px 16px 0 rgba(0,0,0,0.08),0 9px 28px 8px rgba(0,0,0,0.05);box-shadow:0 3px 6px -4px rgba(0,0,0,0.12),0 6px 16px 0 rgba(0,0,0,0.08),0 9px 28px 8px rgba(0,0,0,0.05)}.ant-tooltip-arrow{position:absolute;display:block;width:13.07106781px;height:13.07106781px;overflow:hidden;background:transparent;pointer-events:none}.ant-tooltip-arrow::before{position:absolute;top:0;right:0;bottom:0;left:0;display:block;width:5px;height:5px;margin:auto;background-color:rgba(0,0,0,0.75);content:'';pointer-events:auto}.ant-tooltip-placement-top .ant-tooltip-arrow,.ant-tooltip-placement-topLeft .ant-tooltip-arrow,.ant-tooltip-placement-topRight .ant-tooltip-arrow{bottom:-5.07106781px}.ant-tooltip-placement-top .ant-tooltip-arrow::before,.ant-tooltip-placement-topLeft .ant-tooltip-arrow::before,.ant-tooltip-placement-topRight .ant-tooltip-arrow::before{-webkit-box-shadow:3px 3px 7px rgba(0,0,0,0.07);box-shadow:3px 3px 7px rgba(0,0,0,0.07);-webkit-transform:translateY(-6.53553px) rotate(45deg);transform:translateY(-6.53553px) rotate(45deg)}.ant-tooltip-placement-top .ant-tooltip-arrow{left:50%;-webkit-transform:translateX(-50%);transform:translateX(-50%)}.ant-tooltip-placement-topLeft .ant-tooltip-arrow{left:13px}.ant-tooltip-placement-topRight .ant-tooltip-arrow{right:13px}.ant-tooltip-placement-right .ant-tooltip-arrow,.ant-tooltip-placement-rightTop .ant-tooltip-arrow,.ant-tooltip-placement-rightBottom .ant-tooltip-arrow{left:-5.07106781px}.ant-tooltip-placement-right .ant-tooltip-arrow::before,.ant-tooltip-placement-rightTop .ant-tooltip-arrow::before,.ant-tooltip-placement-rightBottom .ant-tooltip-arrow::before{-webkit-box-shadow:-3px 3px 7px rgba(0,0,0,0.07);box-shadow:-3px 3px 7px rgba(0,0,0,0.07);-webkit-transform:translateX(6.53553px) rotate(45deg);transform:translateX(6.53553px) rotate(45deg)}.ant-tooltip-placement-right .ant-tooltip-arrow{top:50%;-webkit-transform:translateY(-50%);transform:translateY(-50%)}.ant-tooltip-placement-rightTop .ant-tooltip-arrow{top:5px}.ant-tooltip-placement-rightBottom .ant-tooltip-arrow{bottom:5px}.ant-tooltip-placement-left .ant-tooltip-arrow,.ant-tooltip-placement-leftTop .ant-tooltip-arrow,.ant-tooltip-placement-leftBottom .ant-tooltip-arrow{right:-5.07106781px}.ant-tooltip-placement-left .ant-tooltip-arrow::before,.ant-tooltip-placement-leftTop .ant-tooltip-arrow::before,.ant-tooltip-placement-leftBottom .ant-tooltip-arrow::before{-webkit-box-shadow:3px -3px 7px rgba(0,0,0,0.07);box-shadow:3px -3px 7px rgba(0,0,0,0.07);-webkit-transform:translateX(-6.53553px) rotate(45deg);transform:translateX(-6.53553px) rotate(45deg)}.ant-tooltip-placement-left .ant-tooltip-arrow{top:50%;-webkit-transform:translateY(-50%);transform:translateY(-50%)}.ant-tooltip-placement-leftTop .ant-tooltip-arrow{top:5px}.ant-tooltip-placement-leftBottom .ant-tooltip-arrow{bottom:5px}.ant-tooltip-placement-bottom .ant-tooltip-arrow,.ant-tooltip-placement-bottomLeft .ant-tooltip-arrow,.ant-tooltip-placement-bottomRight .ant-tooltip-arrow{top:-5.07106781px}.ant-tooltip-placement-bottom .ant-tooltip-arrow::before,.ant-tooltip-placement-bottomLeft .ant-tooltip-arrow::before,.ant-tooltip-placement-bottomRight .ant-tooltip-arrow::before{-webkit-box-shadow:-3px -3px 7px rgba(0,0,0,0.07);box-shadow:-3px -3px 7px rgba(0,0,0,0.07);-webkit-transform:translateY(6.53553px) rotate(45deg);transform:translateY(6.53553px) rotate(45deg)}.ant-tooltip-placement-bottom .ant-tooltip-arrow{left:50%;-webkit-transform:translateX(-50%);transform:translateX(-50%)}.ant-tooltip-placement-bottomLeft .ant-tooltip-arrow{left:13px}.ant-tooltip-placement-bottomRight .ant-tooltip-arrow{right:13px}.ant-tooltip-rtl{direction:rtl}.ant-tooltip-rtl .ant-tooltip-inner{text-align:right}
|
6 |
+
.ant-radio-group{-webkit-box-sizing:border-box;box-sizing:border-box;margin:0;padding:0;color:rgba(0,0,0,0.65);font-size:14px;font-variant:tabular-nums;line-height:1.5715;list-style:none;-webkit-font-feature-settings:'tnum';font-feature-settings:'tnum';display:inline-block;line-height:unset}.ant-radio-group .ant-badge-count{z-index:1}.ant-radio-group>.ant-badge:not(:first-child)>.ant-radio-button-wrapper{border-left:none}.ant-radio-wrapper{-webkit-box-sizing:border-box;box-sizing:border-box;margin:0;padding:0;color:rgba(0,0,0,0.65);font-size:14px;font-variant:tabular-nums;line-height:1.5715;list-style:none;-webkit-font-feature-settings:'tnum';font-feature-settings:'tnum';position:relative;display:inline-block;margin-right:8px;white-space:nowrap;cursor:pointer}.ant-radio{-webkit-box-sizing:border-box;box-sizing:border-box;margin:0;padding:0;color:rgba(0,0,0,0.65);font-size:14px;font-variant:tabular-nums;line-height:1.5715;list-style:none;-webkit-font-feature-settings:'tnum';font-feature-settings:'tnum';position:relative;top:0px;display:inline-block;line-height:1;white-space:nowrap;vertical-align:sub;outline:none;cursor:pointer}.ant-radio-wrapper:hover .ant-radio,.ant-radio:hover .ant-radio-inner,.ant-radio-input:focus+.ant-radio-inner{border-color:#1890ff}.ant-radio-input:focus+.ant-radio-inner{-webkit-box-shadow:0 0 0 3px rgba(24,144,255,0.08);box-shadow:0 0 0 3px rgba(24,144,255,0.08)}.ant-radio-checked::after{position:absolute;top:0;left:0;width:100%;height:100%;border:1px solid #1890ff;border-radius:50%;visibility:hidden;-webkit-animation:antRadioEffect 0.36s ease-in-out;animation:antRadioEffect 0.36s ease-in-out;-webkit-animation-fill-mode:both;animation-fill-mode:both;content:''}.ant-radio:hover::after,.ant-radio-wrapper:hover .ant-radio::after{visibility:visible}.ant-radio-inner{position:relative;top:0;left:0;display:block;width:16px;height:16px;background-color:#fff;border-color:#d9d9d9;border-style:solid;border-width:1px;border-radius:100px;-webkit-transition:all 0.3s;transition:all 0.3s}.ant-radio-inner::after{position:absolute;top:3px;left:3px;display:table;width:8px;height:8px;background-color:#1890ff;border-top:0;border-left:0;border-radius:8px;-webkit-transform:scale(0);transform:scale(0);opacity:0;-webkit-transition:all 0.3s cubic-bezier(0.78, 0.14, 0.15, 0.86);transition:all 0.3s cubic-bezier(0.78, 0.14, 0.15, 0.86);content:' '}.ant-radio-input{position:absolute;top:0;right:0;bottom:0;left:0;z-index:1;cursor:pointer;opacity:0}.ant-radio-checked .ant-radio-inner{border-color:#1890ff}.ant-radio-checked .ant-radio-inner::after{-webkit-transform:scale(1);transform:scale(1);opacity:1;-webkit-transition:all 0.3s cubic-bezier(0.78, 0.14, 0.15, 0.86);transition:all 0.3s cubic-bezier(0.78, 0.14, 0.15, 0.86)}.ant-radio-disabled .ant-radio-inner{background-color:#f5f5f5;border-color:#d9d9d9 !important;cursor:not-allowed}.ant-radio-disabled .ant-radio-inner::after{background-color:rgba(0,0,0,0.2)}.ant-radio-disabled .ant-radio-input{cursor:not-allowed}.ant-radio-disabled+span{color:rgba(0,0,0,0.25);cursor:not-allowed}span.ant-radio+*{padding-right:8px;padding-left:8px}.ant-radio-button-wrapper{position:relative;display:inline-block;height:32px;margin:0;padding:0 15px;color:rgba(0,0,0,0.65);line-height:30px;background:#fff;border:1px solid #d9d9d9;border-top-width:1.02px;border-left-width:0;cursor:pointer;-webkit-transition:color 0.3s, background 0.3s, border-color 0.3s, -webkit-box-shadow 0.3s;transition:color 0.3s, background 0.3s, border-color 0.3s, -webkit-box-shadow 0.3s;transition:color 0.3s, background 0.3s, border-color 0.3s, box-shadow 0.3s;transition:color 0.3s, background 0.3s, border-color 0.3s, box-shadow 0.3s, -webkit-box-shadow 0.3s}.ant-radio-button-wrapper a{color:rgba(0,0,0,0.65)}.ant-radio-button-wrapper>.ant-radio-button{display:block;width:0;height:0;margin-left:0}.ant-radio-group-large .ant-radio-button-wrapper{height:40px;font-size:16px;line-height:38px}.ant-radio-group-small .ant-radio-button-wrapper{height:24px;padding:0 7px;line-height:22px}.ant-radio-button-wrapper:not(:first-child)::before{position:absolute;top:-1px;left:-1px;display:block;-webkit-box-sizing:content-box;box-sizing:content-box;width:1px;height:100%;padding:1px 0;background-color:#d9d9d9;-webkit-transition:background-color 0.3s;transition:background-color 0.3s;content:''}.ant-radio-button-wrapper:first-child{border-left:1px solid #d9d9d9;border-radius:2px 0 0 2px}.ant-radio-button-wrapper:last-child{border-radius:0 2px 2px 0}.ant-radio-button-wrapper:first-child:last-child{border-radius:2px}.ant-radio-button-wrapper:hover{position:relative;color:#1890ff}.ant-radio-button-wrapper:focus-within{-webkit-box-shadow:0 0 0 3px rgba(24,144,255,0.08);box-shadow:0 0 0 3px rgba(24,144,255,0.08)}.ant-radio-button-wrapper .ant-radio-inner,.ant-radio-button-wrapper input[type='checkbox'],.ant-radio-button-wrapper input[type='radio']{width:0;height:0;opacity:0;pointer-events:none}.ant-radio-button-wrapper-checked:not(.ant-radio-button-wrapper-disabled){z-index:1;color:#1890ff;background:#fff;border-color:#1890ff}.ant-radio-button-wrapper-checked:not(.ant-radio-button-wrapper-disabled)::before{background-color:#1890ff}.ant-radio-button-wrapper-checked:not(.ant-radio-button-wrapper-disabled):first-child{border-color:#1890ff}.ant-radio-button-wrapper-checked:not(.ant-radio-button-wrapper-disabled):hover{color:#40a9ff;border-color:#40a9ff}.ant-radio-button-wrapper-checked:not(.ant-radio-button-wrapper-disabled):hover::before{background-color:#40a9ff}.ant-radio-button-wrapper-checked:not(.ant-radio-button-wrapper-disabled):active{color:#096dd9;border-color:#096dd9}.ant-radio-button-wrapper-checked:not(.ant-radio-button-wrapper-disabled):active::before{background-color:#096dd9}.ant-radio-button-wrapper-checked:not(.ant-radio-button-wrapper-disabled):focus-within{-webkit-box-shadow:0 0 0 3px rgba(24,144,255,0.08);box-shadow:0 0 0 3px rgba(24,144,255,0.08)}.ant-radio-group-solid .ant-radio-button-wrapper-checked:not(.ant-radio-button-wrapper-disabled){color:#fff;background:#1890ff;border-color:#1890ff}.ant-radio-group-solid .ant-radio-button-wrapper-checked:not(.ant-radio-button-wrapper-disabled):hover{color:#fff;background:#40a9ff;border-color:#40a9ff}.ant-radio-group-solid .ant-radio-button-wrapper-checked:not(.ant-radio-button-wrapper-disabled):active{color:#fff;background:#096dd9;border-color:#096dd9}.ant-radio-group-solid .ant-radio-button-wrapper-checked:not(.ant-radio-button-wrapper-disabled):focus-within{-webkit-box-shadow:0 0 0 3px rgba(24,144,255,0.08);box-shadow:0 0 0 3px rgba(24,144,255,0.08)}.ant-radio-button-wrapper-disabled{color:rgba(0,0,0,0.25);background-color:#f5f5f5;border-color:#d9d9d9;cursor:not-allowed}.ant-radio-button-wrapper-disabled:first-child,.ant-radio-button-wrapper-disabled:hover{color:rgba(0,0,0,0.25);background-color:#f5f5f5;border-color:#d9d9d9}.ant-radio-button-wrapper-disabled:first-child{border-left-color:#d9d9d9}.ant-radio-button-wrapper-disabled.ant-radio-button-wrapper-checked{color:#fff;background-color:#e6e6e6;border-color:#d9d9d9;-webkit-box-shadow:none;box-shadow:none}@-webkit-keyframes antRadioEffect{0%{-webkit-transform:scale(1);transform:scale(1);opacity:0.5}100%{-webkit-transform:scale(1.6);transform:scale(1.6);opacity:0}}@keyframes antRadioEffect{0%{-webkit-transform:scale(1);transform:scale(1);opacity:0.5}100%{-webkit-transform:scale(1.6);transform:scale(1.6);opacity:0}}@supports (-moz-appearance: meterbar) and (background-blend-mode: difference,normal){.ant-radio{vertical-align:text-bottom}}.ant-radio-group.ant-radio-group-rtl{direction:rtl}.ant-radio-wrapper.ant-radio-wrapper-rtl{margin-right:0;margin-left:8px;direction:rtl}.ant-radio-button-wrapper.ant-radio-button-wrapper-rtl{border-right-width:0;border-left-width:1px}.ant-radio-button-wrapper.ant-radio-button-wrapper-rtl.ant-radio-button-wrapper:not(:first-child)::before{right:-1px;left:0}.ant-radio-button-wrapper.ant-radio-button-wrapper-rtl.ant-radio-button-wrapper:first-child{border-right:1px solid #d9d9d9;border-radius:0 2px 2px 0}.ant-radio-button-wrapper-checked:not([class*=' ant-radio-button-wrapper-disabled']).ant-radio-button-wrapper:first-child{border-right-color:#40a9ff}.ant-radio-button-wrapper.ant-radio-button-wrapper-rtl.ant-radio-button-wrapper:last-child{border-radius:2px 0 0 2px}.ant-radio-button-wrapper.ant-radio-button-wrapper-rtl.ant-radio-button-wrapper-disabled:first-child{border-right-color:#d9d9d9}
|
dist/js/homeScreen/app.js
ADDED
@@ -0,0 +1 @@
|
|
|
1 |
+
!function(t){var r={};function e(n){if(r[n])return r[n].exports;var o=r[n]={i:n,l:!1,exports:{}};return t[n].call(o.exports,o,o.exports,e),o.l=!0,o.exports}e.m=t,e.c=r,e.d=function(t,r,n){e.o(t,r)||Object.defineProperty(t,r,{configurable:!1,enumerable:!0,get:n})},e.r=function(t){Object.defineProperty(t,"__esModule",{value:!0})},e.n=function(t){var r=t&&t.__esModule?function(){return t.default}:function(){return t};return e.d(r,"a",r),r},e.o=function(t,r){return Object.prototype.hasOwnProperty.call(t,r)},e.p="",e(e.s=2)}([function(t,r,e){"use strict";document.addEventListener("DOMContentLoaded",function(){(0,wp.hooks.addFilter)("woocommerce_admin_homepage_default_stats","wcml/homescreen/remove_revenue_widgets",n)});var n=function(t){return t.filter(function(t){return"revenue/"!==t.substr(0,8)})}},function(t,r,e){var n=function(t){"use strict";var r,e=Object.prototype,n=e.hasOwnProperty,o="function"==typeof Symbol?Symbol:{},i=o.iterator||"@@iterator",a=o.asyncIterator||"@@asyncIterator",c=o.toStringTag||"@@toStringTag";function u(t,r,e,n){var o=r&&r.prototype instanceof v?r:v,i=Object.create(o.prototype),a=new k(n||[]);return i._invoke=function(t,r,e){var n=s;return function(o,i){if(n===l)throw new Error("Generator is already running");if(n===p){if("throw"===o)throw i;return N()}for(e.method=o,e.arg=i;;){var a=e.delegate;if(a){var c=E(a,e);if(c){if(c===y)continue;return c}}if("next"===e.method)e.sent=e._sent=e.arg;else if("throw"===e.method){if(n===s)throw n=p,e.arg;e.dispatchException(e.arg)}else"return"===e.method&&e.abrupt("return",e.arg);n=l;var u=f(t,r,e);if("normal"===u.type){if(n=e.done?p:h,u.arg===y)continue;return{value:u.arg,done:e.done}}"throw"===u.type&&(n=p,e.method="throw",e.arg=u.arg)}}}(t,e,a),i}function f(t,r,e){try{return{type:"normal",arg:t.call(r,e)}}catch(t){return{type:"throw",arg:t}}}t.wrap=u;var s="suspendedStart",h="suspendedYield",l="executing",p="completed",y={};function v(){}function d(){}function g(){}var m={};m[i]=function(){return this};var w=Object.getPrototypeOf,x=w&&w(w(G([])));x&&x!==e&&n.call(x,i)&&(m=x);var L=g.prototype=v.prototype=Object.create(m);function _(t){["next","throw","return"].forEach(function(r){t[r]=function(t){return this._invoke(r,t)}})}function b(t,r){var e;this._invoke=function(o,i){function a(){return new r(function(e,a){!function e(o,i,a,c){var u=f(t[o],t,i);if("throw"!==u.type){var s=u.arg,h=s.value;return h&&"object"==typeof h&&n.call(h,"__await")?r.resolve(h.__await).then(function(t){e("next",t,a,c)},function(t){e("throw",t,a,c)}):r.resolve(h).then(function(t){s.value=t,a(s)},function(t){return e("throw",t,a,c)})}c(u.arg)}(o,i,e,a)})}return e=e?e.then(a,a):a()}}function E(t,e){var n=t.iterator[e.method];if(n===r){if(e.delegate=null,"throw"===e.method){if(t.iterator.return&&(e.method="return",e.arg=r,E(t,e),"throw"===e.method))return y;e.method="throw",e.arg=new TypeError("The iterator does not provide a 'throw' method")}return y}var o=f(n,t.iterator,e.arg);if("throw"===o.type)return e.method="throw",e.arg=o.arg,e.delegate=null,y;var i=o.arg;return i?i.done?(e[t.resultName]=i.value,e.next=t.nextLoc,"return"!==e.method&&(e.method="next",e.arg=r),e.delegate=null,y):i:(e.method="throw",e.arg=new TypeError("iterator result is not an object"),e.delegate=null,y)}function O(t){var r={tryLoc:t[0]};1 in t&&(r.catchLoc=t[1]),2 in t&&(r.finallyLoc=t[2],r.afterLoc=t[3]),this.tryEntries.push(r)}function j(t){var r=t.completion||{};r.type="normal",delete r.arg,t.completion=r}function k(t){this.tryEntries=[{tryLoc:"root"}],t.forEach(O,this),this.reset(!0)}function G(t){if(t){var e=t[i];if(e)return e.call(t);if("function"==typeof t.next)return t;if(!isNaN(t.length)){var o=-1,a=function e(){for(;++o<t.length;)if(n.call(t,o))return e.value=t[o],e.done=!1,e;return e.value=r,e.done=!0,e};return a.next=a}}return{next:N}}function N(){return{value:r,done:!0}}return d.prototype=L.constructor=g,g.constructor=d,g[c]=d.displayName="GeneratorFunction",t.isGeneratorFunction=function(t){var r="function"==typeof t&&t.constructor;return!!r&&(r===d||"GeneratorFunction"===(r.displayName||r.name))},t.mark=function(t){return Object.setPrototypeOf?Object.setPrototypeOf(t,g):(t.__proto__=g,c in t||(t[c]="GeneratorFunction")),t.prototype=Object.create(L),t},t.awrap=function(t){return{__await:t}},_(b.prototype),b.prototype[a]=function(){return this},t.AsyncIterator=b,t.async=function(r,e,n,o,i){void 0===i&&(i=Promise);var a=new b(u(r,e,n,o),i);return t.isGeneratorFunction(e)?a:a.next().then(function(t){return t.done?t.value:a.next()})},_(L),L[c]="Generator",L[i]=function(){return this},L.toString=function(){return"[object Generator]"},t.keys=function(t){var r=[];for(var e in t)r.push(e);return r.reverse(),function e(){for(;r.length;){var n=r.pop();if(n in t)return e.value=n,e.done=!1,e}return e.done=!0,e}},t.values=G,k.prototype={constructor:k,reset:function(t){if(this.prev=0,this.next=0,this.sent=this._sent=r,this.done=!1,this.delegate=null,this.method="next",this.arg=r,this.tryEntries.forEach(j),!t)for(var e in this)"t"===e.charAt(0)&&n.call(this,e)&&!isNaN(+e.slice(1))&&(this[e]=r)},stop:function(){this.done=!0;var t=this.tryEntries[0].completion;if("throw"===t.type)throw t.arg;return this.rval},dispatchException:function(t){if(this.done)throw t;var e=this;function o(n,o){return c.type="throw",c.arg=t,e.next=n,o&&(e.method="next",e.arg=r),!!o}for(var i=this.tryEntries.length-1;i>=0;--i){var a=this.tryEntries[i],c=a.completion;if("root"===a.tryLoc)return o("end");if(a.tryLoc<=this.prev){var u=n.call(a,"catchLoc"),f=n.call(a,"finallyLoc");if(u&&f){if(this.prev<a.catchLoc)return o(a.catchLoc,!0);if(this.prev<a.finallyLoc)return o(a.finallyLoc)}else if(u){if(this.prev<a.catchLoc)return o(a.catchLoc,!0)}else{if(!f)throw new Error("try statement without catch or finally");if(this.prev<a.finallyLoc)return o(a.finallyLoc)}}}},abrupt:function(t,r){for(var e=this.tryEntries.length-1;e>=0;--e){var o=this.tryEntries[e];if(o.tryLoc<=this.prev&&n.call(o,"finallyLoc")&&this.prev<o.finallyLoc){var i=o;break}}i&&("break"===t||"continue"===t)&&i.tryLoc<=r&&r<=i.finallyLoc&&(i=null);var a=i?i.completion:{};return a.type=t,a.arg=r,i?(this.method="next",this.next=i.finallyLoc,y):this.complete(a)},complete:function(t,r){if("throw"===t.type)throw t.arg;return"break"===t.type||"continue"===t.type?this.next=t.arg:"return"===t.type?(this.rval=this.arg=t.arg,this.method="return",this.next="end"):"normal"===t.type&&r&&(this.next=r),y},finish:function(t){for(var r=this.tryEntries.length-1;r>=0;--r){var e=this.tryEntries[r];if(e.finallyLoc===t)return this.complete(e.completion,e.afterLoc),j(e),y}},catch:function(t){for(var r=this.tryEntries.length-1;r>=0;--r){var e=this.tryEntries[r];if(e.tryLoc===t){var n=e.completion;if("throw"===n.type){var o=n.arg;j(e)}return o}}throw new Error("illegal catch attempt")},delegateYield:function(t,e,n){return this.delegate={iterator:G(t),resultName:e,nextLoc:n},"next"===this.method&&(this.arg=r),y}},t}(t.exports);try{regeneratorRuntime=n}catch(t){Function("r","regeneratorRuntime = r")(n)}},function(t,r,e){e(1),e(7),t.exports=e(0)},,,,,function(t,r){}]);
|
dist/js/multicurrencyOptions/app.js
CHANGED
@@ -1,4 +1,4 @@
|
|
1 |
-
!function(e){var t={};function n(r){if(t[r])return t[r].exports;var o=t[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,n),o.l=!0,o.exports}n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{configurable:!1,enumerable:!0,get:r})},n.r=function(e){Object.defineProperty(e,"__esModule",{value:!0})},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=
|
2 |
/*!
|
3 |
Copyright (c) 2017 Jed Watson.
|
4 |
Licensed under the MIT License (MIT), see
|
@@ -9,12 +9,12 @@
|
|
9 |
Licensed under the MIT License (MIT), see
|
10 |
http://jedwatson.github.io/classnames
|
11 |
*/
|
12 |
-
!function(){"use strict";var n={}.hasOwnProperty;function o(){for(var e=[],t=0;t<arguments.length;t++){var r=arguments[t];if(r){var i=typeof r;if("string"===i||"number"===i)e.push(r);else if(Array.isArray(r)&&r.length){var a=o.apply(null,r);a&&e.push(a)}else if("object"===i)for(var u in r)n.call(r,u)&&r[u]&&e.push(u)}}return e.join(" ")}void 0!==e&&e.exports?(o.default=o,e.exports=o):void 0===(r=function(){return o}.apply(t,[]))||(e.exports=r)}()},function(e,t,n){"use strict";n.d(t,"b",function(){return u});var r={};function o(e,t){0}function i(e,t){0}function a(e,t,n){t||r[n]||(e(!1,n),r[n]=!0)}function u(e,t){a(i,e,t)}t.a=function(e,t){a(o,e,t)}},function(e,t,n){"use strict";!function e(){if("undefined"!=typeof __REACT_DEVTOOLS_GLOBAL_HOOK__&&"function"==typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE)try{__REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE(e)}catch(e){console.error(e)}}(),e.exports=n(254)},function(e,t,n){"use strict";var r={MAC_ENTER:3,BACKSPACE:8,TAB:9,NUM_CENTER:12,ENTER:13,SHIFT:16,CTRL:17,ALT:18,PAUSE:19,CAPS_LOCK:20,ESC:27,SPACE:32,PAGE_UP:33,PAGE_DOWN:34,END:35,HOME:36,LEFT:37,UP:38,RIGHT:39,DOWN:40,PRINT_SCREEN:44,INSERT:45,DELETE:46,ZERO:48,ONE:49,TWO:50,THREE:51,FOUR:52,FIVE:53,SIX:54,SEVEN:55,EIGHT:56,NINE:57,QUESTION_MARK:63,A:65,B:66,C:67,D:68,E:69,F:70,G:71,H:72,I:73,J:74,K:75,L:76,M:77,N:78,O:79,P:80,Q:81,R:82,S:83,T:84,U:85,V:86,W:87,X:88,Y:89,Z:90,META:91,WIN_KEY_RIGHT:92,CONTEXT_MENU:93,NUM_ZERO:96,NUM_ONE:97,NUM_TWO:98,NUM_THREE:99,NUM_FOUR:100,NUM_FIVE:101,NUM_SIX:102,NUM_SEVEN:103,NUM_EIGHT:104,NUM_NINE:105,NUM_MULTIPLY:106,NUM_PLUS:107,NUM_MINUS:109,NUM_PERIOD:110,NUM_DIVISION:111,F1:112,F2:113,F3:114,F4:115,F5:116,F6:117,F7:118,F8:119,F9:120,F10:121,F11:122,F12:123,NUMLOCK:144,SEMICOLON:186,DASH:189,EQUALS:187,COMMA:188,PERIOD:190,SLASH:191,APOSTROPHE:192,SINGLE_QUOTE:222,OPEN_SQUARE_BRACKET:219,BACKSLASH:220,CLOSE_SQUARE_BRACKET:221,WIN_KEY:224,MAC_FF_META:224,WIN_IME:229,isTextModifyingKeyEvent:function(e){var t=e.keyCode;if(e.altKey&&!e.ctrlKey||e.metaKey||t>=r.F1&&t<=r.F12)return!1;switch(t){case r.ALT:case r.CAPS_LOCK:case r.CONTEXT_MENU:case r.CTRL:case r.DOWN:case r.END:case r.ESC:case r.HOME:case r.INSERT:case r.LEFT:case r.MAC_FF_META:case r.META:case r.NUMLOCK:case r.NUM_CENTER:case r.PAGE_DOWN:case r.PAGE_UP:case r.PAUSE:case r.PRINT_SCREEN:case r.RIGHT:case r.SHIFT:case r.UP:case r.WIN_KEY:case r.WIN_KEY_RIGHT:return!1;default:return!0}},isCharacterKey:function(e){if(e>=r.ZERO&&e<=r.NINE)return!0;if(e>=r.NUM_ZERO&&e<=r.NUM_MULTIPLY)return!0;if(e>=r.A&&e<=r.Z)return!0;if(-1!==window.navigator.userAgent.indexOf("WebKit")&&0===e)return!0;switch(e){case r.SPACE:case r.QUESTION_MARK:case r.NUM_PLUS:case r.NUM_MINUS:case r.NUM_PERIOD:case r.NUM_DIVISION:case r.SEMICOLON:case r.DASH:case r.EQUALS:case r.COMMA:case r.PERIOD:case r.SLASH:case r.APOSTROPHE:case r.SINGLE_QUOTE:case r.OPEN_SQUARE_BRACKET:case r.BACKSLASH:case r.CLOSE_SQUARE_BRACKET:return!0;default:return!1}}};t.a=r},function(e,t,n){e.exports=n(244)()},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),Object.defineProperty(t,"ConfigConsumer",{enumerable:!0,get:function(){return u.ConfigConsumer}}),Object.defineProperty(t,"ConfigContext",{enumerable:!0,get:function(){return u.ConfigContext}}),t.default=t.configConsumerProps=void 0;var r=s(n(0)),o=n(114),i=s(n(238)),a=function(e){return e&&e.__esModule?e:{default:e}}(n(42)),u=n(233),l=n(35);function c(){if("function"!=typeof WeakMap)return null;var e=new WeakMap;return c=function(){return e},e}function s(e){if(e&&e.__esModule)return e;if(null===e||"object"!==f(e)&&"function"!=typeof e)return{default:e};var t=c();if(t&&t.has(e))return t.get(e);var n={},r=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var o in e)if(Object.prototype.hasOwnProperty.call(e,o)){var i=r?Object.getOwnPropertyDescriptor(e,o):null;i&&(i.get||i.set)?Object.defineProperty(n,o,i):n[o]=e[o]}return n.default=e,t&&t.set(e,n),n}function f(e){"@babel/helpers - typeof";return(f="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(e)}function p(){return(p=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e}).apply(this,arguments)}function d(e,t){for(var n=0;n<t.length;n++){var r=t[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(e,r.key,r)}}function y(e,t){return(y=Object.setPrototypeOf||function(e,t){return e.__proto__=t,e})(e,t)}function h(e){var t=function(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Date.prototype.toString.call(Reflect.construct(Date,[],function(){})),!0}catch(e){return!1}}();return function(){var n,r=m(e);if(t){var o=m(this).constructor;n=Reflect.construct(r,arguments,o)}else n=r.apply(this,arguments);return function(e,t){if(t&&("object"===f(t)||"function"==typeof t))return t;return function(e){if(void 0===e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return e}(e)}(this,n)}}function m(e){return(m=Object.setPrototypeOf?Object.getPrototypeOf:function(e){return e.__proto__||Object.getPrototypeOf(e)})(e)}t.configConsumerProps=["getTargetContainer","getPopupContainer","rootPrefixCls","getPrefixCls","renderEmpty","csp","autoInsertSpaceInButton","locale","pageHeader"];var v=function(e){!function(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function");e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,writable:!0,configurable:!0}}),t&&y(e,t)}(n,r.Component);var t=h(n);function n(){var e;return function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,n),(e=t.apply(this,arguments)).getPrefixClsWrapper=function(t){return function(n,r){var o=e.props.prefixCls;if(r)return r;var i=o||t.getPrefixCls("");return n?"".concat(i,"-").concat(n):i}},e.renderProvider=function(t,n){var a=e.props,c=a.children,s=a.getTargetContainer,f=a.getPopupContainer,d=a.renderEmpty,y=a.csp,h=a.autoInsertSpaceInButton,m=a.form,v=a.input,b=a.locale,g=a.pageHeader,w=a.componentSize,O=a.direction,E=a.space,S=p(p({},t),{getPrefixCls:e.getPrefixClsWrapper(t),csp:y,autoInsertSpaceInButton:h,locale:b||n,direction:O,space:E});s&&(S.getTargetContainer=s),f&&(S.getPopupContainer=f),d&&(S.renderEmpty=d),g&&(S.pageHeader=g),v&&(S.input=v);var _=c,P={};return b&&b.Form&&b.Form.defaultValidateMessages&&(P=b.Form.defaultValidateMessages),m&&m.validateMessages&&(P=p(p({},P),m.validateMessages)),Object.keys(P).length>0&&(_=r.createElement(o.FormProvider,{validateMessages:P},c)),r.createElement(l.SizeContextProvider,{size:w},r.createElement(u.ConfigContext.Provider,{value:S},r.createElement(i.default,{locale:b||n,_ANT_MARK__:i.ANT_MARK},_)))},e}return function(e,t,n){t&&d(e.prototype,t),n&&d(e,n)}(n,[{key:"render",value:function(){var e=this;return r.createElement(a.default,null,function(t,n,o){return r.createElement(u.ConfigConsumer,null,function(t){return e.renderProvider(t,o)})})}}]),n}();t.default=v},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.useStore=t.getStore=t.getStoreAction=t.getStoreProperty=t.getCurrencyIndex=void 0;var r=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},o=n(78),i=n(36),a=function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var n in e)Object.prototype.hasOwnProperty.call(e,n)&&(t[n]=e[n]);return t.default=e,t}(n(28));t.default=function(e){var t=e.activeCurrencies,n=e.allCurrencies,a=e.allCountries,l=e.languages,c=e.gateways,s=e.mode,f=e.maxMindKeyExist;return(0,o.createStore)({activeCurrencies:t,allCurrencies:n,allCountries:a,languages:l,gateways:c,mode:s,maxMindKeyExist:f,modalCurrency:null,updating:!1,setDefaultCurrencyForLang:(0,o.action)(function(e,t){var n=e.languages.findIndex(function(e){return e.code===t.language}),r=e.languages[n];r.defaultCurrency=t.currency,e.languages[n]=r}),getCurrencyIndex:(0,o.action)(function(e,t){e.activeCurrencies.findIndex(function(e){return e.code===t})}),enableCurrencyForLang:(0,o.action)(function(e,t){var n=u(e.activeCurrencies)(t.currency),o=e.activeCurrencies[n],i=t.enable?1:0;o.languages=r({},o.languages,function(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}({},t.language,i)),e.activeCurrencies[n]=o}),deleteCurrency:(0,o.action)(function(e,t){var n=u(e.activeCurrencies)(t),o=r({},e.activeCurrencies[n]);e.activeCurrencies.splice(n,1),(0,i.triggerActiveCurrenciesChange)({action:"remove",currency:o})}),setModalCurrency:(0,o.action)(function(e,t){e.modalCurrency=e.setInitialGatewayCurrency(t,e.activeCurrencies)}),setInitialGatewayCurrency:function(e,t){var n=function(n){return void 0===n.currency||function(e){return t.find(function(t){return t.code===e})}(n.currency)||(n=r({},n,{currency:e.code})),n};return e&&e.gatewaysSettings&&Object.keys(e.gatewaysSettings).map(function(t){e.gatewaysSettings[t]=n(e.gatewaysSettings[t])}),e},saveModalCurrency:(0,o.action)(function(e){var t=u(e.activeCurrencies)(e.modalCurrency.code);if(t<0){var n=r({},e.modalCurrency,{isNew:!1});e.activeCurrencies.push(n),(0,i.triggerActiveCurrenciesChange)({action:"add",currency:n})}else e.activeCurrencies[t]=e.modalCurrency}),newCurrencies:(0,o.computed)(function(e){var t=e.activeCurrencies.map(function(e){return e.code});return e.allCurrencies.filter(function(e){return!t.includes(e.code)})}),defaultCurrency:(0,o.computed)(function(e){return e.activeCurrencies.filter(function(e){return e.isDefault})[0]}),setUpdating:(0,o.action)(function(e,t){e.updating=t}),setMode:(0,o.action)(function(e,t){e.mode=t,(0,i.triggerModeChange)({mode:t})}),setMaxMindKeyExist:(0,o.action)(function(e){e.maxMindKeyExist=!0})})};var u=t.getCurrencyIndex=function(e){return function(t){return a.findIndex(a.propEq("code",t))(e)}},l=t.getStoreProperty=function(e){return(0,o.useStoreState)(a.path(Array.isArray(e)?e:[e]))},c=t.getStoreAction=function(e){return(0,o.useStoreActions)(a.prop(e))};t.getStore=function(e,t){return[l(e),c(t)]},t.useStore=function(e){return[l(e),c("set"+(0,i.capitalize)(e)),c("reset"+(0,i.capitalize)(e))]}},function(e,t,n){"use strict";t.__esModule=!0;var r=function(e){return e&&e.__esModule?e:{default:e}}(n(218));t.default=r.default||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e}},function(e,t,n){(function(t){for(var r=n(242),o="undefined"==typeof window?t:window,i=["moz","webkit"],a="AnimationFrame",u=o["request"+a],l=o["cancel"+a]||o["cancelRequest"+a],c=0;!u&&c<i.length;c++)u=o[i[c]+"Request"+a],l=o[i[c]+"Cancel"+a]||o[i[c]+"CancelRequest"+a];if(!u||!l){var s=0,f=0,p=[];u=function(e){if(0===p.length){var t=r(),n=Math.max(0,1e3/60-(t-s));s=n+t,setTimeout(function(){var e=p.slice(0);p.length=0;for(var t=0;t<e.length;t++)if(!e[t].cancelled)try{e[t].callback(s)}catch(e){setTimeout(function(){throw e},0)}},Math.round(n))}return p.push({handle:++f,callback:e,cancelled:!1}),f},l=function(e){for(var t=0;t<p.length;t++)p[t].handle===e&&(p[t].cancelled=!0)}}e.exports=function(e){return u.call(o,e)},e.exports.cancel=function(){l.apply(o,arguments)},e.exports.polyfill=function(e){e||(e=o),e.requestAnimationFrame=u,e.cancelAnimationFrame=l}}).call(this,n(45))},function(e,t,n){"use strict";function r(e){"@babel/helpers - typeof";return(r="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(e)}Object.defineProperty(t,"__esModule",{value:!0}),t.default=void 0;var o=function(e){if(e&&e.__esModule)return e;if(null===e||"object"!==r(e)&&"function"!=typeof e)return{default:e};var t=s();if(t&&t.has(e))return t.get(e);var n={},o=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var i in e)if(Object.prototype.hasOwnProperty.call(e,i)){var a=o?Object.getOwnPropertyDescriptor(e,i):null;a&&(a.get||a.set)?Object.defineProperty(n,i,a):n[i]=e[i]}n.default=e,t&&t.set(e,n);return n}(n(0)),i=c(n(1)),a=c(n(88)),u=n(174),l=n(56);function c(e){return e&&e.__esModule?e:{default:e}}function s(){if("function"!=typeof WeakMap)return null;var e=new WeakMap;return s=function(){return e},e}function f(e,t){return function(e){if(Array.isArray(e))return e}(e)||function(e,t){if("undefined"==typeof Symbol||!(Symbol.iterator in Object(e)))return;var n=[],r=!0,o=!1,i=void 0;try{for(var a,u=e[Symbol.iterator]();!(r=(a=u.next()).done)&&(n.push(a.value),!t||n.length!==t);r=!0);}catch(e){o=!0,i=e}finally{try{r||null==u.return||u.return()}finally{if(o)throw i}}return n}(e,t)||function(e,t){if(!e)return;if("string"==typeof e)return p(e,t);var n=Object.prototype.toString.call(e).slice(8,-1);"Object"===n&&e.constructor&&(n=e.constructor.name);if("Map"===n||"Set"===n)return Array.from(n);if("Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n))return p(e,t)}(e,t)||function(){throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function p(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=new Array(t);n<t;n++)r[n]=e[n];return r}function d(e,t){if(null==e)return{};var n,r,o=function(e,t){if(null==e)return{};var n,r,o={},i=Object.keys(e);for(r=0;r<i.length;r++)n=i[r],t.indexOf(n)>=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r<i.length;r++)n=i[r],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}(0,u.setTwoToneColor)("#1890ff");var y=o.forwardRef(function(e,t){var n=e.className,r=e.icon,u=e.spin,c=e.rotate,s=e.tabIndex,p=e.onClick,y=e.twoToneColor,h=d(e,["className","icon","spin","rotate","tabIndex","onClick","twoToneColor"]),m=(0,i.default)("anticon",function(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}({},"anticon-".concat(r.name),Boolean(r.name)),n),v=(0,i.default)({"anticon-spin":!!u||"loading"===r.name}),b=s;void 0===b&&p&&(b=-1);var g=c?{msTransform:"rotate(".concat(c,"deg)"),transform:"rotate(".concat(c,"deg)")}:void 0,w=f((0,l.normalizeTwoToneColors)(y),2),O=w[0],E=w[1];return o.createElement("span",Object.assign({role:"img","aria-label":r.name},h,{ref:t,tabIndex:b,onClick:p,className:m}),o.createElement(a.default,{className:v,icon:r,primaryColor:O,secondaryColor:E,style:g}))});y.displayName="AntdIcon",y.getTwoToneColor=u.getTwoToneColor,y.setTwoToneColor=u.setTwoToneColor;var h=y;t.default=h},function(e,t,n){"use strict";function r(e){"@babel/helpers - typeof";return(r="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(e)}function o(){for(var e=arguments.length,t=new Array(e),n=0;n<e;n++)t[n]=arguments[n];return function(e){t.forEach(function(t){!function(e,t){"function"==typeof e?e(t):"object"===r(e)&&e&&"current"in e&&(e.current=t)}(t,e)})}}function i(e){return!(e.type&&e.type.prototype&&!e.type.prototype.render)&&!("function"==typeof e&&e.prototype&&!e.prototype.render)}n.d(t,"a",function(){return o}),n.d(t,"b",function(){return i})},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.Spinner=t.getTooltip=t.InputRow=t.SelectRow=void 0;var r=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},o=a(n(0)),i=a(n(105));function a(e){return e&&e.__esModule?e:{default:e}}t.SelectRow=function(e){var t=e.onChange,n=e.label,i=e.attrs,a=e.tooltip,l=e.children,c=e.afterSelect,s=void 0===c?null:c;return o.default.createElement("div",{className:"wpml-form-row"},o.default.createElement("label",{htmlFor:i.id},n,u(a)),o.default.createElement("select",r({onChange:t},i),l),s)},t.InputRow=function(e){var t=e.onChange,n=e.label,i=e.attrs,a=e.tooltip;return o.default.createElement("div",{className:"wpml-form-row"},o.default.createElement("label",{htmlFor:i.id},n,u(a)),o.default.createElement("input",r({},i,{onChange:t})))};var u=t.getTooltip=function(e){return e&&o.default.createElement(i.default,{title:l(e)}," ",o.default.createElement("i",{className:"wcml-tip otgs-ico-help"}))},l=function(e){return o.default.createElement("div",{dangerouslySetInnerHTML:{__html:e}})};t.Spinner=function(e){var t=e.style,n=r({visibility:"visible"},t);return o.default.createElement("span",{className:"spinner",style:n})}},function(e,t,n){"use strict";n.d(t,"a",function(){return i});var r=n(3),o=n.n(r);function i(e){return e instanceof HTMLElement?e:o.a.findDOMNode(e)}},function(e,t,n){"use strict";(function(e){var r;n.d(t,"a",function(){return $}),n.d(t,"b",function(){return q}),n.d(t,"c",function(){return u}),n.d(t,"d",function(){return c}),n.d(t,"e",function(){return B});var o="undefined"!=typeof Symbol?Symbol("immer-nothing"):((r={})["immer-nothing"]=!0,r),i="undefined"!=typeof Symbol&&Symbol.for?Symbol.for("immer-draftable"):"__$immer_draftable",a="undefined"!=typeof Symbol&&Symbol.for?Symbol.for("immer-state"):"__$immer_state";function u(e){return!!e&&!!e[a]}function l(e){if(!e||"object"!=typeof e)return!1;if(Array.isArray(e))return!0;var t=Object.getPrototypeOf(e);return!t||t===Object.prototype||(!!e[i]||!!e.constructor[i])}function c(e){if(e&&e[a])return e[a].base}var s=Object.assign||function(e,t){for(var n in t)h(t,n)&&(e[n]=t[n]);return e},f="undefined"!=typeof Reflect&&Reflect.ownKeys?Reflect.ownKeys:void 0!==Object.getOwnPropertySymbols?function(e){return Object.getOwnPropertyNames(e).concat(Object.getOwnPropertySymbols(e))}:Object.getOwnPropertyNames;function p(e,t){if(void 0===t&&(t=!1),Array.isArray(e))return e.slice();var n=Object.create(Object.getPrototypeOf(e));return f(e).forEach(function(r){if(r!==a){var o=Object.getOwnPropertyDescriptor(e,r),i=o.value;o.get&&t&&(i=o.get.call(e)),o.enumerable?n[r]=i:t&&Object.defineProperty(n,r,{value:i,writable:!0,configurable:!0})}}),n}function d(e,t){if(Array.isArray(e))for(var n=0;n<e.length;n++)t(n,e[n],e);else f(e).forEach(function(n){return t(n,e[n],e)})}function y(e,t){var n=Object.getOwnPropertyDescriptor(e,t);return!!n&&n.enumerable}function h(e,t){return Object.prototype.hasOwnProperty.call(e,t)}function m(e,t){return e===t?0!==e||1/e==1/t:e!=e&&t!=t}var v=function(e){this.drafts=[],this.parent=e,this.canAutoFreeze=!0,this.patches=null};function b(e){e[a].revoke()}v.prototype.usePatches=function(e){e&&(this.patches=[],this.inversePatches=[],this.patchListener=e)},v.prototype.revoke=function(){this.leave(),this.drafts.forEach(b),this.drafts=null},v.prototype.leave=function(){this===v.current&&(v.current=this.parent)},v.current=null,v.enter=function(){return this.current=new v(this.current)};var g={};function w(e,t){var n=Array.isArray(e),r=x(e);d(r,function(t){!function(e,t,n){var r=g[t];r?r.enumerable=n:g[t]=r={configurable:!0,enumerable:n,get:function(){return function(e,t){j(e);var n=S(E(e),t);if(e.finalizing)return n;if(n===S(e.base,t)&&l(n))return P(e),e.copy[t]=w(n,e);return n}(this[a],t)},set:function(e){!function(e,t,n){if(j(e),e.assigned[t]=!0,!e.modified){if(m(n,S(E(e),t)))return;_(e),P(e)}e.copy[t]=n}(this[a],t,e)}};Object.defineProperty(e,t,r)}(r,t,n||y(e,t))});var o=t?t.scope:v.current;return function(e,t,n){Object.defineProperty(e,t,{value:n,enumerable:!1,writable:!0})}(r,a,{scope:o,modified:!1,finalizing:!1,finalized:!1,assigned:{},parent:t,base:e,draft:r,copy:null,revoke:O,revoked:!1}),o.drafts.push(r),r}function O(){this.revoked=!0}function E(e){return e.copy||e.base}function S(e,t){var n=e[a];if(n&&!n.finalizing){n.finalizing=!0;var r=e[t];return n.finalizing=!1,r}return e[t]}function _(e){e.modified||(e.modified=!0,e.parent&&_(e.parent))}function P(e){e.copy||(e.copy=x(e.base))}function x(e){var t=e&&e[a];if(t){t.finalizing=!0;var n=p(t.draft,!0);return t.finalizing=!1,n}return p(e)}function j(e){if(!0===e.revoked)throw new Error("Cannot use a proxy that has been revoked. Did you pass an object from inside an immer function to an async process? "+JSON.stringify(E(e)))}function C(e){for(var t=e.length-1;t>=0;t--){var n=e[t][a];n.modified||(Array.isArray(n.base)?T(n)&&_(n):k(n)&&_(n))}}function k(e){for(var t=e.base,n=e.draft,r=Object.keys(n),o=r.length-1;o>=0;o--){var i=r[o],u=t[i];if(void 0===u&&!h(t,i))return!0;var l=n[i],c=l&&l[a];if(c?c.base!==u:!m(l,u))return!0}return r.length!==Object.keys(t).length}function T(e){var t=e.draft;if(t.length!==e.base.length)return!0;var n=Object.getOwnPropertyDescriptor(t,t.length-1);return!(!n||n.get)}var M=Object.freeze({willFinalize:function(e,t,n){e.drafts.forEach(function(e){e[a].finalizing=!0}),n?u(t)&&t[a].scope===e&&C(e.drafts):(e.patches&&function e(t){if(t&&"object"==typeof t){var n=t[a];if(n){var r=n.base,o=n.draft,i=n.assigned;if(Array.isArray(t)){if(T(n)){if(_(n),i.length=!0,o.length<r.length)for(var u=o.length;u<r.length;u++)i[u]=!1;else for(var l=r.length;l<o.length;l++)i[l]=!0;for(var c=0;c<o.length;c++)void 0===i[c]&&e(o[c])}}else Object.keys(o).forEach(function(t){void 0!==r[t]||h(r,t)?i[t]||e(o[t]):(i[t]=!0,_(n))}),Object.keys(r).forEach(function(e){void 0!==o[e]||h(o,e)||(i[e]=!1,_(n))})}}}(e.drafts[0]),C(e.drafts))},createProxy:w});function A(e,t){var n=t?t.scope:v.current,r={scope:n,modified:!1,finalized:!1,assigned:{},parent:t,base:e,draft:null,drafts:{},copy:null,revoke:null},o=Array.isArray(e)?Proxy.revocable([r],R):Proxy.revocable(r,N),i=o.revoke,a=o.proxy;return r.draft=a,r.revoke=i,n.drafts.push(a),a}var N={get:function(e,t){if(t===a)return e;var n=e.drafts;if(!e.modified&&h(n,t))return n[t];var r=D(e)[t];if(e.finalized||!l(r))return r;if(e.modified){if(r!==I(e.base,t))return r;n=e.copy}return n[t]=A(r,e)},has:function(e,t){return t in D(e)},ownKeys:function(e){return Reflect.ownKeys(D(e))},set:function(e,t,n){if(!e.modified){var r=I(e.base,t),o=n?m(r,n)||n===e.drafts[t]:m(r,n)&&t in e.base;if(o)return!0;F(e)}return e.assigned[t]=!0,e.copy[t]=n,!0},deleteProperty:function(e,t){(void 0!==I(e.base,t)||t in e.base)&&(e.assigned[t]=!1,F(e));e.copy&&delete e.copy[t];return!0},getOwnPropertyDescriptor:function(e,t){var n=D(e),r=Reflect.getOwnPropertyDescriptor(n,t);r&&(r.writable=!0,r.configurable=!Array.isArray(n)||"length"!==t);return r},defineProperty:function(){throw new Error("Object.defineProperty() cannot be used on an Immer draft")},getPrototypeOf:function(e){return Object.getPrototypeOf(e.base)},setPrototypeOf:function(){throw new Error("Object.setPrototypeOf() cannot be used on an Immer draft")}},R={};function D(e){return e.copy||e.base}function I(e,t){var n=e[a],r=Reflect.getOwnPropertyDescriptor(n?D(n):e,t);return r&&r.value}function F(e){e.modified||(e.modified=!0,e.copy=s(p(e.base),e.drafts),e.drafts=null,e.parent&&F(e.parent))}d(N,function(e,t){R[e]=function(){return arguments[0]=arguments[0][0],t.apply(this,arguments)}}),R.deleteProperty=function(e,t){if(isNaN(parseInt(t)))throw new Error("Immer only supports deleting array indices");return N.deleteProperty.call(this,e[0],t)},R.set=function(e,t,n){if("length"!==t&&isNaN(parseInt(t)))throw new Error("Immer only supports setting array indices and the 'length' property");return N.set.call(this,e[0],t,n)};var L=Object.freeze({willFinalize:function(){},createProxy:A});function z(e,t,n,r){Array.isArray(e.base)?function(e,t,n,r){var o,i,a=e.base,u=e.copy,l=e.assigned;u.length<a.length&&(a=(o=[u,a])[0],u=o[1],n=(i=[r,n])[0],r=i[1]);var c=u.length-a.length,s=0;for(;a[s]===u[s]&&s<a.length;)++s;var f=a.length;for(;f>s&&a[f-1]===u[f+c-1];)--f;for(var p=s;p<f;++p)if(l[p]&&u[p]!==a[p]){var d=t.concat([p]);n.push({op:"replace",path:d,value:u[p]}),r.push({op:"replace",path:d,value:a[p]})}for(var y=f!=a.length,h=n.length,m=f+c-1;m>=f;--m){var v=t.concat([m]);n[h+m-f]={op:"add",path:v,value:u[m]},y&&r.push({op:"remove",path:v})}y||r.push({op:"replace",path:t.concat(["length"]),value:a.length})}(e,t,n,r):function(e,t,n,r){var o=e.base,i=e.copy;d(e.assigned,function(e,a){var u=o[e],l=i[e],c=a?e in o?"replace":"add":"remove";if(u!==l||"replace"!==c){var s=t.concat(e);n.push("remove"===c?{op:c,path:s}:{op:c,path:s,value:l}),r.push("add"===c?{op:"remove",path:s}:"remove"===c?{op:"add",path:s,value:u}:{op:"replace",path:s,value:u})}})}(e,t,n,r)}function V(e,t){for(var n=0;n<t.length;n++){var r=t[n],o=r.path;if(0===o.length&&"replace"===r.op)e=r.value;else{for(var i=e,a=0;a<o.length-1;a++)if(!(i=i[o[a]])||"object"!=typeof i)throw new Error("Cannot apply patch, path doesn't resolve: "+o.join("/"));var u=o[o.length-1];switch(r.op){case"replace":i[u]=r.value;break;case"add":Array.isArray(i)?i.splice(u,0,r.value):i[u]=r.value;break;case"remove":Array.isArray(i)?i.splice(u,1):delete i[u];break;default:throw new Error("Unsupported patch operation: "+r.op)}}}return e}var W={useProxies:"undefined"!=typeof Proxy&&"undefined"!=typeof Reflect,autoFreeze:void 0===e&&"verifyMinified"===function(){}.name,onAssign:null,onDelete:null,onCopy:null},U=function(e){s(this,W,e),this.setUseProxies(this.useProxies),this.produce=this.produce.bind(this)};U.prototype.produce=function(e,t,n){var r,i=this;if("function"==typeof e&&"function"!=typeof t){var a=t;t=e;var u=this;return function(e){var n=this;void 0===e&&(e=a);for(var r=[],o=arguments.length-1;o-- >0;)r[o]=arguments[o+1];return u.produce(e,function(e){return t.call.apply(t,[n,e].concat(r))})}}if("function"!=typeof t)throw new Error("The first or second argument to `produce` must be a function");if(void 0!==n&&"function"!=typeof n)throw new Error("The third argument to `produce` must be a function or undefined");if(l(e)){var c=v.enter(),s=this.createProxy(e),f=!0;try{r=t(s),f=!1}finally{f?c.revoke():c.leave()}return r instanceof Promise?r.then(function(e){return c.usePatches(n),i.processResult(e,c)},function(e){throw c.revoke(),e}):(c.usePatches(n),this.processResult(r,c))}return void 0===(r=t(e))?e:r!==o?r:void 0},U.prototype.createDraft=function(e){if(!l(e))throw new Error("First argument to `createDraft` must be a plain object, an array, or an immerable object");var t=v.enter(),n=this.createProxy(e);return n[a].isManual=!0,t.leave(),n},U.prototype.finishDraft=function(e,t){var n=e&&e[a];if(!n||!n.isManual)throw new Error("First argument to `finishDraft` must be a draft returned by `createDraft`");if(n.finalized)throw new Error("The given draft is already finalized");var r=n.scope;return r.usePatches(t),this.processResult(void 0,r)},U.prototype.setAutoFreeze=function(e){this.autoFreeze=e},U.prototype.setUseProxies=function(e){this.useProxies=e,s(this,e?L:M)},U.prototype.applyPatches=function(e,t){return u(e)?V(e,t):this.produce(e,function(e){return V(e,t)})},U.prototype.processResult=function(e,t){var n=t.drafts[0],r=void 0!==e&&e!==n;if(this.willFinalize(t,e,r),r){if(n[a].modified)throw t.revoke(),new Error("An immer producer returned a new value *and* modified its draft. Either return a new value *or* modify the draft.");l(e)&&(e=this.finalize(e,null,t)),t.patches&&(t.patches.push({op:"replace",path:[],value:e}),t.inversePatches.push({op:"replace",path:[],value:n[a].base}))}else e=this.finalize(n,[],t);return t.revoke(),t.patches&&t.patchListener(t.patches,t.inversePatches),e!==o?e:void 0},U.prototype.finalize=function(e,t,n){var r=this,o=e[a];if(!o)return Object.isFrozen(e)?e:this.finalizeTree(e,null,n);if(o.scope!==n)return e;if(!o.modified)return o.base;if(!o.finalized){if(o.finalized=!0,this.finalizeTree(o.draft,t,n),this.onDelete)if(this.useProxies){var i=o.assigned;for(var u in i)i[u]||this.onDelete(o,u)}else{var l=o.base,c=o.copy;d(l,function(e){h(c,e)||r.onDelete(o,e)})}this.onCopy&&this.onCopy(o),this.autoFreeze&&n.canAutoFreeze&&Object.freeze(o.copy),t&&n.patches&&z(o,t,n.patches,n.inversePatches)}return o.copy},U.prototype.finalizeTree=function(e,t,n){var r=this,o=e[a];o&&(this.useProxies||(o.copy=p(o.draft,!0)),e=o.copy);var i=!!t&&!!n.patches,c=function(a,s,f){if(s===f)throw Error("Immer forbids circular references");var p=!!o&&f===e;if(u(s)){var h=p&&i&&!o.assigned[a]?t.concat(a):null;if(u(s=r.finalize(s,h,n))&&(n.canAutoFreeze=!1),Array.isArray(f)||y(f,a)?f[a]=s:Object.defineProperty(f,a,{value:s}),p&&s===o.base[a])return}else{if(p&&m(s,o.base[a]))return;l(s)&&!Object.isFrozen(s)&&d(s,c)}p&&r.onAssign&&r.onAssign(o,a,s)};return d(e,c),e};var H=new U,B=(H.produce,H.setAutoFreeze.bind(H)),$=(H.setUseProxies.bind(H),H.applyPatches.bind(H),H.createDraft.bind(H)),q=H.finishDraft.bind(H)}).call(this,n(74))},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.default=wcmlMultiCurrency.strings},function(e,t,n){"use strict";n.d(t,"a",function(){return a});var r=n(0),o=n.n(r),i=n(107);function a(e){var t=[];return o.a.Children.forEach(e,function(e){void 0!==e&&null!==e&&(Array.isArray(e)?t=t.concat(a(e)):Object(i.isFragment)(e)&&e.props?t=t.concat(a(e.props.children)):t.push(e))}),t}},function(e,t){var n=e.exports="undefined"!=typeof window&&window.Math==Math?window:"undefined"!=typeof self&&self.Math==Math?self:Function("return this")();"number"==typeof __g&&(__g=n)},function(e,t,n){"use strict";function r(e,t){for(var n=t;n;){if(n===e)return!0;n=n.parentNode}return!1}n.d(t,"a",function(){return r})},function(e,t){var n={}.hasOwnProperty;e.exports=function(e,t){return n.call(e,t)}},function(e,t,n){e.exports=!n(31)(function(){return 7!=Object.defineProperty({},"a",{get:function(){return 7}}).a})},function(e,t){var n=e.exports={version:"2.6.11"};"number"==typeof __e&&(__e=n)},function(e,t,n){e.exports=n(106)},function(e,t,n){var r=n(65)("wks"),o=n(38),i=n(17).Symbol,a="function"==typeof i;(e.exports=function(e){return r[e]||(r[e]=a&&i[e]||(a?i:o)("Symbol."+e))}).store=r},function(e,t,n){var r=n(96),o=n(68);e.exports=function(e){return r(o(e))}},function(e,t){e.exports=function(e){return"object"==typeof e?null!==e:"function"==typeof e}},function(e,t,n){var r=n(32),o=n(99),i=n(69),a=Object.defineProperty;t.f=n(20)?Object.defineProperty:function(e,t,n){if(r(e),t=i(t,!0),r(n),o)try{return a(e,t,n)}catch(e){}if("get"in n||"set"in n)throw TypeError("Accessors not supported!");return"value"in n&&(e[t]=n.value),e}},function(e,t,n){var r=n(26),o=n(41);e.exports=n(20)?function(e,t,n){return r.f(e,t,o(1,n))}:function(e,t,n){return e[t]=n,e}},function(e,t,n){"use strict";n.r(t);var r=function(){return!1},o=function(){return!0},i={"@@functional/placeholder":!0};function a(e){return null!=e&&"object"==typeof e&&!0===e["@@functional/placeholder"]}function u(e){return function t(n){return 0===arguments.length||a(n)?t:e.apply(this,arguments)}}function l(e){return function t(n,r){switch(arguments.length){case 0:return t;case 1:return a(n)?t:u(function(t){return e(n,t)});default:return a(n)&&a(r)?t:a(n)?u(function(t){return e(t,r)}):a(r)?u(function(t){return e(n,t)}):e(n,r)}}}var c=l(function(e,t){return Number(e)+Number(t)});function s(e,t){var n;e=e||[],t=t||[];var r=e.length,o=t.length,i=[];for(n=0;n<r;)i[i.length]=e[n],n+=1;for(n=0;n<o;)i[i.length]=t[n],n+=1;return i}function f(e,t){switch(e){case 0:return function(){return t.apply(this,arguments)};case 1:return function(e){return t.apply(this,arguments)};case 2:return function(e,n){return t.apply(this,arguments)};case 3:return function(e,n,r){return t.apply(this,arguments)};case 4:return function(e,n,r,o){return t.apply(this,arguments)};case 5:return function(e,n,r,o,i){return t.apply(this,arguments)};case 6:return function(e,n,r,o,i,a){return t.apply(this,arguments)};case 7:return function(e,n,r,o,i,a,u){return t.apply(this,arguments)};case 8:return function(e,n,r,o,i,a,u,l){return t.apply(this,arguments)};case 9:return function(e,n,r,o,i,a,u,l,c){return t.apply(this,arguments)};case 10:return function(e,n,r,o,i,a,u,l,c,s){return t.apply(this,arguments)};default:throw new Error("First argument to _arity must be a non-negative integer no greater than ten")}}function p(e,t,n){return function(){for(var r=[],o=0,i=e,u=0;u<t.length||o<arguments.length;){var l;u<t.length&&(!a(t[u])||o>=arguments.length)?l=t[u]:(l=arguments[o],o+=1),r[u]=l,a(l)||(i-=1),u+=1}return i<=0?n.apply(this,r):f(i,p(e,r,n))}}var d=l(function(e,t){return 1===e?u(t):f(e,p(e,[],t))}),y=u(function(e){return d(e.length,function(){var t=0,n=arguments[0],r=arguments[arguments.length-1],o=Array.prototype.slice.call(arguments,0);return o[0]=function(){var e=n.apply(this,s(arguments,[t,r]));return t+=1,e},e.apply(this,o)})});function h(e){return function t(n,r,o){switch(arguments.length){case 0:return t;case 1:return a(n)?t:l(function(t,r){return e(n,t,r)});case 2:return a(n)&&a(r)?t:a(n)?l(function(t,n){return e(t,r,n)}):a(r)?l(function(t,r){return e(n,t,r)}):u(function(t){return e(n,r,t)});default:return a(n)&&a(r)&&a(o)?t:a(n)&&a(r)?l(function(t,n){return e(t,n,o)}):a(n)&&a(o)?l(function(t,n){return e(t,r,n)}):a(r)&&a(o)?l(function(t,r){return e(n,t,r)}):a(n)?u(function(t){return e(t,r,o)}):a(r)?u(function(t){return e(n,t,o)}):a(o)?u(function(t){return e(n,r,t)}):e(n,r,o)}}}var m=h(function(e,t,n){if(e>=n.length||e<-n.length)return n;var r=(e<0?n.length:0)+e,o=s(n);return o[r]=t(n[r]),o}),v=Array.isArray||function(e){return null!=e&&e.length>=0&&"[object Array]"===Object.prototype.toString.call(e)};function b(e){return null!=e&&"function"==typeof e["@@transducer/step"]}function g(e,t,n){return function(){if(0===arguments.length)return n();var r=Array.prototype.slice.call(arguments,0),o=r.pop();if(!v(o)){for(var i=0;i<e.length;){if("function"==typeof o[e[i]])return o[e[i]].apply(o,r);i+=1}if(b(o))return t.apply(null,r)(o)}return n.apply(this,arguments)}}function w(e){return e&&e["@@transducer/reduced"]?e:{"@@transducer/value":e,"@@transducer/reduced":!0}}var O={init:function(){return this.xf["@@transducer/init"]()},result:function(e){return this.xf["@@transducer/result"](e)}},E=function(){function e(e,t){this.xf=t,this.f=e,this.all=!0}return e.prototype["@@transducer/init"]=O.init,e.prototype["@@transducer/result"]=function(e){return this.all&&(e=this.xf["@@transducer/step"](e,!0)),this.xf["@@transducer/result"](e)},e.prototype["@@transducer/step"]=function(e,t){return this.f(t)||(this.all=!1,e=w(this.xf["@@transducer/step"](e,!1))),e},e}(),S=l(g(["all"],l(function(e,t){return new E(e,t)}),function(e,t){for(var n=0;n<t.length;){if(!e(t[n]))return!1;n+=1}return!0})),_=l(function(e,t){return t>e?t:e});function P(e,t){for(var n=0,r=t.length,o=Array(r);n<r;)o[n]=e(t[n]),n+=1;return o}function x(e){return"[object String]"===Object.prototype.toString.call(e)}var j=u(function(e){return!!v(e)||!!e&&("object"==typeof e&&(!x(e)&&(1===e.nodeType?!!e.length:0===e.length||e.length>0&&(e.hasOwnProperty(0)&&e.hasOwnProperty(e.length-1)))))}),C=function(){function e(e){this.f=e}return e.prototype["@@transducer/init"]=function(){throw new Error("init not implemented on XWrap")},e.prototype["@@transducer/result"]=function(e){return e},e.prototype["@@transducer/step"]=function(e,t){return this.f(e,t)},e}();function k(e){return new C(e)}var T=l(function(e,t){return f(e.length,function(){return e.apply(t,arguments)})});function M(e,t,n){for(var r=n.next();!r.done;){if((t=e["@@transducer/step"](t,r.value))&&t["@@transducer/reduced"]){t=t["@@transducer/value"];break}r=n.next()}return e["@@transducer/result"](t)}function A(e,t,n,r){return e["@@transducer/result"](n[r](T(e["@@transducer/step"],e),t))}var N="undefined"!=typeof Symbol?Symbol.iterator:"@@iterator";function R(e,t,n){if("function"==typeof e&&(e=k(e)),j(n))return function(e,t,n){for(var r=0,o=n.length;r<o;){if((t=e["@@transducer/step"](t,n[r]))&&t["@@transducer/reduced"]){t=t["@@transducer/value"];break}r+=1}return e["@@transducer/result"](t)}(e,t,n);if("function"==typeof n["fantasy-land/reduce"])return A(e,t,n,"fantasy-land/reduce");if(null!=n[N])return M(e,t,n[N]());if("function"==typeof n.next)return M(e,t,n);if("function"==typeof n.reduce)return A(e,t,n,"reduce");throw new TypeError("reduce: list must be array or iterable")}var D=function(){function e(e,t){this.xf=t,this.f=e}return e.prototype["@@transducer/init"]=O.init,e.prototype["@@transducer/result"]=O.result,e.prototype["@@transducer/step"]=function(e,t){return this.xf["@@transducer/step"](e,this.f(t))},e}(),I=l(function(e,t){return new D(e,t)});function F(e,t){return Object.prototype.hasOwnProperty.call(t,e)}var L=Object.prototype.toString,z=function(){return"[object Arguments]"===L.call(arguments)?function(e){return"[object Arguments]"===L.call(e)}:function(e){return F("callee",e)}}(),V=!{toString:null}.propertyIsEnumerable("toString"),W=["constructor","valueOf","isPrototypeOf","toString","propertyIsEnumerable","hasOwnProperty","toLocaleString"],U=function(){return arguments.propertyIsEnumerable("length")}(),H=function(e,t){for(var n=0;n<e.length;){if(e[n]===t)return!0;n+=1}return!1},B="function"!=typeof Object.keys||U?u(function(e){if(Object(e)!==e)return[];var t,n,r=[],o=U&&z(e);for(t in e)!F(t,e)||o&&"length"===t||(r[r.length]=t);if(V)for(n=W.length-1;n>=0;)F(t=W[n],e)&&!H(r,t)&&(r[r.length]=t),n-=1;return r}):u(function(e){return Object(e)!==e?[]:Object.keys(e)}),$=l(g(["fantasy-land/map","map"],I,function(e,t){switch(Object.prototype.toString.call(t)){case"[object Function]":return d(t.length,function(){return e.call(this,t.apply(this,arguments))});case"[object Object]":return R(function(n,r){return n[r]=e(t[r]),n},{},B(t));default:return P(e,t)}})),q=Number.isInteger||function(e){return e<<0===e},K=l(function(e,t){var n=e<0?t.length+e:e;return x(t)?t.charAt(n):t[n]}),Y=l(function(e,t){return e.map(function(e){for(var n,r=t,o=0;o<e.length;){if(null==r)return;n=e[o],r=q(n)?K(n,r):r[n],o+=1}return r})}),X=l(function(e,t){return Y([e],t)[0]}),Q=l(function(e,t){return X([e],t)}),G=l(function(e,t){return $(Q(e),t)}),J=h(R),Z=u(function(e){return d(J(_,0,G("length",e)),function(){for(var t=0,n=e.length;t<n;){if(!e[t].apply(this,arguments))return!1;t+=1}return!0})}),ee=u(function(e){return function(){return e}}),te=l(function(e,t){return e&&t}),ne=function(){function e(e,t){this.xf=t,this.f=e,this.any=!1}return e.prototype["@@transducer/init"]=O.init,e.prototype["@@transducer/result"]=function(e){return this.any||(e=this.xf["@@transducer/step"](e,!1)),this.xf["@@transducer/result"](e)},e.prototype["@@transducer/step"]=function(e,t){return this.f(t)&&(this.any=!0,e=w(this.xf["@@transducer/step"](e,!0))),e},e}(),re=l(g(["any"],l(function(e,t){return new ne(e,t)}),function(e,t){for(var n=0;n<t.length;){if(e(t[n]))return!0;n+=1}return!1})),oe=u(function(e){return d(J(_,0,G("length",e)),function(){for(var t=0,n=e.length;t<n;){if(e[t].apply(this,arguments))return!0;t+=1}return!1})}),ie=l(function(e,t){return"function"==typeof t["fantasy-land/ap"]?t["fantasy-land/ap"](e):"function"==typeof e.ap?e.ap(t):"function"==typeof e?function(n){return e(n)(t(n))}:R(function(e,n){return s(e,$(n,t))},[],e)});var ae=function(){function e(e,t){this.xf=t,this.pos=0,this.full=!1,this.acc=new Array(e)}return e.prototype["@@transducer/init"]=O.init,e.prototype["@@transducer/result"]=function(e){return this.acc=null,this.xf["@@transducer/result"](e)},e.prototype["@@transducer/step"]=function(e,t){return this.store(t),this.full?this.xf["@@transducer/step"](e,this.getCopy()):e},e.prototype.store=function(e){this.acc[this.pos]=e,this.pos+=1,this.pos===this.acc.length&&(this.pos=0,this.full=!0)},e.prototype.getCopy=function(){return s(Array.prototype.slice.call(this.acc,this.pos),Array.prototype.slice.call(this.acc,0,this.pos))},e}(),ue=l(g([],l(function(e,t){return new ae(e,t)}),function(e,t){for(var n=0,r=t.length-(e-1),o=new Array(r>=0?r:0);n<r;)o[n]=Array.prototype.slice.call(t,n,n+e),n+=1;return o})),le=l(function(e,t){return s(t,[e])}),ce=l(function(e,t){return e.apply(this,t)}),se=u(function(e){for(var t=B(e),n=t.length,r=[],o=0;o<n;)r[o]=e[t[o]],o+=1;return r});function fe(e,t){return B(t).reduce(function(n,r){return n[r]=e(t[r]),n},{})}var pe=u(function e(t){return t=fe(function(t){return"function"==typeof t?t:e(t)},t),d(J(_,0,G("length",se(t))),function(){var e=arguments;return fe(function(t){return ce(t,e)},t)})}),de=l(function(e,t){return t(e)}),ye=h(function(e,t,n){var r=e(t),o=e(n);return r<o?-1:r>o?1:0}),he=h(function(e,t,n){var r={};for(var o in n)r[o]=n[o];return r[e]=t,r}),me=u(function(e){return null==e}),ve=h(function e(t,n,r){if(0===t.length)return n;var o=t[0];if(t.length>1){var i=!me(r)&&F(o,r)?r[o]:q(t[1])?[]:{};n=e(Array.prototype.slice.call(t,1),n,i)}if(q(o)&&v(r)){var a=[].concat(r);return a[o]=n,a}return he(o,n,r)}),be=l(function(e,t){switch(e){case 0:return function(){return t.call(this)};case 1:return function(e){return t.call(this,e)};case 2:return function(e,n){return t.call(this,e,n)};case 3:return function(e,n,r){return t.call(this,e,n,r)};case 4:return function(e,n,r,o){return t.call(this,e,n,r,o)};case 5:return function(e,n,r,o,i){return t.call(this,e,n,r,o,i)};case 6:return function(e,n,r,o,i,a){return t.call(this,e,n,r,o,i,a)};case 7:return function(e,n,r,o,i,a,u){return t.call(this,e,n,r,o,i,a,u)};case 8:return function(e,n,r,o,i,a,u,l){return t.call(this,e,n,r,o,i,a,u,l)};case 9:return function(e,n,r,o,i,a,u,l,c){return t.call(this,e,n,r,o,i,a,u,l,c)};case 10:return function(e,n,r,o,i,a,u,l,c,s){return t.call(this,e,n,r,o,i,a,u,l,c,s)};default:throw new Error("First argument to nAry must be a non-negative integer no greater than ten")}}),ge=u(function(e){return be(2,e)});function we(e){var t=Object.prototype.toString.call(e);return"[object Function]"===t||"[object AsyncFunction]"===t||"[object GeneratorFunction]"===t||"[object AsyncGeneratorFunction]"===t}var Oe=l(function(e,t){var n=d(e,t);return d(e,function(){return R(ie,$(n,arguments[0]),Array.prototype.slice.call(arguments,1))})}),Ee=u(function(e){return Oe(e.length,e)}),Se=l(function(e,t){return we(e)?function(){return e.apply(this,arguments)&&t.apply(this,arguments)}:Ee(te)(e,t)}),_e=u(function(e){return d(e.length,e)}),Pe=_e(function(e){return e.apply(this,Array.prototype.slice.call(arguments,1))});function xe(e){return function t(n){for(var r,o,i,a=[],u=0,l=n.length;u<l;){if(j(n[u]))for(i=0,o=(r=e?t(n[u]):n[u]).length;i<o;)a[a.length]=r[i],i+=1;else a[a.length]=n[u];u+=1}return a}}var je=function(e){var t=function(e){return{"@@transducer/init":O.init,"@@transducer/result":function(t){return e["@@transducer/result"](t)},"@@transducer/step":function(t,n){var r=e["@@transducer/step"](t,n);return r["@@transducer/reduced"]?function(e){return{"@@transducer/value":e,"@@transducer/reduced":!0}}(r):r}}}(e);return{"@@transducer/init":O.init,"@@transducer/result":function(e){return t["@@transducer/result"](e)},"@@transducer/step":function(e,n){return j(n)?R(t,e,n):R(t,e,[n])}}},Ce=l(g(["fantasy-land/chain","chain"],l(function(e,t){return $(e,je(t))}),function(e,t){return"function"==typeof t?function(n){return e(t(n))(n)}:xe(!1)($(e,t))})),ke=h(function(e,t,n){if(e>t)throw new Error("min must not be greater than max in clamp(min, max, value)");return n<e?e:n>t?t:n});function Te(e){return new RegExp(e.source,(e.global?"g":"")+(e.ignoreCase?"i":"")+(e.multiline?"m":"")+(e.sticky?"y":"")+(e.unicode?"u":""))}var Me=u(function(e){return null===e?"Null":void 0===e?"Undefined":Object.prototype.toString.call(e).slice(8,-1)});function Ae(e,t,n,r){var o=function(o){for(var i=t.length,a=0;a<i;){if(e===t[a])return n[a];a+=1}for(var u in t[a+1]=e,n[a+1]=o,e)o[u]=r?Ae(e[u],t,n,!0):e[u];return o};switch(Me(e)){case"Object":return o({});case"Array":return o([]);case"Date":return new Date(e.valueOf());case"RegExp":return Te(e);default:return e}}var Ne=u(function(e){return null!=e&&"function"==typeof e.clone?e.clone():Ae(e,[],[],!0)}),Re=u(function(e){return function(t,n){return e(t,n)?-1:e(n,t)?1:0}}),De=u(function(e){return!e}),Ie=Ee(De);function Fe(e,t){return function(){return t.call(this,e.apply(this,arguments))}}function Le(e,t){return function(){var n=arguments.length;if(0===n)return t();var r=arguments[n-1];return v(r)||"function"!=typeof r[e]?t.apply(this,arguments):r[e].apply(r,Array.prototype.slice.call(arguments,0,n-1))}}var ze=h(Le("slice",function(e,t,n){return Array.prototype.slice.call(n,e,t)})),Ve=u(Le("tail",ze(1,1/0)));function We(){if(0===arguments.length)throw new Error("pipe requires at least one argument");return f(arguments[0].length,J(Fe,arguments[0],Ve(arguments)))}var Ue=u(function(e){return x(e)?e.split("").reverse().join(""):Array.prototype.slice.call(e,0).reverse()});function He(){if(0===arguments.length)throw new Error("compose requires at least one argument");return We.apply(this,Ue(arguments))}function Be(){if(0===arguments.length)throw new Error("composeK requires at least one argument");var e=Array.prototype.slice.call(arguments),t=e.pop();return He(He.apply(this,$(Ce,e)),t)}function $e(e,t){return function(){var n=this;return e.apply(n,arguments).then(function(e){return t.call(n,e)})}}function qe(){if(0===arguments.length)throw new Error("pipeP requires at least one argument");return f(arguments[0].length,J($e,arguments[0],Ve(arguments)))}function Ke(){if(0===arguments.length)throw new Error("composeP requires at least one argument");return qe.apply(this,Ue(arguments))}var Ye=K(0);function Xe(e){return e}var Qe=u(Xe),Ge=l(function(e,t){if(t.length<=0)return Qe;var n=Ye(t),r=Ve(t);return f(n.length,function(){return R(function(t,n){return e.call(this,n,t)},n.apply(this,arguments),r)})}),Je=l(function(e,t){return Ge.apply(this,[e,Ue(t)])});function Ze(e){for(var t,n=[];!(t=e.next()).done;)n.push(t.value);return n}function et(e,t,n){for(var r=0,o=n.length;r<o;){if(e(t,n[r]))return!0;r+=1}return!1}var tt="function"==typeof Object.is?Object.is:function(e,t){return e===t?0!==e||1/e==1/t:e!=e&&t!=t};function nt(e,t,n,r){var o=Ze(e);function i(e,t){return rt(e,t,n.slice(),r.slice())}return!et(function(e,t){return!et(i,t,e)},Ze(t),o)}function rt(e,t,n,r){if(tt(e,t))return!0;var o=Me(e);if(o!==Me(t))return!1;if(null==e||null==t)return!1;if("function"==typeof e["fantasy-land/equals"]||"function"==typeof t["fantasy-land/equals"])return"function"==typeof e["fantasy-land/equals"]&&e["fantasy-land/equals"](t)&&"function"==typeof t["fantasy-land/equals"]&&t["fantasy-land/equals"](e);if("function"==typeof e.equals||"function"==typeof t.equals)return"function"==typeof e.equals&&e.equals(t)&&"function"==typeof t.equals&&t.equals(e);switch(o){case"Arguments":case"Array":case"Object":if("function"==typeof e.constructor&&"Promise"===function(e){var t=String(e).match(/^function (\w*)/);return null==t?"":t[1]}(e.constructor))return e===t;break;case"Boolean":case"Number":case"String":if(typeof e!=typeof t||!tt(e.valueOf(),t.valueOf()))return!1;break;case"Date":if(!tt(e.valueOf(),t.valueOf()))return!1;break;case"Error":return e.name===t.name&&e.message===t.message;case"RegExp":if(e.source!==t.source||e.global!==t.global||e.ignoreCase!==t.ignoreCase||e.multiline!==t.multiline||e.sticky!==t.sticky||e.unicode!==t.unicode)return!1}for(var i=n.length-1;i>=0;){if(n[i]===e)return r[i]===t;i-=1}switch(o){case"Map":return e.size===t.size&&nt(e.entries(),t.entries(),n.concat([e]),r.concat([t]));case"Set":return e.size===t.size&&nt(e.values(),t.values(),n.concat([e]),r.concat([t]));case"Arguments":case"Array":case"Object":case"Boolean":case"Number":case"String":case"Date":case"Error":case"RegExp":case"Int8Array":case"Uint8Array":case"Uint8ClampedArray":case"Int16Array":case"Uint16Array":case"Int32Array":case"Uint32Array":case"Float32Array":case"Float64Array":case"ArrayBuffer":break;default:return!1}var a=B(e);if(a.length!==B(t).length)return!1;var u=n.concat([e]),l=r.concat([t]);for(i=a.length-1;i>=0;){var c=a[i];if(!F(c,t)||!rt(t[c],e[c],u,l))return!1;i-=1}return!0}var ot=l(function(e,t){return rt(e,t,[],[])});function it(e,t,n){var r,o;if("function"==typeof e.indexOf)switch(typeof t){case"number":if(0===t){for(r=1/t;n<e.length;){if(0===(o=e[n])&&1/o===r)return n;n+=1}return-1}if(t!=t){for(;n<e.length;){if("number"==typeof(o=e[n])&&o!=o)return n;n+=1}return-1}return e.indexOf(t,n);case"string":case"boolean":case"function":case"undefined":return e.indexOf(t,n);case"object":if(null===t)return e.indexOf(t,n)}for(;n<e.length;){if(ot(e[n],t))return n;n+=1}return-1}function at(e,t){return it(t,e,0)>=0}function ut(e){return'"'+e.replace(/\\/g,"\\\\").replace(/[\b]/g,"\\b").replace(/\f/g,"\\f").replace(/\n/g,"\\n").replace(/\r/g,"\\r").replace(/\t/g,"\\t").replace(/\v/g,"\\v").replace(/\0/g,"\\0").replace(/"/g,'\\"')+'"'}var lt=function(e){return(e<10?"0":"")+e},ct="function"==typeof Date.prototype.toISOString?function(e){return e.toISOString()}:function(e){return e.getUTCFullYear()+"-"+lt(e.getUTCMonth()+1)+"-"+lt(e.getUTCDate())+"T"+lt(e.getUTCHours())+":"+lt(e.getUTCMinutes())+":"+lt(e.getUTCSeconds())+"."+(e.getUTCMilliseconds()/1e3).toFixed(3).slice(2,5)+"Z"};function st(e){return function(){return!e.apply(this,arguments)}}function ft(e,t){for(var n=0,r=t.length,o=[];n<r;)e(t[n])&&(o[o.length]=t[n]),n+=1;return o}function pt(e){return"[object Object]"===Object.prototype.toString.call(e)}var dt=function(){function e(e,t){this.xf=t,this.f=e}return e.prototype["@@transducer/init"]=O.init,e.prototype["@@transducer/result"]=O.result,e.prototype["@@transducer/step"]=function(e,t){return this.f(t)?this.xf["@@transducer/step"](e,t):e},e}(),yt=l(g(["filter"],l(function(e,t){return new dt(e,t)}),function(e,t){return pt(t)?R(function(n,r){return e(t[r])&&(n[r]=t[r]),n},{},B(t)):ft(e,t)})),ht=l(function(e,t){return yt(st(e),t)});function mt(e,t){var n=function(n){var r=t.concat([e]);return at(n,r)?"<Circular>":mt(n,r)},r=function(e,t){return P(function(t){return ut(t)+": "+n(e[t])},t.slice().sort())};switch(Object.prototype.toString.call(e)){case"[object Arguments]":return"(function() { return arguments; }("+P(n,e).join(", ")+"))";case"[object Array]":return"["+P(n,e).concat(r(e,ht(function(e){return/^\d+$/.test(e)},B(e)))).join(", ")+"]";case"[object Boolean]":return"object"==typeof e?"new Boolean("+n(e.valueOf())+")":e.toString();case"[object Date]":return"new Date("+(isNaN(e.valueOf())?n(NaN):ut(ct(e)))+")";case"[object Null]":return"null";case"[object Number]":return"object"==typeof e?"new Number("+n(e.valueOf())+")":1/e==-1/0?"-0":e.toString(10);case"[object String]":return"object"==typeof e?"new String("+n(e.valueOf())+")":ut(e);case"[object Undefined]":return"undefined";default:if("function"==typeof e.toString){var o=e.toString();if("[object Object]"!==o)return o}return"{"+r(e,B(e)).join(", ")+"}"}}var vt=u(function(e){return mt(e,[])}),bt=l(function(e,t){if(v(e)){if(v(t))return e.concat(t);throw new TypeError(vt(t)+" is not an array")}if(x(e)){if(x(t))return e+t;throw new TypeError(vt(t)+" is not a string")}if(null!=e&&we(e["fantasy-land/concat"]))return e["fantasy-land/concat"](t);if(null!=e&&we(e.concat))return e.concat(t);throw new TypeError(vt(e)+' does not have a method named "concat" or "fantasy-land/concat"')}),gt=u(function(e){return f(J(_,0,$(function(e){return e[0].length},e)),function(){for(var t=0;t<e.length;){if(e[t][0].apply(this,arguments))return e[t][1].apply(this,arguments);t+=1}})}),wt=l(function(e,t){if(e>10)throw new Error("Constructor with greater than ten arguments");return 0===e?function(){return new t}:_e(be(e,function(e,n,r,o,i,a,u,l,c,s){switch(arguments.length){case 1:return new t(e);case 2:return new t(e,n);case 3:return new t(e,n,r);case 4:return new t(e,n,r,o);case 5:return new t(e,n,r,o,i);case 6:return new t(e,n,r,o,i,a);case 7:return new t(e,n,r,o,i,a,u);case 8:return new t(e,n,r,o,i,a,u,l);case 9:return new t(e,n,r,o,i,a,u,l,c);case 10:return new t(e,n,r,o,i,a,u,l,c,s)}}))}),Ot=u(function(e){return wt(e.length,e)}),Et=l(at),St=l(function(e,t){return d(J(_,0,G("length",t)),function(){var n=arguments,r=this;return e.apply(r,P(function(e){return e.apply(r,n)},t))})}),_t=function(){function e(e,t,n,r){this.valueFn=e,this.valueAcc=t,this.keyFn=n,this.xf=r,this.inputs={}}return e.prototype["@@transducer/init"]=O.init,e.prototype["@@transducer/result"]=function(e){var t;for(t in this.inputs)if(F(t,this.inputs)&&(e=this.xf["@@transducer/step"](e,this.inputs[t]))["@@transducer/reduced"]){e=e["@@transducer/value"];break}return this.inputs=null,this.xf["@@transducer/result"](e)},e.prototype["@@transducer/step"]=function(e,t){var n=this.keyFn(t);return this.inputs[n]=this.inputs[n]||[n,this.valueAcc],this.inputs[n][1]=this.valueFn(this.inputs[n][1],t),e},e}(),Pt=p(4,[],g([],p(4,[],function(e,t,n,r){return new _t(e,t,n,r)}),function(e,t,n,r){return R(function(r,o){var i=n(o);return r[i]=e(F(i,r)?r[i]:Ae(t,[],[],!1),o),r},{},r)})),xt=Pt(function(e,t){return e+1},0),jt=c(-1),Ct=l(function(e,t){return null==t||t!=t?e:t}),kt=h(function(e,t,n){var r=e(t),o=e(n);return r>o?-1:r<o?1:0});function Tt(e,t,n){var r,o=typeof e;switch(o){case"string":case"number":return 0===e&&1/e==-1/0?!!n._items["-0"]||(t&&(n._items["-0"]=!0),!1):null!==n._nativeSet?t?(r=n._nativeSet.size,n._nativeSet.add(e),n._nativeSet.size===r):n._nativeSet.has(e):o in n._items?e in n._items[o]||(t&&(n._items[o][e]=!0),!1):(t&&(n._items[o]={},n._items[o][e]=!0),!1);case"boolean":if(o in n._items){var i=e?1:0;return!!n._items[o][i]||(t&&(n._items[o][i]=!0),!1)}return t&&(n._items[o]=e?[!1,!0]:[!0,!1]),!1;case"function":return null!==n._nativeSet?t?(r=n._nativeSet.size,n._nativeSet.add(e),n._nativeSet.size===r):n._nativeSet.has(e):o in n._items?!!at(e,n._items[o])||(t&&n._items[o].push(e),!1):(t&&(n._items[o]=[e]),!1);case"undefined":return!!n._items[o]||(t&&(n._items[o]=!0),!1);case"object":if(null===e)return!!n._items.null||(t&&(n._items.null=!0),!1);default:return(o=Object.prototype.toString.call(e))in n._items?!!at(e,n._items[o])||(t&&n._items[o].push(e),!1):(t&&(n._items[o]=[e]),!1)}}var Mt=function(){function e(){this._nativeSet="function"==typeof Set?new Set:null,this._items={}}return e.prototype.add=function(e){return!Tt(e,!0,this)},e.prototype.has=function(e){return Tt(e,!1,this)},e}(),At=l(function(e,t){for(var n=[],r=0,o=e.length,i=t.length,a=new Mt,u=0;u<i;u+=1)a.add(t[u]);for(;r<o;)a.add(e[r])&&(n[n.length]=e[r]),r+=1;return n}),Nt=h(function(e,t,n){for(var r=[],o=0,i=t.length;o<i;)et(e,t[o],n)||et(e,t[o],r)||r.push(t[o]),o+=1;return r}),Rt=l(function(e,t){var n={};for(var r in t)n[r]=t[r];return delete n[e],n}),Dt=h(function(e,t,n){var r=Array.prototype.slice.call(n,0);return r.splice(e,t),r}),It=h(function(e,t,n){return m(e,ee(t),n)}),Ft=l(function e(t,n){switch(t.length){case 0:return n;case 1:return q(t[0])&&v(n)?Dt(t[0],1,n):Rt(t[0],n);default:var r=t[0],o=Array.prototype.slice.call(t,1);return null==n[r]?n:q(r)&&v(n)?It(r,e(o,n[r]),n):he(r,e(o,n[r]),n)}}),Lt=l(function(e,t){return e/t}),zt=function(){function e(e,t){this.xf=t,this.n=e}return e.prototype["@@transducer/init"]=O.init,e.prototype["@@transducer/result"]=O.result,e.prototype["@@transducer/step"]=function(e,t){return this.n>0?(this.n-=1,e):this.xf["@@transducer/step"](e,t)},e}(),Vt=l(g(["drop"],l(function(e,t){return new zt(e,t)}),function(e,t){return ze(Math.max(0,e),1/0,t)})),Wt=function(){function e(e,t){this.xf=t,this.n=e,this.i=0}return e.prototype["@@transducer/init"]=O.init,e.prototype["@@transducer/result"]=O.result,e.prototype["@@transducer/step"]=function(e,t){this.i+=1;var n=0===this.n?e:this.xf["@@transducer/step"](e,t);return this.n>=0&&this.i>=this.n?w(n):n},e}(),Ut=l(g(["take"],l(function(e,t){return new Wt(e,t)}),function(e,t){return ze(0,e<0?1/0:e,t)}));var Ht=function(){function e(e,t){this.xf=t,this.pos=0,this.full=!1,this.acc=new Array(e)}return e.prototype["@@transducer/init"]=O.init,e.prototype["@@transducer/result"]=function(e){return this.acc=null,this.xf["@@transducer/result"](e)},e.prototype["@@transducer/step"]=function(e,t){return this.full&&(e=this.xf["@@transducer/step"](e,this.acc[this.pos])),this.store(t),e},e.prototype.store=function(e){this.acc[this.pos]=e,this.pos+=1,this.pos===this.acc.length&&(this.pos=0,this.full=!0)},e}(),Bt=l(g([],l(function(e,t){return new Ht(e,t)}),function(e,t){return Ut(e<t.length?t.length-e:0,t)}));var $t=function(){function e(e,t){this.f=e,this.retained=[],this.xf=t}return e.prototype["@@transducer/init"]=O.init,e.prototype["@@transducer/result"]=function(e){return this.retained=null,this.xf["@@transducer/result"](e)},e.prototype["@@transducer/step"]=function(e,t){return this.f(t)?this.retain(e,t):this.flush(e,t)},e.prototype.flush=function(e,t){return e=R(this.xf["@@transducer/step"],e,this.retained),this.retained=[],this.xf["@@transducer/step"](e,t)},e.prototype.retain=function(e,t){return this.retained.push(t),e},e}(),qt=l(g([],l(function(e,t){return new $t(e,t)}),function(e,t){for(var n=t.length-1;n>=0&&e(t[n]);)n-=1;return ze(0,n+1,t)})),Kt=function(){function e(e,t){this.xf=t,this.pred=e,this.lastValue=void 0,this.seenFirstValue=!1}return e.prototype["@@transducer/init"]=O.init,e.prototype["@@transducer/result"]=O.result,e.prototype["@@transducer/step"]=function(e,t){var n=!1;return this.seenFirstValue?this.pred(this.lastValue,t)&&(n=!0):this.seenFirstValue=!0,this.lastValue=t,n?e:this.xf["@@transducer/step"](e,t)},e}(),Yt=l(function(e,t){return new Kt(e,t)}),Xt=K(-1),Qt=l(g([],Yt,function(e,t){var n=[],r=1,o=t.length;if(0!==o)for(n[0]=t[0];r<o;)e(Xt(n),t[r])||(n[n.length]=t[r]),r+=1;return n})),Gt=u(g([],Yt(ot),Qt(ot))),Jt=function(){function e(e,t){this.xf=t,this.f=e}return e.prototype["@@transducer/init"]=O.init,e.prototype["@@transducer/result"]=O.result,e.prototype["@@transducer/step"]=function(e,t){if(this.f){if(this.f(t))return e;this.f=null}return this.xf["@@transducer/step"](e,t)},e}(),Zt=l(g(["dropWhile"],l(function(e,t){return new Jt(e,t)}),function(e,t){for(var n=0,r=t.length;n<r&&e(t[n]);)n+=1;return ze(n,1/0,t)})),en=l(function(e,t){return e||t}),tn=l(function(e,t){return we(e)?function(){return e.apply(this,arguments)||t.apply(this,arguments)}:Ee(en)(e,t)}),nn=u(function(e){return null!=e&&"function"==typeof e["fantasy-land/empty"]?e["fantasy-land/empty"]():null!=e&&null!=e.constructor&&"function"==typeof e.constructor["fantasy-land/empty"]?e.constructor["fantasy-land/empty"]():null!=e&&"function"==typeof e.empty?e.empty():null!=e&&null!=e.constructor&&"function"==typeof e.constructor.empty?e.constructor.empty():v(e)?[]:x(e)?"":pt(e)?{}:z(e)?function(){return arguments}():void 0}),rn=l(function(e,t){return Vt(e>=0?t.length-e:0,t)}),on=l(function(e,t){return ot(rn(e.length,t),e)}),an=h(function(e,t,n){return ot(e(t),e(n))}),un=h(function(e,t,n){return ot(t[e],n[e])}),ln=l(function e(t,n){var r,o,i,a=n instanceof Array?[]:{};for(o in n)i=typeof(r=t[o]),a[o]="function"===i?r(n[o]):r&&"object"===i?e(r,n[o]):n[o];return a}),cn=function(){function e(e,t){this.xf=t,this.f=e,this.found=!1}return e.prototype["@@transducer/init"]=O.init,e.prototype["@@transducer/result"]=function(e){return this.found||(e=this.xf["@@transducer/step"](e,void 0)),this.xf["@@transducer/result"](e)},e.prototype["@@transducer/step"]=function(e,t){return this.f(t)&&(this.found=!0,e=w(this.xf["@@transducer/step"](e,t))),e},e}(),sn=l(g(["find"],l(function(e,t){return new cn(e,t)}),function(e,t){for(var n=0,r=t.length;n<r;){if(e(t[n]))return t[n];n+=1}})),fn=function(){function e(e,t){this.xf=t,this.f=e,this.idx=-1,this.found=!1}return e.prototype["@@transducer/init"]=O.init,e.prototype["@@transducer/result"]=function(e){return this.found||(e=this.xf["@@transducer/step"](e,-1)),this.xf["@@transducer/result"](e)},e.prototype["@@transducer/step"]=function(e,t){return this.idx+=1,this.f(t)&&(this.found=!0,e=w(this.xf["@@transducer/step"](e,this.idx))),e},e}(),pn=l(g([],l(function(e,t){return new fn(e,t)}),function(e,t){for(var n=0,r=t.length;n<r;){if(e(t[n]))return n;n+=1}return-1})),dn=function(){function e(e,t){this.xf=t,this.f=e}return e.prototype["@@transducer/init"]=O.init,e.prototype["@@transducer/result"]=function(e){return this.xf["@@transducer/result"](this.xf["@@transducer/step"](e,this.last))},e.prototype["@@transducer/step"]=function(e,t){return this.f(t)&&(this.last=t),e},e}(),yn=l(g([],l(function(e,t){return new dn(e,t)}),function(e,t){for(var n=t.length-1;n>=0;){if(e(t[n]))return t[n];n-=1}})),hn=function(){function e(e,t){this.xf=t,this.f=e,this.idx=-1,this.lastIdx=-1}return e.prototype["@@transducer/init"]=O.init,e.prototype["@@transducer/result"]=function(e){return this.xf["@@transducer/result"](this.xf["@@transducer/step"](e,this.lastIdx))},e.prototype["@@transducer/step"]=function(e,t){return this.idx+=1,this.f(t)&&(this.lastIdx=this.idx),e},e}(),mn=l(g([],l(function(e,t){return new hn(e,t)}),function(e,t){for(var n=t.length-1;n>=0;){if(e(t[n]))return n;n-=1}return-1})),vn=u(xe(!0)),bn=u(function(e){return d(e.length,function(t,n){var r=Array.prototype.slice.call(arguments,0);return r[0]=n,r[1]=t,e.apply(this,r)})}),gn=l(Le("forEach",function(e,t){for(var n=t.length,r=0;r<n;)e(t[r]),r+=1;return t})),wn=l(function(e,t){for(var n=B(t),r=0;r<n.length;){var o=n[r];e(t[o],o,t),r+=1}return t}),On=u(function(e){for(var t={},n=0;n<e.length;)t[e[n][0]]=e[n][1],n+=1;return t}),En=l(Le("groupBy",Pt(function(e,t){return null==e&&(e=[]),e.push(t),e},null))),Sn=l(function(e,t){for(var n=[],r=0,o=t.length;r<o;){for(var i=r+1;i<o&&e(t[i-1],t[i]);)i+=1;n.push(t.slice(r,i)),r=i}return n}),_n=l(function(e,t){return e>t}),Pn=l(function(e,t){return e>=t}),xn=l(function(e,t){if(0===e.length||me(t))return!1;for(var n=t,r=0;r<e.length;){if(me(n)||!F(e[r],n))return!1;n=n[e[r]],r+=1}return!0}),jn=l(function(e,t){return xn([e],t)}),Cn=l(function(e,t){return e in t}),kn=l(tt),Tn=h(function(e,t,n){return d(Math.max(e.length,t.length,n.length),function(){return e.apply(this,arguments)?t.apply(this,arguments):n.apply(this,arguments)})}),Mn=c(1),An=l(at),Nn=Pt(function(e,t){return t},null),Rn=l(function(e,t){return"function"!=typeof t.indexOf||v(t)?it(t,e,0):t.indexOf(e)}),Dn=ze(0,-1),In=h(function(e,t,n){return ft(function(t){return et(e,t,n)},t)}),Fn=h(function(e,t,n){e=e<n.length&&e>=0?e:n.length;var r=Array.prototype.slice.call(n,0);return r.splice(e,0,t),r}),Ln=h(function(e,t,n){return e=e<n.length&&e>=0?e:n.length,[].concat(Array.prototype.slice.call(n,0,e),t,Array.prototype.slice.call(n,e))}),zn=l(function(e,t){for(var n,r,o=new Mt,i=[],a=0;a<t.length;)n=e(r=t[a]),o.add(n)&&i.push(r),a+=1;return i}),Vn=zn(Qe),Wn=l(function(e,t){var n,r;return e.length>t.length?(n=e,r=t):(n=t,r=e),Vn(ft(bn(at)(n),r))}),Un=l(Le("intersperse",function(e,t){for(var n=[],r=0,o=t.length;r<o;)r===o-1?n.push(t[r]):n.push(t[r],e),r+=1;return n}));var Hn="function"==typeof Object.assign?Object.assign:function(e){if(null==e)throw new TypeError("Cannot convert undefined or null to object");for(var t=Object(e),n=1,r=arguments.length;n<r;){var o=arguments[n];if(null!=o)for(var i in o)F(i,o)&&(t[i]=o[i]);n+=1}return t},Bn=l(function(e,t){var n={};return n[e]=t,n}),$n={"@@transducer/init":Array,"@@transducer/step":function(e,t){return e.push(t),e},"@@transducer/result":Xe},qn={"@@transducer/init":String,"@@transducer/step":function(e,t){return e+t},"@@transducer/result":Xe},Kn={"@@transducer/init":Object,"@@transducer/step":function(e,t){return Hn(e,j(t)?Bn(t[0],t[1]):t)},"@@transducer/result":Xe};var Yn=h(function(e,t,n){return b(e)?R(t(e),e["@@transducer/init"](),n):R(t(function(e){if(b(e))return e;if(j(e))return $n;if("string"==typeof e)return qn;if("object"==typeof e)return Kn;throw new Error("Cannot create transformer for "+e)}(e)),Ae(e,[],[],!1),n)}),Xn=u(function(e){for(var t=B(e),n=t.length,r=0,o={};r<n;){var i=t[r],a=e[i],u=F(a,o)?o[a]:o[a]=[];u[u.length]=i,r+=1}return o}),Qn=u(function(e){for(var t=B(e),n=t.length,r=0,o={};r<n;){var i=t[r];o[e[i]]=i,r+=1}return o}),Gn=l(function(e,t){return d(e+1,function(){var n=arguments[e];if(null!=n&&we(n[t]))return n[t].apply(n,Array.prototype.slice.call(arguments,0,e));throw new TypeError(vt(n)+' does not have a method named "'+t+'"')})}),Jn=l(function(e,t){return null!=t&&t.constructor===e||t instanceof e}),Zn=u(function(e){return null!=e&&ot(e,nn(e))}),er=Gn(1,"join"),tr=u(function(e){return St(function(){return Array.prototype.slice.call(arguments,0)},e)}),nr=u(function(e){var t,n=[];for(t in e)n[n.length]=t;return n}),rr=l(function(e,t){if("function"!=typeof t.lastIndexOf||v(t)){for(var n=t.length-1;n>=0;){if(ot(t[n],e))return n;n-=1}return-1}return t.lastIndexOf(e)});function or(e){return"[object Number]"===Object.prototype.toString.call(e)}var ir=u(function(e){return null!=e&&or(e.length)?e.length:NaN}),ar=l(function(e,t){return function(n){return function(r){return $(function(e){return t(e,r)},n(e(r)))}}}),ur=u(function(e){return ar(K(e),It(e))}),lr=u(function(e){return ar(X(e),ve(e))}),cr=u(function(e){return ar(Q(e),he(e))}),sr=l(function(e,t){return e<t}),fr=l(function(e,t){return e<=t}),pr=h(function(e,t,n){for(var r=0,o=n.length,i=[],a=[t];r<o;)a=e(a[0],n[r]),i[r]=a[1],r+=1;return[a[0],i]}),dr=h(function(e,t,n){for(var r=n.length-1,o=[],i=[t];r>=0;)i=e(i[0],n[r]),o[r]=i[1],r-=1;return[i[0],o]}),yr=l(function(e,t){return R(function(n,r){return n[r]=e(t[r],r,t),n},{},B(t))}),hr=l(function(e,t){return t.match(e)||[]}),mr=l(function(e,t){return q(e)?!q(t)||t<1?NaN:(e%t+t)%t:NaN}),vr=h(function(e,t,n){return e(n)>e(t)?n:t}),br=J(c,0),gr=u(function(e){return br(e)/e.length}),wr=u(function(e){var t=e.length;if(0===t)return NaN;var n=2-t%2,r=(t-n)/2;return gr(Array.prototype.slice.call(e,0).sort(function(e,t){return e<t?-1:e>t?1:0}).slice(r,r+n))}),Or=l(function(e,t){var n={};return f(t.length,function(){var r=e.apply(this,arguments);return F(r,n)||(n[r]=t.apply(this,arguments)),n[r]})}),Er=l(function(e,t){return Hn({},e,t)}),Sr=u(function(e){return Hn.apply(null,[{}].concat(e))}),_r=h(function(e,t,n){var r,o={};for(r in t)F(r,t)&&(o[r]=F(r,n)?e(r,t[r],n[r]):t[r]);for(r in n)F(r,n)&&!F(r,o)&&(o[r]=n[r]);return o}),Pr=h(function e(t,n,r){return _r(function(n,r,o){return pt(r)&&pt(o)?e(t,r,o):t(n,r,o)},n,r)}),xr=l(function(e,t){return Pr(function(e,t,n){return t},e,t)}),jr=l(function(e,t){return Pr(function(e,t,n){return n},e,t)}),Cr=h(function(e,t,n){return Pr(function(t,n,r){return e(n,r)},t,n)}),kr=l(function(e,t){return Hn({},t,e)}),Tr=l(function(e,t){return Hn({},e,t)}),Mr=h(function(e,t,n){return _r(function(t,n,r){return e(n,r)},t,n)}),Ar=l(function(e,t){return t<e?t:e}),Nr=h(function(e,t,n){return e(n)<e(t)?n:t}),Rr=l(function(e,t){return e%t}),Dr=h(function(e,t,n){var r=n.length,o=n.slice(),i=e<0?r+e:e,a=t<0?r+t:t,u=o.splice(i,1);return i<0||i>=n.length||a<0||a>=n.length?n:[].concat(o.slice(0,a)).concat(u).concat(o.slice(a,n.length))}),Ir=l(function(e,t){return e*t}),Fr=u(function(e){return-e}),Lr=l(function(e,t){return S(st(e),t)}),zr=u(function(e){return d(e<0?1:e+1,function(){return K(e,arguments)})}),Vr=h(function(e,t,n){return e(t(n))});var Wr=u(function(e){return[e]}),Ur=l(function(e,t){for(var n={},r={},o=0,i=e.length;o<i;)r[e[o]]=1,o+=1;for(var a in t)r.hasOwnProperty(a)||(n[a]=t[a]);return n}),Hr=u(function(e){var t,n=!1;return f(e.length,function(){return n?t:(n=!0,t=e.apply(this,arguments))})});function Br(e,t){if(null==t||!we(t.then))throw new TypeError("`"+e+"` expected a Promise, received "+mt(t,[]))}var $r=l(function(e,t){return Br("otherwise",t),t.then(null,e)}),qr=function(e){return{value:e,map:function(t){return qr(t(e))}}},Kr=h(function(e,t,n){return e(function(e){return qr(t(e))})(n).value}),Yr=l(function(e,t){return[e,t]});function Xr(e){return l(function(t,n){return f(Math.max(0,t.length-n.length),function(){return t.apply(this,e(n,arguments))})})}var Qr=Xr(s),Gr=Xr(bn(s)),Jr=tr([yt,ht]),Zr=h(function(e,t,n){return ot(X(e,n),t)}),eo=h(function(e,t,n){return Ct(e,X(t,n))}),to=h(function(e,t,n){return e(X(t,n))}),no=l(function(e,t){for(var n={},r=0;r<e.length;)e[r]in t&&(n[e[r]]=t[e[r]]),r+=1;return n}),ro=l(function(e,t){for(var n={},r=0,o=e.length;r<o;){var i=e[r];n[i]=t[i],r+=1}return n}),oo=l(function(e,t){var n={};for(var r in t)e(t[r],r,t)&&(n[r]=t[r]);return n});function io(){if(0===arguments.length)throw new Error("pipeK requires at least one argument");return Be.apply(this,Ue(arguments))}var ao=l(function(e,t){return s([e],t)}),uo=J(Ir,1),lo=l(function(e,t){return d(t.length,function(){for(var n=[],r=0;r<t.length;)n.push(t[r].call(this,arguments[r])),r+=1;return e.apply(this,n.concat(Array.prototype.slice.call(arguments,t.length)))})}),co=lo(P,[ro,Qe]),so=h(function(e,t,n){return ot(t,n[e])}),fo=h(function(e,t,n){return Jn(e,n[t])}),po=h(function(e,t,n){return eo(e,[t],n)}),yo=h(function(e,t,n){return e(n[t])}),ho=l(function(e,t){return e.map(function(e){return X([e],t)})}),mo=l(function(e,t){if(!or(e)||!or(t))throw new TypeError("Both arguments to range must be numbers");for(var n=[],r=e;r<t;)n.push(r),r+=1;return n}),vo=h(function(e,t,n){for(var r=n.length-1;r>=0;)t=e(n[r],t),r-=1;return t}),bo=p(4,[],function(e,t,n,r){return R(function(n,r){return e(n,r)?t(n,r):w(n)},n,r)}),go=u(w),wo=l(function(e,t){var n,r=Number(t),o=0;if(r<0||isNaN(r))throw new RangeError("n must be a non-negative number");for(n=new Array(r);o<r;)n[o]=e(o),o+=1;return n}),Oo=l(function(e,t){return wo(ee(e),t)}),Eo=h(function(e,t,n){return n.replace(e,t)}),So=h(function(e,t,n){for(var r=0,o=n.length,i=[t];r<o;)t=e(t,n[r]),i[r+1]=t,r+=1;return i}),_o=l(function(e,t){return"function"==typeof t.sequence?t.sequence(e):vo(function(e,t){return ie($(ao,e),t)},e([]),t)}),Po=h(function(e,t,n){return Kr(e,ee(t),n)}),xo=l(function(e,t){return Array.prototype.slice.call(t,0).sort(e)}),jo=l(function(e,t){return Array.prototype.slice.call(t,0).sort(function(t,n){var r=e(t),o=e(n);return r<o?-1:r>o?1:0})}),Co=l(function(e,t){return Array.prototype.slice.call(t,0).sort(function(t,n){for(var r=0,o=0;0===r&&o<e.length;)r=e[o](t,n),o+=1;return r})}),ko=Gn(1,"split"),To=l(function(e,t){return[ze(0,e,t),ze(e,ir(t),t)]}),Mo=l(function(e,t){if(e<=0)throw new Error("First argument to splitEvery must be a positive integer");for(var n=[],r=0;r<t.length;)n.push(ze(r,r+=e,t));return n}),Ao=l(function(e,t){for(var n=0,r=t.length,o=[];n<r&&!e(t[n]);)o.push(t[n]),n+=1;return[o,Array.prototype.slice.call(t,n)]}),No=l(function(e,t){return ot(Ut(e.length,t),e)}),Ro=l(function(e,t){return Number(e)-Number(t)}),Do=l(function(e,t){return bt(At(e,t),At(t,e))}),Io=h(function(e,t,n){return bt(Nt(e,t,n),Nt(e,n,t))}),Fo=l(function(e,t){for(var n=t.length-1;n>=0&&e(t[n]);)n-=1;return ze(n+1,1/0,t)}),Lo=function(){function e(e,t){this.xf=t,this.f=e}return e.prototype["@@transducer/init"]=O.init,e.prototype["@@transducer/result"]=O.result,e.prototype["@@transducer/step"]=function(e,t){return this.f(t)?this.xf["@@transducer/step"](e,t):w(e)},e}(),zo=l(g(["takeWhile"],l(function(e,t){return new Lo(e,t)}),function(e,t){for(var n=0,r=t.length;n<r&&e(t[n]);)n+=1;return ze(0,n,t)})),Vo=function(){function e(e,t){this.xf=t,this.f=e}return e.prototype["@@transducer/init"]=O.init,e.prototype["@@transducer/result"]=O.result,e.prototype["@@transducer/step"]=function(e,t){return this.f(t),this.xf["@@transducer/step"](e,t)},e}(),Wo=l(g([],l(function(e,t){return new Vo(e,t)}),function(e,t){return e(t),t}));var Uo=l(function(e,t){if(!function(e){return"[object RegExp]"===Object.prototype.toString.call(e)}(e))throw new TypeError("‘test’ requires a value of type RegExp as its first argument; received "+vt(e));return Te(e).test(t)}),Ho=l(function(e,t){return Br("andThen",t),t.then(e)}),Bo=Gn(0,"toLowerCase"),$o=u(function(e){var t=[];for(var n in e)F(n,e)&&(t[t.length]=[n,e[n]]);return t}),qo=u(function(e){var t=[];for(var n in e)t[t.length]=[n,e[n]];return t}),Ko=Gn(0,"toUpperCase"),Yo=d(4,function(e,t,n,r){return R(e("function"==typeof t?k(t):t),n,r)}),Xo=u(function(e){for(var t=0,n=[];t<e.length;){for(var r=e[t],o=0;o<r.length;)void 0===n[o]&&(n[o]=[]),n[o].push(r[o]),o+=1;t+=1}return n}),Qo=h(function(e,t,n){return"function"==typeof n["fantasy-land/traverse"]?n["fantasy-land/traverse"](t,e):_o(e,$(t,n))}),Go="\t\n\v\f\r \u2028\u2029\ufeff",Jo=u("function"==typeof String.prototype.trim&&!Go.trim()&&"".trim()?function(e){return e.trim()}:function(e){var t=new RegExp("^["+Go+"]["+Go+"]*"),n=new RegExp("["+Go+"]["+Go+"]*$");return e.replace(t,"").replace(n,"")}),Zo=l(function(e,t){return f(e.length,function(){try{return e.apply(this,arguments)}catch(e){return t.apply(this,s([e],arguments))}})}),ei=u(function(e){return function(){return e(Array.prototype.slice.call(arguments,0))}}),ti=u(function(e){return be(1,e)}),ni=l(function(e,t){return d(e,function(){for(var n,r=1,o=t,i=0;r<=e&&"function"==typeof o;)n=r===e?arguments.length:i+o.length,o=o.apply(this,Array.prototype.slice.call(arguments,i,n)),r+=1,i=n;return o})}),ri=l(function(e,t){for(var n=e(t),r=[];n&&n.length;)r[r.length]=n[0],n=e(n[1]);return r}),oi=l(He(Vn,s)),ii=l(function(e,t){for(var n,r=0,o=t.length,i=[];r<o;)et(e,n=t[r],i)||(i[i.length]=n),r+=1;return i}),ai=h(function(e,t,n){return ii(e,s(t,n))}),ui=h(function(e,t,n){return e(n)?n:t(n)}),li=Ce(Xe),ci=h(function(e,t,n){for(var r=n;!e(r);)r=t(r);return r}),si=u(function(e){var t,n=[];for(t in e)n[n.length]=e[t];return n}),fi=function(e){return{value:e,"fantasy-land/map":function(){return this}}},pi=l(function(e,t){return e(fi)(t).value}),di=h(function(e,t,n){return e(n)?t(n):n}),yi=l(function(e,t){for(var n in e)if(F(n,e)&&!e[n](t[n]))return!1;return!0}),hi=l(function(e,t){return yi($(ot,e),t)}),mi=l(function(e,t){return ht(bn(at)(e),t)}),vi=l(function(e,t){return Boolean(!e^!t)}),bi=l(function(e,t){for(var n,r=0,o=e.length,i=t.length,a=[];r<o;){for(n=0;n<i;)a[a.length]=[e[r],t[n]],n+=1;r+=1}return a}),gi=l(function(e,t){for(var n=[],r=0,o=Math.min(e.length,t.length);r<o;)n[r]=[e[r],t[r]],r+=1;return n}),wi=l(function(e,t){for(var n=0,r=Math.min(e.length,t.length),o={};n<r;)o[e[n]]=t[n],n+=1;return o}),Oi=h(function(e,t,n){for(var r=[],o=0,i=Math.min(t.length,n.length);o<i;)r[o]=e(t[o],n[o]),o+=1;return r}),Ei=u(function(e){return d(e.length,function(){var t=arguments;return function(){return e.apply(this,t)}})});n.d(t,"F",function(){return r}),n.d(t,"T",function(){return o}),n.d(t,"__",function(){return i}),n.d(t,"add",function(){return c}),n.d(t,"addIndex",function(){return y}),n.d(t,"adjust",function(){return m}),n.d(t,"all",function(){return S}),n.d(t,"allPass",function(){return Z}),n.d(t,"always",function(){return ee}),n.d(t,"and",function(){return te}),n.d(t,"any",function(){return re}),n.d(t,"anyPass",function(){return oe}),n.d(t,"ap",function(){return ie}),n.d(t,"aperture",function(){return ue}),n.d(t,"append",function(){return le}),n.d(t,"apply",function(){return ce}),n.d(t,"applySpec",function(){return pe}),n.d(t,"applyTo",function(){return de}),n.d(t,"ascend",function(){return ye}),n.d(t,"assoc",function(){return he}),n.d(t,"assocPath",function(){return ve}),n.d(t,"binary",function(){return ge}),n.d(t,"bind",function(){return T}),n.d(t,"both",function(){return Se}),n.d(t,"call",function(){return Pe}),n.d(t,"chain",function(){return Ce}),n.d(t,"clamp",function(){return ke}),n.d(t,"clone",function(){return Ne}),n.d(t,"comparator",function(){return Re}),n.d(t,"complement",function(){return Ie}),n.d(t,"compose",function(){return He}),n.d(t,"composeK",function(){return Be}),n.d(t,"composeP",function(){return Ke}),n.d(t,"composeWith",function(){return Je}),n.d(t,"concat",function(){return bt}),n.d(t,"cond",function(){return gt}),n.d(t,"construct",function(){return Ot}),n.d(t,"constructN",function(){return wt}),n.d(t,"contains",function(){return Et}),n.d(t,"converge",function(){return St}),n.d(t,"countBy",function(){return xt}),n.d(t,"curry",function(){return _e}),n.d(t,"curryN",function(){return d}),n.d(t,"dec",function(){return jt}),n.d(t,"defaultTo",function(){return Ct}),n.d(t,"descend",function(){return kt}),n.d(t,"difference",function(){return At}),n.d(t,"differenceWith",function(){return Nt}),n.d(t,"dissoc",function(){return Rt}),n.d(t,"dissocPath",function(){return Ft}),n.d(t,"divide",function(){return Lt}),n.d(t,"drop",function(){return Vt}),n.d(t,"dropLast",function(){return Bt}),n.d(t,"dropLastWhile",function(){return qt}),n.d(t,"dropRepeats",function(){return Gt}),n.d(t,"dropRepeatsWith",function(){return Qt}),n.d(t,"dropWhile",function(){return Zt}),n.d(t,"either",function(){return tn}),n.d(t,"empty",function(){return nn}),n.d(t,"endsWith",function(){return on}),n.d(t,"eqBy",function(){return an}),n.d(t,"eqProps",function(){return un}),n.d(t,"equals",function(){return ot}),n.d(t,"evolve",function(){return ln}),n.d(t,"filter",function(){return yt}),n.d(t,"find",function(){return sn}),n.d(t,"findIndex",function(){return pn}),n.d(t,"findLast",function(){return yn}),n.d(t,"findLastIndex",function(){return mn}),n.d(t,"flatten",function(){return vn}),n.d(t,"flip",function(){return bn}),n.d(t,"forEach",function(){return gn}),n.d(t,"forEachObjIndexed",function(){return wn}),n.d(t,"fromPairs",function(){return On}),n.d(t,"groupBy",function(){return En}),n.d(t,"groupWith",function(){return Sn}),n.d(t,"gt",function(){return _n}),n.d(t,"gte",function(){return Pn}),n.d(t,"has",function(){return jn}),n.d(t,"hasIn",function(){return Cn}),n.d(t,"hasPath",function(){return xn}),n.d(t,"head",function(){return Ye}),n.d(t,"identical",function(){return kn}),n.d(t,"identity",function(){return Qe}),n.d(t,"ifElse",function(){return Tn}),n.d(t,"inc",function(){return Mn}),n.d(t,"includes",function(){return An}),n.d(t,"indexBy",function(){return Nn}),n.d(t,"indexOf",function(){return Rn}),n.d(t,"init",function(){return Dn}),n.d(t,"innerJoin",function(){return In}),n.d(t,"insert",function(){return Fn}),n.d(t,"insertAll",function(){return Ln}),n.d(t,"intersection",function(){return Wn}),n.d(t,"intersperse",function(){return Un}),n.d(t,"into",function(){return Yn}),n.d(t,"invert",function(){return Xn}),n.d(t,"invertObj",function(){return Qn}),n.d(t,"invoker",function(){return Gn}),n.d(t,"is",function(){return Jn}),n.d(t,"isEmpty",function(){return Zn}),n.d(t,"isNil",function(){return me}),n.d(t,"join",function(){return er}),n.d(t,"juxt",function(){return tr}),n.d(t,"keys",function(){return B}),n.d(t,"keysIn",function(){return nr}),n.d(t,"last",function(){return Xt}),n.d(t,"lastIndexOf",function(){return rr}),n.d(t,"length",function(){return ir}),n.d(t,"lens",function(){return ar}),n.d(t,"lensIndex",function(){return ur}),n.d(t,"lensPath",function(){return lr}),n.d(t,"lensProp",function(){return cr}),n.d(t,"lift",function(){return Ee}),n.d(t,"liftN",function(){return Oe}),n.d(t,"lt",function(){return sr}),n.d(t,"lte",function(){return fr}),n.d(t,"map",function(){return $}),n.d(t,"mapAccum",function(){return pr}),n.d(t,"mapAccumRight",function(){return dr}),n.d(t,"mapObjIndexed",function(){return yr}),n.d(t,"match",function(){return hr}),n.d(t,"mathMod",function(){return mr}),n.d(t,"max",function(){return _}),n.d(t,"maxBy",function(){return vr}),n.d(t,"mean",function(){return gr}),n.d(t,"median",function(){return wr}),n.d(t,"memoizeWith",function(){return Or}),n.d(t,"merge",function(){return Er}),n.d(t,"mergeAll",function(){return Sr}),n.d(t,"mergeDeepLeft",function(){return xr}),n.d(t,"mergeDeepRight",function(){return jr}),n.d(t,"mergeDeepWith",function(){return Cr}),n.d(t,"mergeDeepWithKey",function(){return Pr}),n.d(t,"mergeLeft",function(){return kr}),n.d(t,"mergeRight",function(){return Tr}),n.d(t,"mergeWith",function(){return Mr}),n.d(t,"mergeWithKey",function(){return _r}),n.d(t,"min",function(){return Ar}),n.d(t,"minBy",function(){return Nr}),n.d(t,"modulo",function(){return Rr}),n.d(t,"move",function(){return Dr}),n.d(t,"multiply",function(){return Ir}),n.d(t,"nAry",function(){return be}),n.d(t,"negate",function(){return Fr}),n.d(t,"none",function(){return Lr}),n.d(t,"not",function(){return De}),n.d(t,"nth",function(){return K}),n.d(t,"nthArg",function(){return zr}),n.d(t,"o",function(){return Vr}),n.d(t,"objOf",function(){return Bn}),n.d(t,"of",function(){return Wr}),n.d(t,"omit",function(){return Ur}),n.d(t,"once",function(){return Hr}),n.d(t,"or",function(){return en}),n.d(t,"otherwise",function(){return $r}),n.d(t,"over",function(){return Kr}),n.d(t,"pair",function(){return Yr}),n.d(t,"partial",function(){return Qr}),n.d(t,"partialRight",function(){return Gr}),n.d(t,"partition",function(){return Jr}),n.d(t,"path",function(){return X}),n.d(t,"paths",function(){return Y}),n.d(t,"pathEq",function(){return Zr}),n.d(t,"pathOr",function(){return eo}),n.d(t,"pathSatisfies",function(){return to}),n.d(t,"pick",function(){return no}),n.d(t,"pickAll",function(){return ro}),n.d(t,"pickBy",function(){return oo}),n.d(t,"pipe",function(){return We}),n.d(t,"pipeK",function(){return io}),n.d(t,"pipeP",function(){return qe}),n.d(t,"pipeWith",function(){return Ge}),n.d(t,"pluck",function(){return G}),n.d(t,"prepend",function(){return ao}),n.d(t,"product",function(){return uo}),n.d(t,"project",function(){return co}),n.d(t,"prop",function(){return Q}),n.d(t,"propEq",function(){return so}),n.d(t,"propIs",function(){return fo}),n.d(t,"propOr",function(){return po}),n.d(t,"propSatisfies",function(){return yo}),n.d(t,"props",function(){return ho}),n.d(t,"range",function(){return mo}),n.d(t,"reduce",function(){return J}),n.d(t,"reduceBy",function(){return Pt}),n.d(t,"reduceRight",function(){return vo}),n.d(t,"reduceWhile",function(){return bo}),n.d(t,"reduced",function(){return go}),n.d(t,"reject",function(){return ht}),n.d(t,"remove",function(){return Dt}),n.d(t,"repeat",function(){return Oo}),n.d(t,"replace",function(){return Eo}),n.d(t,"reverse",function(){return Ue}),n.d(t,"scan",function(){return So}),n.d(t,"sequence",function(){return _o}),n.d(t,"set",function(){return Po}),n.d(t,"slice",function(){return ze}),n.d(t,"sort",function(){return xo}),n.d(t,"sortBy",function(){return jo}),n.d(t,"sortWith",function(){return Co}),n.d(t,"split",function(){return ko}),n.d(t,"splitAt",function(){return To}),n.d(t,"splitEvery",function(){return Mo}),n.d(t,"splitWhen",function(){return Ao}),n.d(t,"startsWith",function(){return No}),n.d(t,"subtract",function(){return Ro}),n.d(t,"sum",function(){return br}),n.d(t,"symmetricDifference",function(){return Do}),n.d(t,"symmetricDifferenceWith",function(){return Io}),n.d(t,"tail",function(){return Ve}),n.d(t,"take",function(){return Ut}),n.d(t,"takeLast",function(){return rn}),n.d(t,"takeLastWhile",function(){return Fo}),n.d(t,"takeWhile",function(){return zo}),n.d(t,"tap",function(){return Wo}),n.d(t,"test",function(){return Uo}),n.d(t,"andThen",function(){return Ho}),n.d(t,"times",function(){return wo}),n.d(t,"toLower",function(){return Bo}),n.d(t,"toPairs",function(){return $o}),n.d(t,"toPairsIn",function(){return qo}),n.d(t,"toString",function(){return vt}),n.d(t,"toUpper",function(){return Ko}),n.d(t,"transduce",function(){return Yo}),n.d(t,"transpose",function(){return Xo}),n.d(t,"traverse",function(){return Qo}),n.d(t,"trim",function(){return Jo}),n.d(t,"tryCatch",function(){return Zo}),n.d(t,"type",function(){return Me}),n.d(t,"unapply",function(){return ei}),n.d(t,"unary",function(){return ti}),n.d(t,"uncurryN",function(){return ni}),n.d(t,"unfold",function(){return ri}),n.d(t,"union",function(){return oi}),n.d(t,"unionWith",function(){return ai}),n.d(t,"uniq",function(){return Vn}),n.d(t,"uniqBy",function(){return zn}),n.d(t,"uniqWith",function(){return ii}),n.d(t,"unless",function(){return ui}),n.d(t,"unnest",function(){return li}),n.d(t,"until",function(){return ci}),n.d(t,"update",function(){return It}),n.d(t,"useWith",function(){return lo}),n.d(t,"values",function(){return se}),n.d(t,"valuesIn",function(){return si}),n.d(t,"view",function(){return pi}),n.d(t,"when",function(){return di}),n.d(t,"where",function(){return yi}),n.d(t,"whereEq",function(){return hi}),n.d(t,"without",function(){return mi}),n.d(t,"xor",function(){return vi}),n.d(t,"xprod",function(){return bi}),n.d(t,"zip",function(){return gi}),n.d(t,"zipObj",function(){return wi}),n.d(t,"zipWith",function(){return Oi}),n.d(t,"thunkify",function(){return Ei})},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.fixControlledValue=w,t.resolveOnChange=O,t.getInputClassName=E,t.default=void 0;var r=p(n(0)),o=s(n(1)),i=s(n(30)),a=p(n(79)),u=n(6),l=s(n(35)),c=s(n(43));function s(e){return e&&e.__esModule?e:{default:e}}function f(){if("function"!=typeof WeakMap)return null;var e=new WeakMap;return f=function(){return e},e}function p(e){if(e&&e.__esModule)return e;if(null===e||"object"!==d(e)&&"function"!=typeof e)return{default:e};var t=f();if(t&&t.has(e))return t.get(e);var n={},r=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var o in e)if(Object.prototype.hasOwnProperty.call(e,o)){var i=r?Object.getOwnPropertyDescriptor(e,o):null;i&&(i.get||i.set)?Object.defineProperty(n,o,i):n[o]=e[o]}return n.default=e,t&&t.set(e,n),n}function d(e){"@babel/helpers - typeof";return(d="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(e)}function y(){return(y=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e}).apply(this,arguments)}function h(e,t){for(var n=0;n<t.length;n++){var r=t[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(e,r.key,r)}}function m(e,t){return(m=Object.setPrototypeOf||function(e,t){return e.__proto__=t,e})(e,t)}function v(e){var t=function(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Date.prototype.toString.call(Reflect.construct(Date,[],function(){})),!0}catch(e){return!1}}();return function(){var n,r=b(e);if(t){var o=b(this).constructor;n=Reflect.construct(r,arguments,o)}else n=r.apply(this,arguments);return function(e,t){if(t&&("object"===d(t)||"function"==typeof t))return t;return function(e){if(void 0===e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return e}(e)}(this,n)}}function b(e){return(b=Object.setPrototypeOf?Object.getPrototypeOf:function(e){return e.__proto__||Object.getPrototypeOf(e)})(e)}function g(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function w(e){return void 0===e||null===e?"":e}function O(e,t,n){if(n){var r=t;if("click"===t.type){(r=Object.create(t)).target=e,r.currentTarget=e;var o=e.value;return e.value="",n(r),void(e.value=o)}n(r)}}function E(e,t,n,r){var i;return(0,o.default)(e,(g(i={},"".concat(e,"-sm"),"small"===t),g(i,"".concat(e,"-lg"),"large"===t),g(i,"".concat(e,"-disabled"),n),g(i,"".concat(e,"-rtl"),"rtl"===r),i))}var S=function(){var e=function(e){!function(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function");e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,writable:!0,configurable:!0}}),t&&m(e,t)}(n,r.Component);var t=v(n);function n(e){var u;!function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,n),(u=t.call(this,e)).direction="ltr",u.focus=function(){u.input.focus()},u.saveClearableInput=function(e){u.clearableInput=e},u.saveInput=function(e){u.input=e},u.onFocus=function(e){var t=u.props.onFocus;u.setState({focused:!0}),t&&t(e)},u.onBlur=function(e){var t=u.props.onBlur;u.setState({focused:!1}),t&&t(e)},u.handleReset=function(e){u.setValue("",function(){u.focus()}),O(u.input,e,u.props.onChange)},u.renderInput=function(e,t){var n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{},a=u.props,l=a.className,c=a.addonBefore,s=a.addonAfter,f=a.size,p=a.disabled,d=(0,i.default)(u.props,["prefixCls","onPressEnter","addonBefore","addonAfter","prefix","suffix","allowClear","defaultValue","size","inputType"]);return r.createElement("input",y({autoComplete:n.autoComplete},d,{onChange:u.handleChange,onFocus:u.onFocus,onBlur:u.onBlur,onKeyDown:u.handleKeyDown,className:(0,o.default)(E(e,f||t,p,u.direction),g({},l,l&&!c&&!s)),ref:u.saveInput}))},u.clearPasswordValueAttribute=function(){u.removePasswordTimeout=setTimeout(function(){u.input&&"password"===u.input.getAttribute("type")&&u.input.hasAttribute("value")&&u.input.removeAttribute("value")})},u.handleChange=function(e){u.setValue(e.target.value,u.clearPasswordValueAttribute),O(u.input,e,u.props.onChange)},u.handleKeyDown=function(e){var t=u.props,n=t.onPressEnter,r=t.onKeyDown;13===e.keyCode&&n&&n(e),r&&r(e)},u.renderComponent=function(e){var t=e.getPrefixCls,n=e.direction,o=e.input,i=u.state,c=i.value,s=i.focused,f=t("input",u.props.prefixCls);return u.direction=n,r.createElement(l.default.Consumer,null,function(e){return r.createElement(a.default,y({size:e},u.props,{prefixCls:f,inputType:"input",value:w(c),element:u.renderInput(f,e,o),handleReset:u.handleReset,ref:u.saveClearableInput,direction:n,focused:s,triggerFocus:u.focus}))})};var c=void 0===e.value?e.defaultValue:e.value;return u.state={value:c,focused:!1,prevValue:e.value},u}return function(e,t,n){t&&h(e.prototype,t),n&&h(e,n)}(n,[{key:"componentDidMount",value:function(){this.clearPasswordValueAttribute()}},{key:"componentDidUpdate",value:function(){}},{key:"getSnapshotBeforeUpdate",value:function(e){return(0,a.hasPrefixSuffix)(e)!==(0,a.hasPrefixSuffix)(this.props)&&(0,c.default)(this.input!==document.activeElement,"Input","When Input is focused, dynamic add or remove prefix / suffix will make it lose focus caused by dom structure change. Read more: https://ant.design/components/input/#FAQ"),null}},{key:"componentWillUnmount",value:function(){this.removePasswordTimeout&&clearTimeout(this.removePasswordTimeout)}},{key:"blur",value:function(){this.input.blur()}},{key:"select",value:function(){this.input.select()}},{key:"setValue",value:function(e,t){void 0===this.props.value&&this.setState({value:e},t)}},{key:"render",value:function(){return r.createElement(u.ConfigConsumer,null,this.renderComponent)}}],[{key:"getDerivedStateFromProps",value:function(e,t){var n=t.prevValue,r={prevValue:e.value};return void 0===e.value&&n===e.value||(r.value=e.value),r}}]),n}();return e.defaultProps={type:"text"},e}();t.default=S},function(e,t,n){"use strict";n.r(t);var r=n(8),o=n.n(r);t.default=function(e,t){for(var n=o()({},e),r=0;r<t.length;r++)delete n[t[r]];return n}},function(e,t){e.exports=function(e){try{return!!e()}catch(e){return!0}}},function(e,t,n){var r=n(25);e.exports=function(e){if(!r(e))throw TypeError(e+" is not an object!");return e}},function(e,t,n){var r=n(17),o=n(21),i=n(100),a=n(27),u=n(19),l=function(e,t,n){var c,s,f,p=e&l.F,d=e&l.G,y=e&l.S,h=e&l.P,m=e&l.B,v=e&l.W,b=d?o:o[t]||(o[t]={}),g=b.prototype,w=d?r:y?r[t]:(r[t]||{}).prototype;for(c in d&&(n=t),n)(s=!p&&w&&void 0!==w[c])&&u(b,c)||(f=s?w[c]:n[c],b[c]=d&&"function"!=typeof w[c]?n[c]:m&&s?i(f,r):v&&w[c]==f?function(e){var t=function(t,n,r){if(this instanceof e){switch(arguments.length){case 0:return new e;case 1:return new e(t);case 2:return new e(t,n)}return new e(t,n,r)}return e.apply(this,arguments)};return t.prototype=e.prototype,t}(f):h&&"function"==typeof f?i(Function.call,f):f,h&&((b.virtual||(b.virtual={}))[c]=f,e&l.R&&g&&!g[c]&&a(g,c,f)))};l.F=1,l.G=2,l.S=4,l.P=8,l.B=16,l.W=32,l.U=64,l.R=128,e.exports=l},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.createAjaxRequest=void 0;var r=n(227),o=function(e,t){return{body:(0,r.stringify)({action:e,nonce:wcmlMultiCurrency.nonce,data:JSON.stringify(t)})}},i={currencyForLang:function(e){var t=e.isEnabled,n=e.currencyCode,r=e.languageCode;return o("wcml_update_currency_lang",{value:t?1:0,code:n,lang:r})},defaultCurrencyForLang:function(e){var t=e.languageCode,n=e.currencyCode;return o("wcml_update_default_currency",{code:n,lang:t})},deleteCurrency:function(e){var t=e.currencyCode;return o("wcml_delete_currency",{code:t})},saveCurrency:function(e){return o("wcml_save_currency",{currency_options:e})},setCurrencyMode:function(e){return o("wcml_set_currency_mode",{mode:e})},setMaxMindKey:function(e){return o("wcml_set_max_mind_key",{MaxMindKey:e})}};t.createAjaxRequest=function(e){if(!i[e])throw new Error("The endpoint "+e+" is not defined");var t=(0,r.createAjax)();return{fetching:t.fetching,send:function(n){return t.doFetch(i[e](n))}}}},function(e,t,n){"use strict";function r(e){"@babel/helpers - typeof";return(r="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(e)}Object.defineProperty(t,"__esModule",{value:!0}),t.default=t.SizeContextProvider=void 0;var o=function(e){if(e&&e.__esModule)return e;if(null===e||"object"!==r(e)&&"function"!=typeof e)return{default:e};var t=i();if(t&&t.has(e))return t.get(e);var n={},o=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var a in e)if(Object.prototype.hasOwnProperty.call(e,a)){var u=o?Object.getOwnPropertyDescriptor(e,a):null;u&&(u.get||u.set)?Object.defineProperty(n,a,u):n[a]=e[a]}n.default=e,t&&t.set(e,n);return n}(n(0));function i(){if("function"!=typeof WeakMap)return null;var e=new WeakMap;return i=function(){return e},e}var a=o.createContext(void 0);t.SizeContextProvider=function(e){var t=e.children,n=e.size;return o.createElement(a.Consumer,null,function(e){return o.createElement(a.Provider,{value:n||e},t)})};var u=a;t.default=u},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.triggerModeChange=t.triggerActiveCurrenciesChange=t.validateRate=t.getCountryLabel=t.getCurrencySymbol=t.getCurrencyLabel=t.getSmallFormattedPrice=t.getFormattedPricePreview=t.capitalize=void 0;var r=function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var n in e)Object.prototype.hasOwnProperty.call(e,n)&&(t[n]=e[n]);return t.default=e,t}(n(28));t.capitalize=function(e){return e[0].toUpperCase()+e.slice(1)},t.getFormattedPricePreview=function(e){return o("1","234","0")(e)},t.getSmallFormattedPrice=function(e){return o("","99","9")(e)};var o=function(e,t,n){return function(r){var o=i(r.code);return a(e,t,r.position).replace(/__SYMBOL__/,o.symbol).replace(/__THOUSAND_SEP__/,e?r.thousand_sep:"").replace(/__DECIMAL_SEP__/,r.num_decimals>0?r.decimal_sep:"").replace(/__DECIMALS_NUMBER__/,n.repeat(r.num_decimals))}},i=function(e){return wcmlMultiCurrency.allCurrencies.filter(function(t){return t.code===e})[0]},a=(t.getCurrencyLabel=r.pipe(i,r.prop("label")),t.getCurrencySymbol=r.pipe(i,r.prop("symbol")),t.getCountryLabel=r.pipe(function(e){return wcmlMultiCurrency.allCountries.filter(function(t){return t.code===e})[0]},r.prop("label")),function(e,t,n){switch(n){case"left":return"__SYMBOL__"+e+"__THOUSAND_SEP__"+t+"__DECIMAL_SEP____DECIMALS_NUMBER__";case"right":return e+"__THOUSAND_SEP__"+t+"__DECIMAL_SEP____DECIMALS_NUMBER____SYMBOL__";case"left_space":return"__SYMBOL__ "+e+"__THOUSAND_SEP__"+t+"__DECIMAL_SEP____DECIMALS_NUMBER__";case"right_space":return e+"__THOUSAND_SEP__"+t+"__DECIMAL_SEP____DECIMALS_NUMBER__ __SYMBOL__"}});t.validateRate=r.allPass([r.pipe(parseFloat,isNaN,r.not),isFinite,r.gt(r.__,0)]),t.triggerActiveCurrenciesChange=function(e){e.currencyData=i(e.currency.code),document.dispatchEvent(new CustomEvent("wcmlActiveCurrenciesChange",{detail:e}))},t.triggerModeChange=function(e){document.dispatchEvent(new CustomEvent("wcmlCurrencyModeChange"),{detail:e})}},function(e,t){t.f={}.propertyIsEnumerable},function(e,t){var n=0,r=Math.random();e.exports=function(e){return"Symbol(".concat(void 0===e?"":e,")_",(++n+r).toString(36))}},function(e,t){e.exports=!0},function(e,t,n){var r=n(97),o=n(64);e.exports=Object.keys||function(e){return r(e,o)}},function(e,t){e.exports=function(e,t){return{enumerable:!(1&e),configurable:!(2&e),writable:!(4&e),value:t}}},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.default=void 0;var r=function(e){if(e&&e.__esModule)return e;if(null===e||"object"!==l(e)&&"function"!=typeof e)return{default:e};var t=u();if(t&&t.has(e))return t.get(e);var n={},r=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var o in e)if(Object.prototype.hasOwnProperty.call(e,o)){var i=r?Object.getOwnPropertyDescriptor(e,o):null;i&&(i.get||i.set)?Object.defineProperty(n,o,i):n[o]=e[o]}n.default=e,t&&t.set(e,n);return n}(n(0)),o=a(n(234)),i=a(n(101));function a(e){return e&&e.__esModule?e:{default:e}}function u(){if("function"!=typeof WeakMap)return null;var e=new WeakMap;return u=function(){return e},e}function l(e){"@babel/helpers - typeof";return(l="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(e)}function c(){return(c=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e}).apply(this,arguments)}function s(e,t){for(var n=0;n<t.length;n++){var r=t[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(e,r.key,r)}}function f(e,t){return(f=Object.setPrototypeOf||function(e,t){return e.__proto__=t,e})(e,t)}function p(e){var t=function(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Date.prototype.toString.call(Reflect.construct(Date,[],function(){})),!0}catch(e){return!1}}();return function(){var n,r=d(e);if(t){var o=d(this).constructor;n=Reflect.construct(r,arguments,o)}else n=r.apply(this,arguments);return function(e,t){if(t&&("object"===l(t)||"function"==typeof t))return t;return function(e){if(void 0===e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return e}(e)}(this,n)}}function d(e){return(d=Object.setPrototypeOf?Object.getPrototypeOf:function(e){return e.__proto__||Object.getPrototypeOf(e)})(e)}var y=function(){var e=function(e){!function(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function");e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,writable:!0,configurable:!0}}),t&&f(e,t)}(n,r.Component);var t=p(n);function n(){return function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,n),t.apply(this,arguments)}return function(e,t,n){t&&s(e.prototype,t),n&&s(e,n)}(n,[{key:"getLocale",value:function(){var e=this.props,t=e.componentName,n=e.defaultLocale||o.default[t||"global"],r=this.context,i=t&&r?r[t]:{};return c(c({},"function"==typeof n?n():n),i||{})}},{key:"getLocaleCode",value:function(){var e=this.context,t=e&&e.locale;return e&&e.exist&&!t?o.default.locale:t}},{key:"render",value:function(){return this.props.children(this.getLocale(),this.getLocaleCode(),this.context)}}]),n}();return e.defaultProps={componentName:"global"},e.contextType=i.default,e}();t.default=y},function(e,t,n){"use strict";function r(e){"@babel/helpers - typeof";return(r="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(e)}Object.defineProperty(t,"__esModule",{value:!0}),Object.defineProperty(t,"resetWarned",{enumerable:!0,get:function(){return o.resetWarned}}),t.default=void 0;var o=function(e){if(e&&e.__esModule)return e;if(null===e||"object"!==r(e)&&"function"!=typeof e)return{default:e};var t=i();if(t&&t.has(e))return t.get(e);var n={},o=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var a in e)if(Object.prototype.hasOwnProperty.call(e,a)){var u=o?Object.getOwnPropertyDescriptor(e,a):null;u&&(u.get||u.set)?Object.defineProperty(n,a,u):n[a]=e[a]}n.default=e,t&&t.set(e,n);return n}(n(104));function i(){if("function"!=typeof WeakMap)return null;var e=new WeakMap;return i=function(){return e},e}t.default=function(e,t,n){(0,o.default)(e,"[antd: ".concat(t,"] ").concat(n))}},function(e,t,n){"use strict";function r(e){"@babel/helpers - typeof";return(r="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(e)}Object.defineProperty(t,"__esModule",{value:!0}),t.replaceElement=u,t.cloneElement=function(e,t){return u(e,e,t)},t.isValidElement=void 0;var o=function(e){if(e&&e.__esModule)return e;if(null===e||"object"!==r(e)&&"function"!=typeof e)return{default:e};var t=i();if(t&&t.has(e))return t.get(e);var n={},o=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var a in e)if(Object.prototype.hasOwnProperty.call(e,a)){var u=o?Object.getOwnPropertyDescriptor(e,a):null;u&&(u.get||u.set)?Object.defineProperty(n,a,u):n[a]=e[a]}n.default=e,t&&t.set(e,n);return n}(n(0));function i(){if("function"!=typeof WeakMap)return null;var e=new WeakMap;return i=function(){return e},e}var a=o.isValidElement;function u(e,t,n){return a(e)?o.cloneElement(e,"function"==typeof n?n():n):t}t.isValidElement=a},function(e,t){var n;n=function(){return this}();try{n=n||Function("return this")()||(0,eval)("this")}catch(e){"object"==typeof window&&(n=window)}e.exports=n},function(e,t,n){"use strict";
|
1 |
+
!function(e){var t={};function n(r){if(t[r])return t[r].exports;var o=t[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,n),o.l=!0,o.exports}n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{configurable:!1,enumerable:!0,get:r})},n.r=function(e){Object.defineProperty(e,"__esModule",{value:!0})},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=266)}([function(e,t,n){"use strict";e.exports=n(264)},function(e,t,n){var r;
|
2 |
/*!
|
3 |
Copyright (c) 2017 Jed Watson.
|
4 |
Licensed under the MIT License (MIT), see
|
9 |
Licensed under the MIT License (MIT), see
|
10 |
http://jedwatson.github.io/classnames
|
11 |
*/
|
12 |
+
!function(){"use strict";var n={}.hasOwnProperty;function o(){for(var e=[],t=0;t<arguments.length;t++){var r=arguments[t];if(r){var i=typeof r;if("string"===i||"number"===i)e.push(r);else if(Array.isArray(r)&&r.length){var a=o.apply(null,r);a&&e.push(a)}else if("object"===i)for(var u in r)n.call(r,u)&&r[u]&&e.push(u)}}return e.join(" ")}void 0!==e&&e.exports?(o.default=o,e.exports=o):void 0===(r=function(){return o}.apply(t,[]))||(e.exports=r)}()},function(e,t,n){"use strict";n.d(t,"b",function(){return u});var r={};function o(e,t){0}function i(e,t){0}function a(e,t,n){t||r[n]||(e(!1,n),r[n]=!0)}function u(e,t){a(i,e,t)}t.a=function(e,t){a(o,e,t)}},function(e,t,n){"use strict";!function e(){if("undefined"!=typeof __REACT_DEVTOOLS_GLOBAL_HOOK__&&"function"==typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE)try{__REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE(e)}catch(e){console.error(e)}}(),e.exports=n(263)},function(e,t,n){"use strict";var r={MAC_ENTER:3,BACKSPACE:8,TAB:9,NUM_CENTER:12,ENTER:13,SHIFT:16,CTRL:17,ALT:18,PAUSE:19,CAPS_LOCK:20,ESC:27,SPACE:32,PAGE_UP:33,PAGE_DOWN:34,END:35,HOME:36,LEFT:37,UP:38,RIGHT:39,DOWN:40,PRINT_SCREEN:44,INSERT:45,DELETE:46,ZERO:48,ONE:49,TWO:50,THREE:51,FOUR:52,FIVE:53,SIX:54,SEVEN:55,EIGHT:56,NINE:57,QUESTION_MARK:63,A:65,B:66,C:67,D:68,E:69,F:70,G:71,H:72,I:73,J:74,K:75,L:76,M:77,N:78,O:79,P:80,Q:81,R:82,S:83,T:84,U:85,V:86,W:87,X:88,Y:89,Z:90,META:91,WIN_KEY_RIGHT:92,CONTEXT_MENU:93,NUM_ZERO:96,NUM_ONE:97,NUM_TWO:98,NUM_THREE:99,NUM_FOUR:100,NUM_FIVE:101,NUM_SIX:102,NUM_SEVEN:103,NUM_EIGHT:104,NUM_NINE:105,NUM_MULTIPLY:106,NUM_PLUS:107,NUM_MINUS:109,NUM_PERIOD:110,NUM_DIVISION:111,F1:112,F2:113,F3:114,F4:115,F5:116,F6:117,F7:118,F8:119,F9:120,F10:121,F11:122,F12:123,NUMLOCK:144,SEMICOLON:186,DASH:189,EQUALS:187,COMMA:188,PERIOD:190,SLASH:191,APOSTROPHE:192,SINGLE_QUOTE:222,OPEN_SQUARE_BRACKET:219,BACKSLASH:220,CLOSE_SQUARE_BRACKET:221,WIN_KEY:224,MAC_FF_META:224,WIN_IME:229,isTextModifyingKeyEvent:function(e){var t=e.keyCode;if(e.altKey&&!e.ctrlKey||e.metaKey||t>=r.F1&&t<=r.F12)return!1;switch(t){case r.ALT:case r.CAPS_LOCK:case r.CONTEXT_MENU:case r.CTRL:case r.DOWN:case r.END:case r.ESC:case r.HOME:case r.INSERT:case r.LEFT:case r.MAC_FF_META:case r.META:case r.NUMLOCK:case r.NUM_CENTER:case r.PAGE_DOWN:case r.PAGE_UP:case r.PAUSE:case r.PRINT_SCREEN:case r.RIGHT:case r.SHIFT:case r.UP:case r.WIN_KEY:case r.WIN_KEY_RIGHT:return!1;default:return!0}},isCharacterKey:function(e){if(e>=r.ZERO&&e<=r.NINE)return!0;if(e>=r.NUM_ZERO&&e<=r.NUM_MULTIPLY)return!0;if(e>=r.A&&e<=r.Z)return!0;if(-1!==window.navigator.userAgent.indexOf("WebKit")&&0===e)return!0;switch(e){case r.SPACE:case r.QUESTION_MARK:case r.NUM_PLUS:case r.NUM_MINUS:case r.NUM_PERIOD:case r.NUM_DIVISION:case r.SEMICOLON:case r.DASH:case r.EQUALS:case r.COMMA:case r.PERIOD:case r.SLASH:case r.APOSTROPHE:case r.SINGLE_QUOTE:case r.OPEN_SQUARE_BRACKET:case r.BACKSLASH:case r.CLOSE_SQUARE_BRACKET:return!0;default:return!1}}};t.a=r},function(e,t,n){e.exports=n(249)()},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),Object.defineProperty(t,"ConfigConsumer",{enumerable:!0,get:function(){return u.ConfigConsumer}}),Object.defineProperty(t,"ConfigContext",{enumerable:!0,get:function(){return u.ConfigContext}}),t.default=t.configConsumerProps=void 0;var r=s(n(0)),o=n(117),i=s(n(243)),a=function(e){return e&&e.__esModule?e:{default:e}}(n(46)),u=n(238),l=n(29);function c(){if("function"!=typeof WeakMap)return null;var e=new WeakMap;return c=function(){return e},e}function s(e){if(e&&e.__esModule)return e;if(null===e||"object"!==f(e)&&"function"!=typeof e)return{default:e};var t=c();if(t&&t.has(e))return t.get(e);var n={},r=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var o in e)if(Object.prototype.hasOwnProperty.call(e,o)){var i=r?Object.getOwnPropertyDescriptor(e,o):null;i&&(i.get||i.set)?Object.defineProperty(n,o,i):n[o]=e[o]}return n.default=e,t&&t.set(e,n),n}function f(e){"@babel/helpers - typeof";return(f="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(e)}function p(){return(p=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e}).apply(this,arguments)}function d(e,t){for(var n=0;n<t.length;n++){var r=t[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(e,r.key,r)}}function y(e,t){return(y=Object.setPrototypeOf||function(e,t){return e.__proto__=t,e})(e,t)}function h(e){var t=function(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Date.prototype.toString.call(Reflect.construct(Date,[],function(){})),!0}catch(e){return!1}}();return function(){var n,r=m(e);if(t){var o=m(this).constructor;n=Reflect.construct(r,arguments,o)}else n=r.apply(this,arguments);return function(e,t){if(t&&("object"===f(t)||"function"==typeof t))return t;return function(e){if(void 0===e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return e}(e)}(this,n)}}function m(e){return(m=Object.setPrototypeOf?Object.getPrototypeOf:function(e){return e.__proto__||Object.getPrototypeOf(e)})(e)}t.configConsumerProps=["getTargetContainer","getPopupContainer","rootPrefixCls","getPrefixCls","renderEmpty","csp","autoInsertSpaceInButton","locale","pageHeader"];var v=function(e){!function(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function");e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,writable:!0,configurable:!0}}),t&&y(e,t)}(n,r.Component);var t=h(n);function n(){var e;return function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,n),(e=t.apply(this,arguments)).getPrefixClsWrapper=function(t){return function(n,r){var o=e.props.prefixCls;if(r)return r;var i=o||t.getPrefixCls("");return n?"".concat(i,"-").concat(n):i}},e.renderProvider=function(t,n){var a=e.props,c=a.children,s=a.getTargetContainer,f=a.getPopupContainer,d=a.renderEmpty,y=a.csp,h=a.autoInsertSpaceInButton,m=a.form,v=a.input,b=a.locale,g=a.pageHeader,w=a.componentSize,O=a.direction,E=a.space,S=p(p({},t),{getPrefixCls:e.getPrefixClsWrapper(t),csp:y,autoInsertSpaceInButton:h,locale:b||n,direction:O,space:E});s&&(S.getTargetContainer=s),f&&(S.getPopupContainer=f),d&&(S.renderEmpty=d),g&&(S.pageHeader=g),v&&(S.input=v);var _=c,P={};return b&&b.Form&&b.Form.defaultValidateMessages&&(P=b.Form.defaultValidateMessages),m&&m.validateMessages&&(P=p(p({},P),m.validateMessages)),Object.keys(P).length>0&&(_=r.createElement(o.FormProvider,{validateMessages:P},c)),r.createElement(l.SizeContextProvider,{size:w},r.createElement(u.ConfigContext.Provider,{value:S},r.createElement(i.default,{locale:b||n,_ANT_MARK__:i.ANT_MARK},_)))},e}return function(e,t,n){t&&d(e.prototype,t),n&&d(e,n)}(n,[{key:"render",value:function(){var e=this;return r.createElement(a.default,null,function(t,n,o){return r.createElement(u.ConfigConsumer,null,function(t){return e.renderProvider(t,o)})})}}]),n}();t.default=v},function(e,t,n){"use strict";t.__esModule=!0;var r=function(e){return e&&e.__esModule?e:{default:e}}(n(227));t.default=r.default||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e}},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.useStore=t.getStore=t.getStoreAction=t.getStoreProperty=t.getCurrencyIndex=void 0;var r=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},o=n(81),i=n(39),a=function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var n in e)Object.prototype.hasOwnProperty.call(e,n)&&(t[n]=e[n]);return t.default=e,t}(n(23)),u=n(38);function l(e){return function(){var t=e.apply(this,arguments);return new Promise(function(e,n){return function r(o,i){try{var a=t[o](i),u=a.value}catch(e){return void n(e)}if(!a.done)return Promise.resolve(u).then(function(e){r("next",e)},function(e){r("throw",e)});e(u)}("next")})}}t.default=function(e){var t=e.activeCurrencies,n=e.allCurrencies,s=e.allCountries,f=e.languages,p=e.gateways,d=e.mode,y=e.maxMindKeyExist,h=e.isStandalone,m=e.isAutoRateEnabled;return(0,o.createStore)({activeCurrencies:t,allCurrencies:n,allCountries:s,languages:f,gateways:p,mode:d,isMaxMindRegistered:y,isValidatingMaxMindRegistration:null,errorOnMaxMindRegistration:null,isStandalone:h,modalCurrency:null,updating:!1,isPresettingRate:!1,isAutoRateEnabled:m,setDefaultCurrencyForLang:(0,o.action)(function(e,t){var n=e.languages.findIndex(function(e){return e.code===t.language}),r=e.languages[n];r.defaultCurrency=t.currency,e.languages[n]=r}),getCurrencyIndex:(0,o.action)(function(e,t){e.activeCurrencies.findIndex(function(e){return e.code===t})}),enableCurrencyForLang:(0,o.action)(function(e,t){var n=c(e.activeCurrencies)(t.currency),o=e.activeCurrencies[n],i=t.enable?1:0;o.languages=r({},o.languages,function(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}({},t.language,i)),e.activeCurrencies[n]=o}),deleteCurrency:(0,o.action)(function(e,t){var n=c(e.activeCurrencies)(t),o=r({},e.activeCurrencies[n]);e.activeCurrencies.splice(n,1),(0,i.triggerActiveCurrenciesChange)({action:"remove",currency:o})}),setModalCurrency:(0,o.action)(function(e,t){e.modalCurrency=e.setInitialGatewayCurrency(t,e.activeCurrencies)}),setInitialGatewayCurrency:function(e,t){var n=function(n){return void 0===n.currency||function(e){return t.find(function(t){return t.code===e})}(n.currency)||(n=r({},n,{currency:e.code})),n};return e&&e.gatewaysSettings&&Object.keys(e.gatewaysSettings).map(function(t){e.gatewaysSettings[t]=n(e.gatewaysSettings[t])}),e},saveModalCurrency:(0,o.action)(function(e){var t=c(e.activeCurrencies)(e.modalCurrency.code);if(t<0){var n=r({},e.modalCurrency,{isNew:!1});e.activeCurrencies.push(n),(0,i.triggerActiveCurrenciesChange)({action:"add",currency:n})}else e.activeCurrencies[t]=e.modalCurrency}),newCurrencies:(0,o.computed)(function(e){var t=e.activeCurrencies.map(function(e){return e.code});return e.allCurrencies.filter(function(e){return!t.includes(e.code)})}),defaultCurrency:(0,o.computed)(function(e){return e.activeCurrencies.filter(function(e){return e.isDefault})[0]}),setUpdating:(0,o.action)(function(e,t){e.updating=t}),setMode:(0,o.action)(function(e,t){e.mode=t,(0,i.triggerModeChange)({mode:t})}),setMaxMindKeyExist:(0,o.action)(function(e){e.maxMindKeyExist=!0}),registerMaxMindKey:(0,o.thunk)(function(){var e=l(regeneratorRuntime.mark(function e(t,n){var r,o,i,l,c;return regeneratorRuntime.wrap(function(e){for(;;)switch(e.prev=e.next){case 0:return t._setErrorOnMaxMindRegistration(null),t._setIsValidatingMaxMindRegistration(!0),e.next=4,(0,u.doAjaxForSetMaxMindKey)(n);case 4:r=e.sent,o=r.data,t._setIsValidatingMaxMindRegistration(!1),i=a.prop("success"),l=a.prop("data"),i(o)?t._setIsMaxMindRegistered():(c=l(o),t._setErrorOnMaxMindRegistration(c||"Error"));case 10:case"end":return e.stop()}},e,void 0)}));return function(t,n){return e.apply(this,arguments)}}()),_setErrorOnMaxMindRegistration:(0,o.action)(function(e,t){e.errorOnMaxMindRegistration=t}),_setIsValidatingMaxMindRegistration:(0,o.action)(function(e,t){e.isValidatingMaxMindRegistration=t}),_setIsMaxMindRegistered:(0,o.action)(function(e){e.isMaxMindRegistered=!0}),presetExchangeRate:(0,o.thunk)(function(){var e=l(regeneratorRuntime.mark(function e(t,n,o){var i,a;return regeneratorRuntime.wrap(function(e){for(;;)switch(e.prev=e.next){case 0:if(!o.getState().isAutoRateEnabled){e.next=8;break}return t._setIsPresettingRate(!0),e.next=4,(0,u.doAjaxForGetAutoExchangeRate)(n);case 4:i=e.sent,a=i.data,t._setIsPresettingRate(!1),t.setModalCurrency(r({},o.getState().modalCurrency,{rate:a.success?a.data:"invalid"}));case 8:case"end":return e.stop()}},e,void 0)}));return function(t,n,r){return e.apply(this,arguments)}}()),_setIsPresettingRate:(0,o.action)(function(e,t){e.isPresettingRate=t}),isValidModalRate:(0,o.computed)(function(e){var t=e.modalCurrency?e.modalCurrency.rate:"1";return(0,i.validateRate)(t)})})};var c=t.getCurrencyIndex=function(e){return function(t){return a.findIndex(a.propEq("code",t))(e)}},s=t.getStoreProperty=function(e){return(0,o.useStoreState)(a.path(Array.isArray(e)?e:[e]))},f=t.getStoreAction=function(e){return(0,o.useStoreActions)(a.prop(e))};t.getStore=function(e,t){return[s(e),f(t)]},t.useStore=function(e){return[s(e),f("set"+(0,i.capitalize)(e)),f("reset"+(0,i.capitalize)(e))]}},function(e,t,n){(function(t){for(var r=n(247),o="undefined"==typeof window?t:window,i=["moz","webkit"],a="AnimationFrame",u=o["request"+a],l=o["cancel"+a]||o["cancelRequest"+a],c=0;!u&&c<i.length;c++)u=o[i[c]+"Request"+a],l=o[i[c]+"Cancel"+a]||o[i[c]+"CancelRequest"+a];if(!u||!l){var s=0,f=0,p=[];u=function(e){if(0===p.length){var t=r(),n=Math.max(0,1e3/60-(t-s));s=n+t,setTimeout(function(){var e=p.slice(0);p.length=0;for(var t=0;t<e.length;t++)if(!e[t].cancelled)try{e[t].callback(s)}catch(e){setTimeout(function(){throw e},0)}},Math.round(n))}return p.push({handle:++f,callback:e,cancelled:!1}),f},l=function(e){for(var t=0;t<p.length;t++)p[t].handle===e&&(p[t].cancelled=!0)}}e.exports=function(e){return u.call(o,e)},e.exports.cancel=function(){l.apply(o,arguments)},e.exports.polyfill=function(e){e||(e=o),e.requestAnimationFrame=u,e.cancelAnimationFrame=l}}).call(this,n(49))},function(e,t,n){"use strict";function r(e){"@babel/helpers - typeof";return(r="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(e)}Object.defineProperty(t,"__esModule",{value:!0}),t.default=void 0;var o=function(e){if(e&&e.__esModule)return e;if(null===e||"object"!==r(e)&&"function"!=typeof e)return{default:e};var t=s();if(t&&t.has(e))return t.get(e);var n={},o=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var i in e)if(Object.prototype.hasOwnProperty.call(e,i)){var a=o?Object.getOwnPropertyDescriptor(e,i):null;a&&(a.get||a.set)?Object.defineProperty(n,i,a):n[i]=e[i]}n.default=e,t&&t.set(e,n);return n}(n(0)),i=c(n(1)),a=c(n(90)),u=n(183),l=n(59);function c(e){return e&&e.__esModule?e:{default:e}}function s(){if("function"!=typeof WeakMap)return null;var e=new WeakMap;return s=function(){return e},e}function f(e,t){return function(e){if(Array.isArray(e))return e}(e)||function(e,t){if("undefined"==typeof Symbol||!(Symbol.iterator in Object(e)))return;var n=[],r=!0,o=!1,i=void 0;try{for(var a,u=e[Symbol.iterator]();!(r=(a=u.next()).done)&&(n.push(a.value),!t||n.length!==t);r=!0);}catch(e){o=!0,i=e}finally{try{r||null==u.return||u.return()}finally{if(o)throw i}}return n}(e,t)||function(e,t){if(!e)return;if("string"==typeof e)return p(e,t);var n=Object.prototype.toString.call(e).slice(8,-1);"Object"===n&&e.constructor&&(n=e.constructor.name);if("Map"===n||"Set"===n)return Array.from(n);if("Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n))return p(e,t)}(e,t)||function(){throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function p(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=new Array(t);n<t;n++)r[n]=e[n];return r}function d(e,t){if(null==e)return{};var n,r,o=function(e,t){if(null==e)return{};var n,r,o={},i=Object.keys(e);for(r=0;r<i.length;r++)n=i[r],t.indexOf(n)>=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r<i.length;r++)n=i[r],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}(0,u.setTwoToneColor)("#1890ff");var y=o.forwardRef(function(e,t){var n=e.className,r=e.icon,u=e.spin,c=e.rotate,s=e.tabIndex,p=e.onClick,y=e.twoToneColor,h=d(e,["className","icon","spin","rotate","tabIndex","onClick","twoToneColor"]),m=(0,i.default)("anticon",function(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}({},"anticon-".concat(r.name),Boolean(r.name)),n),v=(0,i.default)({"anticon-spin":!!u||"loading"===r.name}),b=s;void 0===b&&p&&(b=-1);var g=c?{msTransform:"rotate(".concat(c,"deg)"),transform:"rotate(".concat(c,"deg)")}:void 0,w=f((0,l.normalizeTwoToneColors)(y),2),O=w[0],E=w[1];return o.createElement("span",Object.assign({role:"img","aria-label":r.name},h,{ref:t,tabIndex:b,onClick:p,className:m}),o.createElement(a.default,{className:v,icon:r,primaryColor:O,secondaryColor:E,style:g}))});y.displayName="AntdIcon",y.getTwoToneColor=u.getTwoToneColor,y.setTwoToneColor=u.setTwoToneColor;var h=y;t.default=h},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.Spinner=t.allowBreakRules=t.getTooltip=t.InputRow=t.SelectRow=void 0;var r=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},o=u(n(0)),i=u(n(107)),a=n(74);function u(e){return e&&e.__esModule?e:{default:e}}t.SelectRow=function(e){var t=e.onChange,n=e.label,i=e.attrs,a=e.tooltip,u=e.children,c=e.afterSelect,s=void 0===c?null:c;return o.default.createElement("div",{className:"wpml-form-row"},o.default.createElement("label",{htmlFor:i.id},n,l(a)),o.default.createElement("select",r({onChange:t},i),u),s)},t.InputRow=function(e){var t=e.onChange,n=e.label,i=e.attrs,a=e.tooltip;return o.default.createElement("div",{className:"wpml-form-row"},o.default.createElement("label",{htmlFor:i.id},n,l(a)),o.default.createElement("input",r({},i,{onChange:t})))};var l=t.getTooltip=function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"otgs-ico-help";return e&&o.default.createElement(i.default,{getPopupContainer:a.getPopupContainer,title:c(e)}," ",o.default.createElement("i",{className:"wcml-tip "+t}))},c=t.allowBreakRules=function(e){return o.default.createElement("div",{dangerouslySetInnerHTML:{__html:e}})};t.Spinner=function(e){var t=e.style,n=r({visibility:"visible"},t);return o.default.createElement("span",{className:"spinner",style:n})}},function(e,t,n){"use strict";function r(e){"@babel/helpers - typeof";return(r="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(e)}function o(){for(var e=arguments.length,t=new Array(e),n=0;n<e;n++)t[n]=arguments[n];return function(e){t.forEach(function(t){!function(e,t){"function"==typeof e?e(t):"object"===r(e)&&e&&"current"in e&&(e.current=t)}(t,e)})}}function i(e){return!(e.type&&e.type.prototype&&!e.type.prototype.render)&&!("function"==typeof e&&e.prototype&&!e.prototype.render)}n.d(t,"a",function(){return o}),n.d(t,"b",function(){return i})},function(e,t,n){"use strict";n.d(t,"a",function(){return i});var r=n(3),o=n.n(r);function i(e){return e instanceof HTMLElement?e:o.a.findDOMNode(e)}},function(e,t,n){"use strict";(function(e){var r;n.d(t,"a",function(){return $}),n.d(t,"b",function(){return q}),n.d(t,"c",function(){return u}),n.d(t,"d",function(){return c}),n.d(t,"e",function(){return B});var o="undefined"!=typeof Symbol?Symbol("immer-nothing"):((r={})["immer-nothing"]=!0,r),i="undefined"!=typeof Symbol&&Symbol.for?Symbol.for("immer-draftable"):"__$immer_draftable",a="undefined"!=typeof Symbol&&Symbol.for?Symbol.for("immer-state"):"__$immer_state";function u(e){return!!e&&!!e[a]}function l(e){if(!e||"object"!=typeof e)return!1;if(Array.isArray(e))return!0;var t=Object.getPrototypeOf(e);return!t||t===Object.prototype||(!!e[i]||!!e.constructor[i])}function c(e){if(e&&e[a])return e[a].base}var s=Object.assign||function(e,t){for(var n in t)h(t,n)&&(e[n]=t[n]);return e},f="undefined"!=typeof Reflect&&Reflect.ownKeys?Reflect.ownKeys:void 0!==Object.getOwnPropertySymbols?function(e){return Object.getOwnPropertyNames(e).concat(Object.getOwnPropertySymbols(e))}:Object.getOwnPropertyNames;function p(e,t){if(void 0===t&&(t=!1),Array.isArray(e))return e.slice();var n=Object.create(Object.getPrototypeOf(e));return f(e).forEach(function(r){if(r!==a){var o=Object.getOwnPropertyDescriptor(e,r),i=o.value;o.get&&t&&(i=o.get.call(e)),o.enumerable?n[r]=i:t&&Object.defineProperty(n,r,{value:i,writable:!0,configurable:!0})}}),n}function d(e,t){if(Array.isArray(e))for(var n=0;n<e.length;n++)t(n,e[n],e);else f(e).forEach(function(n){return t(n,e[n],e)})}function y(e,t){var n=Object.getOwnPropertyDescriptor(e,t);return!!n&&n.enumerable}function h(e,t){return Object.prototype.hasOwnProperty.call(e,t)}function m(e,t){return e===t?0!==e||1/e==1/t:e!=e&&t!=t}var v=function(e){this.drafts=[],this.parent=e,this.canAutoFreeze=!0,this.patches=null};function b(e){e[a].revoke()}v.prototype.usePatches=function(e){e&&(this.patches=[],this.inversePatches=[],this.patchListener=e)},v.prototype.revoke=function(){this.leave(),this.drafts.forEach(b),this.drafts=null},v.prototype.leave=function(){this===v.current&&(v.current=this.parent)},v.current=null,v.enter=function(){return this.current=new v(this.current)};var g={};function w(e,t){var n=Array.isArray(e),r=x(e);d(r,function(t){!function(e,t,n){var r=g[t];r?r.enumerable=n:g[t]=r={configurable:!0,enumerable:n,get:function(){return function(e,t){j(e);var n=S(E(e),t);if(e.finalizing)return n;if(n===S(e.base,t)&&l(n))return P(e),e.copy[t]=w(n,e);return n}(this[a],t)},set:function(e){!function(e,t,n){if(j(e),e.assigned[t]=!0,!e.modified){if(m(n,S(E(e),t)))return;_(e),P(e)}e.copy[t]=n}(this[a],t,e)}};Object.defineProperty(e,t,r)}(r,t,n||y(e,t))});var o=t?t.scope:v.current;return function(e,t,n){Object.defineProperty(e,t,{value:n,enumerable:!1,writable:!0})}(r,a,{scope:o,modified:!1,finalizing:!1,finalized:!1,assigned:{},parent:t,base:e,draft:r,copy:null,revoke:O,revoked:!1}),o.drafts.push(r),r}function O(){this.revoked=!0}function E(e){return e.copy||e.base}function S(e,t){var n=e[a];if(n&&!n.finalizing){n.finalizing=!0;var r=e[t];return n.finalizing=!1,r}return e[t]}function _(e){e.modified||(e.modified=!0,e.parent&&_(e.parent))}function P(e){e.copy||(e.copy=x(e.base))}function x(e){var t=e&&e[a];if(t){t.finalizing=!0;var n=p(t.draft,!0);return t.finalizing=!1,n}return p(e)}function j(e){if(!0===e.revoked)throw new Error("Cannot use a proxy that has been revoked. Did you pass an object from inside an immer function to an async process? "+JSON.stringify(E(e)))}function C(e){for(var t=e.length-1;t>=0;t--){var n=e[t][a];n.modified||(Array.isArray(n.base)?T(n)&&_(n):k(n)&&_(n))}}function k(e){for(var t=e.base,n=e.draft,r=Object.keys(n),o=r.length-1;o>=0;o--){var i=r[o],u=t[i];if(void 0===u&&!h(t,i))return!0;var l=n[i],c=l&&l[a];if(c?c.base!==u:!m(l,u))return!0}return r.length!==Object.keys(t).length}function T(e){var t=e.draft;if(t.length!==e.base.length)return!0;var n=Object.getOwnPropertyDescriptor(t,t.length-1);return!(!n||n.get)}var M=Object.freeze({willFinalize:function(e,t,n){e.drafts.forEach(function(e){e[a].finalizing=!0}),n?u(t)&&t[a].scope===e&&C(e.drafts):(e.patches&&function e(t){if(t&&"object"==typeof t){var n=t[a];if(n){var r=n.base,o=n.draft,i=n.assigned;if(Array.isArray(t)){if(T(n)){if(_(n),i.length=!0,o.length<r.length)for(var u=o.length;u<r.length;u++)i[u]=!1;else for(var l=r.length;l<o.length;l++)i[l]=!0;for(var c=0;c<o.length;c++)void 0===i[c]&&e(o[c])}}else Object.keys(o).forEach(function(t){void 0!==r[t]||h(r,t)?i[t]||e(o[t]):(i[t]=!0,_(n))}),Object.keys(r).forEach(function(e){void 0!==o[e]||h(o,e)||(i[e]=!1,_(n))})}}}(e.drafts[0]),C(e.drafts))},createProxy:w});function A(e,t){var n=t?t.scope:v.current,r={scope:n,modified:!1,finalized:!1,assigned:{},parent:t,base:e,draft:null,drafts:{},copy:null,revoke:null},o=Array.isArray(e)?Proxy.revocable([r],R):Proxy.revocable(r,N),i=o.revoke,a=o.proxy;return r.draft=a,r.revoke=i,n.drafts.push(a),a}var N={get:function(e,t){if(t===a)return e;var n=e.drafts;if(!e.modified&&h(n,t))return n[t];var r=D(e)[t];if(e.finalized||!l(r))return r;if(e.modified){if(r!==I(e.base,t))return r;n=e.copy}return n[t]=A(r,e)},has:function(e,t){return t in D(e)},ownKeys:function(e){return Reflect.ownKeys(D(e))},set:function(e,t,n){if(!e.modified){var r=I(e.base,t),o=n?m(r,n)||n===e.drafts[t]:m(r,n)&&t in e.base;if(o)return!0;F(e)}return e.assigned[t]=!0,e.copy[t]=n,!0},deleteProperty:function(e,t){(void 0!==I(e.base,t)||t in e.base)&&(e.assigned[t]=!1,F(e));e.copy&&delete e.copy[t];return!0},getOwnPropertyDescriptor:function(e,t){var n=D(e),r=Reflect.getOwnPropertyDescriptor(n,t);r&&(r.writable=!0,r.configurable=!Array.isArray(n)||"length"!==t);return r},defineProperty:function(){throw new Error("Object.defineProperty() cannot be used on an Immer draft")},getPrototypeOf:function(e){return Object.getPrototypeOf(e.base)},setPrototypeOf:function(){throw new Error("Object.setPrototypeOf() cannot be used on an Immer draft")}},R={};function D(e){return e.copy||e.base}function I(e,t){var n=e[a],r=Reflect.getOwnPropertyDescriptor(n?D(n):e,t);return r&&r.value}function F(e){e.modified||(e.modified=!0,e.copy=s(p(e.base),e.drafts),e.drafts=null,e.parent&&F(e.parent))}d(N,function(e,t){R[e]=function(){return arguments[0]=arguments[0][0],t.apply(this,arguments)}}),R.deleteProperty=function(e,t){if(isNaN(parseInt(t)))throw new Error("Immer only supports deleting array indices");return N.deleteProperty.call(this,e[0],t)},R.set=function(e,t,n){if("length"!==t&&isNaN(parseInt(t)))throw new Error("Immer only supports setting array indices and the 'length' property");return N.set.call(this,e[0],t,n)};var L=Object.freeze({willFinalize:function(){},createProxy:A});function z(e,t,n,r){Array.isArray(e.base)?function(e,t,n,r){var o,i,a=e.base,u=e.copy,l=e.assigned;u.length<a.length&&(a=(o=[u,a])[0],u=o[1],n=(i=[r,n])[0],r=i[1]);var c=u.length-a.length,s=0;for(;a[s]===u[s]&&s<a.length;)++s;var f=a.length;for(;f>s&&a[f-1]===u[f+c-1];)--f;for(var p=s;p<f;++p)if(l[p]&&u[p]!==a[p]){var d=t.concat([p]);n.push({op:"replace",path:d,value:u[p]}),r.push({op:"replace",path:d,value:a[p]})}for(var y=f!=a.length,h=n.length,m=f+c-1;m>=f;--m){var v=t.concat([m]);n[h+m-f]={op:"add",path:v,value:u[m]},y&&r.push({op:"remove",path:v})}y||r.push({op:"replace",path:t.concat(["length"]),value:a.length})}(e,t,n,r):function(e,t,n,r){var o=e.base,i=e.copy;d(e.assigned,function(e,a){var u=o[e],l=i[e],c=a?e in o?"replace":"add":"remove";if(u!==l||"replace"!==c){var s=t.concat(e);n.push("remove"===c?{op:c,path:s}:{op:c,path:s,value:l}),r.push("add"===c?{op:"remove",path:s}:"remove"===c?{op:"add",path:s,value:u}:{op:"replace",path:s,value:u})}})}(e,t,n,r)}function V(e,t){for(var n=0;n<t.length;n++){var r=t[n],o=r.path;if(0===o.length&&"replace"===r.op)e=r.value;else{for(var i=e,a=0;a<o.length-1;a++)if(!(i=i[o[a]])||"object"!=typeof i)throw new Error("Cannot apply patch, path doesn't resolve: "+o.join("/"));var u=o[o.length-1];switch(r.op){case"replace":i[u]=r.value;break;case"add":Array.isArray(i)?i.splice(u,0,r.value):i[u]=r.value;break;case"remove":Array.isArray(i)?i.splice(u,1):delete i[u];break;default:throw new Error("Unsupported patch operation: "+r.op)}}}return e}var W={useProxies:"undefined"!=typeof Proxy&&"undefined"!=typeof Reflect,autoFreeze:void 0===e&&"verifyMinified"===function(){}.name,onAssign:null,onDelete:null,onCopy:null},U=function(e){s(this,W,e),this.setUseProxies(this.useProxies),this.produce=this.produce.bind(this)};U.prototype.produce=function(e,t,n){var r,i=this;if("function"==typeof e&&"function"!=typeof t){var a=t;t=e;var u=this;return function(e){var n=this;void 0===e&&(e=a);for(var r=[],o=arguments.length-1;o-- >0;)r[o]=arguments[o+1];return u.produce(e,function(e){return t.call.apply(t,[n,e].concat(r))})}}if("function"!=typeof t)throw new Error("The first or second argument to `produce` must be a function");if(void 0!==n&&"function"!=typeof n)throw new Error("The third argument to `produce` must be a function or undefined");if(l(e)){var c=v.enter(),s=this.createProxy(e),f=!0;try{r=t(s),f=!1}finally{f?c.revoke():c.leave()}return r instanceof Promise?r.then(function(e){return c.usePatches(n),i.processResult(e,c)},function(e){throw c.revoke(),e}):(c.usePatches(n),this.processResult(r,c))}return void 0===(r=t(e))?e:r!==o?r:void 0},U.prototype.createDraft=function(e){if(!l(e))throw new Error("First argument to `createDraft` must be a plain object, an array, or an immerable object");var t=v.enter(),n=this.createProxy(e);return n[a].isManual=!0,t.leave(),n},U.prototype.finishDraft=function(e,t){var n=e&&e[a];if(!n||!n.isManual)throw new Error("First argument to `finishDraft` must be a draft returned by `createDraft`");if(n.finalized)throw new Error("The given draft is already finalized");var r=n.scope;return r.usePatches(t),this.processResult(void 0,r)},U.prototype.setAutoFreeze=function(e){this.autoFreeze=e},U.prototype.setUseProxies=function(e){this.useProxies=e,s(this,e?L:M)},U.prototype.applyPatches=function(e,t){return u(e)?V(e,t):this.produce(e,function(e){return V(e,t)})},U.prototype.processResult=function(e,t){var n=t.drafts[0],r=void 0!==e&&e!==n;if(this.willFinalize(t,e,r),r){if(n[a].modified)throw t.revoke(),new Error("An immer producer returned a new value *and* modified its draft. Either return a new value *or* modify the draft.");l(e)&&(e=this.finalize(e,null,t)),t.patches&&(t.patches.push({op:"replace",path:[],value:e}),t.inversePatches.push({op:"replace",path:[],value:n[a].base}))}else e=this.finalize(n,[],t);return t.revoke(),t.patches&&t.patchListener(t.patches,t.inversePatches),e!==o?e:void 0},U.prototype.finalize=function(e,t,n){var r=this,o=e[a];if(!o)return Object.isFrozen(e)?e:this.finalizeTree(e,null,n);if(o.scope!==n)return e;if(!o.modified)return o.base;if(!o.finalized){if(o.finalized=!0,this.finalizeTree(o.draft,t,n),this.onDelete)if(this.useProxies){var i=o.assigned;for(var u in i)i[u]||this.onDelete(o,u)}else{var l=o.base,c=o.copy;d(l,function(e){h(c,e)||r.onDelete(o,e)})}this.onCopy&&this.onCopy(o),this.autoFreeze&&n.canAutoFreeze&&Object.freeze(o.copy),t&&n.patches&&z(o,t,n.patches,n.inversePatches)}return o.copy},U.prototype.finalizeTree=function(e,t,n){var r=this,o=e[a];o&&(this.useProxies||(o.copy=p(o.draft,!0)),e=o.copy);var i=!!t&&!!n.patches,c=function(a,s,f){if(s===f)throw Error("Immer forbids circular references");var p=!!o&&f===e;if(u(s)){var h=p&&i&&!o.assigned[a]?t.concat(a):null;if(u(s=r.finalize(s,h,n))&&(n.canAutoFreeze=!1),Array.isArray(f)||y(f,a)?f[a]=s:Object.defineProperty(f,a,{value:s}),p&&s===o.base[a])return}else{if(p&&m(s,o.base[a]))return;l(s)&&!Object.isFrozen(s)&&d(s,c)}p&&r.onAssign&&r.onAssign(o,a,s)};return d(e,c),e};var H=new U,B=(H.produce,H.setAutoFreeze.bind(H)),$=(H.setUseProxies.bind(H),H.applyPatches.bind(H),H.createDraft.bind(H)),q=H.finishDraft.bind(H)}).call(this,n(77))},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.default=wcmlMultiCurrency.strings},function(e,t,n){"use strict";n.d(t,"a",function(){return a});var r=n(0),o=n.n(r),i=n(110);function a(e){var t=[];return o.a.Children.forEach(e,function(e){void 0!==e&&null!==e&&(Array.isArray(e)?t=t.concat(a(e)):Object(i.isFragment)(e)&&e.props?t=t.concat(a(e.props.children)):t.push(e))}),t}},function(e,t){var n=e.exports="undefined"!=typeof window&&window.Math==Math?window:"undefined"!=typeof self&&self.Math==Math?self:Function("return this")();"number"==typeof __g&&(__g=n)},function(e,t,n){"use strict";function r(e,t){for(var n=t;n;){if(n===e)return!0;n=n.parentNode}return!1}n.d(t,"a",function(){return r})},function(e,t){var n={}.hasOwnProperty;e.exports=function(e,t){return n.call(e,t)}},function(e,t,n){e.exports=!n(35)(function(){return 7!=Object.defineProperty({},"a",{get:function(){return 7}}).a})},function(e,t){var n=e.exports={version:"2.6.11"};"number"==typeof __e&&(__e=n)},function(e,t,n){e.exports=n(108)},function(e,t,n){"use strict";n.r(t);var r=function(){return!1},o=function(){return!0},i={"@@functional/placeholder":!0};function a(e){return null!=e&&"object"==typeof e&&!0===e["@@functional/placeholder"]}function u(e){return function t(n){return 0===arguments.length||a(n)?t:e.apply(this,arguments)}}function l(e){return function t(n,r){switch(arguments.length){case 0:return t;case 1:return a(n)?t:u(function(t){return e(n,t)});default:return a(n)&&a(r)?t:a(n)?u(function(t){return e(t,r)}):a(r)?u(function(t){return e(n,t)}):e(n,r)}}}var c=l(function(e,t){return Number(e)+Number(t)});function s(e,t){var n;e=e||[],t=t||[];var r=e.length,o=t.length,i=[];for(n=0;n<r;)i[i.length]=e[n],n+=1;for(n=0;n<o;)i[i.length]=t[n],n+=1;return i}function f(e,t){switch(e){case 0:return function(){return t.apply(this,arguments)};case 1:return function(e){return t.apply(this,arguments)};case 2:return function(e,n){return t.apply(this,arguments)};case 3:return function(e,n,r){return t.apply(this,arguments)};case 4:return function(e,n,r,o){return t.apply(this,arguments)};case 5:return function(e,n,r,o,i){return t.apply(this,arguments)};case 6:return function(e,n,r,o,i,a){return t.apply(this,arguments)};case 7:return function(e,n,r,o,i,a,u){return t.apply(this,arguments)};case 8:return function(e,n,r,o,i,a,u,l){return t.apply(this,arguments)};case 9:return function(e,n,r,o,i,a,u,l,c){return t.apply(this,arguments)};case 10:return function(e,n,r,o,i,a,u,l,c,s){return t.apply(this,arguments)};default:throw new Error("First argument to _arity must be a non-negative integer no greater than ten")}}function p(e,t,n){return function(){for(var r=[],o=0,i=e,u=0;u<t.length||o<arguments.length;){var l;u<t.length&&(!a(t[u])||o>=arguments.length)?l=t[u]:(l=arguments[o],o+=1),r[u]=l,a(l)||(i-=1),u+=1}return i<=0?n.apply(this,r):f(i,p(e,r,n))}}var d=l(function(e,t){return 1===e?u(t):f(e,p(e,[],t))}),y=u(function(e){return d(e.length,function(){var t=0,n=arguments[0],r=arguments[arguments.length-1],o=Array.prototype.slice.call(arguments,0);return o[0]=function(){var e=n.apply(this,s(arguments,[t,r]));return t+=1,e},e.apply(this,o)})});function h(e){return function t(n,r,o){switch(arguments.length){case 0:return t;case 1:return a(n)?t:l(function(t,r){return e(n,t,r)});case 2:return a(n)&&a(r)?t:a(n)?l(function(t,n){return e(t,r,n)}):a(r)?l(function(t,r){return e(n,t,r)}):u(function(t){return e(n,r,t)});default:return a(n)&&a(r)&&a(o)?t:a(n)&&a(r)?l(function(t,n){return e(t,n,o)}):a(n)&&a(o)?l(function(t,n){return e(t,r,n)}):a(r)&&a(o)?l(function(t,r){return e(n,t,r)}):a(n)?u(function(t){return e(t,r,o)}):a(r)?u(function(t){return e(n,t,o)}):a(o)?u(function(t){return e(n,r,t)}):e(n,r,o)}}}var m=h(function(e,t,n){if(e>=n.length||e<-n.length)return n;var r=(e<0?n.length:0)+e,o=s(n);return o[r]=t(n[r]),o}),v=Array.isArray||function(e){return null!=e&&e.length>=0&&"[object Array]"===Object.prototype.toString.call(e)};function b(e){return null!=e&&"function"==typeof e["@@transducer/step"]}function g(e,t,n){return function(){if(0===arguments.length)return n();var r=Array.prototype.slice.call(arguments,0),o=r.pop();if(!v(o)){for(var i=0;i<e.length;){if("function"==typeof o[e[i]])return o[e[i]].apply(o,r);i+=1}if(b(o))return t.apply(null,r)(o)}return n.apply(this,arguments)}}function w(e){return e&&e["@@transducer/reduced"]?e:{"@@transducer/value":e,"@@transducer/reduced":!0}}var O={init:function(){return this.xf["@@transducer/init"]()},result:function(e){return this.xf["@@transducer/result"](e)}},E=function(){function e(e,t){this.xf=t,this.f=e,this.all=!0}return e.prototype["@@transducer/init"]=O.init,e.prototype["@@transducer/result"]=function(e){return this.all&&(e=this.xf["@@transducer/step"](e,!0)),this.xf["@@transducer/result"](e)},e.prototype["@@transducer/step"]=function(e,t){return this.f(t)||(this.all=!1,e=w(this.xf["@@transducer/step"](e,!1))),e},e}(),S=l(g(["all"],l(function(e,t){return new E(e,t)}),function(e,t){for(var n=0;n<t.length;){if(!e(t[n]))return!1;n+=1}return!0})),_=l(function(e,t){return t>e?t:e});function P(e,t){for(var n=0,r=t.length,o=Array(r);n<r;)o[n]=e(t[n]),n+=1;return o}function x(e){return"[object String]"===Object.prototype.toString.call(e)}var j=u(function(e){return!!v(e)||!!e&&("object"==typeof e&&(!x(e)&&(1===e.nodeType?!!e.length:0===e.length||e.length>0&&(e.hasOwnProperty(0)&&e.hasOwnProperty(e.length-1)))))}),C=function(){function e(e){this.f=e}return e.prototype["@@transducer/init"]=function(){throw new Error("init not implemented on XWrap")},e.prototype["@@transducer/result"]=function(e){return e},e.prototype["@@transducer/step"]=function(e,t){return this.f(e,t)},e}();function k(e){return new C(e)}var T=l(function(e,t){return f(e.length,function(){return e.apply(t,arguments)})});function M(e,t,n){for(var r=n.next();!r.done;){if((t=e["@@transducer/step"](t,r.value))&&t["@@transducer/reduced"]){t=t["@@transducer/value"];break}r=n.next()}return e["@@transducer/result"](t)}function A(e,t,n,r){return e["@@transducer/result"](n[r](T(e["@@transducer/step"],e),t))}var N="undefined"!=typeof Symbol?Symbol.iterator:"@@iterator";function R(e,t,n){if("function"==typeof e&&(e=k(e)),j(n))return function(e,t,n){for(var r=0,o=n.length;r<o;){if((t=e["@@transducer/step"](t,n[r]))&&t["@@transducer/reduced"]){t=t["@@transducer/value"];break}r+=1}return e["@@transducer/result"](t)}(e,t,n);if("function"==typeof n["fantasy-land/reduce"])return A(e,t,n,"fantasy-land/reduce");if(null!=n[N])return M(e,t,n[N]());if("function"==typeof n.next)return M(e,t,n);if("function"==typeof n.reduce)return A(e,t,n,"reduce");throw new TypeError("reduce: list must be array or iterable")}var D=function(){function e(e,t){this.xf=t,this.f=e}return e.prototype["@@transducer/init"]=O.init,e.prototype["@@transducer/result"]=O.result,e.prototype["@@transducer/step"]=function(e,t){return this.xf["@@transducer/step"](e,this.f(t))},e}(),I=l(function(e,t){return new D(e,t)});function F(e,t){return Object.prototype.hasOwnProperty.call(t,e)}var L=Object.prototype.toString,z=function(){return"[object Arguments]"===L.call(arguments)?function(e){return"[object Arguments]"===L.call(e)}:function(e){return F("callee",e)}}(),V=!{toString:null}.propertyIsEnumerable("toString"),W=["constructor","valueOf","isPrototypeOf","toString","propertyIsEnumerable","hasOwnProperty","toLocaleString"],U=function(){return arguments.propertyIsEnumerable("length")}(),H=function(e,t){for(var n=0;n<e.length;){if(e[n]===t)return!0;n+=1}return!1},B="function"!=typeof Object.keys||U?u(function(e){if(Object(e)!==e)return[];var t,n,r=[],o=U&&z(e);for(t in e)!F(t,e)||o&&"length"===t||(r[r.length]=t);if(V)for(n=W.length-1;n>=0;)F(t=W[n],e)&&!H(r,t)&&(r[r.length]=t),n-=1;return r}):u(function(e){return Object(e)!==e?[]:Object.keys(e)}),$=l(g(["fantasy-land/map","map"],I,function(e,t){switch(Object.prototype.toString.call(t)){case"[object Function]":return d(t.length,function(){return e.call(this,t.apply(this,arguments))});case"[object Object]":return R(function(n,r){return n[r]=e(t[r]),n},{},B(t));default:return P(e,t)}})),q=Number.isInteger||function(e){return e<<0===e},K=l(function(e,t){var n=e<0?t.length+e:e;return x(t)?t.charAt(n):t[n]}),Y=l(function(e,t){return e.map(function(e){for(var n,r=t,o=0;o<e.length;){if(null==r)return;n=e[o],r=q(n)?K(n,r):r[n],o+=1}return r})}),X=l(function(e,t){return Y([e],t)[0]}),G=l(function(e,t){return X([e],t)}),Q=l(function(e,t){return $(G(e),t)}),J=h(R),Z=u(function(e){return d(J(_,0,Q("length",e)),function(){for(var t=0,n=e.length;t<n;){if(!e[t].apply(this,arguments))return!1;t+=1}return!0})}),ee=u(function(e){return function(){return e}}),te=l(function(e,t){return e&&t}),ne=function(){function e(e,t){this.xf=t,this.f=e,this.any=!1}return e.prototype["@@transducer/init"]=O.init,e.prototype["@@transducer/result"]=function(e){return this.any||(e=this.xf["@@transducer/step"](e,!1)),this.xf["@@trans
|