WooCommerce Multilingual – run WooCommerce with WPML - Version 4.4.0

Version Description

  • Added the ability to associate BACS accounts with currencies
  • Fix and removed duplicated entries in code
  • Hide reviews in other languages link, if there are no reviews in product
  • Update WCML Logo
  • Added support for wpml endpoints
  • Removed Product Type Column from WCML backend and added compatibility with the WC Product Type Column plugin
  • Fix low_stock_amount not synchronized to translations
  • Fix custom attribute with number in name not appears to translation in Translation editor
  • Fix not applied price rule for WooCommerce Table Rate Shipping in second currency
  • Fix translated custom field wrongly saved to translation if contains array of strings
  • Endless loop when using troubleshooting action to duplicate terms
  • Fixed an issue with Elementor PRO products block showing all categories in the translated page.
  • Fixed Xliff doesn't contains variation descriptions for WooCommerce Subscriptions
  • Fixed compatibility issue with Flatsome theme
  • Fix issue with custom product attribute title when trying to upload translation with XLIFF file
  • Fixed cart validate for specific situations
  • Added filter for translated package rates
  • Added WPML switcher buttons library for Multi Currency in backend
  • Fix loading Jquery to any place in code and in header
  • Added fix for variation product "become" out-of-stock when translating using native screen
  • Removed backward compatibility filters for terms synchronization
  • Fixed attribute slug language always set to English
  • Wrong path in Bookings compatibility class
  • Fixed a fatal error occuring with older versions of WooCommerce (3.3.5)
  • Fixed confirming order as complete from the order edit screen, does not decrement the second language stock qty
  • Product category data always synchronizes on save of the translation and does not respect WPML option to sync taxonomies
  • Fixed call to undefined method WPML_URL_Filters::remove_global_hooks with WPML < 3.6.0
  • Fixed compatibility class name for wc product addons
  • Fixed manual order creation does not respect manual prices
  • Fix email language for the order as complete emails
  • Fixed Composite Products compatibility - Price not rounding to the nearest integer
  • Fixed missing custom attribute in XLIFF file / Pro Translation
  • Fix Endpoint error to prevent 404 in some cases
  • Fixed accepted arguments for terms_clause
  • Resolved an exception causing an error message in the cart in some setups
  • Fixed missed synchronization of 'outofstock' visibility term between product translations
  • Fix broken logic with Table Rate Shipping when product uses class with "break and abort" rule
  • Custom attributes terms not copied to diplicated translation after update values in original
  • WP Fastest Cache compatibility - fixed currency switcher problem
  • Added ability to set custom prices for secondary currencies in WC Product Add-Ons
  • Update minimum requirements
Download this release

Release Info

Developer sergey.r
Plugin Icon 128x128 WooCommerce Multilingual – run WooCommerce with WPML
Version 4.4.0
Comparing to
See all releases

Code changes from version 4.3.7 to 4.4.0

Files changed (241) hide show
  1. changelog/4.2.0.md +3 -0
  2. changelog/4.2.1.1.md +0 -2
  3. changelog/4.2.1.md +2 -0
  4. changelog/4.2.10.md +2 -1
  5. changelog/4.2.2.md +1 -5
  6. changelog/4.3.3.md +1 -0
  7. changelog/4.3.7.md +0 -2
  8. changelog/4.4.0.md +44 -0
  9. classes/class-woocommerce-wpml.php +23 -38
  10. classes/currencies/class-wcml-admin-currency-selector.php +13 -18
  11. classes/multi-currency/exchange-rate-services/class-wcml-exchange-rates-currencylayer.php +1 -3
  12. classes/multi-currency/exchange-rate-services/class-wcml-exchange-rates-fixerio.php +1 -3
  13. classes/multi-currency/payment-gateways/class-wcml-currencies-payment-gateways.php +185 -0
  14. classes/multi-currency/payment-gateways/class-wcml-not-supported-payment-gateway.php +23 -0
  15. classes/multi-currency/payment-gateways/class-wcml-payment-gateway-bacs.php +59 -0
  16. classes/multi-currency/payment-gateways/class-wcml-payment-gateway-paypal.php +117 -0
  17. classes/multi-currency/payment-gateways/class-wcml-payment-gateway-stripe.php +109 -0
  18. classes/multi-currency/payment-gateways/class-wcml-payment-gateway.php +122 -0
  19. classes/rest-api-support/class-wcml-rest-api-support-v1.php +0 -326
  20. classes/rest-api-support/class-wcml-rest-api-support.php +58 -20
  21. classes/rest-api-support/class-wcml-rest-api.php +1 -1
  22. classes/rest-api-support/filters/class-wcml-rest-api-query-filters-terms.php +1 -1
  23. classes/shortcodes/class-wcml-wc-shortcode-product-category.php +3 -3
  24. classes/wcml-setup/class-wcml-setup.php +13 -15
  25. compatibility/class-wcml-adventure-tours.php +2 -2
  26. compatibility/class-wcml-bookings.php +24 -48
  27. compatibility/class-wcml-composite-products.php +9 -3
  28. compatibility/class-wcml-dynamic-pricing.php +1 -1
  29. compatibility/class-wcml-flatsome.php +4 -3
  30. compatibility/class-wcml-pip.php +1 -1
  31. compatibility/class-wcml-product-addons.php +322 -34
  32. compatibility/class-wcml-product-bundles-legacy.php +0 -436
  33. compatibility/class-wcml-product-bundles.php +1 -1
  34. compatibility/class-wcml-tab-manager.php +1 -4
  35. compatibility/class-wcml-table-rate-shipping.php +8 -7
  36. compatibility/class-wcml-wc-memberships.php +3 -2
  37. compatibility/class-wcml-wc-product-type-column.php +18 -0
  38. compatibility/class-wcml-wc-subscriptions.php +15 -0
  39. compatibility/class-wcml-wpfastest-cache.php +29 -0
  40. compatibility/res/css/wcml-product-addons.css +34 -0
  41. compatibility/res/js/wcml-product-addons.js +93 -0
  42. compatibility/res/js/wcml-product-addons.min.js +1 -0
  43. inc/admin-menus/class-wcml-admin-menus.php +2 -2
  44. inc/class-wcml-ajax-setup.php +1 -62
  45. inc/class-wcml-attributes.php +37 -54
  46. inc/class-wcml-cart.php +56 -58
  47. inc/class-wcml-comments.php +25 -23
  48. inc/class-wcml-compatibility.php +22 -15
  49. inc/class-wcml-coupons.php +1 -6
  50. inc/class-wcml-dependencies.php +4 -37
  51. inc/class-wcml-emails.php +26 -18
  52. inc/class-wcml-endpoints-legacy.php +301 -0
  53. inc/class-wcml-endpoints.php +217 -292
  54. inc/class-wcml-fix-copied-custom-fields-wpml353.php +0 -40
  55. inc/class-wcml-languages-upgrader.php +4 -11
  56. inc/class-wcml-orders.php +11 -6
  57. inc/class-wcml-products.php +45 -81
  58. inc/class-wcml-resources.php +17 -23
  59. inc/class-wcml-store-pages.php +21 -39
  60. inc/class-wcml-terms.php +20 -29
  61. inc/class-wcml-tp-support.php +240 -228
  62. inc/class-wcml-troubleshooting.php +36 -34
  63. inc/class-wcml-url-translation.php +42 -49
  64. inc/class-wcml-wc-gateways.php +33 -0
  65. inc/class-wcml-wc-shipping.php +17 -33
  66. inc/class-wcml-wc-strings.php +3 -3
  67. inc/class-wcml-woocommerce-rest-api-support.php +0 -414
  68. inc/currencies/class-wcml-custom-prices.php +15 -24
  69. inc/currencies/class-wcml-multi-currency-configuration.php +13 -0
  70. inc/currencies/class-wcml-multi-currency-orders.php +7 -5
  71. inc/currencies/class-wcml-multi-currency-prices.php +53 -8
  72. inc/currencies/class-wcml-multi-currency-shipping-legacy.php +0 -58
  73. inc/currencies/class-wcml-multi-currency-shipping.php +4 -9
  74. inc/currencies/class-wcml-multi-currency.php +9 -2
  75. inc/currencies/currency-switcher/class-wcml-currency-switcher-templates.php +1 -1
  76. inc/template-classes/class-wcml-currencies-dropdown-ui.php +29 -0
  77. inc/template-classes/class-wcml-plugins-wrap.php +4 -7
  78. inc/template-classes/class-wcml-products-ui.php +21 -7
  79. inc/template-classes/class-wcml-troubleshooting-ui.php +6 -2
  80. inc/template-classes/multi-currency/class-wcml-custom-currency-options.php +19 -8
  81. inc/template-classes/multi-currency/class-wcml-multi-currency-ui.php +23 -23
  82. inc/template-classes/status/class-wcml-status-config-warnings-ui.php +22 -30
  83. inc/template-classes/store-urls/class-wcml-store-urls-edit-base-ui.php +1 -1
  84. inc/template-classes/store-urls/class-wcml-store-urls-translation-statuses-ui.php +1 -1
  85. inc/template-classes/store-urls/class-wcml-store-urls-ui.php +4 -1
  86. inc/translation-editor/class-wcml-downloadable-products.php +2 -2
  87. inc/translation-editor/class-wcml-editor-ui-product-job.php +23 -19
  88. inc/translation-editor/class-wcml-synchronize-product-data.php +152 -186
  89. inc/translation-editor/class-wcml-synchronize-variations-data.php +2 -2
  90. inc/translation-editor/class-wcml-translation-editor.php +2 -2
  91. inc/translation-editor/class-wcml-wc-admin-duplicate-product.php +5 -15
  92. inc/woocommerce-functions-wrapper.php +0 -91
  93. locale/woocommerce-multilingual-ar.mo +0 -0
  94. locale/woocommerce-multilingual-de_DE.mo +0 -0
  95. locale/woocommerce-multilingual-el.mo +0 -0
  96. locale/woocommerce-multilingual-es_ES.mo +0 -0
  97. locale/woocommerce-multilingual-fr_FR.mo +0 -0
  98. locale/woocommerce-multilingual-he_IL.mo +0 -0
  99. locale/woocommerce-multilingual-it_IT.mo +0 -0
  100. locale/woocommerce-multilingual-ja.mo +0 -0
  101. locale/woocommerce-multilingual-ko_KR.mo +0 -0
  102. locale/woocommerce-multilingual-nl_NL.mo +0 -0
  103. locale/woocommerce-multilingual-pl_PL.mo +0 -0
  104. locale/woocommerce-multilingual-pt_BR.mo +0 -0
  105. locale/woocommerce-multilingual-pt_PT.mo +0 -0
  106. locale/woocommerce-multilingual-ru_RU.mo +0 -0
  107. locale/woocommerce-multilingual-sv_SE.mo +0 -0
  108. locale/woocommerce-multilingual-uk.mo +0 -0
  109. locale/woocommerce-multilingual-uk_UA.mo +0 -0
  110. locale/woocommerce-multilingual-vi.mo +0 -0
  111. locale/woocommerce-multilingual-zh_CN.mo +0 -0
  112. locale/woocommerce-multilingual-zh_TW.mo +0 -0
  113. readme.txt +77 -11
  114. res/css/currency-switcher.css +1 -1
  115. res/css/dialogs.css +1 -1
  116. res/css/management.css +1 -1
  117. res/css/wcml-setup.css +1 -1
  118. res/images/banner-772x120.png +0 -0
  119. res/js/bacs-accounts-currencies.js +20 -0
  120. res/js/bacs-accounts-currencies.min.js +1 -0
  121. res/js/dialogs.js +13 -7
  122. res/js/dialogs.min.js +1 -1
  123. res/js/multi-currency.js +73 -14
  124. res/js/multi-currency.min.js +1 -1
  125. res/js/tooltip_init.min.js +1 -1
  126. res/js/trnsl_interface_dialog_warning.js +2 -1
  127. res/js/trnsl_interface_dialog_warning.min.js +1 -1
  128. templates/compatibility/product-addons-prices-dialog.twig +29 -0
  129. templates/compatibility/product-addons-prices-settings.twig +22 -0
  130. templates/multi-currency/currencies-dropdown.twig +5 -0
  131. templates/multi-currency/custom-currency-options.twig +15 -1
  132. templates/multi-currency/multi-currency.twig +127 -117
  133. templates/multi-currency/payment-gateways/bacs.twig +20 -0
  134. templates/multi-currency/payment-gateways/not-supported.twig +4 -0
  135. templates/multi-currency/payment-gateways/paypal.twig +14 -0
  136. templates/multi-currency/payment-gateways/stripe.twig +17 -0
  137. templates/plugins-wrap.twig +0 -13
  138. templates/products-list/products.twig +12 -9
  139. templates/troubleshooting.twig +2 -2
  140. vendor/autoload.php +1 -1
  141. vendor/autoload_52.php +1 -1
  142. vendor/composer/ClassLoader.php +1 -1
  143. vendor/composer/autoload_classmap.php +10 -294
  144. vendor/composer/autoload_files.php +10 -0
  145. vendor/composer/autoload_real.php +22 -4
  146. vendor/composer/autoload_real_52.php +5 -3
  147. vendor/composer/autoload_static.php +19 -299
  148. vendor/composer/installers/README.md +221 -0
  149. vendor/jakeasmith/http_build_url/LICENSE +21 -0
  150. vendor/jakeasmith/http_build_url/src/http_build_url.php +174 -0
  151. vendor/otgs/installer/Makefile +83 -0
  152. vendor/otgs/installer/README.md +61 -0
  153. vendor/otgs/installer/dist/css/component-settings-reports/styles.css +1 -0
  154. vendor/otgs/installer/dist/css/otgs-installer-support/styles.css +1 -0
  155. vendor/otgs/installer/dist/css/ui/styles.css +0 -1
  156. vendor/otgs/installer/dist/js/component-settings-reports/app.js +1 -0
  157. vendor/otgs/installer/dist/js/otgs-installer-support/app.js +1 -0
  158. vendor/otgs/installer/dist/js/ui/app.js +0 -1
  159. vendor/otgs/installer/includes/buy-url/class-otgs-installer-buy-url-hooks.php +25 -0
  160. vendor/otgs/installer/includes/class-installer-dependencies.php +32 -0
  161. vendor/otgs/installer/includes/class-otgs-installer-autoloader.php +20 -0
  162. vendor/otgs/installer/includes/class-otgs-installer-debug-info.php +43 -0
  163. vendor/otgs/installer/includes/class-otgs-installer-factory.php +211 -14
  164. vendor/otgs/installer/includes/class-otgs-installer-icons.php +18 -6
  165. vendor/otgs/installer/includes/class-otgs-installer-loader.php +32 -0
  166. vendor/otgs/installer/includes/class-otgs-installer-package-product-finder.php +32 -0
  167. vendor/otgs/installer/includes/class-otgs-installer-package-product.php +93 -0
  168. vendor/otgs/installer/includes/class-otgs-installer-package.php +81 -0
  169. vendor/otgs/installer/includes/class-otgs-installer-plugin-factory.php +13 -0
  170. vendor/otgs/installer/includes/class-otgs-installer-plugin-finder.php +144 -0
  171. vendor/otgs/installer/includes/class-otgs-installer-plugin.php +141 -0
  172. vendor/otgs/installer/includes/class-otgs-installer-plugins-page-notice.php +44 -11
  173. vendor/otgs/installer/includes/class-otgs-installer-plugins-update-cache-cleaner.php +12 -0
  174. vendor/otgs/installer/includes/class-otgs-installer-source-factory.php +12 -0
  175. vendor/otgs/installer/includes/class-otgs-installer-source.php +19 -0
  176. vendor/otgs/installer/includes/class-otgs-installer-subscription-factory.php +8 -0
  177. vendor/otgs/installer/includes/class-otgs-installer-subscription.php +55 -10
  178. vendor/otgs/installer/includes/class-otgs-installer-wp-components-setting-resources.php +11 -17
  179. vendor/otgs/installer/includes/class-otgs-installer-wp-share-local-components-setting-hooks.php +11 -8
  180. vendor/otgs/installer/includes/class-translation-service-info.php +2 -3
  181. vendor/otgs/installer/includes/class-wp-installer.php +270 -200
  182. vendor/otgs/installer/includes/debug/class-otgs-installer-log-factory.php +11 -0
  183. vendor/otgs/installer/includes/debug/class-otgs-installer-log.php +95 -0
  184. vendor/otgs/installer/includes/debug/class-otgs-installer-logger-storage.php +85 -0
  185. vendor/otgs/installer/includes/debug/class-otgs-installer-logger.php +29 -0
  186. vendor/otgs/installer/includes/exceptions/class-otgs-installer-fetch-subscription-exception.php +5 -0
  187. vendor/otgs/installer/includes/exceptions/class-otgs-installer-site-key-exception.php +4 -0
  188. vendor/otgs/installer/includes/instances/class-otgs-installer-instance.php +92 -0
  189. vendor/otgs/installer/includes/instances/class-otgs-installer-instances-factory.php +10 -0
  190. vendor/otgs/installer/includes/instances/class-otgs-installer-instances.php +32 -0
  191. vendor/otgs/installer/includes/otgs-installer-autoload-classmap.php +66 -0
  192. vendor/otgs/installer/includes/repository/class-otgs-installer-repositories-factory.php +8 -0
  193. vendor/otgs/installer/includes/repository/class-otgs-installer-repositories.php +130 -0
  194. vendor/otgs/installer/includes/repository/class-otgs-installer-repository-factory.php +16 -0
  195. vendor/otgs/installer/includes/repository/class-otgs-installer-repository.php +114 -0
  196. vendor/otgs/installer/includes/site-key/class-otgs-installer-fetch-subscription.php +197 -0
  197. vendor/otgs/installer/includes/site-key/class-otgs-installer-site-key-ajax.php +133 -0
  198. vendor/otgs/installer/includes/support/class-otgs-installer-connection-test-ajax.php +37 -0
  199. vendor/otgs/installer/includes/support/class-otgs-installer-connection-test-exception.php +5 -0
  200. vendor/otgs/installer/includes/support/class-otgs-installer-connection-test.php +131 -0
  201. vendor/otgs/installer/includes/support/class-otgs-installer-requirements.php +27 -0
  202. vendor/otgs/installer/includes/support/class-otgs-installer-support-hooks.php +42 -0
  203. vendor/otgs/installer/includes/support/class-otgs-installer-support-template-factory.php +28 -0
  204. vendor/otgs/installer/includes/support/class-otgs-installer-support-template.php +131 -0
  205. vendor/otgs/installer/{templates → includes}/template-service/class-otgs-installer-twig-template-service-loader.php +0 -0
  206. vendor/otgs/installer/{templates → includes}/template-service/class-otgs-installer-twig-template-service.php +0 -0
  207. vendor/otgs/installer/{templates → includes}/template-service/interface-iotgs-installer-template-service.php +0 -0
  208. vendor/otgs/installer/includes/upgrade/class-otgs-installer-upgrade-response.php +166 -0
  209. vendor/otgs/installer/installer.php +5 -46
  210. vendor/otgs/installer/loader.php +8 -10
  211. vendor/otgs/installer/locale/{installer-uk_UA.mo → installer-uk.mo} +0 -0
  212. vendor/otgs/installer/phpcs.compatibility.xml +19 -0
  213. vendor/otgs/installer/phpcs.xml +17 -0
  214. vendor/otgs/installer/phpunit.xml +24 -0
  215. vendor/otgs/installer/{src/postcss.config.js → postcss.config.js} +0 -0
  216. vendor/otgs/installer/repositories.xml +13 -0
  217. vendor/otgs/installer/res/css/admin.css +12 -1
  218. vendor/otgs/installer/res/css/tooltip/tooltip.css +0 -1
  219. vendor/otgs/installer/res/js/admin.js +5 -22
  220. vendor/otgs/installer/res/js/dismiss-nag.js +23 -0
  221. vendor/otgs/installer/res/js/iframeResizer.min.js +0 -10
  222. vendor/otgs/installer/res/js/tooltip/tooltip.js +0 -82
  223. vendor/otgs/installer/src/js/component-settings-reports/app.js +2 -0
  224. vendor/otgs/installer/src/js/otgs-installer-support/app.js +7 -0
  225. vendor/otgs/installer/src/js/otgs-installer-support/testConnection.js +66 -0
  226. vendor/otgs/installer/src/js/ui/Switcher.js +0 -44
  227. vendor/otgs/installer/src/js/ui/UI.js +0 -14
  228. vendor/otgs/installer/src/js/ui/app.js +0 -10
  229. vendor/otgs/installer/src/webpack.config.js +0 -56
  230. vendor/otgs/installer/templates/channel-selector.php +2 -2
  231. vendor/otgs/installer/templates/components-setting/commercial-tab.twig +0 -7
  232. vendor/otgs/installer/templates/components-setting/share-local-data-setting-radio.twig +1 -1
  233. vendor/otgs/installer/templates/components-setting/share-local-data-setting.twig +22 -17
  234. vendor/otgs/installer/templates/downloads-list.php +1 -1
  235. vendor/otgs/installer/templates/support/header-instance.twig +14 -0
  236. vendor/otgs/installer/templates/support/header.twig +17 -0
  237. vendor/otgs/installer/templates/support/installer-support.twig +130 -0
  238. vendor/otgs/installer/templates/support/support-link.twig +7 -0
  239. vendor/otgs/installer/webpack.config.js +82 -0
  240. wpml-config.xml +2 -1
  241. wpml-woocommerce.php +7 -9
changelog/4.2.0.md CHANGED
@@ -12,9 +12,12 @@
12
  * [wcml-2010] A fatal error occurred when using old WordPress versions (before 4.4.0) - rest_get_url_prefix didn't exist
13
  * [wcml-2009] The admin orders page was loading slower than necessary
14
  * [wcml-1997] A PHP fatal error was occurring when using the Adventure Tours extension
 
15
  * [wcml-1965] For translated products, the product variation names were displayed in the old format (before WooCommerce 3.0)
16
  * [wcml-1961] The prices in the secondary currencies for products in secondary languages for products read via the REST API were incorrect
17
  * [wcml-1960] CSS for the currency switcher was loaded when the multi-currency was not enabled
 
 
18
  * [wcml-1955] Fixed a javascript error on the shop page
19
  * [wcml-1936] It was not possible to use the clear cart feature with enabled WPML Ajax cookies only
20
  * [wcml-1934] WooCommerce Product Bundles: Bundled items filtering by variation was not synced with translations
12
  * [wcml-2010] A fatal error occurred when using old WordPress versions (before 4.4.0) - rest_get_url_prefix didn't exist
13
  * [wcml-2009] The admin orders page was loading slower than necessary
14
  * [wcml-1997] A PHP fatal error was occurring when using the Adventure Tours extension
15
+ * [wcml-1990] A product addon was added to the cart more then once in combination with Bookings
16
  * [wcml-1965] For translated products, the product variation names were displayed in the old format (before WooCommerce 3.0)
17
  * [wcml-1961] The prices in the secondary currencies for products in secondary languages for products read via the REST API were incorrect
18
  * [wcml-1960] CSS for the currency switcher was loaded when the multi-currency was not enabled
19
+ * [wcml-1959] Visual Composer field value not updated in WooCommerce Multilingual translation editor after update original
20
+ * [wcml-1957] Wrong count of not translated products on WooCommerce Multilingual Status tab
21
  * [wcml-1955] Fixed a javascript error on the shop page
22
  * [wcml-1936] It was not possible to use the clear cart feature with enabled WPML Ajax cookies only
23
  * [wcml-1934] WooCommerce Product Bundles: Bundled items filtering by variation was not synced with translations
changelog/4.2.1.1.md DELETED
@@ -1,2 +0,0 @@
1
- # Fixes
2
- * [wcml-2109] WC Subscriptions compatibility error
 
 
changelog/4.2.1.md CHANGED
@@ -7,6 +7,7 @@
7
  * [wcml-2098] Missing Woocommerce pages were created in default language
8
  * [wcml-2085] Fatal error while custom call not active currency switcher template
9
  * [wcml-2075] Duplicating from WooCommerce resulted in losing language data for the original product
 
10
  * [wcml-2064] PHP errors were shown on the admin dashboard when no orders existed and displaying errors was on
11
  * [wcml-2061] A fatal error (undefiend get_current_screen) was occurring in some conditions on the WP admin side
12
  * [wcml-2059] Cart widget shows wrong product names
@@ -25,4 +26,5 @@
25
  * [wcml-2007] Checkout Field Editor compatibility fix
26
  * [wcml-2006] Fixed issue with displaying custom prices in Bundles Products
27
  * [wcml-2004] Add filter for 'woocommerce_subscriptions_product_price'
 
28
  * [wcml-1978] The `wcml_raw_price_amount` filter could not be used to convert to a different currency than the current user currency
7
  * [wcml-2098] Missing Woocommerce pages were created in default language
8
  * [wcml-2085] Fatal error while custom call not active currency switcher template
9
  * [wcml-2075] Duplicating from WooCommerce resulted in losing language data for the original product
10
+ * [wcml-2074] Coupon with category restriction removed when switching language on cart page
11
  * [wcml-2064] PHP errors were shown on the admin dashboard when no orders existed and displaying errors was on
12
  * [wcml-2061] A fatal error (undefiend get_current_screen) was occurring in some conditions on the WP admin side
13
  * [wcml-2059] Cart widget shows wrong product names
26
  * [wcml-2007] Checkout Field Editor compatibility fix
27
  * [wcml-2006] Fixed issue with displaying custom prices in Bundles Products
28
  * [wcml-2004] Add filter for 'woocommerce_subscriptions_product_price'
29
+ * [wcml-2003] Fixed compatibi;ity issue with coupos not applied correctly in a subscription product
30
  * [wcml-1978] The `wcml_raw_price_amount` filter could not be used to convert to a different currency than the current user currency
changelog/4.2.10.md CHANGED
@@ -15,4 +15,5 @@
15
  * [wcml-2307] WooCommerce Bookings : Fix Block cost recalculation in second currency
16
  * [wcml-2306] Added filter for oder_item_quantity
17
  * [wcml-2305] Fix issue in endpoints when set My Account as homepage
18
- * [wcml-2302] WooCommerce Dynamic Pricing: Fix Order total rules by category
 
15
  * [wcml-2307] WooCommerce Bookings : Fix Block cost recalculation in second currency
16
  * [wcml-2306] Added filter for oder_item_quantity
17
  * [wcml-2305] Fix issue in endpoints when set My Account as homepage
18
+ * [wcml-2302] WooCommerce Dynamic Pricing: Fix Order total rules by category
19
+ * [wcml-2282] Relevanssi compatibility - add missing terms for translated product
changelog/4.2.2.md CHANGED
@@ -1,8 +1,3 @@
1
- # Features
2
- * [wcml-2120] Added a filter to include links to the String Translation table for custom options/settings in Woocommerce Gateway settings panel
3
- * [wcml-2119] Added logic to display a warning in the back-end when built in taxonomies translation status (set to 'translate') is overridden
4
- * [wcml-1484] Added the ability to translate the currency switcher format in String Translation
5
-
6
  # Fixes
7
  * [wcml-2137] My account Bookings list page displays bookings in all languages
8
  * [wcml-2134] Updating variable product does not refresh product visibility terms
@@ -12,6 +7,7 @@
12
  * [wcml-2116] When updating a translation, the product translation slug was overwritten if product contains page builders fields
13
  * [wcml-2115] The 'reset password' form in a secondary language pointed to a 404 error
14
  * [wcml-2114] "product/%product_cat%" product permalink doesn't work for products without category assigned in second language if "Uncategorized" string not translated in String Translation module
 
15
  * [wcml-2107] It was not possible to set the custom price value in secondary currencies as '0'
16
  * [wcml-2090] It was not possible to translate attribute slugs if the attributes base was not translated
17
  * [wcml-2086] Currency switcher styles were not loaded when using only a shortcode currency switcher
 
 
 
 
 
1
  # Fixes
2
  * [wcml-2137] My account Bookings list page displays bookings in all languages
3
  * [wcml-2134] Updating variable product does not refresh product visibility terms
7
  * [wcml-2116] When updating a translation, the product translation slug was overwritten if product contains page builders fields
8
  * [wcml-2115] The 'reset password' form in a secondary language pointed to a 404 error
9
  * [wcml-2114] "product/%product_cat%" product permalink doesn't work for products without category assigned in second language if "Uncategorized" string not translated in String Translation module
10
+ * [wcml-2109] WC Subscriptions compatibility error
11
  * [wcml-2107] It was not possible to set the custom price value in secondary currencies as '0'
12
  * [wcml-2090] It was not possible to translate attribute slugs if the attributes base was not translated
13
  * [wcml-2086] Currency switcher styles were not loaded when using only a shortcode currency switcher
changelog/4.3.3.md CHANGED
@@ -1,5 +1,6 @@
1
  # Fixes
2
  * [wcml-2464] Fixed small issue in WC Bookings where block cost in other currencies is not saved correctly
 
3
  * [wcml-2456] Fix compatibility issue with WC Product Addons and not displayed label in secondary language
4
  * [wcml-2455] Return back duplication logic for product image and gallery
5
  * [wcml-2453] Fix warning in secondary language if you don't have any wc pages
1
  # Fixes
2
  * [wcml-2464] Fixed small issue in WC Bookings where block cost in other currencies is not saved correctly
3
+ * [wcml-2462] Fix an error due to a bug in upgrade logic
4
  * [wcml-2456] Fix compatibility issue with WC Product Addons and not displayed label in secondary language
5
  * [wcml-2455] Return back duplication logic for product image and gallery
6
  * [wcml-2453] Fix warning in secondary language if you don't have any wc pages
changelog/4.3.7.md CHANGED
@@ -1,6 +1,4 @@
1
  # Fixes
2
- * [wcml-2566] Fix broken logic with Table Rate Shipping when product uses class with "break and abort" rule
3
- * [wcml-2550] Custom attributes terms not copied to diplicated translation after update values in original
4
  * [wcml-2549] Fixed issue which was changing the current language of the site when saving an order
5
  * [wcml-2547] Better compatibility class for LiteSpeed Cache that doesn't require changing the URL
6
  * [wcml-2541] Fixed issue with serialized data in term meta table
1
  # Fixes
 
 
2
  * [wcml-2549] Fixed issue which was changing the current language of the site when saving an order
3
  * [wcml-2547] Better compatibility class for LiteSpeed Cache that doesn't require changing the URL
4
  * [wcml-2541] Fixed issue with serialized data in term meta table
changelog/4.4.0.md ADDED
@@ -0,0 +1,44 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Features
2
+ * [wcml-436] Added the ability to associate BACS accounts with currencies
3
+ * [wcml-2641] Fix and removed duplicated entries in code
4
+ * [wcml-2625] Hide reviews in other languages link, if there are no reviews in product
5
+ * [wcml-2594] Update WCML Logo
6
+ * [wcml-2539] Added support for wpml endpoints
7
+ * [wcml-2375] Removed Product Type Column from WCML backend and added compatibility with the WC Product Type Column plugin
8
+
9
+ # Fixes
10
+ * [wcml-2647] Fix low_stock_amount not synchronized to translations
11
+ * [wcml-2646] Fix custom attribute with number in name not appears to translation in Translation editor
12
+ * [wcml-2644] Fix not applied price rule for WooCommerce Table Rate Shipping in second currency
13
+ * [wcml-2640] Fix translated custom field wrongly saved to translation if contains array of strings
14
+ * [wcml-2639] Endless loop when using troubleshooting action to duplicate terms
15
+ * [wcml-2634] Fixed an issue with Elementor PRO products block showing all categories in the translated page.
16
+ * [wcml-2633] Fixed Xliff doesn't contains variation descriptions for WooCommerce Subscriptions
17
+ * [wcml-2630] Fixed compatibility issue with Flatsome theme
18
+ * [wcml-2628] Fix issue with custom product attribute title when trying to upload translation with XLIFF file
19
+ * [wcml-2627] Fixed cart validate for specific situations
20
+ * [wcml-2618] Added filter for translated package rates
21
+ * [wcml-2616] Added WPML switcher buttons library for Multi Currency in backend
22
+ * [wcml-2614] Fix loading Jquery to any place in code and in header
23
+ * [wcml-2608] Added fix for variation product "become" out-of-stock when translating using native screen
24
+ * [wcml-2607] Removed backward compatibility filters for terms synchronization
25
+ * [wcml-2605] Fixed attribute slug language always set to English
26
+ * [wcml-2604] Wrong path in Bookings compatibility class
27
+ * [wcml-2602] Fixed a fatal error occuring with older versions of WooCommerce (3.3.5)
28
+ * [wcml-2600] Fixed confirming order as complete from the order edit screen, does not decrement the second language stock qty
29
+ * [wcml-2599] Product category data always synchronizes on save of the translation and does not respect WPML option to sync taxonomies
30
+ * [wcml-2592] Fixed call to undefined method WPML_URL_Filters::remove_global_hooks with WPML < 3.6.0
31
+ * [wcml-2590] Fixed compatibility class name for wc product addons
32
+ * [wcml-2589] Fixed manual order creation does not respect manual prices
33
+ * [wcml-2587] Fix email language for the order as complete emails
34
+ * [wcml-2585] Fixed Composite Products compatibility - Price not rounding to the nearest integer
35
+ * [wcml-2576] Fixed missing custom attribute in XLIFF file / Pro Translation
36
+ * [wcml-2575] Fix Endpoint error to prevent 404 in some cases
37
+ * [wcml-2574] Fixed accepted arguments for terms_clause
38
+ * [wcml-2572] Resolved an exception causing an error message in the cart in some setups
39
+ * [wcml-2568] Fixed missed synchronization of 'outofstock' visibility term between product translations
40
+ * [wcml-2566] Fix broken logic with Table Rate Shipping when product uses class with "break and abort" rule
41
+ * [wcml-2550] Custom attributes terms not copied to diplicated translation after update values in original
42
+ * [wcml-2538] WP Fastest Cache compatibility - fixed currency switcher problem
43
+ * [wcml-2532] Added ability to set custom prices for secondary currencies in WC Product Add-Ons
44
+ * [wcml-2201] Update minimum requirements
classes/class-woocommerce-wpml.php CHANGED
@@ -86,40 +86,26 @@ class woocommerce_wpml {
86
 
87
  }
88
 
89
- private function load_rest_api(){
90
  global $sitepress, $wpdb, $wpml_query_filter, $wpml_post_translations;
91
 
92
  $WCML_REST_API = new WCML_REST_API();
93
 
94
- if ( class_exists( 'WooCommerce' ) && defined( 'WC_VERSION' ) && ! is_null( $sitepress ) ) {
95
- if ( version_compare( WC_VERSION, '2.6', '>=' ) && $WCML_REST_API->is_rest_api_request() ) {
96
- $wcml_rest_api_query_filters_products = new WCML_REST_API_Query_Filters_Products( $wpml_query_filter );
97
- $wcml_rest_api_query_filters_orders = new WCML_REST_API_Query_Filters_Orders( $wpdb );
98
- $wcml_rest_api_query_filters_terms = new WCML_REST_API_Query_Filters_Terms( $sitepress );
99
- if( 1 === $WCML_REST_API->get_api_request_version() ) {
100
- $wcml_rest_api_support = new WCML_REST_API_Support_V1(
101
- $this,
102
- $sitepress,
103
- $wcml_rest_api_query_filters_products,
104
- $wcml_rest_api_query_filters_orders,
105
- $wcml_rest_api_query_filters_terms,
106
- $wpml_post_translations
107
- );
108
- }else{
109
- $wcml_rest_api_support = new WCML_REST_API_Support(
110
- $this,
111
- $sitepress,
112
- $wpdb,
113
- $wcml_rest_api_query_filters_products,
114
- $wcml_rest_api_query_filters_orders,
115
- $wcml_rest_api_query_filters_terms,
116
- $wpml_post_translations
117
- );
118
- }
119
- $wcml_rest_api_support->add_hooks();
120
- } else {
121
- new WCML_WooCommerce_Rest_API_Support( $this, $sitepress );
122
- }
123
  }
124
  }
125
 
@@ -133,7 +119,7 @@ class woocommerce_wpml {
133
  }
134
 
135
  public function init(){
136
- global $sitepress, $wpdb, $woocommerce, $wpml_url_converter;
137
 
138
  $this->load_rest_api();
139
 
@@ -198,10 +184,10 @@ class woocommerce_wpml {
198
  $wcml_pointers->add_hooks();
199
  }
200
 
201
- $this->sync_product_data = new WCML_Synchronize_Product_Data( $this, $sitepress, $wpdb );
202
  $this->sync_product_data->add_hooks();
203
  $this->duplicate_product = new WCML_WC_Admin_Duplicate_Product( $this, $sitepress, $wpdb );
204
- $this->products = new WCML_Products( $this, $sitepress, $wpdb );
205
  $this->products->add_hooks();
206
  $this->store = new WCML_Store_Pages ($this, $sitepress ) ;
207
  $this->store->add_hooks();
@@ -211,7 +197,7 @@ class woocommerce_wpml {
211
  $this->emails->add_hooks();
212
  $this->terms = new WCML_Terms( $this, $sitepress, $wpdb );
213
  $this->terms->add_hooks();
214
- $this->attributes = new WCML_Attributes( $this, $sitepress, $wpdb );
215
  $this->attributes->add_hooks();
216
  $this->orders = new WCML_Orders( $this, $sitepress );
217
  $this->shipping = new WCML_WC_Shipping( $sitepress );
@@ -219,7 +205,8 @@ class woocommerce_wpml {
219
  $this->gateways = new WCML_WC_Gateways( $this, $sitepress );
220
  $this->url_translation = new WCML_Url_Translation ( $this, $sitepress, $wpdb );
221
  $this->url_translation->set_up();
222
- $this->endpoints = new WCML_Endpoints( $this );
 
223
  $this->requests = new WCML_Requests;
224
  $this->cart = new WCML_Cart( $this, $sitepress, $woocommerce );
225
  $this->cart->add_hooks();
@@ -236,7 +223,7 @@ class woocommerce_wpml {
236
  $this->wcml_products_screen->init();
237
  $this->cart_sync_warnings = new WCML_Cart_Sync_Warnings( $this, $sitepress );
238
  $this->cart_sync_warnings->add_hooks();
239
- $this->comments = new WCML_Comments( $this, $sitepress );
240
  $this->comments->add_hooks();
241
 
242
  $payment_method_filter = new WCML_Payment_Method_Filter();
@@ -244,8 +231,6 @@ class woocommerce_wpml {
244
 
245
  $wcml_ajax_setup = new WCML_Ajax_Setup( $sitepress );
246
  $wcml_ajax_setup->add_hooks();
247
- new WCML_Fix_Copied_Custom_Fields_WPML353();
248
-
249
  WCML_Install::initialize( $this, $sitepress );
250
 
251
  WCML_Resources::set_up_resources( $this, $sitepress );
86
 
87
  }
88
 
89
+ private function load_rest_api() {
90
  global $sitepress, $wpdb, $wpml_query_filter, $wpml_post_translations;
91
 
92
  $WCML_REST_API = new WCML_REST_API();
93
 
94
+ if ( class_exists( 'WooCommerce' ) && defined( 'WC_VERSION' ) && ! is_null( $sitepress ) && $WCML_REST_API->is_rest_api_request() ) {
95
+ $wcml_rest_api_query_filters_products = new WCML_REST_API_Query_Filters_Products( $wpml_query_filter );
96
+ $wcml_rest_api_query_filters_orders = new WCML_REST_API_Query_Filters_Orders( $wpdb );
97
+ $wcml_rest_api_query_filters_terms = new WCML_REST_API_Query_Filters_Terms( $sitepress );
98
+
99
+ $wcml_rest_api_support = new WCML_REST_API_Support(
100
+ $this,
101
+ $sitepress,
102
+ $wcml_rest_api_query_filters_products,
103
+ $wcml_rest_api_query_filters_orders,
104
+ $wcml_rest_api_query_filters_terms,
105
+ $wpml_post_translations
106
+ );
107
+
108
+ $wcml_rest_api_support->add_hooks();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
109
  }
110
  }
111
 
119
  }
120
 
121
  public function init(){
122
+ global $sitepress, $wpdb, $woocommerce, $wpml_url_converter, $wpml_post_translations, $wpml_term_translations;
123
 
124
  $this->load_rest_api();
125
 
184
  $wcml_pointers->add_hooks();
185
  }
186
 
187
+ $this->sync_product_data = new WCML_Synchronize_Product_Data( $this, $sitepress, $wpml_post_translations, $wpdb );
188
  $this->sync_product_data->add_hooks();
189
  $this->duplicate_product = new WCML_WC_Admin_Duplicate_Product( $this, $sitepress, $wpdb );
190
+ $this->products = new WCML_Products( $this, $sitepress, $wpml_post_translations, $wpdb );
191
  $this->products->add_hooks();
192
  $this->store = new WCML_Store_Pages ($this, $sitepress ) ;
193
  $this->store->add_hooks();
197
  $this->emails->add_hooks();
198
  $this->terms = new WCML_Terms( $this, $sitepress, $wpdb );
199
  $this->terms->add_hooks();
200
+ $this->attributes = new WCML_Attributes( $this, $sitepress, $wpml_post_translations, $wpml_term_translations, $wpdb );
201
  $this->attributes->add_hooks();
202
  $this->orders = new WCML_Orders( $this, $sitepress );
203
  $this->shipping = new WCML_WC_Shipping( $sitepress );
205
  $this->gateways = new WCML_WC_Gateways( $this, $sitepress );
206
  $this->url_translation = new WCML_Url_Translation ( $this, $sitepress, $wpdb );
207
  $this->url_translation->set_up();
208
+ $this->endpoints = new WCML_Endpoints( $this, $sitepress, $wpdb );
209
+ $this->endpoints->add_hooks();
210
  $this->requests = new WCML_Requests;
211
  $this->cart = new WCML_Cart( $this, $sitepress, $woocommerce );
212
  $this->cart->add_hooks();
223
  $this->wcml_products_screen->init();
224
  $this->cart_sync_warnings = new WCML_Cart_Sync_Warnings( $this, $sitepress );
225
  $this->cart_sync_warnings->add_hooks();
226
+ $this->comments = new WCML_Comments( $this, $sitepress, $wpml_post_translations );
227
  $this->comments->add_hooks();
228
 
229
  $payment_method_filter = new WCML_Payment_Method_Filter();
231
 
232
  $wcml_ajax_setup = new WCML_Ajax_Setup( $sitepress );
233
  $wcml_ajax_setup->add_hooks();
 
 
234
  WCML_Install::initialize( $this, $sitepress );
235
 
236
  WCML_Resources::set_up_resources( $this, $sitepress );
classes/currencies/class-wcml-admin-currency-selector.php CHANGED
@@ -33,15 +33,10 @@ class WCML_Admin_Currency_Selector {
33
  add_filter( 'woocommerce_currency_symbol', array( $this, 'filter_dashboard_currency_symbol' ) );
34
  }
35
 
36
- if ( 'index.php' === $pagenow && version_compare( WOOCOMMERCE_VERSION, '2.4', '<' ) ) {
37
- add_action( 'admin_footer', array( $this, 'show_dashboard_currency_selector' ) );
38
- } else {
39
- add_action( 'woocommerce_after_dashboard_status_widget', array(
40
- $this,
41
- 'show_dashboard_currency_selector'
42
- ) );
43
- }
44
-
45
  add_action( 'admin_enqueue_scripts', array( $this, 'load_js' ) );
46
  }
47
  }
@@ -57,19 +52,19 @@ class WCML_Admin_Currency_Selector {
57
  }
58
 
59
  public function load_js(){
60
- wp_enqueue_script(
61
- 'wcml-admin-currency-selector',
62
- $this->woocommerce_wpml->plugin_url() .
63
- '/res/js/admin-currency-selector' . $this->woocommerce_wpml->js_min_suffix() . '.js',
64
- array('jquery'),
65
- $this->woocommerce_wpml->version()
66
- );
 
67
  wp_localize_script( 'wcml-admin-currency-selector', 'wcml_admin_currency_selector',
68
  array(
69
  'nonce' => wp_create_nonce( self::NONCE_KEY )
70
  )
71
  );
72
-
73
  }
74
 
75
  /**
@@ -158,4 +153,4 @@ class WCML_Admin_Currency_Selector {
158
  return $currency;
159
  }
160
 
161
- }
33
  add_filter( 'woocommerce_currency_symbol', array( $this, 'filter_dashboard_currency_symbol' ) );
34
  }
35
 
36
+ add_action( 'woocommerce_after_dashboard_status_widget', array(
37
+ $this,
38
+ 'show_dashboard_currency_selector'
39
+ ) );
 
 
 
 
 
40
  add_action( 'admin_enqueue_scripts', array( $this, 'load_js' ) );
41
  }
42
  }
52
  }
53
 
54
  public function load_js(){
55
+ wp_enqueue_script(
56
+ 'wcml-admin-currency-selector',
57
+ $this->woocommerce_wpml->plugin_url() .
58
+ '/res/js/admin-currency-selector' . $this->woocommerce_wpml->js_min_suffix() . '.js',
59
+ array( 'jquery' ),
60
+ $this->woocommerce_wpml->version(),
61
+ true
62
+ );
63
  wp_localize_script( 'wcml-admin-currency-selector', 'wcml_admin_currency_selector',
64
  array(
65
  'nonce' => wp_create_nonce( self::NONCE_KEY )
66
  )
67
  );
 
68
  }
69
 
70
  /**
153
  return $currency;
154
  }
155
 
156
+ }
classes/multi-currency/exchange-rate-services/class-wcml-exchange-rates-currencylayer.php CHANGED
@@ -10,11 +10,9 @@ class WCML_Exchange_Rates_Currencylayer extends WCML_Exchange_Rate_Service {
10
  private $url = 'https://currencylayer.com/';
11
  private $api_url = 'http://apilayer.net/api/live?access_key=%s&source=%s&currencies=%s&amount=1';
12
 
13
- protected $api_key = '';
14
- protected $requires_key = true;
15
-
16
  public function __construct() {
17
  parent::__construct( $this->id, $this->name, $this->api_url, $this->url );
 
18
  }
19
 
20
  /**
10
  private $url = 'https://currencylayer.com/';
11
  private $api_url = 'http://apilayer.net/api/live?access_key=%s&source=%s&currencies=%s&amount=1';
12
 
 
 
 
13
  public function __construct() {
14
  parent::__construct( $this->id, $this->name, $this->api_url, $this->url );
15
+ $this->requires_key = true;
16
  }
17
 
18
  /**
classes/multi-currency/exchange-rate-services/class-wcml-exchange-rates-fixerio.php CHANGED
@@ -10,11 +10,9 @@ class WCML_Exchange_Rates_Fixerio extends WCML_Exchange_Rate_Service {
10
  private $url = 'http://fixer.io/';
11
  private $api_url = 'http://data.fixer.io/api/latest?access_key=%1$s&base=%2$s&symbols=%3$s';
12
 
13
- protected $api_key = '';
14
- protected $requires_key = true;
15
-
16
  public function __construct() {
17
  parent::__construct( $this->id, $this->name, $this->api_url, $this->url );
 
18
  }
19
 
20
  /**
10
  private $url = 'http://fixer.io/';
11
  private $api_url = 'http://data.fixer.io/api/latest?access_key=%1$s&base=%2$s&symbols=%3$s';
12
 
 
 
 
13
  public function __construct() {
14
  parent::__construct( $this->id, $this->name, $this->api_url, $this->url );
15
+ $this->requires_key = true;
16
  }
17
 
18
  /**
classes/multi-currency/payment-gateways/class-wcml-currencies-payment-gateways.php ADDED
@@ -0,0 +1,185 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Class WCML_Currencies_Payment_Gateways
5
+ */
6
+ class WCML_Currencies_Payment_Gateways {
7
+
8
+ const OPTION_KEY = 'wcml_custom_payment_gateways_for_currencies';
9
+ const TEMPLATE_FOLDER = '/templates/multi-currency/payment-gateways/';
10
+
11
+ private $available_gateways = array();
12
+ private $supported_gateways = array();
13
+ private $payment_gateways = array();
14
+
15
+ /** @var woocommerce_wpml */
16
+ private $woocommerce_wpml;
17
+ /** @var WPML_WP_API */
18
+ private $wp_api;
19
+
20
+ /**
21
+ * @param woocommerce_wpml $woocommerce_wpml
22
+ * @param WPML_WP_API $wp_api
23
+ */
24
+ public function __construct( woocommerce_wpml $woocommerce_wpml, WPML_WP_API $wp_api ) {
25
+ $this->woocommerce_wpml = $woocommerce_wpml;
26
+ $this->wp_api = $wp_api;
27
+ }
28
+
29
+ public function add_hooks(){
30
+ add_action( 'init', array( $this, 'init_gateways' ) );
31
+
32
+ add_filter( 'woocommerce_gateway_description', array( $this, 'filter_gateway_description' ), 10, 2 );
33
+ add_filter( 'option_woocommerce_stripe_settings', array( 'WCML_Payment_Gateway_Stripe', 'filter_stripe_settings' ) );
34
+ }
35
+
36
+ /**
37
+ * @param string $currency
38
+ *
39
+ * @return bool
40
+ */
41
+ public function is_enabled( $currency ) {
42
+
43
+ $gateway_enabled_settings = $this->get_settings();
44
+
45
+ if( isset( $gateway_enabled_settings[ $currency ] ) ) {
46
+ return $gateway_enabled_settings[ $currency ];
47
+ }
48
+
49
+ return false;
50
+ }
51
+
52
+ /**
53
+ * @param string $currency
54
+ * @param bool $value
55
+ */
56
+ public function set_enabled( $currency, $value ) {
57
+
58
+ $gateway_enabled_settings = $this->get_settings();
59
+ $gateway_enabled_settings[ $currency ] = $value;
60
+
61
+ update_option( self::OPTION_KEY, $gateway_enabled_settings );
62
+ }
63
+
64
+ /**
65
+ * @return array
66
+ */
67
+ private function get_settings() {
68
+ return get_option( self::OPTION_KEY, array() );
69
+ }
70
+
71
+ public function init_gateways(){
72
+
73
+ do_action( 'wcml_before_init_currency_payment_gateways' );
74
+
75
+ $this->available_gateways = $this->get_available_payment_gateways();
76
+
77
+ $this->supported_gateways = array(
78
+ 'bacs' => 'WCML_Payment_Gateway_Bacs',
79
+ 'paypal' => 'WCML_Payment_Gateway_PayPal',
80
+ 'stripe' => 'WCML_Payment_Gateway_Stripe'
81
+ );
82
+ $this->supported_gateways = apply_filters( 'wcml_supported_currency_payment_gateways', $this->supported_gateways );
83
+
84
+ $this->store_supported_gateways();
85
+ $this->store_non_supported_gateways();
86
+ }
87
+
88
+ /**
89
+ * @return array
90
+ */
91
+ public function get_gateways() {
92
+
93
+ return $this->payment_gateways;
94
+ }
95
+
96
+ /**
97
+ * @return array
98
+ */
99
+ public function get_supported_gateways() {
100
+
101
+ return $this->supported_gateways;
102
+ }
103
+
104
+ /**
105
+ * @param string $description
106
+ * @param string $id
107
+ *
108
+ * @return string
109
+ */
110
+ public function filter_gateway_description( $description, $id ) {
111
+
112
+ if ( in_array( $id, array_keys( $this->supported_gateways ), true ) ) {
113
+
114
+ $client_currency = $this->woocommerce_wpml->multi_currency->get_client_currency();
115
+ $gateway_setting = $this->payment_gateways[ $id ]->get_setting( $client_currency );
116
+ $active_currencies = $this->woocommerce_wpml->multi_currency->get_currency_codes();
117
+
118
+ if (
119
+ $this->is_enabled( $client_currency ) &&
120
+ $gateway_setting &&
121
+ $client_currency !== $gateway_setting['currency'] &&
122
+ in_array( $gateway_setting['currency'], $active_currencies )
123
+ ) {
124
+ $cart_total = $this->woocommerce_wpml->cart->get_formatted_cart_total_in_currency( $gateway_setting['currency'] );
125
+
126
+ $description .= '<p>';
127
+ $description .= sprintf( __( 'Please note that the payment will be made in %1$s. %2$s will be debited from your account.', 'woocommerce-multilingual' ), $gateway_setting['currency'], $cart_total );
128
+ $description .= '</p>';
129
+ }
130
+ }
131
+
132
+ return $description;
133
+ }
134
+
135
+ /**
136
+ * @param string $id
137
+ * @param object $supported_gateway
138
+ *
139
+ * @return bool
140
+ */
141
+ private function is_a_valid_gateway( $id, $supported_gateway ) {
142
+ return is_subclass_of( $supported_gateway, 'WCML_Payment_Gateway' ) && array_key_exists( $id, $this->available_gateways );
143
+ }
144
+
145
+ private function store_supported_gateways() {
146
+ if ( is_array( $this->supported_gateways ) ) {
147
+ /** @var \WCML_Payment_Gateway $supported_gateway */
148
+ $client_currency = $this->woocommerce_wpml->multi_currency->get_client_currency();
149
+ foreach ( $this->supported_gateways as $id => $supported_gateway ) {
150
+ if ( $this->is_a_valid_gateway( $id, $supported_gateway ) ) {
151
+ $this->payment_gateways[ $id ] = new $supported_gateway( $this->available_gateways[ $id ], $this->get_template_service(), $this->woocommerce_wpml );
152
+ if ( $this->is_enabled( $client_currency ) ) {
153
+ $this->payment_gateways[ $id ]->add_hooks();
154
+ }
155
+ }
156
+ }
157
+ }
158
+ }
159
+
160
+ private function store_non_supported_gateways() {
161
+ $non_supported_gateways = array_diff( array_keys( $this->available_gateways ), array_keys( $this->payment_gateways ) );
162
+
163
+ /** @var int $non_supported_gateway */
164
+ foreach ( $non_supported_gateways as $non_supported_gateway ) {
165
+ $this->payment_gateways[ $non_supported_gateway ] = new WCML_Not_Supported_Payment_Gateway( $this->available_gateways[ $non_supported_gateway ], $this->get_template_service(), $this->woocommerce_wpml );
166
+ }
167
+ }
168
+
169
+ /**
170
+ * @return \WPML_Twig_Template
171
+ */
172
+ private function get_template_service() {
173
+ $twig_loader = new WPML_Twig_Template_Loader( array( $this->wp_api->constant( 'WCML_PLUGIN_PATH' ) . self::TEMPLATE_FOLDER ) );
174
+
175
+ return $twig_loader->get_template();
176
+ }
177
+
178
+ /**
179
+ * @return array
180
+ */
181
+ private function get_available_payment_gateways() {
182
+ return WC()->payment_gateways()->get_available_payment_gateways();
183
+ }
184
+
185
+ }
classes/multi-currency/payment-gateways/class-wcml-not-supported-payment-gateway.php ADDED
@@ -0,0 +1,23 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Class WCML_Not_Supported_Payment_Gateway
5
+ */
6
+ class WCML_Not_Supported_Payment_Gateway extends WCML_Payment_Gateway{
7
+
8
+ const TEMPLATE = 'not-supported.twig';
9
+
10
+ protected function get_output_model() {
11
+ return array(
12
+ 'strings' => array(
13
+ 'not_supported' => __( 'Not yet supported', 'woocommerce-multilingual' )
14
+ ),
15
+ 'gateway_title' => $this->get_title()
16
+ );
17
+ }
18
+
19
+ protected function get_output_template() {
20
+ return self::TEMPLATE;
21
+ }
22
+
23
+ }
classes/multi-currency/payment-gateways/class-wcml-payment-gateway-bacs.php ADDED
@@ -0,0 +1,59 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Class WCML_Payment_Gateway_Bacs
5
+ */
6
+ class WCML_Payment_Gateway_Bacs extends WCML_Payment_Gateway {
7
+
8
+ const TEMPLATE = 'bacs.twig';
9
+
10
+ protected function get_output_model() {
11
+ return array(
12
+ 'strings' => array(
13
+ 'currency_label' => __( 'Currency', 'woocommerce-multilingual' ),
14
+ 'setting_label' => __( 'Bank Account', 'woocommerce-multilingual' ),
15
+ 'all_label' => __( 'All Accounts', 'woocommerce-multilingual' ),
16
+ 'all_in_label' => __( 'All in selected currency', 'woocommerce-multilingual' ),
17
+ 'tooltip' => __( 'Set the currency in which your customer will see the final price when they checkout. Choose which accounts they will see in their payment message.', 'woocommerce-multilingual' )
18
+ ),
19
+ 'gateway_id' => $this->get_id(),
20
+ 'gateway_title' => $this->get_title(),
21
+ 'current_currency' => $this->current_currency,
22
+ 'gateway_settings' => $this->get_setting( $this->current_currency ),
23
+ 'active_currencies' => $this->get_active_currencies(),
24
+ 'account_details' => $this->get_gateway()->account_details,
25
+ );
26
+ }
27
+
28
+ protected function get_output_template() {
29
+ return self::TEMPLATE;
30
+ }
31
+
32
+ public function add_hooks(){
33
+ add_filter( 'woocommerce_bacs_accounts', array( $this, 'filter_bacs_accounts' ) );
34
+ }
35
+
36
+ public function filter_bacs_accounts( $accounts ) {
37
+
38
+ $client_currency = $this->woocommerce_wpml->multi_currency->get_client_currency();
39
+ $gateway_setting = $this->get_setting( $client_currency );
40
+
41
+ if ( $gateway_setting && 'all' !== $gateway_setting['value'] ) {
42
+
43
+ if( 'all_in' === $gateway_setting['value'] ){
44
+ $allowed_accounts = array();
45
+ $bacs_accounts_currencies = get_option( WCML_WC_Gateways::WCML_BACS_ACCOUNTS_CURRENCIES_OPTION, array() );
46
+ foreach ( $bacs_accounts_currencies as $account_key => $currency ){
47
+ if( $gateway_setting['currency'] === $currency ){
48
+ $allowed_accounts[] = $accounts[ $account_key ];
49
+ }
50
+ }
51
+ }else{
52
+ $allowed_accounts[] = $accounts[ $gateway_setting['value'] ];
53
+ }
54
+ }
55
+
56
+ return $allowed_accounts ? $allowed_accounts : $accounts;
57
+ }
58
+
59
+ }
classes/multi-currency/payment-gateways/class-wcml-payment-gateway-paypal.php ADDED
@@ -0,0 +1,117 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Class WCML_Payment_Gateway_PayPal
5
+ */
6
+ class WCML_Payment_Gateway_PayPal extends WCML_Payment_Gateway {
7
+
8
+ const TEMPLATE = 'paypal.twig';
9
+
10
+ protected function get_output_model() {
11
+ $currencies_details = $this->get_currencies_details();
12
+
13
+ return array(
14
+ 'strings' => array(
15
+ 'currency_label' => __( 'Currency', 'woocommerce-multilingual' ),
16
+ 'setting_label' => __( 'PayPal Email', 'woocommerce-multilingual' ),
17
+ 'not_supported' => sprintf( __( 'This gateway does not support %s. To show this gateway please select another currency.', 'woocommerce-multilingual' ), $this->current_currency )
18
+ ),
19
+ 'gateway_id' => $this->get_id(),
20
+ 'gateway_title' => $this->get_title(),
21
+ 'current_currency' => $this->current_currency,
22
+ 'gateway_settings' => $this->get_setting( $this->current_currency ),
23
+ 'currencies_details' => array_intersect_key( $currencies_details, $this->get_active_currencies() ),
24
+ 'selected_currency_valid' => $this->is_valid_for_use( $currencies_details[ $this->current_currency ]['currency'] ),
25
+ 'current_currency_valid' => $currencies_details[ $this->current_currency ]['is_valid']
26
+ );
27
+ }
28
+
29
+ protected function get_output_template() {
30
+ return self::TEMPLATE;
31
+ }
32
+
33
+ /**
34
+ * @param $currency
35
+ *
36
+ * @return bool
37
+ */
38
+ public function is_valid_for_use( $currency ) {
39
+ return in_array(
40
+ $currency,
41
+ apply_filters(
42
+ 'woocommerce_paypal_supported_currencies',
43
+ array( 'AUD', 'BRL', 'CAD', 'MXN', 'NZD', 'HKD', 'SGD', 'USD', 'EUR', 'JPY', 'TRY', 'NOK', 'CZK', 'DKK', 'HUF', 'ILS', 'MYR', 'PHP', 'PLN', 'SEK', 'CHF', 'TWD', 'THB', 'GBP', 'RMB', 'RUB', 'INR' )
44
+ ),
45
+ true
46
+ );
47
+ }
48
+
49
+ /**
50
+ * @param array $active_currencies
51
+ *
52
+ * @return array
53
+ */
54
+ public function get_currencies_details(){
55
+
56
+ $currencies_details = array();
57
+ $default_currency = get_option( 'woocommerce_currency' );
58
+ $woocommerce_currencies = get_woocommerce_currencies();
59
+
60
+ foreach ( $woocommerce_currencies as $code => $currency ) {
61
+
62
+ if ( $default_currency === $code ) {
63
+ $currencies_details[ $code ]['value'] = $this->get_gateway()->settings['email'];
64
+ $currencies_details[ $code ]['currency'] = $code;
65
+ $currencies_details[ $code ]['is_valid'] = $this->is_valid_for_use( $default_currency );
66
+ } else {
67
+ $currency_gateway_setting = $this->get_setting( $code );
68
+ $currencies_details[ $code ]['value'] = $currency_gateway_setting ? $currency_gateway_setting['value'] : '';
69
+ $currencies_details[ $code ]['currency'] = $currency_gateway_setting ? $currency_gateway_setting['currency'] : $code;
70
+ $currencies_details[ $code ]['is_valid'] = $this->is_valid_for_use( $code );
71
+ }
72
+ }
73
+
74
+ return $currencies_details;
75
+
76
+ }
77
+
78
+ public function add_hooks(){
79
+ add_filter( 'woocommerce_paypal_args', array( $this, 'filter_paypal_args' ), 10, 2 );
80
+ }
81
+
82
+ /**
83
+ * @param array $args
84
+ * @param WC_Order $order
85
+ *
86
+ * @return array
87
+ */
88
+ public function filter_paypal_args( $args, $order ) {
89
+
90
+ $order_data = $order->get_data();
91
+ $client_currency = $order_data['currency'];
92
+ $gateway_setting = $this->get_setting( $client_currency );
93
+
94
+ if ( $gateway_setting ) {
95
+
96
+ if ( $gateway_setting['value'] ) {
97
+ $args['business'] = $gateway_setting['value'];
98
+ }
99
+
100
+ if ( $client_currency !== $gateway_setting['currency'] ) {
101
+ $args['currency_code'] = $gateway_setting['currency'];
102
+ $cart_items = WC()->cart->get_cart_contents();
103
+ $item_id = 1;
104
+
105
+ foreach ( $cart_items as $item ) {
106
+ $args[ 'amount_' . $item_id ] = $this->woocommerce_wpml->multi_currency->prices->get_product_price_in_currency( $item['product_id'], $gateway_setting['currency'] );
107
+ $item_id ++;
108
+ }
109
+
110
+ $args['shipping_1'] = $this->woocommerce_wpml->multi_currency->prices->convert_price_amount_by_currencies( WC()->cart->get_shipping_total(), $client_currency, $gateway_setting['currency'] );
111
+ }
112
+ }
113
+
114
+ return $args;
115
+ }
116
+
117
+ }
classes/multi-currency/payment-gateways/class-wcml-payment-gateway-stripe.php ADDED
@@ -0,0 +1,109 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Class WCML_Payment_Gateway_Stripe
5
+ */
6
+ class WCML_Payment_Gateway_Stripe extends WCML_Payment_Gateway {
7
+
8
+ const TEMPLATE = 'stripe.twig';
9
+ const ID = 'stripe';
10
+
11
+ protected function get_output_model() {
12
+ return array(
13
+ 'strings' => array(
14
+ 'currency_label' => __( 'Currency', 'woocommerce-multilingual' ),
15
+ 'publishable_label' => __( 'Live Publishable Key', 'woocommerce-multilingual' ),
16
+ 'secret_label' => __( 'Live Secret Key', 'woocommerce-multilingual' ),
17
+ ),
18
+ 'gateway_id' => $this->get_id(),
19
+ 'gateway_title' => $this->get_title(),
20
+ 'current_currency' => $this->current_currency,
21
+ 'gateway_settings' => $this->get_setting( $this->current_currency ),
22
+ 'currencies_details' => $this->get_currencies_details( $this->get_active_currencies() )
23
+ );
24
+ }
25
+
26
+ protected function get_output_template() {
27
+ return self::TEMPLATE;
28
+ }
29
+
30
+ public function add_hooks(){
31
+ add_filter( 'woocommerce_stripe_request_body', array( $this, 'filter_request_body' ) );
32
+ }
33
+
34
+ public function filter_request_body( $request ) {
35
+
36
+ $client_currency = $this->woocommerce_wpml->multi_currency->get_client_currency();
37
+ $gateway_setting = $this->get_setting( strtoupper( $request['currency'] ) );
38
+
39
+ if ( $gateway_setting ) {
40
+
41
+ if ( $client_currency !== $gateway_setting['currency'] ) {
42
+ $request['currency'] = strtolower( $gateway_setting['currency'] );
43
+ $request['amount'] = WC_Stripe_Helper::get_stripe_amount( $this->woocommerce_wpml->cart->get_cart_total_in_currency( $gateway_setting['currency'] ), $gateway_setting['currency'] );
44
+ }
45
+ }
46
+
47
+ return $request;
48
+ }
49
+
50
+ /**
51
+ * @param array $active_currencies
52
+ *
53
+ * @return array
54
+ */
55
+ public function get_currencies_details( $active_currencies ){
56
+
57
+ $currencies_details = array();
58
+ $default_currency = get_option( 'woocommerce_currency' );
59
+
60
+ foreach ( $active_currencies as $code => $currency ) {
61
+
62
+ if ( $default_currency === $code ) {
63
+ $currencies_details[ $code ]['publishable_key'] = $this->get_gateway()->settings['publishable_key'];
64
+ $currencies_details[ $code ]['secret_key'] = $this->get_gateway()->settings['secret_key'];
65
+ } else {
66
+ $currency_gateway_setting = $this->get_setting( $code );
67
+ $currencies_details[ $code ]['publishable_key'] = $currency_gateway_setting ? $currency_gateway_setting['publishable_key'] : '';
68
+ $currencies_details[ $code ]['secret_key'] = $currency_gateway_setting ? $currency_gateway_setting['secret_key'] : '';
69
+ }
70
+ }
71
+
72
+ return $currencies_details;
73
+
74
+ }
75
+
76
+ /**
77
+ * Filter Stripe settings before WC initialized them
78
+ *
79
+ * @param array $settings
80
+ *
81
+ * @return array
82
+ */
83
+ public static function filter_stripe_settings( $settings ) {
84
+ if ( is_admin() ){
85
+ return $settings;
86
+ }
87
+
88
+ global $woocommerce_wpml;
89
+
90
+ $client_currency = $woocommerce_wpml->multi_currency->get_client_currency();
91
+ $gateway_settings = get_option( self::OPTION_KEY . self::ID, array() );
92
+
93
+ if( $gateway_settings && isset( $gateway_settings[ $client_currency ] ) ){
94
+ $gateway_setting = $gateway_settings[ $client_currency ];
95
+ if( $gateway_setting['publishable_key'] && $gateway_setting['secret_key'] ){
96
+ if ( 'yes' === $settings['testmode'] ) {
97
+ $settings['test_publishable_key'] = $gateway_setting['publishable_key'];
98
+ $settings['test_secret_key'] = $gateway_setting['secret_key'];
99
+ } else {
100
+ $settings['publishable_key'] = $gateway_setting['publishable_key'];
101
+ $settings['secret_key'] = $gateway_setting['secret_key'];
102
+ }
103
+ }
104
+ }
105
+
106
+ return $settings;
107
+ }
108
+
109
+ }
classes/multi-currency/payment-gateways/class-wcml-payment-gateway.php ADDED
@@ -0,0 +1,122 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Class WCML_Payment_Gateway
5
+ */
6
+ abstract class WCML_Payment_Gateway {
7
+
8
+ const OPTION_KEY = 'wcml_payment_gateway_';
9
+
10
+ /**
11
+ * @var string
12
+ */
13
+ protected $current_currency;
14
+ /**
15
+ * @var array
16
+ */
17
+ protected $active_currencies;
18
+ /**
19
+ * @var WC_Payment_Gateway
20
+ */
21
+ protected $gateway;
22
+
23
+ private $settings = array();
24
+
25
+ /**
26
+ * @var \IWPML_Template_Service
27
+ */
28
+ private $template_service;
29
+ /**
30
+ * @var woocommerce_wpml
31
+ */
32
+ protected $woocommerce_wpml;
33
+
34
+ /**
35
+ * @param WC_Payment_Gateway $gateway
36
+ * @param \IWPML_Template_Service $template_service
37
+ * @param woocommerce_wpml $woocommerce_wpml
38
+ */
39
+ public function __construct( WC_Payment_Gateway $gateway, IWPML_Template_Service $template_service, woocommerce_wpml $woocommerce_wpml ) {
40
+ $this->gateway = $gateway;
41
+ $this->template_service = $template_service;
42
+ $this->woocommerce_wpml = $woocommerce_wpml;
43
+ $this->settings = get_option( self::OPTION_KEY . $this->get_id(), array() );
44
+ }
45
+
46
+ public function get_settings_output( $current_currency, $active_currencies ) {
47
+ $this->current_currency = $current_currency;
48
+ $this->active_currencies = $active_currencies;
49
+
50
+ return $this->template_service->show( $this->get_output_model(), $this->get_output_template() );
51
+ }
52
+
53
+ public function show() {
54
+ return $this->get_settings_output();
55
+ }
56
+
57
+ abstract protected function get_output_model();
58
+
59
+ abstract protected function get_output_template();
60
+
61
+ /**
62
+ * @return WC_Payment_Gateway
63
+ */
64
+ public function get_gateway(){
65
+ return $this->gateway;
66
+ }
67
+
68
+ /**
69
+ * @return string
70
+ */
71
+ public function get_id(){
72
+ return $this->gateway->id;
73
+ }
74
+
75
+ /**
76
+ * @return string
77
+ */
78
+ public function get_title(){
79
+ return $this->gateway->title;
80
+ }
81
+
82
+ /**
83
+ * @return array
84
+ */
85
+ public function get_settings() {
86
+ return $this->settings;
87
+ }
88
+
89
+ private function save_settings() {
90
+ update_option( self::OPTION_KEY . $this->get_id(), $this->settings );
91
+ }
92
+
93
+ /**
94
+ * @param string $key
95
+ *
96
+ * @return mixed|null
97
+ */
98
+ public function get_setting( $key ) {
99
+ return isset( $this->settings[ $key ] ) ? $this->settings[ $key ] : null;
100
+ }
101
+
102
+ /**
103
+ * @param string $key
104
+ * @param mixed $value
105
+ */
106
+ public function save_setting( $key, $value ) {
107
+ $this->settings[ $key ] = $value;
108
+ $this->save_settings();
109
+ }
110
+
111
+ public function get_active_currencies(){
112
+
113
+ $active_currencies = $this->active_currencies;
114
+
115
+ if( !in_array( $this->current_currency, array_keys( $active_currencies ) ) ){
116
+ $active_currencies[ $this->current_currency ] = array();
117
+ }
118
+
119
+ return $active_currencies;
120
+ }
121
+
122
+ }
classes/rest-api-support/class-wcml-rest-api-support-v1.php DELETED
@@ -1,326 +0,0 @@
1
- <?php
2
-
3
- class WCML_REST_API_Support_V1{
4
-
5
- /** @var woocommerce_wpml */
6
- private $woocommerce_wpml;
7
- /** @var Sitepress */
8
- private $sitepress;
9
- /** @var WCML_REST_API_Query_Filters_Products */
10
- private $query_filters_products;
11
- /** @var WCML_REST_API_Query_Filters_Orders */
12
- private $query_filters_orders;
13
- /** @var WCML_REST_API_Query_Filters_Terms */
14
- private $query_filters_terms;
15
- /** @var WPML_Admin_Post_Actions */
16
- private $wpml_post_translations;
17
-
18
- /**
19
- * WCML_REST_API_Support_V1 constructor.
20
- *
21
- * @param woocommerce_wpml $woocommerce_wpml
22
- * @param SitePress $sitepress
23
- * @param WCML_REST_API_Query_Filters_Products $query_filters_products
24
- * @param WCML_REST_API_Query_Filters_Orders $query_filters_orders
25
- * @param WCML_REST_API_Query_Filters_Terms $query_filters_terms
26
- * @param WPML_Post_Translation $wpml_post_translations
27
- */
28
- public function __construct(
29
- woocommerce_wpml $woocommerce_wpml,
30
- SitePress $sitepress,
31
- WCML_REST_API_Query_Filters_Products $query_filters_products,
32
- WCML_REST_API_Query_Filters_Orders $query_filters_orders,
33
- WCML_REST_API_Query_Filters_Terms $query_filters_terms,
34
- WPML_Post_Translation $wpml_post_translations
35
- ) {
36
- $this->woocommerce_wpml = $woocommerce_wpml;
37
- $this->sitepress = $sitepress;
38
- $this->query_filters_products = $query_filters_products;
39
- $this->query_filters_orders = $query_filters_orders;
40
- $this->query_filters_terms = $query_filters_terms;
41
- $this->wpml_post_translations = $wpml_post_translations;
42
-
43
- $this->prevent_default_lang_url_redirect();
44
- }
45
-
46
- /**
47
- * Adding hooks
48
- */
49
- public function add_hooks(){
50
- add_action( 'rest_api_init', array( $this, 'set_language_for_request' ) );
51
-
52
- add_action( 'parse_query', array($this, 'auto_adjust_included_ids') );
53
-
54
- // Products
55
- add_action( 'woocommerce_rest_prepare_product', array( $this, 'append_product_language_and_translations' ) );
56
- add_action( 'woocommerce_rest_prepare_product', array( $this, 'append_product_secondary_prices' ) );
57
-
58
- add_action( 'woocommerce_rest_insert_product', array( $this, 'set_product_language' ), 10, 2 );
59
- add_action( 'woocommerce_rest_update_product', array( $this, 'set_product_language' ), 10, 2 );
60
-
61
- add_action( 'woocommerce_rest_insert_product', array( $this, 'set_product_custom_prices' ), 10, 2 );
62
- add_action( 'woocommerce_rest_update_product', array( $this, 'set_product_custom_prices' ), 10, 2 );
63
-
64
- add_action( 'woocommerce_rest_prepare_product', array( $this, 'copy_product_custom_fields' ), 10 , 3 );
65
- add_action( 'woocommerce_rest_insert_product', array( $this, 'copy_custom_fields_from_original' ), 10, 1 );
66
-
67
- // Orders
68
- add_action( 'woocommerce_rest_insert_shop_order' , array( $this, 'set_order_language' ), 10, 2 );
69
-
70
- $this->query_filters_products->add_hooks();
71
- $this->query_filters_orders->add_hooks();
72
- $this->query_filters_terms->add_hooks();
73
-
74
- }
75
-
76
- /**
77
- * @param WP_REST_Server $wp_rest_server
78
- * enforces the language of request as the current language to be able to filter items by language
79
- */
80
- public function set_language_for_request( $wp_rest_server ){
81
- if( isset( $_GET['lang'] ) ){
82
- $request_language = $_GET['lang'];
83
- $active_languages = $this->sitepress->get_active_languages();
84
- if( isset( $active_languages[ $request_language ] ) ){
85
- $this->sitepress->switch_lang( $request_language );
86
- }
87
- }
88
- }
89
-
90
- /**
91
- * Prevent WPML redirection when using the default language as a parameter in the url
92
- */
93
- private function prevent_default_lang_url_redirect(){
94
- $exp = explode( '?', $_SERVER['REQUEST_URI'] );
95
- if ( ! empty( $exp[1] ) ) {
96
- parse_str( $exp[1], $vars );
97
- if ( isset($vars['lang']) && $vars['lang'] === $this->sitepress->get_default_language() ) {
98
- unset( $vars['lang'] );
99
- $_SERVER['REQUEST_URI'] = $exp[0] . '?' . http_build_query( $vars );
100
- }
101
- }
102
- }
103
-
104
- /**
105
- * @param WP_Query $wp_query
106
- */
107
- public function auto_adjust_included_ids( $wp_query ){
108
- $lang = $wp_query->get('lang');
109
- $include = $wp_query->get('post__in');
110
- if( empty( $lang ) && !empty( $include ) ){
111
- $filtered_include = array();
112
- foreach( $include as $id ){
113
- $filtered_include[] = apply_filters( 'translate_object_id', $id, get_post_type($id), true );
114
- }
115
- $wp_query->set( 'post__in' , $filtered_include );
116
- }
117
- }
118
-
119
- /**
120
- * Appends the language and translation information to the get_product response
121
- *
122
- * @param $product_data
123
- *
124
- * @return WP_REST_Response
125
- */
126
- public function append_product_language_and_translations( $product_data ){
127
-
128
- $product_data->data['translations'] = array();
129
-
130
- $trid = $this->sitepress->get_element_trid( $product_data->data['id'], 'post_product' );
131
-
132
- if( $trid ) {
133
- $translations = $this->sitepress->get_element_translations( $trid, 'post_product' );
134
- foreach ( $translations as $translation ) {
135
- if ( $translation->element_id == $product_data->data['id'] ) {
136
- $product_language = $translation->language_code;
137
- } else {
138
- $product_data->data['translations'][ $translation->language_code ] = $translation->element_id;
139
- }
140
- }
141
-
142
- $product_data->data['lang'] = $product_language;
143
- }
144
-
145
- return $product_data;
146
- }
147
-
148
- /**
149
- * Appends the secondary prices information to the get_product response
150
- *
151
- * @param $product_data
152
- *
153
- * @return WP_REST_Response
154
- */
155
- public function append_product_secondary_prices( $product_data ){
156
-
157
- if( !empty($this->woocommerce_wpml->multi_currency) && !empty($this->woocommerce_wpml->settings['currencies_order']) ){
158
-
159
- $product_data->data['multi-currency-prices'] = array();
160
-
161
- $custom_prices_on = get_post_meta( $product_data->data['id'], '_wcml_custom_prices_status', true);
162
-
163
- foreach( $this->woocommerce_wpml->settings['currencies_order'] as $currency ){
164
-
165
- if( $currency != get_option('woocommerce_currency') ){
166
-
167
- if( $custom_prices_on ){
168
-
169
- $custom_prices = (array) $this->woocommerce_wpml->multi_currency->custom_prices->get_product_custom_prices( $product_data->data['id'], $currency );
170
- foreach( $custom_prices as $key => $price){
171
- $product_data->data['multi-currency-prices'][$currency][ preg_replace('#^_#', '', $key) ] = $price;
172
-
173
- }
174
-
175
- } else {
176
- $product_data->data['multi-currency-prices'][$currency]['regular_price'] =
177
- $this->woocommerce_wpml->multi_currency->prices->raw_price_filter( $product_data->data['regular_price'], $currency );
178
- if( !empty($product_data->data['sale_price']) ){
179
- $product_data->data['multi-currency-prices'][$currency]['sale_price'] =
180
- $this->woocommerce_wpml->multi_currency->prices->raw_price_filter( $product_data->data['sale_price'], $currency );
181
- }
182
- }
183
-
184
- }
185
-
186
- }
187
-
188
- }
189
-
190
- return $product_data;
191
- }
192
-
193
- /**
194
- * Sets the product information according to the provided language
195
- *
196
- * @param WP_Post $post
197
- * @param WP_REST_Request $request
198
- *
199
- * @throws WCML_REST_Invalid_Language_Exception
200
- * @throws WCML_REST_Invalid_Product_Exception
201
- *
202
- */
203
- public function set_product_language( $post, $request ){
204
-
205
- $data = $request->get_params();
206
-
207
- if( isset( $data['lang'] ) && 'POST' === $request->get_method() ){
208
- $active_languages = $this->sitepress->get_active_languages();
209
- if( !isset( $active_languages[$data['lang']] ) ){
210
- throw new WCML_REST_Invalid_Language_Exception( $data['lang'] );
211
- }
212
- if( isset( $data['translation_of'] ) ){
213
- $trid = $this->sitepress->get_element_trid( $data['translation_of'], 'post_product' );
214
- if( empty($trid) ){
215
- throw new WCML_REST_Invalid_Product_Exception( $data['translation_of'] );
216
- }
217
- }else{
218
- $trid = null;
219
- }
220
-
221
- $this->sitepress->set_element_language_details( $post->ID, 'post_product', $trid, $data['lang'] );
222
- wpml_tm_save_post( $post->ID, $post , ICL_TM_COMPLETE );
223
- }else{
224
- if( isset( $data['translation_of'] ) ){
225
- throw new WCML_REST_Generic_Exception( __( 'Using "translation_of" requires providing a "lang" parameter too', 'woocommerce-multilingual' ) );
226
- }
227
- }
228
-
229
- }
230
-
231
- /**
232
- * Sets custom prices in secondary currencies for products
233
- *
234
- * @param WP_Post $post
235
- * @param WP_REST_Request $request
236
- *
237
- * @throws WC_API_Exception
238
- *
239
- */
240
- public function set_product_custom_prices( $post, $request ){
241
-
242
- $data = $request->get_params();
243
-
244
- if( !empty( $this->woocommerce_wpml->multi_currency ) ){
245
-
246
- if( !empty( $data['custom_prices'] ) ){
247
-
248
- $original_post_id = $this->sitepress->get_original_element_id_filter('', $post->ID, 'post_product' );
249
-
250
- update_post_meta( $original_post_id, '_wcml_custom_prices_status', 1);
251
-
252
- foreach( $data['custom_prices'] as $currency => $prices ){
253
-
254
- $prices_uscore = array();
255
- foreach( $prices as $k => $p){
256
- $prices_uscore['_' . $k] = $p;
257
- }
258
- $this->woocommerce_wpml->multi_currency->custom_prices->update_custom_prices( $original_post_id, $prices_uscore, $currency );
259
-
260
- }
261
-
262
- }
263
- }
264
-
265
- }
266
-
267
- /**
268
- * @param WP_Post $post
269
- */
270
- public function copy_custom_fields_from_original( $post ){
271
- $original_post_id = $this->sitepress->get_original_element_id_filter('', $post->ID, 'post_product' );
272
-
273
- if( $original_post_id !== $post->ID ){
274
- $this->sitepress->copy_custom_fields( $original_post_id, $post->ID );
275
- }
276
- }
277
-
278
- /**
279
- * @param WP_REST_Response $response
280
- * @param mixed $object
281
- * @param WP_REST_Request $request
282
- *
283
- * Copy custom fields explicitly
284
- *
285
- * @return WP_REST_Response
286
- */
287
- public function copy_product_custom_fields($response, $object, $request){
288
- $data = $request->get_params();
289
-
290
- if( isset( $data['id'] ) ){
291
- $translations = $this->wpml_post_translations->get_element_translations( $data['id'], false, true );
292
- foreach ( $translations as $translation_id ) {
293
- $this->sitepress->copy_custom_fields ( $data['id'], $translation_id );
294
- }
295
- }
296
-
297
- return $response;
298
- }
299
-
300
- /**
301
- * Sets the language for a new order
302
- *
303
- * @param WP_Post $post
304
- * @param WP_REST_Request $request
305
- *
306
- * @throws WCML_REST_Invalid_Language_Exception
307
- */
308
- public function set_order_language( $post, $request ){
309
-
310
- $data = $request->get_params();
311
- if( isset( $data['lang'] ) ){
312
- $order_id = $post->ID;
313
- $active_languages = $this->sitepress->get_active_languages();
314
- if( !isset( $active_languages[$data['lang']] ) ){
315
- throw new WCML_REST_Invalid_Language_Exception( $data['lang'] );
316
- }
317
-
318
- update_post_meta( $order_id, 'wpml_language', $data['lang'] );
319
-
320
- }
321
-
322
- }
323
-
324
-
325
-
326
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
classes/rest-api-support/class-wcml-rest-api-support.php CHANGED
@@ -6,8 +6,6 @@ class WCML_REST_API_Support{
6
  private $woocommerce_wpml;
7
  /** @var Sitepress */
8
  private $sitepress;
9
- /** @var wpdb */
10
- private $wpdb;
11
  /** @var WCML_REST_API_Query_Filters_Products */
12
  private $query_filters_products;
13
  /** @var WCML_REST_API_Query_Filters_Orders */
@@ -23,7 +21,6 @@ class WCML_REST_API_Support{
23
  *
24
  * @param woocommerce_wpml $woocommerce_wpml
25
  * @param SitePress $sitepress
26
- * @param wpdb $wpdb
27
  * @param WCML_REST_API_Query_Filters_Products $query_filters_products
28
  * @param WCML_REST_API_Query_Filters_Orders $query_filters_orders
29
  * @param WCML_REST_API_Query_Filters_Terms $query_filters_terms
@@ -32,7 +29,6 @@ class WCML_REST_API_Support{
32
  public function __construct(
33
  woocommerce_wpml $woocommerce_wpml,
34
  SitePress $sitepress,
35
- wpdb $wpdb,
36
  WCML_REST_API_Query_Filters_Products $query_filters_products,
37
  WCML_REST_API_Query_Filters_Orders $query_filters_orders,
38
  WCML_REST_API_Query_Filters_Terms $query_filters_terms,
@@ -40,7 +36,6 @@ class WCML_REST_API_Support{
40
  ) {
41
  $this->woocommerce_wpml = $woocommerce_wpml;
42
  $this->sitepress = $sitepress;
43
- $this->wpdb = $wpdb;
44
  $this->query_filters_products = $query_filters_products;
45
  $this->query_filters_orders = $query_filters_orders;
46
  $this->query_filters_terms = $query_filters_terms;
@@ -51,7 +46,6 @@ class WCML_REST_API_Support{
51
 
52
  public function add_hooks(){
53
  add_action( 'rest_api_init', array( $this, 'set_language_for_request' ) );
54
-
55
  add_action( 'parse_query', array($this, 'auto_adjust_included_ids') );
56
 
57
  // Products
@@ -60,17 +54,37 @@ class WCML_REST_API_Support{
60
 
61
  add_action( 'woocommerce_rest_insert_product_object', array( $this, 'set_product_language' ), 10, 2 );
62
  add_action( 'woocommerce_rest_insert_product_object', array( $this, 'set_product_custom_prices' ), 10, 2 );
63
- add_action( 'woocommerce_rest_insert_product_object', array( $this, 'copy_custom_fields_from_original' ), 10, 1 );
64
 
 
65
  add_action( 'woocommerce_rest_prepare_product_object', array( $this, 'copy_product_custom_fields' ), 10 , 3 );
66
 
67
  // Orders
68
  add_action( 'woocommerce_rest_insert_shop_order_object' , array( $this, 'set_order_language' ), 10, 2 );
69
 
 
70
  $this->query_filters_products->add_hooks();
71
  $this->query_filters_orders->add_hooks();
72
  $this->query_filters_terms->add_hooks();
 
 
 
 
 
 
 
 
 
 
73
 
 
 
 
 
 
 
 
 
 
74
  }
75
 
76
  /**
@@ -193,7 +207,7 @@ class WCML_REST_API_Support{
193
  /**
194
  * Sets the product information according to the provided language
195
  *
196
- * @param object $product
197
  * @param WP_REST_Request $request
198
  *
199
  * @throws WCML_REST_Invalid_Language_Exception
@@ -219,8 +233,10 @@ class WCML_REST_API_Support{
219
  $trid = null;
220
  }
221
 
222
- $this->sitepress->set_element_language_details( $product->get_id(), 'post_product', $trid, $data['lang'] );
223
- wpml_tm_save_post( $product->get_id(), get_post( $product->get_id() ), ICL_TM_COMPLETE );
 
 
224
  }else{
225
  if( isset( $data['translation_of'] ) ){
226
  throw new WCML_REST_Generic_Exception( __( 'Using "translation_of" requires providing a "lang" parameter too', 'woocommerce-multilingual' ) );
@@ -232,7 +248,7 @@ class WCML_REST_API_Support{
232
  /**
233
  * Sets custom prices in secondary currencies for products
234
  *
235
- * @param object $product
236
  * @param WP_REST_Request $request
237
  *
238
  * @throws WC_API_Exception
@@ -246,7 +262,9 @@ class WCML_REST_API_Support{
246
 
247
  if( !empty( $data['custom_prices'] ) ){
248
 
249
- $original_post_id = $this->sitepress->get_original_element_id_filter('', $product->get_id(), 'post_product' );
 
 
250
 
251
  update_post_meta( $original_post_id, '_wcml_custom_prices_status', 1);
252
 
@@ -266,13 +284,16 @@ class WCML_REST_API_Support{
266
  }
267
 
268
  /**
269
- * @param WC_Product $product
270
  */
271
- public function copy_custom_fields_from_original( WC_Product $product ){
272
- $original_post_id = $this->sitepress->get_original_element_id_filter('', $product->get_id(), 'post_product' );
273
 
274
- if( $original_post_id !== $product->get_id() ){
275
- $this->sitepress->copy_custom_fields( $original_post_id, $product->get_id() );
 
 
 
 
276
  }
277
  }
278
 
@@ -301,7 +322,7 @@ class WCML_REST_API_Support{
301
  /**
302
  * Sets the language for a new order
303
  *
304
- * @param WC_Order $order
305
  * @param WP_REST_Request $request
306
  *
307
  * @throws WCML_REST_Invalid_Language_Exception
@@ -310,7 +331,11 @@ class WCML_REST_API_Support{
310
 
311
  $data = $request->get_params();
312
  if( isset( $data['lang'] ) ){
313
- $order_id = $order->get_id();
 
 
 
 
314
  $active_languages = $this->sitepress->get_active_languages();
315
  if( !isset( $active_languages[$data['lang']] ) ){
316
  throw new WCML_REST_Invalid_Language_Exception( $data['lang'] );
@@ -331,7 +356,7 @@ class WCML_REST_API_Support{
331
  public function set_order_currency( $order, $request ) {
332
  $data = $request->get_params();
333
  if ( isset( $data['currency'] ) ) {
334
- $order_id = $order->get_id();
335
  $currencies = get_woocommerce_currencies();
336
  if ( ! isset( $currencies[ $data['currency'] ] ) ) {
337
  throw new WCML_REST_Invalid_Currency_Exception( $data['currency'] );
@@ -340,4 +365,17 @@ class WCML_REST_API_Support{
340
  }
341
  }
342
 
 
 
 
 
 
 
 
 
 
 
 
 
 
343
  }
6
  private $woocommerce_wpml;
7
  /** @var Sitepress */
8
  private $sitepress;
 
 
9
  /** @var WCML_REST_API_Query_Filters_Products */
10
  private $query_filters_products;
11
  /** @var WCML_REST_API_Query_Filters_Orders */
21
  *
22
  * @param woocommerce_wpml $woocommerce_wpml
23
  * @param SitePress $sitepress
 
24
  * @param WCML_REST_API_Query_Filters_Products $query_filters_products
25
  * @param WCML_REST_API_Query_Filters_Orders $query_filters_orders
26
  * @param WCML_REST_API_Query_Filters_Terms $query_filters_terms
29
  public function __construct(
30
  woocommerce_wpml $woocommerce_wpml,
31
  SitePress $sitepress,
 
32
  WCML_REST_API_Query_Filters_Products $query_filters_products,
33
  WCML_REST_API_Query_Filters_Orders $query_filters_orders,
34
  WCML_REST_API_Query_Filters_Terms $query_filters_terms,
36
  ) {
37
  $this->woocommerce_wpml = $woocommerce_wpml;
38
  $this->sitepress = $sitepress;
 
39
  $this->query_filters_products = $query_filters_products;
40
  $this->query_filters_orders = $query_filters_orders;
41
  $this->query_filters_terms = $query_filters_terms;
46
 
47
  public function add_hooks(){
48
  add_action( 'rest_api_init', array( $this, 'set_language_for_request' ) );
 
49
  add_action( 'parse_query', array($this, 'auto_adjust_included_ids') );
50
 
51
  // Products
54
 
55
  add_action( 'woocommerce_rest_insert_product_object', array( $this, 'set_product_language' ), 10, 2 );
56
  add_action( 'woocommerce_rest_insert_product_object', array( $this, 'set_product_custom_prices' ), 10, 2 );
 
57
 
58
+ add_action( 'woocommerce_rest_insert_product_object', array( $this, 'copy_custom_fields_from_original' ), 10, 1 );
59
  add_action( 'woocommerce_rest_prepare_product_object', array( $this, 'copy_product_custom_fields' ), 10 , 3 );
60
 
61
  // Orders
62
  add_action( 'woocommerce_rest_insert_shop_order_object' , array( $this, 'set_order_language' ), 10, 2 );
63
 
64
+ $this->add_hooks_specific_for_v1();
65
  $this->query_filters_products->add_hooks();
66
  $this->query_filters_orders->add_hooks();
67
  $this->query_filters_terms->add_hooks();
68
+ }
69
+
70
+ private function add_hooks_specific_for_v1(){
71
+
72
+ if ( 1 === WCML_REST_API::get_api_request_version()){
73
+ add_action( 'woocommerce_rest_prepare_product', array( $this, 'append_product_language_and_translations' ) );
74
+ add_action( 'woocommerce_rest_prepare_product', array( $this, 'append_product_secondary_prices' ) );
75
+
76
+ add_action( 'woocommerce_rest_insert_product', array( $this, 'set_product_language' ), 10, 2 );
77
+ add_action( 'woocommerce_rest_update_product', array( $this, 'set_product_language' ), 10, 2 );
78
 
79
+ add_action( 'woocommerce_rest_insert_product', array( $this, 'set_product_custom_prices' ), 10, 2 );
80
+ add_action( 'woocommerce_rest_update_product', array( $this, 'set_product_custom_prices' ), 10, 2 );
81
+
82
+ add_action( 'woocommerce_rest_insert_product', array( $this, 'copy_custom_fields_from_original' ), 10, 1 );
83
+
84
+ add_action( 'woocommerce_rest_prepare_product', array( $this, 'copy_product_custom_fields' ), 10 , 3 );
85
+
86
+ add_action( 'woocommerce_rest_insert_shop_order' , array( $this, 'set_order_language' ), 10, 2 );
87
+ }
88
  }
89
 
90
  /**
207
  /**
208
  * Sets the product information according to the provided language
209
  *
210
+ * @param WC_Product|WP_Post $product
211
  * @param WP_REST_Request $request
212
  *
213
  * @throws WCML_REST_Invalid_Language_Exception
233
  $trid = null;
234
  }
235
 
236
+ $product_id = $this->get_product_id( $product );
237
+
238
+ $this->sitepress->set_element_language_details( $product_id, 'post_product', $trid, $data['lang'] );
239
+ wpml_tm_save_post( $product_id, get_post( $product_id ), ICL_TM_COMPLETE );
240
  }else{
241
  if( isset( $data['translation_of'] ) ){
242
  throw new WCML_REST_Generic_Exception( __( 'Using "translation_of" requires providing a "lang" parameter too', 'woocommerce-multilingual' ) );
248
  /**
249
  * Sets custom prices in secondary currencies for products
250
  *
251
+ * @param WC_Product|WP_Post $product
252
  * @param WP_REST_Request $request
253
  *
254
  * @throws WC_API_Exception
262
 
263
  if( !empty( $data['custom_prices'] ) ){
264
 
265
+ $product_id = $this->get_product_id( $product );
266
+
267
+ $original_post_id = $this->sitepress->get_original_element_id_filter( '', $product_id, 'post_product' );
268
 
269
  update_post_meta( $original_post_id, '_wcml_custom_prices_status', 1);
270
 
284
  }
285
 
286
  /**
287
+ * @param WC_Product|WP_Post $product
288
  */
289
+ public function copy_custom_fields_from_original( $product ){
 
290
 
291
+ $product_id = $this->get_product_id( $product );
292
+
293
+ $original_post_id = $this->sitepress->get_original_element_id_filter( '', $product_id, 'post_product' );
294
+
295
+ if( $original_post_id !== $product_id ){
296
+ $this->sitepress->copy_custom_fields( $original_post_id, $product_id );
297
  }
298
  }
299
 
322
  /**
323
  * Sets the language for a new order
324
  *
325
+ * @param WC_Order|WP_Post $order
326
  * @param WP_REST_Request $request
327
  *
328
  * @throws WCML_REST_Invalid_Language_Exception
331
 
332
  $data = $request->get_params();
333
  if( isset( $data['lang'] ) ){
334
+ if( $order instanceof WC_Order ){
335
+ $order_id = $order->get_id();
336
+ }else{
337
+ $order_id = $order->ID;
338
+ }
339
  $active_languages = $this->sitepress->get_active_languages();
340
  if( !isset( $active_languages[$data['lang']] ) ){
341
  throw new WCML_REST_Invalid_Language_Exception( $data['lang'] );
356
  public function set_order_currency( $order, $request ) {
357
  $data = $request->get_params();
358
  if ( isset( $data['currency'] ) ) {
359
+ $order_id = $order->get_id();
360
  $currencies = get_woocommerce_currencies();
361
  if ( ! isset( $currencies[ $data['currency'] ] ) ) {
362
  throw new WCML_REST_Invalid_Currency_Exception( $data['currency'] );
365
  }
366
  }
367
 
368
+ /**
369
+ * @param WC_Product|WP_Post $product
370
+ *
371
+ * @return int
372
+ */
373
+ private function get_product_id( $product ) {
374
+ if ( $product instanceof WC_Product ) {
375
+ return $product->get_id();
376
+ } else {
377
+ return $product->ID;
378
+ }
379
+ }
380
+
381
  }
classes/rest-api-support/class-wcml-rest-api.php CHANGED
@@ -25,7 +25,7 @@ class WCML_REST_API {
25
  * @return int
26
  * Returns the version number of the API used for the current request
27
  */
28
- public function get_api_request_version(){
29
  $version = 0;
30
  $rest_prefix = trailingslashit( rest_get_url_prefix() );
31
  if( preg_match( "@" . $rest_prefix . "wc/v([0-9]+)/@", $_SERVER['REQUEST_URI'], $matches ) ){
25
  * @return int
26
  * Returns the version number of the API used for the current request
27
  */
28
+ public static function get_api_request_version(){
29
  $version = 0;
30
  $rest_prefix = trailingslashit( rest_get_url_prefix() );
31
  if( preg_match( "@" . $rest_prefix . "wc/v([0-9]+)/@", $_SERVER['REQUEST_URI'], $matches ) ){
classes/rest-api-support/filters/class-wcml-rest-api-query-filters-terms.php CHANGED
@@ -37,7 +37,7 @@ class WCML_REST_API_Query_Filters_Terms{
37
  $active_languages = $this->sitepress->get_active_languages();
38
 
39
  if ( 'all' === $data['lang'] ) {
40
- remove_filter( 'terms_clauses', array( $this->sitepress, 'terms_clauses' ), 10, 4 );
41
  remove_filter( 'get_term', array( $this->sitepress, 'get_term_adjust_id' ), 1, 1 );
42
  } elseif ( ! isset( $active_languages[ $data['lang'] ] ) ) {
43
  throw new WCML_REST_Invalid_Language_Exception( $data['lang'] );
37
  $active_languages = $this->sitepress->get_active_languages();
38
 
39
  if ( 'all' === $data['lang'] ) {
40
+ remove_filter( 'terms_clauses', array( $this->sitepress, 'terms_clauses' ), 10 );
41
  remove_filter( 'get_term', array( $this->sitepress, 'get_term_adjust_id' ), 1, 1 );
42
  } elseif ( ! isset( $active_languages[ $data['lang'] ] ) ) {
43
  throw new WCML_REST_Invalid_Language_Exception( $data['lang'] );
classes/shortcodes/class-wcml-wc-shortcode-product-category.php CHANGED
@@ -37,7 +37,7 @@ class WCML_WC_Shortcode_Product_Category {
37
 
38
  if ( isset( $args['product_cat'] ) ) {
39
  $args = $this->translate_categories_using_simple_tax_query( $args );
40
- } elseif ( isset( $atts['category'] ) && isset( $args['tax_query'] ) ) {
41
 
42
  // Get translated category slugs, we need to remove WPML filter.
43
  $filter_exists = remove_filter( 'terms_clauses', array( $this->sitepress, 'terms_clauses' ), 10 );
@@ -45,7 +45,7 @@ class WCML_WC_Shortcode_Product_Category {
45
  $categories = get_terms( array( 'slug' => $slugs, 'taxonomy' => 'product_cat' ) );
46
 
47
  if ( $filter_exists ) {
48
- add_filter( 'terms_clauses', array( $this->sitepress, 'terms_clauses' ), 10, 4 );
49
  }
50
 
51
  // Replace slugs in query arguments.
@@ -82,7 +82,7 @@ class WCML_WC_Shortcode_Product_Category {
82
  $filter_exists = remove_filter( 'terms_clauses', array( $this->sitepress, 'terms_clauses' ), 10 );
83
  $categories_translated = get_terms( array( 'slug' => $category_slugs, 'taxonomy' => 'product_cat' ) );
84
  if ( $filter_exists ) {
85
- add_filter( 'terms_clauses', array( $this->sitepress, 'terms_clauses' ), 10, 4 );
86
  }
87
 
88
  $category_slugs_translated = array();
37
 
38
  if ( isset( $args['product_cat'] ) ) {
39
  $args = $this->translate_categories_using_simple_tax_query( $args );
40
+ } elseif ( ! empty( $atts['category'] ) && isset( $args['tax_query'] ) ) {
41
 
42
  // Get translated category slugs, we need to remove WPML filter.
43
  $filter_exists = remove_filter( 'terms_clauses', array( $this->sitepress, 'terms_clauses' ), 10 );
45
  $categories = get_terms( array( 'slug' => $slugs, 'taxonomy' => 'product_cat' ) );
46
 
47
  if ( $filter_exists ) {
48
+ add_filter( 'terms_clauses', array( $this->sitepress, 'terms_clauses' ), 10, 3 );
49
  }
50
 
51
  // Replace slugs in query arguments.
82
  $filter_exists = remove_filter( 'terms_clauses', array( $this->sitepress, 'terms_clauses' ), 10 );
83
  $categories_translated = get_terms( array( 'slug' => $category_slugs, 'taxonomy' => 'product_cat' ) );
84
  if ( $filter_exists ) {
85
+ add_filter( 'terms_clauses', array( $this->sitepress, 'terms_clauses' ), 10, 3 );
86
  }
87
 
88
  $category_slugs_translated = array();
classes/wcml-setup/class-wcml-setup.php CHANGED
@@ -35,8 +35,6 @@ class WCML_Setup {
35
  $this->woocommerce_wpml = $woocommerce_wpml;
36
  $this->sitepress = $sitepress;
37
 
38
- $include_translation_options_step = $this->sitepress->get_wp_api()->version_compare( $this->sitepress->get_wp_api()->constant( 'ICL_SITEPRESS_VERSION' ), '3.9.0', '>=' );
39
-
40
  $this->steps = array(
41
  'introduction' => array(
42
  'name' => __( 'Introduction', 'woocommerce-multilingual' ),
@@ -67,22 +65,22 @@ class WCML_Setup {
67
  'name' => __( 'Multiple Currencies', 'woocommerce-multilingual' ),
68
  'view' => new WCML_Setup_Multi_Currency_UI(
69
  $this->woocommerce_wpml,
70
- $this->step_url( $include_translation_options_step ? 'translation-options' :'ready' )
71
  ),
72
  'handler' => array( $this->handlers, 'save_multi_currency' )
73
  )
74
  );
75
 
76
- if ( $include_translation_options_step ) {
77
- $this->steps['translation-options'] = array(
78
- 'name' => __( 'Translation Options', 'woocommerce-multilingual' ),
79
- 'view' => new WCML_Setup_Translation_Options_UI(
80
- $this->woocommerce_wpml,
81
- $this->step_url( 'ready' )
82
- ),
83
- 'handler' => array( $this->handlers, 'save_translation_options' )
84
- );
85
- }
86
 
87
  $this->steps['ready'] = array(
88
  'name' => __( 'Ready!', 'woocommerce-multilingual' ),
@@ -165,7 +163,7 @@ class WCML_Setup {
165
  'install'
166
  ), WCML_VERSION );
167
 
168
- wp_enqueue_script( 'wcml-setup', WCML_PLUGIN_URL . '/res/js/wcml-setup.js', array( 'jquery' ), WCML_VERSION );
169
 
170
 
171
  $this->ui->setup_header( $this->steps, $this->step );
@@ -279,4 +277,4 @@ class WCML_Setup {
279
  }
280
  }
281
 
282
- }
35
  $this->woocommerce_wpml = $woocommerce_wpml;
36
  $this->sitepress = $sitepress;
37
 
 
 
38
  $this->steps = array(
39
  'introduction' => array(
40
  'name' => __( 'Introduction', 'woocommerce-multilingual' ),
65
  'name' => __( 'Multiple Currencies', 'woocommerce-multilingual' ),
66
  'view' => new WCML_Setup_Multi_Currency_UI(
67
  $this->woocommerce_wpml,
68
+ $this->step_url( 'translation-options' )
69
  ),
70
  'handler' => array( $this->handlers, 'save_multi_currency' )
71
  )
72
  );
73
 
74
+
75
+ $this->steps['translation-options'] = array(
76
+ 'name' => __( 'Translation Options', 'woocommerce-multilingual' ),
77
+ 'view' => new WCML_Setup_Translation_Options_UI(
78
+ $this->woocommerce_wpml,
79
+ $this->step_url( 'ready' )
80
+ ),
81
+ 'handler' => array( $this->handlers, 'save_translation_options' )
82
+ );
83
+
84
 
85
  $this->steps['ready'] = array(
86
  'name' => __( 'Ready!', 'woocommerce-multilingual' ),
163
  'install'
164
  ), WCML_VERSION );
165
 
166
+ wp_enqueue_script( 'wcml-setup', WCML_PLUGIN_URL . '/res/js/wcml-setup.js', array( 'jquery' ), WCML_VERSION, true );
167
 
168
 
169
  $this->ui->setup_header( $this->steps, $this->step );
277
  }
278
  }
279
 
280
+ }
compatibility/class-wcml-adventure-tours.php CHANGED
@@ -262,7 +262,7 @@ class WCML_Adventure_tours{
262
  global $pagenow;
263
 
264
  if( $pagenow == 'post.php' || $pagenow == 'post-new.php' ){
265
- wp_register_script( 'wcml-adventure-tours', WCML_PLUGIN_URL . '/compatibility/res/js/wcml-adventure-tours.js', array( 'jquery' ), WCML_VERSION );
266
  wp_enqueue_script( 'wcml-adventure-tours' );
267
  }
268
  }
@@ -392,4 +392,4 @@ class WCML_Adventure_tours{
392
  return $fields;
393
  }
394
 
395
- }
262
  global $pagenow;
263
 
264
  if( $pagenow == 'post.php' || $pagenow == 'post-new.php' ){
265
+ wp_register_script( 'wcml-adventure-tours', WCML_PLUGIN_URL . '/compatibility/res/js/wcml-adventure-tours.js', array( 'jquery' ), WCML_VERSION, true );
266
  wp_enqueue_script( 'wcml-adventure-tours' );
267
  }
268
  }
392
  return $fields;
393
  }
394
 
395
+ }
compatibility/class-wcml-bookings.php CHANGED
@@ -173,17 +173,6 @@ class WCML_Bookings {
173
  //allow filtering resources by language
174
  add_filter( 'get_booking_resources_args', array( $this, 'filter_get_booking_resources_args' ) );
175
 
176
- if ( $this->sitepress->get_wp_api()->version_compare( $this->sitepress->get_wp_api()->constant( 'ICL_SITEPRESS_VERSION' ), '3.8.0', '<' ) ) {
177
- add_filter( 'get_translatable_documents', array( $this, 'filter_translatable_documents' ) );
178
-
179
- //@TODO review after WPML 3.6
180
- if ( $this->sitepress->get_wp_api()->version_compare( $this->sitepress->get_wp_api()->constant( 'ICL_SITEPRESS_VERSION' ), '3.6', '<' ) ) {
181
- add_action( 'added_post_meta', array(
182
- $this,
183
- 'maybe_fix_double_serialized_wc_booking_availability'
184
- ), 10, 4 );
185
- }
186
- }
187
  add_filter( 'get_translatable_documents_all', array( $this, 'filter_translatable_documents' ) );
188
 
189
  add_filter( 'pre_wpml_is_translated_post_type', array( $this, 'filter_is_translated_post_type' ) );
@@ -305,7 +294,7 @@ class WCML_Bookings {
305
  $wc_currencies = get_woocommerce_currencies();
306
 
307
  if ( ! function_exists( 'woocommerce_wp_text_input' ) ) {
308
- include_once dirname( WC_PLUGIN_FILE ) . 'includes/admin/wc-meta-box-functions.php';
309
  }
310
 
311
  echo '<div class="wcml_custom_cost_field" >';
@@ -1085,14 +1074,15 @@ class WCML_Bookings {
1085
  $product_id = $pagenow == 'post.php' && isset( $_GET['post'] ) ? (int)$_GET['post'] : false;
1086
 
1087
  if( $product_id && get_post_type( $product_id ) === 'product' ){
1088
- $product_type = WooCommerce_Functions_Wrapper::get_product_type( $product_id );
 
1089
 
1090
- if ( ( $product_type === 'booking' || $product_type === $external_product_type ) || $pagenow == 'post-new.php' ) {
1091
 
1092
  wp_register_style( 'wcml-bookings-css', WCML_PLUGIN_URL . '/compatibility/res/css/wcml-bookings.css', array(), WCML_VERSION );
1093
  wp_enqueue_style( 'wcml-bookings-css' );
1094
 
1095
- wp_register_script( 'wcml-bookings-js', WCML_PLUGIN_URL . '/compatibility/res/js/wcml-bookings.js', array( 'jquery' ), WCML_VERSION );
1096
  wp_enqueue_script( 'wcml-bookings-js' );
1097
 
1098
  }
@@ -1314,7 +1304,8 @@ class WCML_Bookings {
1314
  }
1315
 
1316
  function custom_box_html( $obj, $product_id, $data ) {
1317
- if ( WooCommerce_Functions_Wrapper::get_product_type( $product_id ) !== 'booking' ) {
 
1318
  return;
1319
  }
1320
 
@@ -1377,7 +1368,7 @@ class WCML_Bookings {
1377
 
1378
  function custom_box_html_data( $data, $product_id, $translation, $lang ) {
1379
 
1380
- if ( WooCommerce_Functions_Wrapper::get_product_type( $product_id ) !== 'booking' ) {
1381
  return $data;
1382
  }
1383
 
@@ -1865,9 +1856,7 @@ class WCML_Bookings {
1865
  function append_persons_to_translation_package( $package, $post ) {
1866
 
1867
  if ( $post->post_type == 'product' ) {
1868
- $product_type = WooCommerce_Functions_Wrapper::get_product_type( $post->ID );
1869
-
1870
- if ( $product_type === 'booking' ) {
1871
 
1872
  $bookable_product = new WC_Product_Booking( $post->ID );
1873
 
@@ -1902,7 +1891,7 @@ class WCML_Bookings {
1902
  function save_person_translation( $post_id, $data, $job ) {
1903
  $person_translations = array();
1904
 
1905
- if ( WooCommerce_Functions_Wrapper::get_product_type( $post_id ) === 'booking' ) {
1906
 
1907
  foreach ( $data as $value ) {
1908
 
@@ -1968,10 +1957,7 @@ class WCML_Bookings {
1968
 
1969
  if ( $post->post_type == 'product' ) {
1970
  $product = wc_get_product( $post->ID );
1971
-
1972
- $product_type = WooCommerce_Functions_Wrapper::get_product_type( $post->ID );
1973
-
1974
- if ( $product_type === 'booking' && $product->has_resources() ) {
1975
 
1976
  $resources = $product->get_resources();
1977
 
@@ -1996,7 +1982,7 @@ class WCML_Bookings {
1996
  function save_resource_translation( $post_id, $data, $job ) {
1997
  $resource_translations = array();
1998
 
1999
- if ( WooCommerce_Functions_Wrapper::get_product_type( $post_id ) === 'booking' ) {
2000
 
2001
  foreach ( $data as $value ) {
2002
 
@@ -2298,28 +2284,6 @@ class WCML_Bookings {
2298
  return true;
2299
  }
2300
 
2301
- public function maybe_fix_double_serialized_wc_booking_availability( $mid, $object_id, $meta_key, $_meta_value ) {
2302
- global $wpdb;
2303
-
2304
- if ( version_compare( ICL_SITEPRESS_VERSION, '3.6', '<' ) ) {
2305
-
2306
- $meta_keys_to_fix = array(
2307
- '_wc_booking_availability',
2308
- '_wc_booking_pricing'
2309
- );
2310
-
2311
- if ( in_array( $meta_key, $meta_keys_to_fix ) ) {
2312
-
2313
- if ( is_string( $_meta_value ) ) {
2314
- $wpdb->update( $wpdb->postmeta, array( 'meta_value' => $_meta_value ), array( 'meta_id' => $mid ) );
2315
- }
2316
-
2317
- }
2318
-
2319
- }
2320
-
2321
- }
2322
-
2323
  public function extra_conditions_to_filter_bookings( $extra_conditions ){
2324
 
2325
  if( isset( $_GET[ 'post_type' ] ) && $_GET[ 'post_type' ] == 'wc_booking' && !isset( $_GET[ 'post_status' ] ) ){
@@ -2569,4 +2533,16 @@ class WCML_Bookings {
2569
 
2570
  }
2571
 
 
 
 
 
 
 
 
 
 
 
 
 
2572
  }
173
  //allow filtering resources by language
174
  add_filter( 'get_booking_resources_args', array( $this, 'filter_get_booking_resources_args' ) );
175
 
 
 
 
 
 
 
 
 
 
 
 
176
  add_filter( 'get_translatable_documents_all', array( $this, 'filter_translatable_documents' ) );
177
 
178
  add_filter( 'pre_wpml_is_translated_post_type', array( $this, 'filter_is_translated_post_type' ) );
294
  $wc_currencies = get_woocommerce_currencies();
295
 
296
  if ( ! function_exists( 'woocommerce_wp_text_input' ) ) {
297
+ include_once dirname( WC_PLUGIN_FILE ) . '/includes/admin/wc-meta-box-functions.php';
298
  }
299
 
300
  echo '<div class="wcml_custom_cost_field" >';
1074
  $product_id = $pagenow == 'post.php' && isset( $_GET['post'] ) ? (int)$_GET['post'] : false;
1075
 
1076
  if( $product_id && get_post_type( $product_id ) === 'product' ){
1077
+ $product = wc_get_product( $product_id );
1078
+ $product_type = $product->get_type();
1079
 
1080
+ if ( ( $this->is_booking( $product ) || $product_type === $external_product_type ) || $pagenow == 'post-new.php' ) {
1081
 
1082
  wp_register_style( 'wcml-bookings-css', WCML_PLUGIN_URL . '/compatibility/res/css/wcml-bookings.css', array(), WCML_VERSION );
1083
  wp_enqueue_style( 'wcml-bookings-css' );
1084
 
1085
+ wp_register_script( 'wcml-bookings-js', WCML_PLUGIN_URL . '/compatibility/res/js/wcml-bookings.js', array( 'jquery' ), WCML_VERSION, true );
1086
  wp_enqueue_script( 'wcml-bookings-js' );
1087
 
1088
  }
1304
  }
1305
 
1306
  function custom_box_html( $obj, $product_id, $data ) {
1307
+
1308
+ if ( !$this->is_booking( $product_id ) ) {
1309
  return;
1310
  }
1311
 
1368
 
1369
  function custom_box_html_data( $data, $product_id, $translation, $lang ) {
1370
 
1371
+ if ( !$this->is_booking( $product_id ) ) {
1372
  return $data;
1373
  }
1374
 
1856
  function append_persons_to_translation_package( $package, $post ) {
1857
 
1858
  if ( $post->post_type == 'product' ) {
1859
+ if ( $this->is_booking( $post->ID ) ) {
 
 
1860
 
1861
  $bookable_product = new WC_Product_Booking( $post->ID );
1862
 
1891
  function save_person_translation( $post_id, $data, $job ) {
1892
  $person_translations = array();
1893
 
1894
+ if ( $this->is_booking( $post_id ) ) {
1895
 
1896
  foreach ( $data as $value ) {
1897
 
1957
 
1958
  if ( $post->post_type == 'product' ) {
1959
  $product = wc_get_product( $post->ID );
1960
+ if ( $this->is_booking( $product ) && $product->has_resources() ) {
 
 
 
1961
 
1962
  $resources = $product->get_resources();
1963
 
1982
  function save_resource_translation( $post_id, $data, $job ) {
1983
  $resource_translations = array();
1984
 
1985
+ if ( $this->is_booking( $post_id ) ) {
1986
 
1987
  foreach ( $data as $value ) {
1988
 
2284
  return true;
2285
  }
2286
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2287
  public function extra_conditions_to_filter_bookings( $extra_conditions ){
2288
 
2289
  if( isset( $_GET[ 'post_type' ] ) && $_GET[ 'post_type' ] == 'wc_booking' && !isset( $_GET[ 'post_status' ] ) ){
2533
 
2534
  }
2535
 
2536
+ /**
2537
+ * @param WC_Product|int|string $product
2538
+ *
2539
+ * @return bool
2540
+ */
2541
+ private function is_booking( $product ){
2542
+ if( !$product instanceof WC_Product ){
2543
+ $product = wc_get_product( $product );
2544
+ }
2545
+ return $product->get_type() === 'booking';
2546
+ }
2547
+
2548
  }
compatibility/class-wcml-composite-products.php CHANGED
@@ -34,6 +34,8 @@ class WCML_Composite_Products extends WCML_Compatibility_Helper{
34
  add_filter( 'wcml_cart_contents', array($this, 'wpml_composites_compat'), 11, 4 );
35
  add_filter( 'woocommerce_composite_component_options_query_args', array($this, 'wpml_composites_transients_cache_per_language'), 10, 3 );
36
  add_action( 'wcml_before_sync_product', array( $this, 'sync_composite_data_across_translations'), 10, 2 );
 
 
37
 
38
  if( is_admin() ){
39
 
@@ -259,7 +261,7 @@ class WCML_Composite_Products extends WCML_Compatibility_Helper{
259
  return $data;
260
  }
261
 
262
- function components_update( $original_product_id, $product_id, $data, $language ){
263
 
264
  $composite_data = $this->get_composite_data( $original_product_id );
265
 
@@ -458,8 +460,8 @@ class WCML_Composite_Products extends WCML_Compatibility_Helper{
458
  function load_assets( ){
459
  global $pagenow;
460
 
461
- if( ( $pagenow == 'post.php' && isset( $_GET[ 'post' ] ) && WooCommerce_Functions_Wrapper::get_product_type( $_GET[ 'post' ] ) === 'composite' ) || $pagenow == 'post-new.php' ){
462
- wp_register_script( 'wcml-composite-js', WCML_PLUGIN_URL . '/compatibility/res/js/wcml-composite.js', array( 'jquery' ), WCML_VERSION );
463
  wp_enqueue_script( 'wcml-composite-js' );
464
 
465
  }
@@ -556,4 +558,8 @@ class WCML_Composite_Products extends WCML_Compatibility_Helper{
556
  return $fields;
557
  }
558
 
 
 
 
 
559
  }
34
  add_filter( 'wcml_cart_contents', array($this, 'wpml_composites_compat'), 11, 4 );
35
  add_filter( 'woocommerce_composite_component_options_query_args', array($this, 'wpml_composites_transients_cache_per_language'), 10, 3 );
36
  add_action( 'wcml_before_sync_product', array( $this, 'sync_composite_data_across_translations'), 10, 2 );
37
+ add_filter( 'raw_woocommerce_price', array( $this, 'apply_rounding_rules' ) );
38
+
39
 
40
  if( is_admin() ){
41
 
261
  return $data;
262
  }
263
 
264
+ function components_update( $original_product_id, $product_id, $data, $language ){
265
 
266
  $composite_data = $this->get_composite_data( $original_product_id );
267
 
460
  function load_assets( ){
461
  global $pagenow;
462
 
463
+ if( ( $pagenow == 'post.php' && isset( $_GET[ 'post' ] ) && wc_get_product( $_GET[ 'post' ] )->get_type() === 'composite' ) || $pagenow == 'post-new.php' ){
464
+ wp_register_script( 'wcml-composite-js', WCML_PLUGIN_URL . '/compatibility/res/js/wcml-composite.js', array( 'jquery' ), WCML_VERSION, true );
465
  wp_enqueue_script( 'wcml-composite-js' );
466
 
467
  }
558
  return $fields;
559
  }
560
 
561
+ public function apply_rounding_rules( $price ) {
562
+ return $this->woocommerce_wpml->multi_currency->prices->apply_rounding_rules( $price );
563
+ }
564
+
565
  }
compatibility/class-wcml-dynamic-pricing.php CHANGED
@@ -97,7 +97,7 @@ class WCML_Dynamic_Pricing {
97
  $cat_ids[$i] = apply_filters( 'translate_object_id', $cat_id, 'product_cat', true );
98
  }
99
 
100
- $process_discounts = is_object_in_term( WooCommerce_Functions_Wrapper::get_product_id( $_product ), 'product_cat', $cat_ids );
101
  }
102
 
103
  return $process_discounts;
97
  $cat_ids[$i] = apply_filters( 'translate_object_id', $cat_id, 'product_cat', true );
98
  }
99
 
100
+ $process_discounts = is_object_in_term( $_product->get_id(), 'product_cat', $cat_ids );
101
  }
102
 
103
  return $process_discounts;
compatibility/class-wcml-flatsome.php CHANGED
@@ -6,11 +6,12 @@ class WCML_Flatsome{
6
  add_filter( 'wcml_multi_currency_ajax_actions', array( $this, 'add_action_to_multi_currency_ajax' ) );
7
  }
8
 
9
- function add_action_to_multi_currency_ajax($actions){
 
10
  $actions[] = 'ux_quickview';
 
 
11
  return $actions;
12
  }
13
 
14
-
15
  }
16
-
6
  add_filter( 'wcml_multi_currency_ajax_actions', array( $this, 'add_action_to_multi_currency_ajax' ) );
7
  }
8
 
9
+ function add_action_to_multi_currency_ajax( $actions ){
10
+
11
  $actions[] = 'ux_quickview';
12
+ $actions[] = 'flatsome_ajax_search_products';
13
+
14
  return $actions;
15
  }
16
 
 
17
  }
 
compatibility/class-wcml-pip.php CHANGED
@@ -78,7 +78,7 @@ class WCML_Pip{
78
  $the_order = WC()->order_factory->get_order( $pip_order_id );
79
 
80
  if( $the_order ){
81
- $currency = WooCommerce_Functions_Wrapper::get_order_currency( $the_order );
82
 
83
  if( !$currency && isset( $_COOKIE[ '_wcml_order_currency' ] ) ){
84
  $currency = $_COOKIE[ '_wcml_order_currency' ];
78
  $the_order = WC()->order_factory->get_order( $pip_order_id );
79
 
80
  if( $the_order ){
81
+ $currency = $the_order->get_currency();
82
 
83
  if( !$currency && isset( $_COOKIE[ '_wcml_order_currency' ] ) ){
84
  $currency = $_COOKIE[ '_wcml_order_currency' ];
compatibility/class-wcml-product-addons.php CHANGED
@@ -5,47 +5,54 @@
5
  */
6
  class WCML_Product_Addons {
7
 
 
 
 
 
 
8
  /**
9
  * @var SitePress
10
  */
11
  public $sitepress;
 
 
 
 
12
  /**
13
  * @var int
14
  */
15
- private $enable_multi_currency_setting;
16
 
17
  /**
18
  * WCML_Product_Addons constructor.
19
  * @param SitePress $sitepress
20
- * @param int $enable_multi_currency_setting
21
  */
22
- function __construct( SitePress $sitepress, $enable_multi_currency_setting ){
23
- $this->sitepress = $sitepress;
24
- $this->enable_multi_currency_setting = $enable_multi_currency_setting;
 
25
  }
26
 
27
  public function add_hooks(){
 
 
28
  add_filter( 'get_product_addons_product_terms', array( $this, 'addons_product_terms' ) );
29
- add_filter( 'get_product_addons_fields', array( $this, 'product_addons_filter' ), 10, 1 );
30
 
31
  add_action( 'updated_post_meta', array( $this, 'register_addons_strings' ), 10, 4 );
32
  add_action( 'added_post_meta', array( $this, 'register_addons_strings' ), 10, 4 );
33
 
34
- global $pagenow;
35
- if ( 'edit.php' === $pagenow &&
36
- isset( $_GET['post_type'] ) &&
37
- 'product' === $_GET['post_type'] &&
38
- isset( $_GET['page'] ) &&
39
- 'global_addons' === $_GET['page'] &&
40
- ! isset( $_GET['edit'] )
41
- ) {
42
- add_action( 'admin_notices', array( $this, 'inf_translate_strings' ) );
43
- }
44
-
45
  add_action( 'woocommerce-product-addons_panel_start', array( $this, 'show_pointer_info' ) );
46
 
47
  if ( is_admin() ) {
48
 
 
 
 
 
 
 
49
  add_action( 'wcml_gui_additional_box_html', array( $this, 'custom_box_html' ), 10, 3 );
50
  add_filter( 'wcml_gui_additional_box_data', array( $this, 'custom_box_html_data' ), 10, 3 );
51
  add_action( 'wcml_update_extra_fields', array( $this, 'addons_update' ), 10, 3 );
@@ -53,6 +60,14 @@ class WCML_Product_Addons {
53
  add_action( 'woocommerce_product_data_panels', array( $this, 'show_pointer_info' ) );
54
 
55
  add_filter( 'wcml_do_not_display_custom_fields_for_product', array( $this, 'replace_tm_editor_custom_fields_with_own_sections' ) );
 
 
 
 
 
 
 
 
56
  }else{
57
  add_filter( 'get_post_metadata', array( $this, 'translate_addons_strings' ), 10, 4 );
58
  }
@@ -66,7 +81,26 @@ class WCML_Product_Addons {
66
  $this,
67
  'set_global_ids_in_query_args'
68
  ) );
 
 
69
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
70
  }
71
 
72
  /**
@@ -77,6 +111,7 @@ class WCML_Product_Addons {
77
  */
78
  function register_addons_strings( $meta_id, $id, $meta_key, $addons ) {
79
  if ( '_product_addons' === $meta_key && 'global_product_addon' === get_post_type( $id ) ) {
 
80
  foreach ( $addons as $addon ) {
81
  //register name
82
  do_action( 'wpml_register_single_string', 'wc_product_addons_strings', $id . '_addon_' . $addon['type'] . '_' . $addon['position'] . '_name', $addon['name'] );
@@ -128,22 +163,48 @@ class WCML_Product_Addons {
128
 
129
  /**
130
  * @param $addons
 
131
  *
132
  * @return mixed
133
  */
134
- function product_addons_filter( $addons ) {
 
 
135
 
136
- foreach ( $addons as $add_id => $addon ) {
137
- foreach ( $addon['options'] as $key => $option ) {
138
- //price filter
139
- $addons[ $add_id ]['options'][ $key ]['price'] = apply_filters( 'wcml_raw_price_amount', $option['price'] );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
140
  }
141
  }
142
 
143
  return $addons;
144
  }
145
 
146
-
147
  /**
148
  * @param $product_terms
149
  *
@@ -162,7 +223,7 @@ class WCML_Product_Addons {
162
  $pointer_ui = new WCML_Pointer_UI(
163
  sprintf( __( 'You can translate strings related to global add-ons on the %sWPML String Translation page%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>' ),
164
  'https://wpml.org/documentation/woocommerce-extensions-compatibility/translating-woocommerce-product-add-ons-woocommerce-multilingual/',
165
- 'wpbody-content .woocommerce h2'
166
  );
167
 
168
  $pointer_ui->show();
@@ -175,7 +236,7 @@ class WCML_Product_Addons {
175
  */
176
  function custom_box_html( $obj, $product_id, $data ) {
177
 
178
- $product_addons = maybe_unserialize( get_post_meta( $product_id, '_product_addons', true ) );
179
 
180
  if ( ! empty( $product_addons ) ) {
181
  foreach ( $product_addons as $addon_id => $product_addon ) {
@@ -214,7 +275,7 @@ class WCML_Product_Addons {
214
  */
215
  function custom_box_html_data( $data, $product_id, $translation ) {
216
 
217
- $product_addons = maybe_unserialize( get_post_meta( $product_id, '_product_addons', true ) );
218
 
219
  if ( ! empty( $product_addons ) ) {
220
  foreach ( $product_addons as $addon_id => $product_addon ) {
@@ -228,9 +289,9 @@ class WCML_Product_Addons {
228
  }
229
 
230
  if ( $translation ) {
231
- $transalted_product_addons = maybe_unserialize( get_post_meta( $translation->ID, '_product_addons', true ) );
232
- if ( ! empty( $transalted_product_addons ) ) {
233
- foreach ( $transalted_product_addons as $addon_id => $transalted_product_addon ) {
234
  $data[ 'addon_' . $addon_id . '_name' ]['translation'] = $transalted_product_addon['name'];
235
  $data[ 'addon_' . $addon_id . '_description' ]['translation'] = $transalted_product_addon['description'];
236
  if ( ! empty( $transalted_product_addon['options'] ) ) {
@@ -253,7 +314,7 @@ class WCML_Product_Addons {
253
  */
254
  function addons_update( $original_product_id, $product_id, $data ) {
255
 
256
- $product_addons = maybe_unserialize( get_post_meta( $original_product_id, '_product_addons', true ) );
257
 
258
  if ( ! empty( $product_addons ) ) {
259
 
@@ -294,10 +355,9 @@ class WCML_Product_Addons {
294
  // special case for WC Bookings plugin - need add addon cost after re-calculating booking costs #wcml-1877
295
  public function filter_booking_addon_product_in_cart_contents( $cart_item ) {
296
 
297
- $is_multi_currency_on = $this->enable_multi_currency_setting == WCML_MULTI_CURRENCIES_INDEPENDENT;
298
  $is_booking_product_with_addons = $cart_item['data'] instanceof WC_Product_Booking && isset( $cart_item['addons'] );
299
 
300
- if ( $is_multi_currency_on && $is_booking_product_with_addons ) {
301
  $cost = $cart_item['data']->get_price();
302
 
303
  foreach( $cart_item['addons'] as $addon ){
@@ -316,7 +376,7 @@ class WCML_Product_Addons {
316
 
317
  remove_filter( 'get_terms_args', array( $this->sitepress, 'get_terms_args_filter' ), 10, 2 );
318
  remove_filter( 'get_term', array( $this->sitepress, 'get_term_adjust_id' ), 1 );
319
- remove_filter( 'terms_clauses', array( $this->sitepress, 'terms_clauses' ), 10, 4 );
320
 
321
  $matched_addons_ids = wp_list_pluck( get_posts( $args ), 'ID' );
322
 
@@ -327,10 +387,238 @@ class WCML_Product_Addons {
327
 
328
  add_filter( 'get_terms_args', array( $this->sitepress, 'get_terms_args_filter' ), 10, 2 );
329
  add_filter( 'get_term', array( $this->sitepress, 'get_term_adjust_id' ), 1 );
330
- add_filter( 'terms_clauses', array( $this->sitepress, 'terms_clauses' ), 10, 4 );
331
  }
332
 
333
  return $args;
334
  }
335
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
336
  }
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
  * @param SitePress $sitepress
29
+ * @param woocommerce_wpml $woocommerce_wpml
30
  */
31
+ function __construct( SitePress $sitepress, woocommerce_wpml $woocommerce_wpml ) {
32
+ $this->sitepress = $sitepress;
33
+ $this->woocommerce_wpml = $woocommerce_wpml;
34
+ $this->multi_currency_mode = $woocommerce_wpml->settings['enable_multi_currency'];
35
  }
36
 
37
  public function add_hooks(){
38
+
39
+ add_action( 'init', array( $this, 'load_assets' ) );
40
  add_filter( 'get_product_addons_product_terms', array( $this, 'addons_product_terms' ) );
41
+ add_filter( 'get_product_addons_fields', array( $this, 'product_addons_price_filter' ), 10, 2 );
42
 
43
  add_action( 'updated_post_meta', array( $this, 'register_addons_strings' ), 10, 4 );
44
  add_action( 'added_post_meta', array( $this, 'register_addons_strings' ), 10, 4 );
45
 
 
 
 
 
 
 
 
 
 
 
 
46
  add_action( 'woocommerce-product-addons_panel_start', array( $this, 'show_pointer_info' ) );
47
 
48
  if ( is_admin() ) {
49
 
50
+ if ( $this->is_global_addon_edit_page() ) {
51
+ if( ! isset( $_GET['edit'] ) ){
52
+ add_action( 'admin_notices', array( $this, 'inf_translate_strings' ) );
53
+ }
54
+ }
55
+
56
  add_action( 'wcml_gui_additional_box_html', array( $this, 'custom_box_html' ), 10, 3 );
57
  add_filter( 'wcml_gui_additional_box_data', array( $this, 'custom_box_html_data' ), 10, 3 );
58
  add_action( 'wcml_update_extra_fields', array( $this, 'addons_update' ), 10, 3 );
60
  add_action( 'woocommerce_product_data_panels', array( $this, 'show_pointer_info' ) );
61
 
62
  add_filter( 'wcml_do_not_display_custom_fields_for_product', array( $this, 'replace_tm_editor_custom_fields_with_own_sections' ) );
63
+
64
+ if( $this->is_multi_currency_on() ){
65
+ add_action( 'woocommerce_product_addons_panel_start', array( $this, 'load_dialog_resources' ) );
66
+ add_action( 'woocommerce_product_addons_panel_option_row', array( $this, 'dialog_button_after_option_row' ), 10, 4 );
67
+ add_action( 'woocommerce_product_addons_panel_before_options', array( $this, 'dialog_button_before_options' ), 10, 3 );
68
+ add_action( 'wcml_before_sync_product', array( $this, 'update_custom_prices_values' ) );
69
+ add_action( 'woocommerce_product_addons_global_edit_objects', array( $this, 'custom_prices_settings_block' ) );
70
+ }
71
  }else{
72
  add_filter( 'get_post_metadata', array( $this, 'translate_addons_strings' ), 10, 4 );
73
  }
81
  $this,
82
  'set_global_ids_in_query_args'
83
  ) );
84
+ }
85
+
86
 
87
+ private function is_global_addon_edit_page() {
88
+ global $pagenow;
89
+
90
+ return 'edit.php' === $pagenow &&
91
+ isset( $_GET['post_type'] ) &&
92
+ 'product' === $_GET['post_type'] &&
93
+ isset( $_GET['page'] ) &&
94
+ ( 'global_addons' === $_GET['page'] || 'addons' === $_GET['page'] );
95
+ }
96
+
97
+ /**
98
+ * @param string $product_id
99
+ *
100
+ * @return array
101
+ */
102
+ private function get_product_addons( $product_id ) {
103
+ return maybe_unserialize( get_post_meta( $product_id, '_product_addons', true ) );
104
  }
105
 
106
  /**
111
  */
112
  function register_addons_strings( $meta_id, $id, $meta_key, $addons ) {
113
  if ( '_product_addons' === $meta_key && 'global_product_addon' === get_post_type( $id ) ) {
114
+ $this->update_custom_prices_values( $id );
115
  foreach ( $addons as $addon ) {
116
  //register name
117
  do_action( 'wpml_register_single_string', 'wc_product_addons_strings', $id . '_addon_' . $addon['type'] . '_' . $addon['position'] . '_name', $addon['name'] );
163
 
164
  /**
165
  * @param $addons
166
+ * @param $post_id
167
  *
168
  * @return mixed
169
  */
170
+ function product_addons_price_filter( $addons, $post_id ) {
171
+
172
+ if ( $this->is_multi_currency_on() ) {
173
 
174
+ $client_currency = $this->woocommerce_wpml->multi_currency->get_client_currency();
175
+ $is_custom_prices_on = $this->is_product_custom_prices_on( $post_id );
176
+
177
+ foreach ( $addons as $add_id => $addon ) {
178
+
179
+ if ( $addon['price'] ) {
180
+ if (
181
+ $is_custom_prices_on &&
182
+ isset( $addon[ 'price_' . $client_currency ] ) &&
183
+ $addon[ 'price_' . $client_currency ]
184
+ ) {
185
+ $addons[ $add_id ]['price'] = $addon[ 'price_' . $client_currency ];
186
+ } else {
187
+ $addons[ $add_id ]['price'] = apply_filters( 'wcml_raw_price_amount', $addon['price'] );
188
+ }
189
+ }
190
+
191
+ foreach ( $addon['options'] as $key => $option ) {
192
+ if (
193
+ $is_custom_prices_on &&
194
+ isset( $option[ 'price_' . $client_currency ] ) &&
195
+ $option[ 'price_' . $client_currency ]
196
+ ) {
197
+ $addons[ $add_id ]['options'][ $key ]['price'] = $option[ 'price_' . $client_currency ];
198
+ } else {
199
+ $addons[ $add_id ]['options'][ $key ]['price'] = apply_filters( 'wcml_raw_price_amount', $option['price'] );
200
+ }
201
+ }
202
  }
203
  }
204
 
205
  return $addons;
206
  }
207
 
 
208
  /**
209
  * @param $product_terms
210
  *
223
  $pointer_ui = new WCML_Pointer_UI(
224
  sprintf( __( 'You can translate strings related to global add-ons on the %sWPML String Translation page%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>' ),
225
  'https://wpml.org/documentation/woocommerce-extensions-compatibility/translating-woocommerce-product-add-ons-woocommerce-multilingual/',
226
+ 'wpbody-content .woocommerce>h2'
227
  );
228
 
229
  $pointer_ui->show();
236
  */
237
  function custom_box_html( $obj, $product_id, $data ) {
238
 
239
+ $product_addons = $this->get_product_addons( $product_id );
240
 
241
  if ( ! empty( $product_addons ) ) {
242
  foreach ( $product_addons as $addon_id => $product_addon ) {
275
  */
276
  function custom_box_html_data( $data, $product_id, $translation ) {
277
 
278
+ $product_addons = $this->get_product_addons( $product_id );
279
 
280
  if ( ! empty( $product_addons ) ) {
281
  foreach ( $product_addons as $addon_id => $product_addon ) {
289
  }
290
 
291
  if ( $translation ) {
292
+ $translated_product_addons = $this->get_product_addons( $translation->ID );
293
+ if ( ! empty( $translated_product_addons ) ) {
294
+ foreach ( $translated_product_addons as $addon_id => $transalted_product_addon ) {
295
  $data[ 'addon_' . $addon_id . '_name' ]['translation'] = $transalted_product_addon['name'];
296
  $data[ 'addon_' . $addon_id . '_description' ]['translation'] = $transalted_product_addon['description'];
297
  if ( ! empty( $transalted_product_addon['options'] ) ) {
314
  */
315
  function addons_update( $original_product_id, $product_id, $data ) {
316
 
317
+ $product_addons = $this->get_product_addons( $original_product_id );
318
 
319
  if ( ! empty( $product_addons ) ) {
320
 
355
  // special case for WC Bookings plugin - need add addon cost after re-calculating booking costs #wcml-1877
356
  public function filter_booking_addon_product_in_cart_contents( $cart_item ) {
357
 
 
358
  $is_booking_product_with_addons = $cart_item['data'] instanceof WC_Product_Booking && isset( $cart_item['addons'] );
359
 
360
+ if ( $this->is_multi_currency_on() && $is_booking_product_with_addons ) {
361
  $cost = $cart_item['data']->get_price();
362
 
363
  foreach( $cart_item['addons'] as $addon ){
376
 
377
  remove_filter( 'get_terms_args', array( $this->sitepress, 'get_terms_args_filter' ), 10, 2 );
378
  remove_filter( 'get_term', array( $this->sitepress, 'get_term_adjust_id' ), 1 );
379
+ remove_filter( 'terms_clauses', array( $this->sitepress, 'terms_clauses' ), 10 );
380
 
381
  $matched_addons_ids = wp_list_pluck( get_posts( $args ), 'ID' );
382
 
387
 
388
  add_filter( 'get_terms_args', array( $this->sitepress, 'get_terms_args_filter' ), 10, 2 );
389
  add_filter( 'get_term', array( $this->sitepress, 'get_term_adjust_id' ), 1 );
390
+ add_filter( 'terms_clauses', array( $this->sitepress, 'terms_clauses' ), 10, 3 );
391
  }
392
 
393
  return $args;
394
  }
395
 
396
+ /**
397
+ * @return bool
398
+ */
399
+ private function is_multi_currency_on(){
400
+ return $this->multi_currency_mode === $this->sitepress->get_wp_api()->constant( 'WCML_MULTI_CURRENCIES_INDEPENDENT' );
401
+ }
402
+
403
+ public function load_dialog_resources(){
404
+ wp_enqueue_script( 'wcml-dialogs', WCML_PLUGIN_URL . '/res/js/dialogs' . WCML_JS_MIN . '.js', array('jquery-ui-dialog'), WCML_VERSION );
405
+ }
406
+
407
+ /**
408
+ * @param WP_Post|null $product
409
+ * @param array $product_addons
410
+ * @param int $loop
411
+ * @param array $option
412
+ */
413
+ public function dialog_button_after_option_row( $product, $product_addons, $loop, $option ){
414
+ if( $option ){
415
+ $this->render_edit_price_element( $this->get_prices_dialog_model( $product_addons, $option, $loop, $this->is_product_custom_prices_on( $product ? $product->ID : false ) ) );
416
+ }
417
+
418
+ }
419
+
420
+ /**
421
+ * @param WP_Post|null $product
422
+ * @param array $product_addons
423
+ * @param int $loop
424
+ */
425
+ public function dialog_button_before_options( $product, $product_addons, $loop ){
426
+ $this->render_edit_price_element( $this->get_prices_dialog_model( array(), $product_addons, $loop, $this->is_product_custom_prices_on( $product ? $product->ID : false ) ) );
427
+ }
428
+
429
+ /**
430
+ * @param array $model
431
+ */
432
+ private function render_edit_price_element( $model ){
433
+ $twig_loader = $this->get_twig_loader();
434
+ echo $twig_loader->get_template()->show( $model, self::DIALOG_TEMPLATE );
435
+ }
436
+
437
+ /**
438
+ * @return array
439
+ */
440
+ private function get_one_price_types(){
441
+
442
+ return array(
443
+ 'custom_text',
444
+ 'custom_textarea',
445
+ 'file_upload',
446
+ 'input_multiplier'
447
+ );
448
+ }
449
+
450
+ /**
451
+ * @return WPML_Twig_Template_Loader
452
+ */
453
+ private function get_twig_loader(){
454
+ return new WPML_Twig_Template_Loader( array( $this->sitepress->get_wp_api()->constant( 'WCML_PLUGIN_PATH' ) . self::TEMPLATE_FOLDER ) );
455
+ }
456
+
457
+ /**
458
+ * @param int|false $product
459
+ *
460
+ * @return mixed
461
+ */
462
+ private function is_product_custom_prices_on( $product_id ){
463
+
464
+ if( $product_id ){
465
+ return get_post_meta( $product_id, '_wcml_custom_prices_status', true );
466
+ }
467
+
468
+ if( $this->is_global_addon_edit_page() ){
469
+ return $this->get_global_addon_prices_status();
470
+ }
471
+
472
+ return false;
473
+ }
474
+
475
+ /**
476
+ * @return bool|mixed
477
+ */
478
+ private function get_global_addon_prices_status() {
479
+
480
+ if ( isset( $_GET['edit'] ) ) {
481
+ return get_post_meta( $_GET['edit'], '_wcml_custom_prices_status', true );
482
+ } elseif ( isset( $_POST['_wcml_custom_prices'] ) ) {
483
+ return $_POST['_wcml_custom_prices'];
484
+ }
485
+
486
+ return false;
487
+ }
488
+
489
+ public function load_assets() {
490
+ global $pagenow;
491
+
492
+ $is_product_page = 'post.php' === $pagenow && isset( $_GET['post'] );
493
+ $is_product_new_page = 'post-new.php' === $pagenow && isset( $_GET['post_type'] ) && 'product' === $_GET['post_type'];
494
+
495
+ if ( $is_product_page || $is_product_new_page || $this->is_global_addon_edit_page() ) {
496
+ wp_enqueue_script( 'wcml-product-addons', WCML_PLUGIN_URL . '/compatibility/res/js/wcml-product-addons' . WCML_JS_MIN . '.js', array( 'jquery' ), WCML_VERSION );
497
+ wp_enqueue_style( 'wcml-product-addons', WCML_PLUGIN_URL . '/compatibility/res/css/wcml-product-addons.css', '', WCML_VERSION );
498
+ }
499
+
500
+ }
501
+
502
+ /**
503
+ * @param string $product_id
504
+ */
505
+ public function update_custom_prices_values( $product_id ) {
506
+
507
+ $this->save_global_addon_prices_setting( $product_id );
508
+
509
+ $product_addons = $this->get_product_addons( $product_id );
510
+
511
+ if ( $product_addons ) {
512
+ $active_currencies = $this->woocommerce_wpml->multi_currency->get_currencies();
513
+
514
+ foreach ( $product_addons as $addon_key => $product_addon ) {
515
+
516
+ foreach ( $active_currencies as $code => $currency ) {
517
+ $price_option_key = self::PRICE_OPTION_KEY;
518
+
519
+ if( in_array( $product_addon['type'], $this->get_one_price_types() ) ){
520
+ $product_addons = $this->update_single_option_prices( $product_addons, $price_option_key, $addon_key, $code );
521
+ }else{
522
+ $product_addons = $this->update_multiple_options_prices( $product_addons, $price_option_key, $addon_key, $code );
523
+ }
524
+ }
525
+ }
526
+
527
+ update_post_meta( $product_id, '_product_addons', $product_addons );
528
+ }
529
+ }
530
+
531
+ /**
532
+ * @param array $product_addons
533
+ * @param string $price_option_key
534
+ * @param string $addon_key
535
+ * @param string $code
536
+ *
537
+ * @return array
538
+ */
539
+ private function update_single_option_prices( $product_addons, $price_option_key, $addon_key, $code ){
540
+ if ( isset( $_POST[ $price_option_key ][ $addon_key ][ 'price_'.$code ][ 0 ] ) ) {
541
+ $product_addons[ $addon_key ][ 'price_' . $code ] = wc_format_decimal( $_POST[ $price_option_key ][ $addon_key ][ 'price_'.$code ][ 0 ] );
542
+ }
543
+
544
+ return $product_addons;
545
+ }
546
+
547
+ /**
548
+ * @param array $product_addons
549
+ * @param string $price_option_key
550
+ * @param string $addon_key
551
+ * @param string $code
552
+ *
553
+ * @return array
554
+ */
555
+ private function update_multiple_options_prices( $product_addons, $price_option_key, $addon_key, $code ){
556
+ foreach ( $product_addons[ $addon_key ]['options'] as $option_key => $option ) {
557
+ if ( isset( $_POST[ $price_option_key ][ $addon_key ][ 'price_'.$code ][ $option_key ] ) ) {
558
+ $product_addons[ $addon_key ]['options'][ $option_key ][ 'price_' . $code ] = wc_format_decimal( $_POST[ $price_option_key ][ $addon_key ][ 'price_'.$code ][ $option_key ] );
559
+ }
560
+ }
561
+
562
+ return $product_addons;
563
+ }
564
+
565
+ /**
566
+ * @param array $product_addons
567
+ * @param array $option
568
+ * @param int $loop
569
+ * @param string|bool $custom_prices_on
570
+ *
571
+ * @return array
572
+ */
573
+ private function get_prices_dialog_model( $product_addons, $option, $loop, $custom_prices_on ) {
574
+
575
+ $label = isset( $option['label'] ) ? $option['label'] : $option['name'];
576
+
577
+ return array(
578
+ 'strings' => array(
579
+ 'dialog_title' => __( 'Multi-currency settings', 'woocommerce-multilingual' ),
580
+ 'description' => sprintf(__( 'Here you can set different prices for the %s in multiple currencies:', 'woocommerce-multilingual' ), '<strong>' . $label . '</strong>' ),
581
+ 'apply' => __( 'Apply', 'woocommerce-multilingual' ),
582
+ 'cancel' => __( 'Cancel', 'woocommerce-multilingual' )
583
+ ),
584
+ 'custom_prices_on' => $custom_prices_on,
585
+ 'dialog_id' => '_product_addon_option_' . md5( uniqid( $loop . $label ) ),
586
+ 'option_id' => isset( $product_addons[ $loop ]['options'] ) ? array_search( $option, $product_addons[ $loop ]['options'] ) : '',
587
+ 'addon_id' => $loop,
588
+ 'option_details' => $option,
589
+ 'default_currency' => get_option( 'woocommerce_currency' ),
590
+ 'active_currencies' => $this->woocommerce_wpml->multi_currency->get_currencies(),
591
+ );
592
+ }
593
+
594
+ public function custom_prices_settings_block() {
595
+ $twig_loader = $this->get_twig_loader();
596
+ echo $twig_loader->get_template()->show( $this->get_custom_prices_settings_model(), self::SETTINGS_TEMPLATE );
597
+ }
598
+
599
+ private function get_custom_prices_settings_model() {
600
+ return array(
601
+ 'strings' => array(
602
+ 'label' => __( 'Multi-currency settings', 'woocommerce-multilingual' ),
603
+ 'auto' => __( 'Calculate prices in other currencies automatically', 'woocommerce-multilingual' ),
604
+ 'manually' => __( 'Set prices in other currencies manually', 'woocommerce-multilingual' )
605
+ ),
606
+ 'custom_prices_on' => $this->get_global_addon_prices_status(),
607
+ 'nonce' => wp_create_nonce( 'wcml_save_custom_prices' )
608
+ );
609
+ }
610
+
611
+ /**
612
+ * @param int $global_addon_id
613
+ */
614
+ private function save_global_addon_prices_setting( $global_addon_id ) {
615
+
616
+ $nonce = filter_var( isset( $_POST['_wcml_custom_prices_nonce'] ) ? $_POST['_wcml_custom_prices_nonce'] : '', FILTER_SANITIZE_FULL_SPECIAL_CHARS );
617
+
618
+ if ( isset( $_POST['_wcml_custom_prices'] ) && isset( $nonce ) && wp_verify_nonce( $nonce, 'wcml_save_custom_prices' ) ) {
619
+ update_post_meta( $global_addon_id, '_wcml_custom_prices_status', $_POST['_wcml_custom_prices'] );
620
+ }
621
+
622
+ }
623
+
624
  }
compatibility/class-wcml-product-bundles-legacy.php DELETED
@@ -1,436 +0,0 @@
1
- <?php
2
- class WCML_Product_Bundles_Legacy{
3
-
4
- /**
5
- * @var WPML_Element_Translation_Package
6
- */
7
- private $tp;
8
- /**
9
- * @var SitePress
10
- */
11
- private $sitepress;
12
- /**
13
- * @var woocommerce_wpml
14
- */
15
- private $woocommerce_wpml;
16
-
17
- /**
18
- * WCML_Product_Bundles constructor.
19
- * @param SitePress $sitepress
20
- * @param woocommerce_wpml $woocommerce_wpml
21
- * @param WPML_Element_Translation_Package $tp
22
- */
23
- function __construct( SitePress $sitepress, woocommerce_wpml $woocommerce_wpml, WPML_Element_Translation_Package $tp ) {
24
- $this->sitepress = $sitepress;
25
- $this->woocommerce_wpml = $woocommerce_wpml;
26
- $this->tp = $tp;
27
- }
28
-
29
- public function add_hooks(){
30
-
31
- add_action( 'wcml_gui_additional_box_html', array( $this, 'custom_box_html' ), 10, 3 );
32
- add_filter( 'wcml_gui_additional_box_data', array( $this, 'custom_box_html_data' ), 10, 4 );
33
- add_action( 'wcml_after_duplicate_product_post_meta', array( $this, 'sync_bundled_ids' ), 10, 2 );
34
- add_action( 'wcml_update_extra_fields', array( $this, 'bundle_update' ), 10, 4 );
35
- add_action( 'woocommerce_get_cart_item_from_session', array( $this, 'resync_bundle' ), 5, 3 );
36
- add_filter( 'woocommerce_cart_loaded_from_session', array( $this, 'resync_bundle_clean' ), 10 );
37
-
38
- if ( $this->sitepress->get_wp_api()->version_compare( $this->sitepress->get_wp_api()->constant( 'WCML_VERSION' ), '3.7.2', '>' ) ) {
39
- add_filter( 'option_wpml_config_files_arr', array( $this, 'make__bundle_data_not_translatable_by_default' ), 0 );
40
- }
41
-
42
- if( is_admin() ){
43
-
44
- add_filter( 'wpml_tm_translation_job_data', array( $this, 'append_bundle_data_translation_package' ), 10, 2 );
45
- add_action( 'wpml_translation_job_saved', array( $this, 'save_bundle_data_translation' ), 10, 3 );
46
-
47
- add_filter( 'wcml_do_not_display_custom_fields_for_product', array( $this, 'replace_tm_editor_custom_fields_with_own_sections' ) );
48
- }
49
-
50
-
51
- }
52
-
53
- function make__bundle_data_not_translatable_by_default( $wpml_config_array ){
54
-
55
- if( isset( $wpml_config_array->plugins[ 'WooCommerce Product Bundles' ] ) ){
56
- $wpml_config_array->plugins[ 'WooCommerce Product Bundles' ] =
57
- str_replace(
58
- '<custom-field action="translate">_bundle_data</custom-field>',
59
- '<custom-field action="nothing">_bundle_data</custom-field>',
60
- $wpml_config_array->plugins[ 'WooCommerce Product Bundles' ] );
61
- }
62
-
63
- return $wpml_config_array;
64
- }
65
-
66
- // Sync Bundled product '_bundle_data' with translated values when the product is duplicated
67
- function sync_bundled_ids( $original_product_id, $trnsl_product_id ){
68
-
69
- $bundle_data_array = maybe_unserialize( get_post_meta( $original_product_id, '_bundle_data', true ) );
70
- if( $bundle_data_array ){
71
- $lang = $this->sitepress->get_language_for_element( $trnsl_product_id, 'post_product' );
72
- $tr_bundle_meta = maybe_unserialize( get_post_meta( $trnsl_product_id, '_bundle_data', true ) );
73
-
74
- $i = 2;
75
- foreach( $bundle_data_array as $bundle_key => $bundle_data ){
76
-
77
- $key_data = $this->translate_bundle_key( $bundle_key, $lang );
78
- $tr_id = $key_data->tr_id;
79
- $tr_bundle_key = $key_data->tr_key;
80
-
81
- $tr_bundle[ $tr_bundle_key ] = $bundle_data;
82
- $tr_bundle[ $tr_bundle_key ][ 'product_id' ] = $tr_id;
83
- if( isset( $bundle_data[ 'product_title' ] ) ){
84
- if( $bundle_data[ 'override_title' ] == 'yes' ){
85
- $tr_bundle[ $tr_bundle_key ][ 'product_title' ] =
86
- isset( $tr_bundle_meta[ $tr_bundle_key ][ 'product_title' ] ) ?
87
- $tr_bundle_meta[ $tr_bundle_key ][ 'product_title' ] :
88
- '';
89
- }else{
90
- $tr_title= get_the_title( $tr_id );
91
- $tr_bundle[ $tr_bundle_key ][ 'product_title' ] = $tr_title;
92
- }
93
- }
94
- if( isset( $bundle_data[ 'product_description' ] ) ){
95
- if( $bundle_data[ 'override_description' ] == 'yes' ){
96
- $tr_bundle[ $tr_bundle_key ][ 'product_description' ] =
97
- isset( $tr_bundle_meta[ $tr_bundle_key ][ 'product_description' ] ) ?
98
- $tr_bundle_meta[ $tr_bundle_key ][ 'product_description' ] :
99
- '';
100
- }else{
101
- $tr_prod = get_post( $tr_id );
102
- $tr_desc = $tr_prod->post_excerpt;
103
- $tr_bundle[ $tr_bundle_key ][ 'product_description' ] = $tr_desc;
104
- }
105
- }
106
- if( isset( $bundle_data[ 'filter_variations' ] ) && $bundle_data[ 'filter_variations' ] == 'yes' ){
107
- $allowed_var = $bundle_data[ 'allowed_variations' ];
108
- foreach( $allowed_var as $key => $var_id ){
109
- $tr_var_id = apply_filters( 'translate_object_id', $var_id, get_post_type( $var_id ), true, $lang );
110
- $tr_bundle[ $tr_bundle_key ][ 'allowed_variations' ][ $key ] = $tr_var_id;
111
- }
112
- }
113
- if( isset( $bundle_data[ 'bundle_defaults' ] ) && !empty( $bundle_data[ 'bundle_defaults' ] ) ){
114
- foreach( $bundle_data[ 'bundle_defaults' ] as $tax => $term_slug ){
115
-
116
- $term_id = $this->woocommerce_wpml->terms->wcml_get_term_id_by_slug( $tax, $term_slug );
117
- if( $term_id ){
118
- // Global Attribute
119
- $tr_def_id = apply_filters( 'translate_object_id', $term_id, $tax, true, $lang );
120
- $tr_term = $this->woocommerce_wpml->terms->wcml_get_term_by_id( $tr_def_id, $tax );
121
- $tr_bundle[ $tr_bundle_key ][ 'bundle_defaults' ][ $tax ] = $tr_term->slug;
122
- }else{
123
- // Custom Attribute
124
- $args = array(
125
- 'post_type' => 'product_variation',
126
- 'meta_key' => 'attribute_'.$tax,
127
- 'meta_value' => $term_slug,
128
- 'meta_compare' => '='
129
- );
130
- $variationloop = new WP_Query( $args );
131
- while ( $variationloop->have_posts() ) : $variationloop->the_post();
132
- $tr_var_id = apply_filters( 'translate_object_id', get_the_ID(), 'product_variation', true, $lang );
133
- $tr_meta = get_post_meta( $tr_var_id, 'attribute_'.$tax , true );
134
- $tr_bundle[ $tr_bundle_key ][ 'bundle_defaults' ][ $tax ] = $tr_meta;
135
- endwhile;
136
- }
137
- }
138
- }
139
- }
140
- update_post_meta( $trnsl_product_id, '_bundle_data', $tr_bundle );
141
-
142
- return $tr_bundle;
143
- }
144
-
145
- }
146
-
147
-
148
- public function translate_bundle_key( $key, $lang, $return_original_if_missing = true ) {
149
- $key_parts = explode( '_', $key );
150
- $has_multiple_products = count( $key_parts ) > 1;
151
-
152
- $data = new stdClass;
153
- $data->id = $has_multiple_products ? $key_parts[ 0 ] : $key;
154
- $data->tr_id = apply_filters( 'translate_object_id', $data->id, get_post_type( $data->id ), $return_original_if_missing, $lang );
155
- $data->tr_key = $data->tr_id . ( $has_multiple_products ? '_' . $key_parts[ 1 ] : '' );
156
-
157
- return $data;
158
- }
159
-
160
- // Update Bundled products title and descritpion after saving the translation
161
- function bundle_update( $original_product_id, $tr_id, $data, $lang ){
162
-
163
- $tr_bundle_data = array();
164
- $tr_bundle_data = maybe_unserialize( get_post_meta($tr_id,'_bundle_data', true ) );
165
-
166
- $bundle_data = maybe_unserialize( get_post_meta( $original_product_id, '_bundle_data', true ) );
167
-
168
- if( empty( $bundle_data ) ){
169
- return;
170
- }
171
-
172
- $product_bundles = array_keys( $bundle_data );
173
-
174
- foreach ( $product_bundles as $key => $bundle_key ) {
175
-
176
- $key_data = $this->translate_bundle_key( $bundle_key, $lang );
177
- $tr_bundle_key = $key_data->tr_key;
178
-
179
- if( isset( $tr_bundle_data[ $tr_bundle_key ] ) ){
180
- $tr_bundle_data[ $tr_bundle_key ][ 'product_title' ] = $data[ md5( 'bundle_'.$bundle_key.'_title' ) ];
181
- $tr_bundle_data[ $tr_bundle_key ][ 'product_description' ] = $data[ md5( 'bundle_'.$bundle_key.'_desc' ) ];
182
- }
183
- }
184
- update_post_meta( $tr_id, '_bundle_data', $tr_bundle_data );
185
-
186
- return $tr_bundle_data;
187
- }
188
-
189
- // Add Bundles Box to WCML Translation GUI
190
- function custom_box_html( $obj, $product_id, $data ){
191
-
192
- $product_bundles = maybe_unserialize( get_post_meta( $product_id, '_bundle_data', true ) );
193
-
194
- if( empty( $product_bundles ) || $product_bundles == false ){
195
- return false;
196
- }
197
-
198
- $bundles_section = new WPML_Editor_UI_Field_Section( __( 'Product Bundles', 'woocommerce-multilingual' ) );
199
- end( $product_bundles );
200
- $last_key = key( $product_bundles );
201
- $divider = true;
202
- $flag = false;
203
-
204
- foreach ( $product_bundles as $bundle_id => $product_bundle ) {
205
- $add_group = false;
206
- if( $bundle_id == $last_key ){
207
- $divider = false;
208
- }
209
-
210
- $group = new WPML_Editor_UI_Field_Group( get_the_title( $bundle_id ), $divider );
211
-
212
- if( $product_bundle[ 'override_title' ] == 'yes' ) {
213
- $bundle_field = new WPML_Editor_UI_Single_Line_Field(
214
- 'bundle_' . $bundle_id . '_title',
215
- __( 'Name', 'woocommerce-multilingual' ),
216
- $data,
217
- false
218
- );
219
- $group->add_field( $bundle_field );
220
- $add_group = true;
221
- }
222
-
223
- if( $product_bundle[ 'override_description' ] == 'yes' ){
224
- $bundle_field = new WPML_Editor_UI_Single_Line_Field(
225
- 'bundle_'.$bundle_id.'_desc' ,
226
- __( 'Description', 'woocommerce-multilingual' ),
227
- $data,
228
- false
229
- );
230
- $group->add_field( $bundle_field );
231
- $add_group = true;
232
- }
233
-
234
- if( $add_group ){
235
- $bundles_section->add_field( $group );
236
- $flag = true;
237
- }
238
- }
239
-
240
- if( $flag ){
241
- $obj->add_field( $bundles_section );
242
- }
243
- }
244
-
245
-
246
- function custom_box_html_data( $data, $product_id, $translation, $lang ){
247
- $bundle_data = maybe_unserialize( get_post_meta( $product_id, '_bundle_data', true ) );
248
-
249
- if( $translation ) {
250
- $tr_product_id = $translation->ID;
251
- $tr_bundle_data = maybe_unserialize( get_post_meta( $tr_product_id, '_bundle_data', true ) );
252
- }
253
-
254
- if( empty( $bundle_data ) || $bundle_data == false ){
255
- return $data;
256
- }
257
-
258
- $product_bundles = array_keys( $bundle_data );
259
-
260
- foreach ( $product_bundles as $bundle_key ) {
261
-
262
- $key_data = $this->translate_bundle_key( $bundle_key, $lang );
263
- $tr_bundle_key = $key_data->tr_key;
264
-
265
- if( $bundle_data[ $bundle_key ][ 'override_title' ] == 'yes' ){
266
- $data[ 'bundle_'.$bundle_key.'_title' ] = array( 'original' => $bundle_data[ $bundle_key ][ 'product_title' ] );
267
- if( isset( $tr_bundle_data[ $tr_bundle_key ][ 'override_title' ] ) ){
268
- $data[ 'bundle_'.$bundle_key.'_title' ][ 'translation' ] = $tr_bundle_data[ $tr_bundle_key ][ 'product_title' ];
269
- }else{
270
- $data[ 'bundle_'.$bundle_key.'_title' ][ 'translation' ] = '';
271
- }
272
- }
273
-
274
- if( $bundle_data[ $bundle_key ][ 'override_description' ] == 'yes' ){
275
- $data[ 'bundle_'.$bundle_key.'_desc' ] = array( 'original' => $bundle_data[ $bundle_key ][ 'product_description' ] );
276
- if( isset( $tr_bundle_data[ $tr_bundle_key ][ 'override_description' ] ) ){
277
- $data[ 'bundle_'.$bundle_key.'_desc' ][ 'translation' ] = $tr_bundle_data[ $tr_bundle_key ][ 'product_description' ];
278
- }else{
279
- $data[ 'bundle_'.$bundle_key.'_desc' ][ 'translation' ] = '';
280
- }
281
- }
282
- }
283
-
284
- return $data;
285
- }
286
-
287
- function resync_bundle( $cart_item, $session_values, $cart_item_key ) {
288
- if ( isset( $cart_item[ 'bundled_items' ] ) && $cart_item[ 'data' ]->product_type === 'bundle' ) {
289
- $current_bundle_id = apply_filters( 'translate_object_id', $cart_item[ 'product_id' ], 'product', true );
290
- if ( $cart_item[ 'product_id' ] != $current_bundle_id ) {
291
- $old_bundled_item_ids = array_keys( $cart_item[ 'data' ]->bundle_data );
292
- $cart_item[ 'data' ] = wc_get_product( $current_bundle_id );
293
- if( is_array( $cart_item[ 'data' ]->bundle_data ) ){
294
- $new_bundled_item_ids = array_keys( $cart_item[ 'data' ]->bundle_data );
295
- $remapped_bundled_item_ids = array();
296
- foreach ( $old_bundled_item_ids as $old_item_id_index => $old_item_id ) {
297
- $remapped_bundled_item_ids[ $old_item_id ] = $new_bundled_item_ids[ $old_item_id_index ];
298
- }
299
- $cart_item[ 'remapped_bundled_item_ids' ] = $remapped_bundled_item_ids;
300
- if ( isset( $cart_item[ 'stamp' ] ) ) {
301
- $new_stamp = array();
302
- foreach ( $cart_item[ 'stamp' ] as $bundled_item_id => $stamp_data ) {
303
- $new_stamp[ $remapped_bundled_item_ids[ $bundled_item_id ] ] = $stamp_data;
304
- }
305
- $cart_item[ 'stamp' ] = $new_stamp;
306
- }
307
- }
308
- }
309
- }
310
- if ( isset( $cart_item[ 'bundled_by' ] ) && isset( WC()->cart->cart_contents[ $cart_item[ 'bundled_by' ] ] ) ) {
311
- $bundle_cart_item = WC()->cart->cart_contents[ $cart_item[ 'bundled_by' ] ];
312
- if (
313
- isset( $bundle_cart_item[ 'remapped_bundled_item_ids' ] ) &&
314
- isset( $cart_item[ 'bundled_item_id' ] ) &&
315
- isset( $bundle_cart_item[ 'remapped_bundled_item_ids' ][ $cart_item[ 'bundled_item_id' ] ] )
316
- ) {
317
- $old_id = $cart_item[ 'bundled_item_id' ];
318
- $remapped_bundled_item_ids = $bundle_cart_item[ 'remapped_bundled_item_ids' ];
319
- $cart_item[ 'bundled_item_id' ] = $remapped_bundled_item_ids[ $cart_item[ 'bundled_item_id' ] ];
320
- if ( isset( $cart_item[ 'stamp' ] ) ) {
321
- $new_stamp = array();
322
- foreach ( $cart_item[ 'stamp' ] as $bundled_item_id => $stamp_data ) {
323
- $new_stamp[ $remapped_bundled_item_ids[ $bundled_item_id ] ] = $stamp_data;
324
- }
325
- $cart_item[ 'stamp' ] = $new_stamp;
326
- }
327
- }
328
- }
329
-
330
- return $cart_item;
331
- }
332
-
333
- function resync_bundle_clean( $cart ) {
334
- foreach ( $cart->cart_contents as $cart_item_key => $cart_item ) {
335
- if ( isset( $cart_item[ 'bundled_items' ] ) && $this->is_bundle_product( $cart_item[ 'product_id' ] ) ) {
336
- if ( isset( $cart_item[ 'remapped_bundled_item_ids' ] ) ) {
337
- unset( WC()->cart->cart_contents[ $cart_item_key ][ 'remapped_bundled_item_ids' ] );
338
- }
339
- }
340
- }
341
- }
342
-
343
- function append_bundle_data_translation_package( $package, $post ){
344
-
345
- if( $post->post_type == 'product' ) {
346
-
347
- $bundle_data = get_post_meta( $post->ID, '_bundle_data', true );
348
-
349
- if( $bundle_data ){
350
-
351
- $fields = array( 'title', 'description' );
352
-
353
- foreach( $bundle_data as $bundle_key => $product ){
354
-
355
- foreach( $fields as $field ) {
356
- if ( $product[ 'override_' . $field ] == 'yes' && !empty( $product[ 'product_' . $field ] ) ) {
357
-
358
- $package[ 'contents' ][ 'product_bundles:' . $bundle_key . ':' . $field ] = array(
359
- 'translate' => 1,
360
- 'data' => $this->tp->encode_field_data( $product[ 'product_' . $field ], 'base64' ),
361
- 'format' => 'base64'
362
- );
363
-
364
- }
365
- }
366
- }
367
- }
368
- }
369
-
370
- return $package;
371
-
372
- }
373
-
374
- function save_bundle_data_translation( $post_id, $data, $job ){
375
-
376
- if ( $this->is_bundle_product( $post_id ) ) {
377
-
378
- remove_action( 'wcml_after_duplicate_product_post_meta', array( $this, 'sync_bundled_ids' ), 10, 2 );
379
-
380
- $bundle_data = get_post_meta( $post_id, '_bundle_data', true );
381
-
382
- $bundle_data_original = get_post_meta( $job->original_doc_id , '_bundle_data', true );
383
-
384
- $translated_bundle_pieces = array();
385
-
386
- foreach( $data as $value){
387
-
388
- if( preg_match( '/product_bundles:([0-9]+):(.+)/', $value[ 'field_type' ], $matches ) ){
389
-
390
- $bundle_key = $matches[1];
391
- $field = $matches[2];
392
-
393
- $key_data = $this->translate_bundle_key( $bundle_key, $job->language_code );
394
-
395
- if( !isset( $bundle_data[ $key_data->tr_key ] ) ){
396
- $bundle_data[ $key_data->tr_key ] = array(
397
- 'product_id' => $key_data->tr_id,
398
- 'hide_thumbnail' => $bundle_data_original[ $bundle_key ][ 'hide_thumbnail' ],
399
- 'override_title' => $bundle_data_original[ $bundle_key ][ 'override_title' ],
400
- 'product_title' => '',
401
- 'override_description' => $bundle_data_original[ $bundle_key ][ 'override_description' ],
402
- 'product_description' => '',
403
- 'optional' => $bundle_data_original[ $bundle_key ][ 'optional' ],
404
- 'bundle_quantity' => $bundle_data_original[ $bundle_key ][ 'bundle_quantity' ],
405
- 'bundle_quantity_max' => $bundle_data_original[ $bundle_key ][ 'bundle_quantity_max' ],
406
- 'bundle_discount' => $bundle_data_original[ $bundle_key ][ 'bundle_discount' ],
407
- 'visibility' => $bundle_data_original[ $bundle_key ][ 'visibility' ],
408
- );
409
- }
410
-
411
- $bundle_data[ $key_data->tr_key ][ 'product_'.$field ] = $value[ 'data' ];
412
-
413
- }
414
- }
415
-
416
- update_post_meta( $post_id, '_bundle_data', $bundle_data );
417
-
418
- }
419
-
420
- }
421
-
422
- function replace_tm_editor_custom_fields_with_own_sections( $fields ){
423
- $fields[] = '_bundle_data';
424
-
425
- return $fields;
426
- }
427
-
428
- public function is_bundle_product( $product_id ){
429
- if ( 'bundle' === WooCommerce_Functions_Wrapper::get_product_type( $product_id ) ) {
430
- return true;
431
- }
432
-
433
- return false;
434
- }
435
-
436
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
compatibility/class-wcml-product-bundles.php CHANGED
@@ -777,7 +777,7 @@ class WCML_Product_Bundles {
777
  }
778
 
779
  public function is_bundle_product( $product_id ){
780
- if ( 'bundle' === WooCommerce_Functions_Wrapper::get_product_type( $product_id ) ) {
781
  return true;
782
  }
783
 
777
  }
778
 
779
  public function is_bundle_product( $product_id ){
780
+ if ( 'bundle' === wc_get_product( $product_id )->get_type() ) {
781
  return true;
782
  }
783
 
compatibility/class-wcml-tab-manager.php CHANGED
@@ -54,10 +54,7 @@ class WCML_Tab_Manager {
54
  add_action( 'wcml_after_duplicate_product', array( $this, 'duplicate_product_tabs' ) , 10, 2 );
55
 
56
  add_filter( 'wc_tab_manager_tab_id', array( $this, 'wc_tab_manager_tab_id' ), 10, 1 );
57
-
58
- if ( $this->sitepress->get_wp_api()->version_compare( $this->sitepress->get_wp_api()->constant( 'WCML_VERSION' ), '3.7.2', '>' ) ) {
59
- add_filter( 'option_wpml_config_files_arr', array( $this, 'make__product_tabs_not_translatable_by_default' ), 0 );
60
- }
61
 
62
  if ( is_admin() ) {
63
 
54
  add_action( 'wcml_after_duplicate_product', array( $this, 'duplicate_product_tabs' ) , 10, 2 );
55
 
56
  add_filter( 'wc_tab_manager_tab_id', array( $this, 'wc_tab_manager_tab_id' ), 10, 1 );
57
+ add_filter( 'option_wpml_config_files_arr', array( $this, 'make__product_tabs_not_translatable_by_default' ), 0 );
 
 
 
58
 
59
  if ( is_admin() ) {
60
 
compatibility/class-wcml-table-rate-shipping.php CHANGED
@@ -36,7 +36,11 @@ class WCML_Table_Rate_Shipping {
36
  }
37
 
38
  if ( wcml_is_multi_currency_on() ) {
39
- add_filter( 'woocommerce_table_rate_query_rates_args', array( $this, 'filter_query_rates_args' ) );
 
 
 
 
40
  add_filter( 'woocommerce_table_rate_package_row_base_price', array(
41
  $this,
42
  'filter_product_base_price'
@@ -67,11 +71,8 @@ class WCML_Table_Rate_Shipping {
67
  if( isset( $_POST[ 'shipping_label' ] ) &&
68
  isset( $_POST[ 'woocommerce_table_rate_title' ] ) ){
69
  do_action( 'wpml_register_single_string', 'woocommerce', sanitize_text_field( $_POST[ 'woocommerce_table_rate_title' ] ) . '_shipping_method_title', sanitize_text_field( $_POST[ 'woocommerce_table_rate_title' ] ) );
70
- if( version_compare( WC()->version, '3.0.0', '<' ) ){
71
- $shipping_labels = array_map( 'woocommerce_clean', $_POST[ 'shipping_label' ] );
72
- } else{
73
- $shipping_labels = array_map( 'wc_clean', $_POST[ 'shipping_label' ] );
74
- }
75
  foreach ( $shipping_labels as $key => $shipping_label ) {
76
  $rate_key = isset( $_GET[ 'instance_id' ] ) ? 'table_rate'.$_GET[ 'instance_id' ].$_POST[ 'rate_id' ][ $key ] : $shipping_label;
77
  do_action( 'wpml_register_single_string', 'woocommerce', $rate_key. '_shipping_method_title', $shipping_label );
@@ -161,7 +162,7 @@ class WCML_Table_Rate_Shipping {
161
  public function filter_product_base_price( $row_base_price, $_product, $qty ){
162
 
163
  if( get_option( 'woocommerce_currency') != $this->woocommerce_wpml->multi_currency->get_client_currency() ){
164
- $row_base_price = apply_filters( 'wcml_product_price_by_currency', WooCommerce_Functions_Wrapper::get_product_id( $_product ), get_option( 'woocommerce_currency') ) * $qty;
165
  }
166
 
167
  return $row_base_price;
36
  }
37
 
38
  if ( wcml_is_multi_currency_on() ) {
39
+ $wpml_api = $this->sitepress->get_wp_api();
40
+ if ( $wpml_api->version_compare( $wpml_api->constant( 'TABLE_RATE_SHIPPING_VERSION' ), '3.0.11', '<' ) ) {
41
+ add_filter( 'woocommerce_table_rate_query_rates_args', array( $this, 'filter_query_rates_args' ) );
42
+ }
43
+
44
  add_filter( 'woocommerce_table_rate_package_row_base_price', array(
45
  $this,
46
  'filter_product_base_price'
71
  if( isset( $_POST[ 'shipping_label' ] ) &&
72
  isset( $_POST[ 'woocommerce_table_rate_title' ] ) ){
73
  do_action( 'wpml_register_single_string', 'woocommerce', sanitize_text_field( $_POST[ 'woocommerce_table_rate_title' ] ) . '_shipping_method_title', sanitize_text_field( $_POST[ 'woocommerce_table_rate_title' ] ) );
74
+
75
+ $shipping_labels = array_map( 'wc_clean', $_POST[ 'shipping_label' ] );
 
 
 
76
  foreach ( $shipping_labels as $key => $shipping_label ) {
77
  $rate_key = isset( $_GET[ 'instance_id' ] ) ? 'table_rate'.$_GET[ 'instance_id' ].$_POST[ 'rate_id' ][ $key ] : $shipping_label;
78
  do_action( 'wpml_register_single_string', 'woocommerce', $rate_key. '_shipping_method_title', $shipping_label );
162
  public function filter_product_base_price( $row_base_price, $_product, $qty ){
163
 
164
  if( get_option( 'woocommerce_currency') != $this->woocommerce_wpml->multi_currency->get_client_currency() ){
165
+ $row_base_price = apply_filters( 'wcml_product_price_by_currency', $_product->get_id(), get_option( 'woocommerce_currency') ) * $qty;
166
  }
167
 
168
  return $row_base_price;
compatibility/class-wcml-wc-memberships.php CHANGED
@@ -73,7 +73,7 @@ class WCML_WC_Memberships {
73
  if ( isset( $post->ID ) && wc_get_page_id( 'myaccount' ) == $post->ID ) {
74
  $wcml_plugin_url = $this->wp_api->constant( 'WCML_PLUGIN_URL' );
75
  $wcml_version = $this->wp_api->constant( 'WCML_VERSION' );
76
- wp_register_script( 'wcml-members-js', $wcml_plugin_url . '/compatibility/res/js/wcml-members.js', array( 'jquery' ), $wcml_version );
77
  wp_enqueue_script( 'wcml-members-js' );
78
  wp_localize_script( 'wcml-members-js', 'wc_memberships_memebers_area_endpoint', $this->get_members_area_endpoint() );
79
  }
@@ -83,7 +83,8 @@ class WCML_WC_Memberships {
83
  public function get_members_area_endpoint() {
84
 
85
  $endpoint = get_option( 'woocommerce_myaccount_members_area_endpoint', 'members-area' );
86
- $translated_endpoint = apply_filters( 'wpml_translate_single_string', $endpoint, 'WooCommerce Endpoints', 'members_area' );
 
87
 
88
  return array(
89
  'original' => $endpoint,
73
  if ( isset( $post->ID ) && wc_get_page_id( 'myaccount' ) == $post->ID ) {
74
  $wcml_plugin_url = $this->wp_api->constant( 'WCML_PLUGIN_URL' );
75
  $wcml_version = $this->wp_api->constant( 'WCML_VERSION' );
76
+ wp_register_script( 'wcml-members-js', $wcml_plugin_url . '/compatibility/res/js/wcml-members.js', array( 'jquery' ), $wcml_version, true );
77
  wp_enqueue_script( 'wcml-members-js' );
78
  wp_localize_script( 'wcml-members-js', 'wc_memberships_memebers_area_endpoint', $this->get_members_area_endpoint() );
79
  }
83
  public function get_members_area_endpoint() {
84
 
85
  $endpoint = get_option( 'woocommerce_myaccount_members_area_endpoint', 'members-area' );
86
+ $string_context = class_exists( 'WPML_Endpoints_Support' ) ? WPML_Endpoints_Support::STRING_CONTEXT : 'WooCommerce Endpoints';
87
+ $translated_endpoint = apply_filters( 'wpml_translate_single_string', $endpoint, $string_context, 'members_area' );
88
 
89
  return array(
90
  'original' => $endpoint,
compatibility/class-wcml-wc-product-type-column.php ADDED
@@ -0,0 +1,18 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class WCML_WC_Product_Type_Column {
4
+
5
+ public function add_hooks() {
6
+
7
+ add_filter( 'wcml_show_type_column', array( $this, 'show_type_column' ) );
8
+
9
+ }
10
+
11
+ public function show_type_column( $show ) {
12
+
13
+ wp_enqueue_style( 'wc-product-type-column-admin-styles' );
14
+
15
+ return true;
16
+ }
17
+
18
+ }
compatibility/class-wcml-wc-subscriptions.php CHANGED
@@ -38,6 +38,8 @@ class WCML_WC_Subscriptions{
38
  'woocommerce_subscription_price_from'
39
  ), 10, 2 );
40
 
 
 
41
  }
42
 
43
  function init(){
@@ -293,4 +295,17 @@ class WCML_WC_Subscriptions{
293
  }
294
  }
295
 
 
 
 
 
 
 
 
 
 
 
 
 
 
296
  }
38
  'woocommerce_subscription_price_from'
39
  ), 10, 2 );
40
 
41
+ add_filter( 'wcml_xliff_allowed_variations_types', array( $this, 'set_allowed_variations_types_in_xliff') );
42
+
43
  }
44
 
45
  function init(){
295
  }
296
  }
297
 
298
+ /**
299
+ * @param array $allowed_types
300
+ *
301
+ * @return array
302
+ */
303
+ public function set_allowed_variations_types_in_xliff( $allowed_types ){
304
+
305
+ $allowed_types[] = 'variable-subscription';
306
+ $allowed_types[] = 'subscription_variation';
307
+
308
+ return $allowed_types;
309
+ }
310
+
311
  }
compatibility/class-wcml-wpfastest-cache.php ADDED
@@ -0,0 +1,29 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class WCML_WpFastest_Cache {
4
+
5
+ public function add_hooks() {
6
+ add_filter( 'wcml_is_cache_enabled_for_switching_currency', array(
7
+ $this,
8
+ 'is_cache_enabled_for_switching_currency'
9
+ ) );
10
+ }
11
+
12
+ /**
13
+ * @param bool $cache_enabled
14
+ *
15
+ * @return bool
16
+ */
17
+ public function is_cache_enabled_for_switching_currency( $cache_enabled ) {
18
+
19
+ $wp_fastest_cache_options = json_decode( get_option( 'WpFastestCache' ) );
20
+
21
+ if ( isset( $wp_fastest_cache_options->wpFastestCacheStatus ) && 'on' === $wp_fastest_cache_options->wpFastestCacheStatus ) {
22
+ $cache_enabled = true;
23
+ }
24
+
25
+ return $cache_enabled;
26
+ }
27
+
28
+ }
29
+
compatibility/res/css/wcml-product-addons.css ADDED
@@ -0,0 +1,34 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ .wc-pao-addon-option-row .wcml-option-prices:not(.hidden) {
2
+ align-self: center;
3
+ justify-self: center;
4
+ grid-column: 13/14;
5
+ }
6
+ .wc-pao-addon-option-row .wcml-option-prices:not(.hidden) + .wc-pao-addon-content-remove {
7
+ grid-column: 14/15;
8
+ }
9
+
10
+ .wcml-dialog-product-addons .wpml-form-row label {
11
+ text-align: start;
12
+ width: 30px;
13
+ margin: 4px 15px;
14
+ }
15
+ .wcml-dialog-product-addons .wpml-form-row input {
16
+ margin: 4px 10px;
17
+ }
18
+
19
+ .wcml-dialog-product-addons {
20
+ min-width: 300px;
21
+ max-width: 90%;
22
+ }
23
+ .wcml-dialog-product-addons .wcml-dialog-container {
24
+ padding-bottom: 20px !important;
25
+ }
26
+ .wcml-dialog-product-addons .wpml-form-row.default-price span {
27
+ display: inline-block;
28
+ margin: 0 14px 9px;
29
+ font-size: 1.3em;
30
+ }
31
+
32
+ .wc-pao-addon-adjust-price-settings .wcml-option-prices {
33
+ margin-inline-start: 10px;
34
+ }
compatibility/res/js/wcml-product-addons.js ADDED
@@ -0,0 +1,93 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ jQuery(document).ready(function ($) {
2
+
3
+ $('.wc-pao-addon-header').each(function () {
4
+ fix_dialogs_visibility($(this));
5
+ });
6
+
7
+ if( $('.wcml_custom_prices').length > 0 ){
8
+ $('.wcml_custom_prices').insertAfter( $('.global-addons-form tr:eq(2)') ).show();
9
+ }
10
+
11
+ $(document).on('click', '#product_addons_data .js-wcml-dialog-trigger', function () {
12
+ var dialog = $(this).parent().find('.wcml-dialog');
13
+ var default_price = $(this).parent().parent().find('input.wc_input_price').val();
14
+ var option_type = $(this).closest('.wc-pao-addon-content').find('.wc-pao-addon-type-select').val();
15
+
16
+ dialog.find('.default-price strong').html(default_price ? default_price : 0);
17
+
18
+ if ('multiple_choice' === option_type || 'checkbox' === option_type) {
19
+ var option_text = $(this).parent().parent().find('.wc-pao-addon-content-label input[type="text"]').val();
20
+ if (option_text) {
21
+ dialog.find('p>strong').html(option_text);
22
+ }
23
+ } else {
24
+ var addon_text = $(this).closest('.wc-pao-addon-content').find('.wc-pao-addon-title input[type="text"]').val();
25
+ if (addon_text) {
26
+ dialog.find('p>strong').html(addon_text);
27
+ }
28
+ }
29
+ });
30
+
31
+ $(document).on('change', '.wc-pao-addon-type-select', function () {
32
+ fix_dialogs_visibility($(this));
33
+ maybe_set_prices_dialog_visible($(this));
34
+ });
35
+
36
+ $(document).on('click', '.wcml_product_addons_apply_prices', function () {
37
+
38
+ var dialog = $(this).closest('.wcml-ui-dialog');
39
+ var dialog_id = $(this).data('dialog');
40
+
41
+ dialog.find('.wc_input_price').each(function () {
42
+ $('.wcml-dialog#' + dialog_id).find('input[name="' + $(this).attr('name') + '"]').attr('value', $(this).val());
43
+ });
44
+ dialog.find('.wcml-dialog-close-button').trigger('click');
45
+ });
46
+
47
+ $(document).on('change', '.wcml_custom_prices_input', function () {
48
+ if (parseInt($(this).val()) === 1) {
49
+ $('#product_addons_data .js-wcml-option-prices').each(function () {
50
+ $(this).removeClass('hidden');
51
+ });
52
+ } else {
53
+ $('#product_addons_data .js-wcml-option-prices').each(function () {
54
+ $(this).addClass('hidden');
55
+ });
56
+ }
57
+ });
58
+
59
+ });
60
+
61
+ function fix_dialogs_visibility(element) {
62
+
63
+ var parent = element.closest('.wc-pao-addon');
64
+ var option_type = parent.find('.wc-pao-addon-type-select').val();
65
+
66
+ parent.find('.wc-pao-addon-adjust-price-settings').append(parent.find('.wc-pao-addon-content>.wcml-option-prices'));
67
+
68
+ if ('multiple_choice' !== option_type && 'checkbox' !== option_type) {
69
+ parent.find('.wc-pao-addon-content-option-rows .wcml-option-prices .wc_input_price').each(function () {
70
+ jQuery(this).attr('disabled', 'disabled');
71
+ });
72
+ parent.find('.wc-pao-addon-adjust-price-settings .wcml-option-prices .wc_input_price').each(function () {
73
+ jQuery(this).removeAttr('disabled');
74
+ });
75
+ } else {
76
+ parent.find('.wc-pao-addon-adjust-price-settings .wcml-option-prices .wc_input_price').each(function () {
77
+ jQuery(this).attr('disabled', 'disabled');
78
+ });
79
+
80
+ parent.find('.wc-pao-addon-content-option-rows .wcml-option-prices .wc_input_price').each(function () {
81
+ jQuery(this).removeAttr('disabled');
82
+ });
83
+ }
84
+
85
+ }
86
+
87
+ function maybe_set_prices_dialog_visible(element) {
88
+ if (element.closest('#wpbody').find('.wcml_custom_prices_input:checked').val() == 1) {
89
+ element.closest('.wc-pao-addon').find('.js-wcml-option-prices').each(function () {
90
+ jQuery(this).removeClass('hidden');
91
+ });
92
+ }
93
+ }
compatibility/res/js/wcml-product-addons.min.js ADDED
@@ -0,0 +1 @@
 
1
+ jQuery(document).ready(function($){$(".wc-pao-addon-header").each(function(){fix_dialogs_visibility($(this))});if($(".wcml_custom_prices").length>0){$(".wcml_custom_prices").insertAfter($(".global-addons-form tr:eq(2)")).show()}$(document).on("click","#product_addons_data .js-wcml-dialog-trigger",function(){var dialog=$(this).parent().find(".wcml-dialog");var default_price=$(this).parent().parent().find("input.wc_input_price").val();var option_type=$(this).closest(".wc-pao-addon-content").find(".wc-pao-addon-type-select").val();dialog.find(".default-price strong").html(default_price?default_price:0);if("multiple_choice"===option_type||"checkbox"===option_type){var option_text=$(this).parent().parent().find('.wc-pao-addon-content-label input[type="text"]').val();if(option_text){dialog.find("p>strong").html(option_text)}}else{var addon_text=$(this).closest(".wc-pao-addon-content").find('.wc-pao-addon-title input[type="text"]').val();if(addon_text){dialog.find("p>strong").html(addon_text)}}});$(document).on("change",".wc-pao-addon-type-select",function(){fix_dialogs_visibility($(this));maybe_set_prices_dialog_visible($(this))});$(document).on("click",".wcml_product_addons_apply_prices",function(){var dialog=$(this).closest(".wcml-ui-dialog");var dialog_id=$(this).data("dialog");dialog.find(".wc_input_price").each(function(){$(".wcml-dialog#"+dialog_id).find('input[name="'+$(this).attr("name")+'"]').attr("value",$(this).val())});dialog.find(".wcml-dialog-close-button").trigger("click")});$(document).on("change",".wcml_custom_prices_input",function(){if(parseInt($(this).val())===1){$("#product_addons_data .js-wcml-option-prices").each(function(){$(this).removeClass("hidden")})}else{$("#product_addons_data .js-wcml-option-prices").each(function(){$(this).addClass("hidden")})}})});function fix_dialogs_visibility(element){var parent=element.closest(".wc-pao-addon");var option_type=parent.find(".wc-pao-addon-type-select").val();parent.find(".wc-pao-addon-adjust-price-settings").append(parent.find(".wc-pao-addon-content>.wcml-option-prices"));if("multiple_choice"!==option_type&&"checkbox"!==option_type){parent.find(".wc-pao-addon-content-option-rows .wcml-option-prices .wc_input_price").each(function(){jQuery(this).attr("disabled","disabled")});parent.find(".wc-pao-addon-adjust-price-settings .wcml-option-prices .wc_input_price").each(function(){jQuery(this).removeAttr("disabled")})}else{parent.find(".wc-pao-addon-adjust-price-settings .wcml-option-prices .wc_input_price").each(function(){jQuery(this).attr("disabled","disabled")});parent.find(".wc-pao-addon-content-option-rows .wcml-option-prices .wc_input_price").each(function(){jQuery(this).removeAttr("disabled")})}}function maybe_set_prices_dialog_visible(element){if(element.closest("#wpbody").find(".wcml_custom_prices_input:checked").val()==1){element.closest(".wc-pao-addon").find(".js-wcml-option-prices").each(function(){jQuery(this).removeClass("hidden")})}}
inc/admin-menus/class-wcml-admin-menus.php CHANGED
@@ -11,14 +11,14 @@ class WCML_Admin_Menus{
11
  self::$sitepress =& $sitepress;
12
  self::$wpdb =& $wpdb;
13
 
 
 
14
  if( self::is_page_without_admin_language_switcher() ){
15
  self::remove_wpml_admin_language_switcher();
16
  }
17
 
18
  if( is_admin() && !is_null( $sitepress ) && $check_dependencies ){
19
 
20
- add_action( 'admin_menu', array(__CLASS__, 'register_menus' ), 80 );
21
-
22
  add_action( 'admin_footer', array(__CLASS__, 'documentation_links' ) );
23
  add_action( 'admin_head', array( __CLASS__, 'hide_multilingual_content_setup_box' ) );
24
  add_action( 'admin_init', array( __CLASS__, 'restrict_admin_with_redirect' ) );
11
  self::$sitepress =& $sitepress;
12
  self::$wpdb =& $wpdb;
13
 
14
+ add_action( 'admin_menu', array(__CLASS__, 'register_menus' ), 80 );
15
+
16
  if( self::is_page_without_admin_language_switcher() ){
17
  self::remove_wpml_admin_language_switcher();
18
  }
19
 
20
  if( is_admin() && !is_null( $sitepress ) && $check_dependencies ){
21
 
 
 
22
  add_action( 'admin_footer', array(__CLASS__, 'documentation_links' ) );
23
  add_action( 'admin_head', array( __CLASS__, 'hide_multilingual_content_setup_box' ) );
24
  add_action( 'admin_init', array( __CLASS__, 'restrict_admin_with_redirect' ) );
inc/class-wcml-ajax-setup.php CHANGED
@@ -29,17 +29,7 @@ class WCML_Ajax_Setup{
29
  do_action( 'wcml_localize_woocommerce_on_ajax' );
30
  }
31
 
32
- if ( $this->sitepress->get_wp_api()->version_compare( $this->sitepress->get_wp_api()->constant( 'WC_VERSION' ), '3.3', '<' ) ) {
33
- add_filter( 'woocommerce_params', array( $this, 'filter_woocommerce_ajax_params' ) );
34
-
35
- add_filter( 'wc_checkout_params', array( $this, 'add_language_parameter_to_ajax_url' ) );
36
- add_filter( 'wc_cart', array( $this, 'add_language_parameter_to_ajax_url' ) );
37
- add_filter( 'wc_cart_fragments_params', array( $this, 'add_language_parameter_to_ajax_url' ) );
38
- add_filter( 'wc_add_to_cart_params', array( $this, 'add_language_parameter_to_ajax_url' ) );
39
- } else {
40
- add_filter( 'woocommerce_get_script_data', array( $this, 'add_language_parameter_to_ajax_url' ) );
41
- }
42
-
43
  add_action( 'woocommerce_checkout_order_review', array( $this, 'filter_woocommerce_order_review' ), 9 );
44
  add_action( 'woocommerce_checkout_order_review', array( $this, 'add_hidden_language_field' ) );
45
  add_action( 'woocommerce_checkout_update_order_review', array( $this, 'filter_woocommerce_order_review' ), 9 );
@@ -64,57 +54,6 @@ class WCML_Ajax_Setup{
64
 
65
  return $woocommerce_params;
66
  }
67
-
68
- function filter_woocommerce_ajax_params($woocommerce_params){
69
- global $post;
70
-
71
- $value = $woocommerce_params;
72
-
73
- if($this->sitepress->get_current_language() !== $this->sitepress->get_default_language()){
74
- if( isset( $value['ajax_url'] ) ){
75
- $value['ajax_url'] = add_query_arg('lang', ICL_LANGUAGE_CODE, $woocommerce_params['ajax_url']);
76
- if( isset( $value['checkout_url'] ) ){
77
- $value['checkout_url'] = add_query_arg('action', 'woocommerce-checkout', $value['ajax_url']);
78
- }
79
- }
80
- }
81
-
82
- if(!isset($post->ID)){
83
- return $value;
84
- }
85
-
86
- $ch_pages = wp_cache_get('ch_pages', 'wcml_ch_pages');
87
-
88
- if(empty($ch_pages)){
89
-
90
- $ch_pages = array(
91
-
92
- 'checkout_page_id' => get_option('woocommerce_checkout_page_id'),
93
- 'pay_page_id' => get_option('woocommerce_pay_page_id'),
94
- 'cart_page_id' => get_option('woocommerce_cart_page_id'));
95
-
96
- $ch_pages['translated_checkout_page_id'] = apply_filters( 'translate_object_id',$ch_pages['checkout_page_id'], 'page', false);
97
- $ch_pages['translated_pay_page_id'] = apply_filters( 'translate_object_id',$ch_pages['pay_page_id'], 'page', false);
98
- $ch_pages['translated_cart_page_id'] = apply_filters( 'translate_object_id',$ch_pages['cart_page_id'], 'page', false);
99
-
100
- }
101
-
102
- wp_cache_set( 'ch_pages', $ch_pages, 'wcml_ch_pages' );
103
-
104
- if($ch_pages['translated_cart_page_id'] == $post->ID){
105
- $value['is_cart'] = 1;
106
- $value['cart_url'] = get_permalink($ch_pages['translated_cart_page_id']);
107
- } else if($ch_pages['translated_checkout_page_id'] == $post->ID || $ch_pages['checkout_page_id'] == $post->ID){
108
- $value['is_checkout'] = 1;
109
-
110
- $_SESSION['wpml_globalcart_language'] = $this->sitepress->get_current_language();
111
-
112
- } else if($ch_pages['translated_pay_page_id'] == $post->ID){
113
- $value['is_pay_page'] = 1;
114
- }
115
-
116
- return $value;
117
- }
118
 
119
  public function wcml_localize_woocommerce_on_ajax() {
120
  $action = isset( $_POST['action'] ) ? filter_var( $_POST['action'], FILTER_SANITIZE_STRING ) : false;
29
  do_action( 'wcml_localize_woocommerce_on_ajax' );
30
  }
31
 
32
+ add_filter( 'woocommerce_get_script_data', array( $this, 'add_language_parameter_to_ajax_url' ) );
 
 
 
 
 
 
 
 
 
 
33
  add_action( 'woocommerce_checkout_order_review', array( $this, 'filter_woocommerce_order_review' ), 9 );
34
  add_action( 'woocommerce_checkout_order_review', array( $this, 'add_hidden_language_field' ) );
35
  add_action( 'woocommerce_checkout_update_order_review', array( $this, 'filter_woocommerce_order_review' ), 9 );
54
 
55
  return $woocommerce_params;
56
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
57
 
58
  public function wcml_localize_woocommerce_on_ajax() {
59
  $action = isset( $_POST['action'] ) ? filter_var( $_POST['action'], FILTER_SANITIZE_STRING ) : false;
inc/class-wcml-attributes.php CHANGED
@@ -2,25 +2,33 @@
2
 
3
  class WCML_Attributes{
4
 
5
- /** @var woocommerce_wpml */
6
- private $woocommerce_wpml;
7
- /** @var Sitepress */
8
- private $sitepress;
9
- /** @var wpdb */
10
- private $wpdb;
11
-
12
- /**
13
- * WCML_Attributes constructor.
14
- *
15
- * @param woocommerce_wpml $woocommerce_wpml
16
- * @param SitePress $sitepress
17
- * @param wpdb $wpdb
18
- */
19
- public function __construct( woocommerce_wpml $woocommerce_wpml, SitePress $sitepress, wpdb $wpdb ){
20
- $this->woocommerce_wpml = $woocommerce_wpml;
21
- $this->sitepress = $sitepress;
22
- $this->wpdb = $wpdb;
23
- }
 
 
 
 
 
 
 
 
24
 
25
  public function add_hooks(){
26
 
@@ -34,14 +42,7 @@ class WCML_Attributes{
34
  $this->icl_custom_tax_sync_options();
35
  }
36
 
37
- add_action( 'woocommerce_before_attribute_delete', array( $this, 'refresh_taxonomy_translations_cache' ), 10, 3 );
38
-
39
- $deprecated_wc = $this->sitepress->get_wp_api()->version_compare( $this->sitepress->get_wp_api()->constant( 'WC_VERSION' ), '3.0.0', '<' );
40
- if ( $deprecated_wc ) {
41
- add_filter( 'woocommerce_get_product_attributes', array( $this, 'filter_adding_to_cart_product_attributes_names' ) );
42
- }else{
43
- add_filter( 'woocommerce_product_get_attributes', array( $this, 'filter_adding_to_cart_product_attributes_names' ) );
44
- }
45
 
46
  if ( $this->woocommerce_wpml->products->is_product_display_as_translated_post_type() ) {
47
  add_filter( 'woocommerce_available_variation', array(
@@ -75,19 +76,6 @@ class WCML_Attributes{
75
 
76
  }
77
 
78
- /*
79
- * This creates the terms translation cache so the translations can be deleted via the 'delete_term' hook
80
- * after the original term was deleted and getting the translations directly from the db is not possible
81
- */
82
- public function refresh_taxonomy_translations_cache( $attribute_id, $attribute_name, $taxonomy ){
83
-
84
- $terms = get_terms( $taxonomy, 'orderby=name&hide_empty=0' );
85
- foreach ( $terms as $term ) {
86
- $trid = $this->sitepress->get_element_trid( $term->term_taxonomy_id, 'tax_' . $taxonomy );
87
- }
88
-
89
- }
90
-
91
  public function not_translatable_html(){
92
  $attr_id = isset( $_GET[ 'edit' ] ) ? absint( $_GET[ 'edit' ] ) : false;
93
 
@@ -140,8 +128,7 @@ class WCML_Attributes{
140
  $terms = $this->get_attribute_terms( $attribute );
141
 
142
  foreach( $terms as $term ){
143
- $term_language_details = $this->sitepress->get_element_language_details( $term->term_id, 'tax_'.$attribute );
144
- if( $term_language_details && $term_language_details->source_language_code ){
145
  wp_delete_term( $term->term_id, $attribute );
146
  }
147
  }
@@ -152,8 +139,7 @@ class WCML_Attributes{
152
  $terms = $this->get_attribute_terms( $attribute );
153
 
154
  foreach( $terms as $term ){
155
- $term_language_details = $this->sitepress->get_element_language_details( $term->term_id, 'tax_'.$attribute );
156
- if( $term_language_details && is_null( $term_language_details->source_language_code ) ){
157
  $variations = $this->wpdb->get_results( $this->wpdb->prepare( "SELECT post_id FROM {$this->wpdb->postmeta} WHERE meta_key=%s AND meta_value = %s", 'attribute_'.$attribute, $term->slug ) );
158
 
159
  foreach( $variations as $variation ){
@@ -175,8 +161,7 @@ class WCML_Attributes{
175
  $terms = $this->get_attribute_terms( $attribute );
176
  $cleared_products = array();
177
  foreach( $terms as $term ) {
178
- $term_language_details = $this->sitepress->get_element_language_details( $term->term_id, 'tax_'.$attribute );
179
- if( $term_language_details && is_null( $term_language_details->source_language_code ) ){
180
  $args = array(
181
  'tax_query' => array(
182
  array(
@@ -532,7 +517,7 @@ class WCML_Attributes{
532
  function filter_dropdown_variation_attribute_options_args( $args ){
533
 
534
  if( isset( $args['attribute'] ) && isset( $args['product'] ) ){
535
- $args['attribute'] = $this->filter_attribute_name( $args['attribute'], WooCommerce_Functions_Wrapper::get_product_id( $args['product'] ) );
536
 
537
  if( $this->woocommerce_wpml->products->is_product_display_as_translated_post_type() ){
538
  foreach( $args[ 'options' ] as $key => $attribute_value ){
@@ -715,14 +700,12 @@ class WCML_Attributes{
715
  public function set_translation_status_as_needs_update( $meta_id, $object_id, $meta_key ) {
716
  if ( $meta_key === '_product_attributes' ) {
717
 
718
- $status_helper = wpml_get_post_status_helper();
719
- $translation_element_factory = new WPML_Translation_Element_Factory( $this->sitepress );
720
- $post_element = $translation_element_factory->create_post( $object_id );
721
 
722
- if ( null === $post_element->get_source_language_code() ) {
723
- foreach ( $post_element->get_translations() as $translation ) {
724
- if ( null !== $translation->get_source_language_code() ) {
725
- $status_helper->set_update_status( $translation->get_id(), 1 );
726
  }
727
  }
728
  }
2
 
3
  class WCML_Attributes{
4
 
5
+ /** @var woocommerce_wpml */
6
+ private $woocommerce_wpml;
7
+ /** @var Sitepress */
8
+ private $sitepress;
9
+ /** @var WPML_Post_Translation */
10
+ private $post_translations;
11
+ /** @var WPML_Term_Translation */
12
+ private $term_translations;
13
+ /** @var wpdb */
14
+ private $wpdb;
15
+
16
+ /**
17
+ * WCML_Attributes constructor.
18
+ *
19
+ * @param woocommerce_wpml $woocommerce_wpml
20
+ * @param SitePress $sitepress
21
+ * @param WPML_Post_Translation $post_translations
22
+ * @param WPML_Term_Translation $term_translations
23
+ * @param wpdb $wpdb
24
+ */
25
+ public function __construct( woocommerce_wpml $woocommerce_wpml, SitePress $sitepress, WPML_Post_Translation $post_translations, WPML_Term_Translation $term_translations, wpdb $wpdb ) {
26
+ $this->woocommerce_wpml = $woocommerce_wpml;
27
+ $this->sitepress = $sitepress;
28
+ $this->post_translations = $post_translations;
29
+ $this->term_translations = $term_translations;
30
+ $this->wpdb = $wpdb;
31
+ }
32
 
33
  public function add_hooks(){
34
 
42
  $this->icl_custom_tax_sync_options();
43
  }
44
 
45
+ add_filter( 'woocommerce_product_get_attributes', array( $this, 'filter_adding_to_cart_product_attributes_names' ) );
 
 
 
 
 
 
 
46
 
47
  if ( $this->woocommerce_wpml->products->is_product_display_as_translated_post_type() ) {
48
  add_filter( 'woocommerce_available_variation', array(
76
 
77
  }
78
 
 
 
 
 
 
 
 
 
 
 
 
 
 
79
  public function not_translatable_html(){
80
  $attr_id = isset( $_GET[ 'edit' ] ) ? absint( $_GET[ 'edit' ] ) : false;
81
 
128
  $terms = $this->get_attribute_terms( $attribute );
129
 
130
  foreach( $terms as $term ){
131
+ if( $this->term_translations->get_source_lang_code( $term->term_id ) ){
 
132
  wp_delete_term( $term->term_id, $attribute );
133
  }
134
  }
139
  $terms = $this->get_attribute_terms( $attribute );
140
 
141
  foreach( $terms as $term ){
142
+ if( is_null( $this->term_translations->get_source_lang_code( $term->term_id ) ) ){
 
143
  $variations = $this->wpdb->get_results( $this->wpdb->prepare( "SELECT post_id FROM {$this->wpdb->postmeta} WHERE meta_key=%s AND meta_value = %s", 'attribute_'.$attribute, $term->slug ) );
144
 
145
  foreach( $variations as $variation ){
161
  $terms = $this->get_attribute_terms( $attribute );
162
  $cleared_products = array();
163
  foreach( $terms as $term ) {
164
+ if( is_null( $this->term_translations->get_source_lang_code( $term->term_id ) ) ){
 
165
  $args = array(
166
  'tax_query' => array(
167
  array(
517
  function filter_dropdown_variation_attribute_options_args( $args ){
518
 
519
  if( isset( $args['attribute'] ) && isset( $args['product'] ) ){
520
+ $args['attribute'] = $this->filter_attribute_name( $args['attribute'], $args['product']->get_id() );
521
 
522
  if( $this->woocommerce_wpml->products->is_product_display_as_translated_post_type() ){
523
  foreach( $args[ 'options' ] as $key => $attribute_value ){
700
  public function set_translation_status_as_needs_update( $meta_id, $object_id, $meta_key ) {
701
  if ( $meta_key === '_product_attributes' ) {
702
 
703
+ if ( null === $this->post_translations->get_source_lang_code( $object_id ) ) {
704
+ $status_helper = wpml_get_post_status_helper();
 
705
 
706
+ foreach ( $this->post_translations->get_element_translations( $object_id ) as $translation ) {
707
+ if ( null !== $this->post_translations->get_source_lang_code( $translation ) ) {
708
+ $status_helper->set_update_status( $translation, 1 );
 
709
  }
710
  }
711
  }
inc/class-wcml-cart.php CHANGED
@@ -67,12 +67,6 @@ class WCML_Cart {
67
 
68
  $this->localize_flat_rates_shipping_classes();
69
  }
70
-
71
- add_filter( 'woocommerce_cart_needs_payment', array(
72
- $this,
73
- 'use_cart_contents_total_for_needs_payment'
74
- ), 10, 2 );
75
-
76
  }
77
 
78
  public function is_clean_cart_enabled() {
@@ -213,12 +207,13 @@ class WCML_Cart {
213
  closeOnEscape: false,
214
  dialogClass: "otgs-ui-dialog wcml-cart-dialog",
215
  create: function () {
216
- jQuery('#jquery-ui-style-css').attr('disabled', 'disabled');
217
- },
218
- open: function (event, ui) {
219
- jQuery(".ui-dialog-titlebar-close", ui.dialog | ui).hide();
220
- repositionDialog();
221
  },
 
 
 
 
 
222
  close: function (event, ui) {
223
  jQuery('#jquery-ui-style-css').removeAttr('disabled');
224
  },
@@ -288,18 +283,7 @@ class WCML_Cart {
288
  $tr_product_id = apply_filters( 'translate_object_id', $cart_item['product_id'], 'product', false, $current_language );
289
  //translate custom attr labels in cart object
290
 
291
- if ( version_compare( WC_VERSION, '3.0.0', '<' ) && isset( $cart_item['data']->product_attributes ) ) {
292
- foreach ( $cart_item['data']->product_attributes as $attr_key => $product_attribute ) {
293
- if ( isset( $product_attribute['is_taxonomy'] ) && ! $product_attribute['is_taxonomy'] ) {
294
- $cart->cart_contents[ $key ]['data']->product_attributes[ $attr_key ]['name'] = $this->woocommerce_wpml->strings->translated_attribute_label(
295
- $product_attribute['name'],
296
- $product_attribute['name'],
297
- $tr_product_id );
298
- }
299
- }
300
- }
301
-
302
- //translate custom attr value in cart object
303
  if ( isset( $cart_item['variation'] ) && is_array( $cart_item['variation'] ) ) {
304
  foreach ( $cart_item['variation'] as $attr_key => $attribute ) {
305
  $cart->cart_contents[ $key ]['variation'][ $attr_key ] = $this->get_cart_attribute_translation(
@@ -329,21 +313,13 @@ class WCML_Cart {
329
  if ( ! is_null( $tr_variation_id ) ) {
330
  $cart->cart_contents[ $key ]['product_id'] = intval( $tr_product_id );
331
  $cart->cart_contents[ $key ]['variation_id'] = intval( $tr_variation_id );
332
- if ( defined( 'WC_VERSION' ) && version_compare( WC_VERSION, '2.7', '<' ) ) {
333
- $cart->cart_contents[ $key ]['data']->id = intval( $tr_product_id );
334
- } else {
335
- $cart->cart_contents[ $key ]['data']->set_id( intval( $tr_product_id ) );
336
- }
337
  $cart->cart_contents[ $key ]['data']->post = get_post( $tr_product_id );
338
  }
339
  } else {
340
  if ( ! is_null( $tr_product_id ) ) {
341
  $cart->cart_contents[ $key ]['product_id'] = intval( $tr_product_id );
342
- if ( defined( 'WC_VERSION' ) && version_compare( WC_VERSION, '2.7', '<' ) ) {
343
- $cart->cart_contents[ $key ]['data']->id = intval( $tr_product_id );
344
- } else {
345
- $cart->cart_contents[ $key ]['data']->set_id( intval( $tr_product_id ) );
346
- }
347
  $cart->cart_contents[ $key ]['data']->post = get_post( $tr_product_id );
348
  }
349
  }
@@ -390,7 +366,7 @@ class WCML_Cart {
390
  *
391
  * @return array
392
  */
393
- public function validate_cart_item_data( array $item_data, WC_Product $product ) {
394
 
395
  if( $item_data['attributes'] ){
396
 
@@ -496,19 +472,23 @@ class WCML_Cart {
496
  public function translate_cart_contents( $item ) {
497
 
498
  // translate the product id and product data
499
- $item['product_id'] = apply_filters( 'translate_object_id', $item['product_id'], 'product', true );
500
- if ( $item['variation_id'] ) {
501
- $item['variation_id'] = apply_filters( 'translate_object_id', $item['variation_id'], 'product_variation', true );
502
  }
503
 
504
- $item_product_title = $item['variation_id'] ? get_the_title( $item['variation_id'] ) : get_the_title( $item['product_id'] );
 
505
 
506
- if ( $this->sitepress->get_wp_api()->version_compare( $this->sitepress->get_wp_api()->constant( 'WC_VERSION' ), '3.0.0', '>=' ) ) {
507
- $item['data']->set_name( $item_product_title );
508
- } else {
509
- $item['data']->post->post_title = $item_product_title;
510
  }
511
 
 
 
 
 
512
  return $item;
513
  }
514
 
@@ -638,35 +618,53 @@ class WCML_Cart {
638
  }
639
 
640
  /**
641
- * @param bool $needs
642
- * @param WC_Cart $cart
643
  *
644
- * @return bool
645
  */
646
- public function use_cart_contents_total_for_needs_payment( $needs, $cart ) {
647
 
648
- if ( version_compare( WC()->version, '3.2', '<' ) ) {
649
- $needs = ( isset( $cart->cart_contents_total ) && $cart->cart_contents_total > 0 )
650
- || ( isset( $cart->total ) && $cart->total > 0 )
651
- || isset( $cart->recurring_carts );
652
  }
653
 
654
- return $needs;
655
  }
656
 
657
  /**
658
- * @param string $permalink
659
- * @param array $cart_item
660
  *
661
- * @return string
662
  */
663
- public function cart_item_permalink( $permalink, $cart_item ) {
664
 
665
- if ( ! $this->sitepress->get_setting( 'auto_adjust_ids' ) ) {
666
- $permalink = get_permalink( $cart_item['product_id'] );
 
 
 
 
 
667
  }
668
 
669
- return $permalink;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
670
  }
671
 
672
  }
67
 
68
  $this->localize_flat_rates_shipping_classes();
69
  }
 
 
 
 
 
 
70
  }
71
 
72
  public function is_clean_cart_enabled() {
207
  closeOnEscape: false,
208
  dialogClass: "otgs-ui-dialog wcml-cart-dialog",
209
  create: function () {
210
+
 
 
 
 
211
  },
212
+ open: function (event, ui) {
213
+ jQuery(".ui-dialog-titlebar-close", ui.dialog | ui).hide();
214
+ jQuery('#jquery-ui-style-css').attr('disabled', 'disabled');
215
+ repositionDialog();
216
+ },
217
  close: function (event, ui) {
218
  jQuery('#jquery-ui-style-css').removeAttr('disabled');
219
  },
283
  $tr_product_id = apply_filters( 'translate_object_id', $cart_item['product_id'], 'product', false, $current_language );
284
  //translate custom attr labels in cart object
285
 
286
+ //translate custom attr value in cart object
 
 
 
 
 
 
 
 
 
 
 
287
  if ( isset( $cart_item['variation'] ) && is_array( $cart_item['variation'] ) ) {
288
  foreach ( $cart_item['variation'] as $attr_key => $attribute ) {
289
  $cart->cart_contents[ $key ]['variation'][ $attr_key ] = $this->get_cart_attribute_translation(
313
  if ( ! is_null( $tr_variation_id ) ) {
314
  $cart->cart_contents[ $key ]['product_id'] = intval( $tr_product_id );
315
  $cart->cart_contents[ $key ]['variation_id'] = intval( $tr_variation_id );
316
+ $cart->cart_contents[ $key ]['data']->set_id( intval( $tr_product_id ) );
 
 
 
 
317
  $cart->cart_contents[ $key ]['data']->post = get_post( $tr_product_id );
318
  }
319
  } else {
320
  if ( ! is_null( $tr_product_id ) ) {
321
  $cart->cart_contents[ $key ]['product_id'] = intval( $tr_product_id );
322
+ $cart->cart_contents[ $key ]['data']->set_id( intval( $tr_product_id ) );
 
 
 
 
323
  $cart->cart_contents[ $key ]['data']->post = get_post( $tr_product_id );
324
  }
325
  }
366
  *
367
  * @return array
368
  */
369
+ public function validate_cart_item_data( array $item_data, $product ) {
370
 
371
  if( $item_data['attributes'] ){
372
 
472
  public function translate_cart_contents( $item ) {
473
 
474
  // translate the product id and product data
475
+ $translated_product_id = apply_filters( 'translate_object_id', $item['product_id'], 'product', true );
476
+ if( $item['product_id'] !== $translated_product_id ){
477
+ $item['product_id'] = $translated_product_id;
478
  }
479
 
480
+ if ( $item['variation_id'] ) {
481
+ $translated_variation_id = apply_filters( 'translate_object_id', $item['variation_id'], 'product_variation', true );
482
 
483
+ if( $item['variation_id'] !== $translated_variation_id ){
484
+ $item['variation_id'] = $translated_variation_id;
485
+ }
 
486
  }
487
 
488
+ $item_product_title = $item['variation_id'] ? get_the_title( $translated_variation_id ) : get_the_title( $translated_product_id );
489
+ $item['data']->set_name( $item_product_title );
490
+ $item['data_hash'] = $this->get_data_cart_hash( $item );
491
+
492
  return $item;
493
  }
494
 
618
  }
619
 
620
  /**
621
+ * @param string $permalink
622
+ * @param array $cart_item
623
  *
624
+ * @return string
625
  */
626
+ public function cart_item_permalink( $permalink, $cart_item ) {
627
 
628
+ if ( ! $this->sitepress->get_setting( 'auto_adjust_ids' ) ) {
629
+ $permalink = get_permalink( $cart_item['product_id'] );
 
 
630
  }
631
 
632
+ return $permalink;
633
  }
634
 
635
  /**
636
+ * @param $currency
 
637
  *
638
+ * @return float
639
  */
640
+ public function get_cart_total_in_currency( $currency ){
641
 
642
+ $client_currency = $this->woocommerce_wpml->multi_currency->get_client_currency();
643
+ $cart_total = 0;
644
+ $cart_items = WC()->cart->get_cart_contents();
645
+
646
+ //items total
647
+ foreach( $cart_items as $item ){
648
+ $cart_total += $this->woocommerce_wpml->multi_currency->prices->get_product_price_in_currency( $item['product_id'], $currency ) * $item['quantity'];
649
  }
650
 
651
+ $cart_total += $this->woocommerce_wpml->multi_currency->prices->convert_price_amount_by_currencies( WC()->cart->get_shipping_total(), $client_currency, $currency );
652
+
653
+ $cart_total = $this->woocommerce_wpml->multi_currency->prices->apply_rounding_rules( $cart_total, $currency );
654
+
655
+ return $cart_total;
656
+ }
657
+
658
+ /**
659
+ * @param string $currency
660
+ *
661
+ * @return string
662
+ */
663
+ public function get_formatted_cart_total_in_currency( $currency ){
664
+
665
+ $cart_total = $this->woocommerce_wpml->multi_currency->prices->formatted_price( $this->get_cart_total_in_currency( $currency ), $currency );
666
+
667
+ return $cart_total;
668
  }
669
 
670
  }
inc/class-wcml-comments.php CHANGED
@@ -10,16 +10,20 @@ class WCML_Comments {
10
  private $woocommerce_wpml;
11
  /** @var Sitepress */
12
  private $sitepress;
 
 
13
 
14
  /**
15
  * WCML_Comments constructor.
16
  *
17
  * @param woocommerce_wpml $woocommerce_wpml
18
  * @param SitePress $sitepress
 
19
  */
20
- public function __construct( woocommerce_wpml $woocommerce_wpml, SitePress $sitepress ) {
21
- $this->woocommerce_wpml = $woocommerce_wpml;
22
- $this->sitepress = $sitepress;
 
23
  }
24
 
25
  public function add_hooks() {
@@ -58,15 +62,14 @@ class WCML_Comments {
58
  */
59
  public function recalculate_comment_rating( $product_id ){
60
 
61
- $trid = $this->sitepress->get_element_trid( $product_id, 'post_product' );
62
- $translations = $this->sitepress->get_element_translations( $trid, 'post_product', false, true );
63
  $average_ratings_sum = 0;
64
  $average_ratings_count = 0;
65
  $reviews_count = 0;
66
 
67
  foreach ( $translations as $translation ) {
68
- $ratings = get_post_meta( $translation->element_id, '_wc_rating_count', true );
69
- $review_count = get_post_meta( $translation->element_id, self::WC_REVIEW_COUNT_KEY, true );
70
 
71
  if ( $ratings ) {
72
  foreach ( $ratings as $rating => $count ) {
@@ -82,8 +85,8 @@ class WCML_Comments {
82
  $average_rating = number_format( $average_ratings_sum / $average_ratings_count, 2, '.', '' );
83
 
84
  foreach ( $translations as $translation ) {
85
- update_post_meta( $translation->element_id, self::WCML_AVERAGE_RATING_KEY, $average_rating );
86
- update_post_meta( $translation->element_id, self::WCML_REVIEW_COUNT_KEY, $reviews_count );
87
  }
88
  }
89
 
@@ -149,15 +152,9 @@ class WCML_Comments {
149
  */
150
  private function get_translations_ids_list( $product_id ){
151
 
152
- $trid = $this->sitepress->get_element_trid( $product_id, 'post_product' );
153
- $translations = $this->sitepress->get_element_translations( $trid, 'post_product', false, true );
154
 
155
- $ids = array();
156
- foreach ( $translations as $translation ) {
157
- $ids[] = $translation->element_id;
158
- }
159
-
160
- return implode( ',', array_filter( $ids ) );
161
 
162
  }
163
 
@@ -174,16 +171,21 @@ class WCML_Comments {
174
 
175
  if ( ! isset( $_GET['clang'] ) || $current_language === $_GET['clang'] ) {
176
  $comments_link = add_query_arg( array( 'clang' => 'all' ), $current_url );
177
- $reviews_count = $this->get_reviews_count( 'all' );
178
- $comments_link_text = sprintf( __( 'Show reviews in all languages (%s)', 'woocommerce-multilingual'), $reviews_count);
 
 
 
 
179
  } elseif ( 'all' === $_GET['clang'] ) {
 
 
180
  $comments_link = add_query_arg( array( 'clang' => $current_language ), $current_url );
181
  $language_details = $this->sitepress->get_language_details( $current_language );
182
- $reviews_count = $this->get_reviews_count( );
183
- $comments_link_text = sprintf( __( 'Show only reviews in %s (%s)', 'woocommerce-multilingual'), $language_details['display_name'], $reviews_count );
184
  }
185
 
186
- if( isset( $reviews_count ) && $reviews_count ){
187
  echo '<p><a id="lang-comments-link" href="' . $comments_link . '">' . $comments_link_text . '</a></p>';
188
  }
189
 
@@ -214,7 +216,7 @@ class WCML_Comments {
214
  public function add_comment_flag( $comment ) {
215
 
216
  if ( $this->is_reviews_in_all_languages( $comment->comment_post_ID ) ) {
217
- $comment_language = $this->sitepress->get_language_for_element( $comment->comment_post_ID, 'post_product' );
218
 
219
  $html = '<div style="float: left; padding-right: 5px;">';
220
  $html .= '<img src="' . $this->sitepress->get_flag_url( $comment_language ) . '" width=18" height="12">';
10
  private $woocommerce_wpml;
11
  /** @var Sitepress */
12
  private $sitepress;
13
+ /** @var WPML_Post_Translation */
14
+ private $post_translations;
15
 
16
  /**
17
  * WCML_Comments constructor.
18
  *
19
  * @param woocommerce_wpml $woocommerce_wpml
20
  * @param SitePress $sitepress
21
+ * @param WPML_Post_Translation $post_translations
22
  */
23
+ public function __construct( woocommerce_wpml $woocommerce_wpml, SitePress $sitepress, WPML_Post_Translation $post_translations ) {
24
+ $this->woocommerce_wpml = $woocommerce_wpml;
25
+ $this->sitepress = $sitepress;
26
+ $this->post_translations = $post_translations;
27
  }
28
 
29
  public function add_hooks() {
62
  */
63
  public function recalculate_comment_rating( $product_id ){
64
 
65
+ $translations = $this->post_translations->get_element_translations( $product_id );
 
66
  $average_ratings_sum = 0;
67
  $average_ratings_count = 0;
68
  $reviews_count = 0;
69
 
70
  foreach ( $translations as $translation ) {
71
+ $ratings = get_post_meta( $translation, '_wc_rating_count', true );
72
+ $review_count = get_post_meta( $translation, self::WC_REVIEW_COUNT_KEY, true );
73
 
74
  if ( $ratings ) {
75
  foreach ( $ratings as $rating => $count ) {
85
  $average_rating = number_format( $average_ratings_sum / $average_ratings_count, 2, '.', '' );
86
 
87
  foreach ( $translations as $translation ) {
88
+ update_post_meta( $translation, self::WCML_AVERAGE_RATING_KEY, $average_rating );
89
+ update_post_meta( $translation, self::WCML_REVIEW_COUNT_KEY, $reviews_count );
90
  }
91
  }
92
 
152
  */
153
  private function get_translations_ids_list( $product_id ){
154
 
155
+ $translations = $this->post_translations->get_element_translations( $product_id );
 
156
 
157
+ return implode( ',', array_filter( $translations ) );
 
 
 
 
 
158
 
159
  }
160
 
171
 
172
  if ( ! isset( $_GET['clang'] ) || $current_language === $_GET['clang'] ) {
173
  $comments_link = add_query_arg( array( 'clang' => 'all' ), $current_url );
174
+ $all_languages_reviews_count = $this->get_reviews_count( 'all' );
175
+ $current_language_reviews_count = $this->get_reviews_count();
176
+
177
+ if( $all_languages_reviews_count > $current_language_reviews_count ){
178
+ $comments_link_text = sprintf( __( 'Show reviews in all languages (%s)', 'woocommerce-multilingual'), $all_languages_reviews_count);
179
+ }
180
  } elseif ( 'all' === $_GET['clang'] ) {
181
+
182
+ $current_language_reviews_count = $this->get_reviews_count();
183
  $comments_link = add_query_arg( array( 'clang' => $current_language ), $current_url );
184
  $language_details = $this->sitepress->get_language_details( $current_language );
185
+ $comments_link_text = sprintf( __( 'Show only reviews in %s (%s)', 'woocommerce-multilingual'), $language_details['display_name'], $current_language_reviews_count );
 
186
  }
187
 
188
+ if( isset( $comments_link_text ) && $comments_link_text ){
189
  echo '<p><a id="lang-comments-link" href="' . $comments_link . '">' . $comments_link_text . '</a></p>';
190
  }
191
 
216
  public function add_comment_flag( $comment ) {
217
 
218
  if ( $this->is_reviews_in_all_languages( $comment->comment_post_ID ) ) {
219
+ $comment_language = $this->post_translations->get_element_lang_code( $comment->comment_post_ID );
220
 
221
  $html = '<div style="float: left; padding-right: 5px;">';
222
  $html .= '<img src="' . $this->sitepress->get_flag_url( $comment_language ) . '" width=18" height="12">';
inc/class-wcml-compatibility.php CHANGED
@@ -63,13 +63,8 @@ class WCML_Compatibility {
63
 
64
  //Product Bundle
65
  if ( class_exists( 'WC_Product_Bundle' ) && function_exists( 'WC_PB' ) ) {
66
- if ( version_compare( WC_PB()->version, '5.0.0', '<' ) ) {
67
- $this->product_bundles = new WCML_Product_Bundles_Legacy( $this->sitepress, $this->woocommerce_wpml, $this->tp );
68
- $this->product_bundles->add_hooks();
69
- } else {
70
- $product_bundle_items = new WCML_WC_Product_Bundles_Items();
71
- $this->product_bundles = new WCML_Product_Bundles( $this->sitepress, $this->woocommerce_wpml, $product_bundle_items, $this->wpdb );
72
- }
73
  }
74
 
75
  // WooCommerce Variation Swatches and Photos
@@ -78,8 +73,8 @@ class WCML_Compatibility {
78
  }
79
 
80
  // Product Add-ons
81
- if ( class_exists( 'Product_Addon_Display' ) ) {
82
- $this->product_addons = new WCML_Product_Addons( $this->sitepress, $this->woocommerce_wpml->settings['enable_multi_currency'] );
83
  $this->product_addons->add_hooks();
84
  }
85
 
@@ -161,11 +156,6 @@ class WCML_Compatibility {
161
  $this->wc_checkout_addons = new WCML_Checkout_Addons();
162
  }
163
 
164
- // woocommerce checkout addons
165
- if ( wp_get_theme() == 'Flatsome' ) {
166
- $this->flatsome = new WCML_Flatsome();
167
- }
168
-
169
  if ( class_exists( 'WC_Mix_and_Match' ) ) {
170
  $this->mix_and_match_products = new WCML_Mix_and_Match_Products();
171
  }
@@ -180,8 +170,13 @@ class WCML_Compatibility {
180
  $this->adventure_tours->add_hooks();
181
  }
182
 
 
 
 
 
 
183
  //Aurum Theme
184
- if ( wp_get_theme() == 'Aurum' ) {
185
  new WCML_Aurum();
186
  }
187
 
@@ -259,6 +254,18 @@ class WCML_Compatibility {
259
  $this->litespeed_cache->add_hooks();
260
  }
261
 
 
 
 
 
 
 
 
 
 
 
 
 
262
  }
263
 
264
  }
63
 
64
  //Product Bundle
65
  if ( class_exists( 'WC_Product_Bundle' ) && function_exists( 'WC_PB' ) ) {
66
+ $product_bundle_items = new WCML_WC_Product_Bundles_Items();
67
+ $this->product_bundles = new WCML_Product_Bundles( $this->sitepress, $this->woocommerce_wpml, $product_bundle_items, $this->wpdb );
 
 
 
 
 
68
  }
69
 
70
  // WooCommerce Variation Swatches and Photos
73
  }
74
 
75
  // Product Add-ons
76
+ if ( defined( 'WC_PRODUCT_ADDONS_VERSION' ) || class_exists( 'Product_Addon_Display' ) ) {
77
+ $this->product_addons = new WCML_Product_Addons( $this->sitepress, $this->woocommerce_wpml );
78
  $this->product_addons->add_hooks();
79
  }
80
 
156
  $this->wc_checkout_addons = new WCML_Checkout_Addons();
157
  }
158
 
 
 
 
 
 
159
  if ( class_exists( 'WC_Mix_and_Match' ) ) {
160
  $this->mix_and_match_products = new WCML_Mix_and_Match_Products();
161
  }
170
  $this->adventure_tours->add_hooks();
171
  }
172
 
173
+ // flatsome theme
174
+ if ( wp_get_theme()->get( 'Name' ) === 'Flatsome' ) {
175
+ $this->flatsome = new WCML_Flatsome();
176
+ }
177
+
178
  //Aurum Theme
179
+ if ( wp_get_theme()->get( 'Name' ) === 'Aurum' ) {
180
  new WCML_Aurum();
181
  }
182
 
254
  $this->litespeed_cache->add_hooks();
255
  }
256
 
257
+ // WpFastest Cache
258
+ if ( class_exists( 'WpFastestCache' ) ) {
259
+ $this->wpfastestcache = new WCML_WpFastest_Cache();
260
+ $this->wpfastestcache->add_hooks();
261
+ }
262
+
263
+ // WooCommerce Product Type Column
264
+ if ( class_exists( 'WC_Product_Type_Column' ) ) {
265
+ $this->wc_type_column = new WCML_WC_Product_Type_Column();
266
+ $this->wc_type_column->add_hooks();
267
+ }
268
+
269
  }
270
 
271
  }
inc/class-wcml-coupons.php CHANGED
@@ -102,12 +102,7 @@ class WCML_Coupons {
102
  */
103
  public function is_valid_for_product( $valid, $product, $object, $values ) {
104
 
105
- if ( version_compare( WC()->version, '3.0', '<' ) ) {
106
- $product_id = $product->is_type( 'variation' ) ? $product->parent->id : $product->id;
107
- } else {
108
- $product_id = $product->is_type( 'variation' ) ? $product->get_parent_id() : $product->get_id();
109
- }
110
-
111
  $translated_product_id = apply_filters( 'translate_object_id', $product_id, 'product', false, $this->sitepress->get_current_language() );
112
 
113
  if ( $translated_product_id && $product_id !== $translated_product_id ) {
102
  */
103
  public function is_valid_for_product( $valid, $product, $object, $values ) {
104
 
105
+ $product_id = $product->is_type( 'variation' ) ? $product->get_parent_id() : $product->get_id();
 
 
 
 
 
106
  $translated_product_id = apply_filters( 'translate_object_id', $product_id, 'product', false, $this->sitepress->get_current_language() );
107
 
108
  if ( $translated_product_id && $product_id !== $translated_product_id ) {
inc/class-wcml-dependencies.php CHANGED
@@ -2,10 +2,10 @@
2
 
3
  class WCML_Dependencies {
4
 
5
- const MIN_WPML = '3.4';
6
- const MIN_WPML_TM = '1.9';
7
- const MIN_WPML_ST = '2.0';
8
- const MIN_WOOCOMMERCE = '2.1';
9
 
10
  private $missing = array();
11
  private $err_message = '';
@@ -219,33 +219,6 @@ class WCML_Dependencies {
219
  $message .= ' | ';
220
  $message .= '<a href="' . admin_url( 'admin.php?page=' . WPML_TM_FOLDER . '/menu/main.php&sm=mcsetup#icl_custom_posts_sync_options' ) . '">' . __( 'Configure products slug translation', 'woocommerce-multilingual' ) . '</a>';
221
 
222
-
223
- // Check if translated shop pages have the same slug (only 1.x)
224
- $allsame = true;
225
- if ( version_compare( WOOCOMMERCE_VERSION, "2.0.0" ) >= 0 ) {
226
- } else {
227
- $shop_page_id = get_option( 'woocommerce_shop_page_id', false );
228
- if ( ! empty( $shop_page_id ) ) {
229
- $slug = @get_post( $shop_page_id )->post_name;
230
- $languages = $sitepress->get_active_languages();
231
- if ( sizeof( $languages ) < 2 ) {
232
- return;
233
- }
234
- foreach ( $languages as $language ) {
235
- if ( $language['code'] != $sitepress->get_default_language() ) {
236
- $translated_shop_page_id = apply_filters( 'translate_object_id', $shop_page_id, 'page', false, $language['code'] );
237
- if ( ! empty( $translated_shop_page_id ) ) {
238
- $translated_slug = get_post( $translated_shop_page_id )->post_name;
239
- if ( ! empty( $translated_slug ) && $translated_slug != $slug ) {
240
- $allsame = false;
241
- break;
242
- }
243
- }
244
- }
245
- }
246
- }
247
- }
248
-
249
  // Check if slug translation is enabled
250
  $compatible = true;
251
  $permalink_structure = get_option( 'permalink_structure' );
@@ -256,12 +229,6 @@ class WCML_Dependencies {
256
  $compatible = false;
257
  }
258
 
259
- // display messages
260
- if ( ! $allsame ) {
261
- $this->err_message = '<div class="message error"><p>' . printf( __( 'If you want different slugs for shop pages (%s/%s), you need to disable the shop prefix for products in <a href="%s">WooCommerce Settings</a>', 'woocommerce-multilingual' ),
262
- $slug, $translated_slug, admin_url( "admin.php?page=woocommerce_settings&tab=pages" ) ) . '</p></div>';
263
- add_action( 'admin_notices', array( $this, 'plugin_notice_message' ) );
264
- }
265
 
266
  if ( ! $compatible && ( $pagenow == 'options-permalink.php' || ( isset( $_GET['page'] ) && $_GET['page'] == 'wpml-wcml' ) ) ) {
267
  $this->err_message = '<div class="message error"><p>' . $message . ' </p></div>';
2
 
3
  class WCML_Dependencies {
4
 
5
+ const MIN_WPML = '4.0.0';
6
+ const MIN_WPML_TM = '2.6';
7
+ const MIN_WPML_ST = '2.8';
8
+ const MIN_WOOCOMMERCE = '3.3.0';
9
 
10
  private $missing = array();
11
  private $err_message = '';
219
  $message .= ' | ';
220
  $message .= '<a href="' . admin_url( 'admin.php?page=' . WPML_TM_FOLDER . '/menu/main.php&sm=mcsetup#icl_custom_posts_sync_options' ) . '">' . __( 'Configure products slug translation', 'woocommerce-multilingual' ) . '</a>';
221
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
222
  // Check if slug translation is enabled
223
  $compatible = true;
224
  $permalink_structure = get_option( 'permalink_structure' );
229
  $compatible = false;
230
  }
231
 
 
 
 
 
 
 
232
 
233
  if ( ! $compatible && ( $pagenow == 'options-permalink.php' || ( isset( $_GET['page'] ) && $_GET['page'] == 'wpml-wcml' ) ) ) {
234
  $this->err_message = '<div class="message error"><p>' . $message . ' </p></div>';
inc/class-wcml-emails.php CHANGED
@@ -3,6 +3,7 @@ class WCML_Emails{
3
 
4
  private $order_id = false;
5
  private $locale = false;
 
6
  /** @var woocommerce_wpml */
7
  private $woocommerce_wpml;
8
  /** @var Sitepress */
@@ -35,7 +36,7 @@ class WCML_Emails{
35
  $this,
36
  'email_heading_completed'
37
  ), 9 );
38
- add_action( 'woocommerce_order_status_changed', array( $this, 'comments_language' ), 10 );
39
  }
40
 
41
  add_action( 'woocommerce_new_customer_note_notification', array( $this, 'email_heading_note' ), 9 );
@@ -200,12 +201,17 @@ class WCML_Emails{
200
  $this->sitepress->switch_lang( $this->sitepress->get_default_language() );
201
  }
202
 
203
- function comments_language(){
204
- $this->change_email_language( $this->woocommerce_wpml->strings->get_domain_language( 'woocommerce' ) );
 
 
 
 
 
 
205
 
206
- }
207
 
208
- function email_heading_completed( $order_id, $no_checking = false ){
209
 
210
  if( ( class_exists( 'WC_Email_Customer_Completed_Order' ) || $no_checking ) && isset( $this->woocommerce->mailer()->emails[ 'WC_Email_Customer_Completed_Order' ] ) ){
211
 
@@ -361,22 +367,22 @@ class WCML_Emails{
361
 
362
  }
363
 
364
- function change_email_language( $lang ) {
 
365
 
366
- if ( isset( $_POST['post_type'] ) && 'shop_order' === $_POST['post_type'] ) {
367
- return;
368
- }
369
 
370
- $this->sitepress->switch_lang( $lang, true );
371
- $this->locale = $this->sitepress->get_locale( $lang );
372
- unload_textdomain( 'woocommerce' );
373
- unload_textdomain( 'default' );
374
- global $wp_locale;
375
- $wp_locale = new WP_Locale();
376
 
377
- $this->woocommerce->load_plugin_textdomain();
378
- load_default_textdomain( $this->locale );
379
- }
 
380
 
381
  function admin_string_return_cached( $value, $option ){
382
  if( in_array( $option, array ( 'woocommerce_email_from_address', 'woocommerce_email_from_name' ) ) )
@@ -556,8 +562,10 @@ class WCML_Emails{
556
  function translate_woocommerce_countries( $countries ){
557
 
558
  if( isset( $_POST[ 'wc_order_action' ] ) && $_POST[ 'wc_order_action' ] !== 'send_email_new_order' && isset( $_POST[ 'post_ID' ] ) ){
 
559
  $this->refresh_email_lang( $_POST[ 'post_ID' ] );
560
  $countries = include( WC()->plugin_path() . '/i18n/countries.php' );
 
561
  }
562
 
563
  return $countries;
3
 
4
  private $order_id = false;
5
  private $locale = false;
6
+ private $admin_language = false;
7
  /** @var woocommerce_wpml */
8
  private $woocommerce_wpml;
9
  /** @var Sitepress */
36
  $this,
37
  'email_heading_completed'
38
  ), 9 );
39
+ add_action( 'woocommerce_order_status_changed', array( $this, 'comments_language' ), 10 );
40
  }
41
 
42
  add_action( 'woocommerce_new_customer_note_notification', array( $this, 'email_heading_note' ), 9 );
201
  $this->sitepress->switch_lang( $this->sitepress->get_default_language() );
202
  }
203
 
204
+ public function comments_language(){
205
+
206
+ if ( is_admin() && false !== $this->admin_language ) {
207
+ $this->change_email_language( $this->admin_language );
208
+ }else{
209
+ $this->change_email_language( $this->woocommerce_wpml->strings->get_domain_language( 'woocommerce' ) );
210
+ }
211
+ }
212
 
 
213
 
214
+ function email_heading_completed( $order_id, $no_checking = false ){
215
 
216
  if( ( class_exists( 'WC_Email_Customer_Completed_Order' ) || $no_checking ) && isset( $this->woocommerce->mailer()->emails[ 'WC_Email_Customer_Completed_Order' ] ) ){
217
 
367
 
368
  }
369
 
370
+ function change_email_language( $lang ) {
371
+ global $wp_locale;
372
 
373
+ if ( ! $this->admin_language ) {
374
+ $this->admin_language = $this->sitepress->get_user_admin_language( get_current_user_id(), true );
375
+ }
376
 
377
+ $this->sitepress->switch_lang( $lang, true );
378
+ $this->locale = $this->sitepress->get_locale( $lang );
379
+ unload_textdomain( 'woocommerce' );
380
+ unload_textdomain( 'default' );
 
 
381
 
382
+ $wp_locale = new WP_Locale();
383
+ $this->woocommerce->load_plugin_textdomain();
384
+ load_default_textdomain( $this->locale );
385
+ }
386
 
387
  function admin_string_return_cached( $value, $option ){
388
  if( in_array( $option, array ( 'woocommerce_email_from_address', 'woocommerce_email_from_name' ) ) )
562
  function translate_woocommerce_countries( $countries ){
563
 
564
  if( isset( $_POST[ 'wc_order_action' ] ) && $_POST[ 'wc_order_action' ] !== 'send_email_new_order' && isset( $_POST[ 'post_ID' ] ) ){
565
+ $current_language = $this->sitepress->get_current_language();
566
  $this->refresh_email_lang( $_POST[ 'post_ID' ] );
567
  $countries = include( WC()->plugin_path() . '/i18n/countries.php' );
568
+ $this->change_email_language( $current_language );
569
  }
570
 
571
  return $countries;
inc/class-wcml-endpoints-legacy.php ADDED
@@ -0,0 +1,301 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class WCML_Endpoints_Legacy {
4
+
5
+ /** @var woocommerce_wpml */
6
+ private $woocommerce_wpml;
7
+ var $endpoints_strings = array();
8
+
9
+ function __construct( $woocommerce_wpml ) {
10
+ $this->woocommerce_wpml = $woocommerce_wpml;
11
+ }
12
+
13
+ public function add_hooks() {
14
+
15
+ add_action( 'icl_ajx_custom_call', array( $this, 'rewrite_rule_endpoints' ), 11, 2 );
16
+ add_action( 'woocommerce_update_options', array( $this, 'add_endpoints' ) );
17
+
18
+ add_filter( 'pre_update_option_rewrite_rules', array( $this, 'update_rewrite_rules' ), 100, 2 );
19
+ add_filter( 'option_rewrite_rules', array(
20
+ $this,
21
+ 'translate_endpoints_in_rewrite_rules'
22
+ ), 0, 1 ); // high priority
23
+ add_filter( 'page_link', array( $this, 'endpoint_permalink_filter' ), 10, 2 ); //after WPML
24
+
25
+ if ( ! is_admin() ) {
26
+ $this->maybe_flush_rules();
27
+ $this->register_endpoints_translations();
28
+ }
29
+
30
+ add_filter( 'woocommerce_settings_saved', array( $this, 'update_original_endpoints_strings' ) );
31
+ }
32
+
33
+ function register_endpoints_translations( $language = null ) {
34
+
35
+ if ( ! class_exists( 'WooCommerce' ) || ! defined( 'ICL_SITEPRESS_VERSION' ) || ICL_PLUGIN_INACTIVE || version_compare( WOOCOMMERCE_VERSION, '2.2', '<' ) ) {
36
+ return false;
37
+ }
38
+
39
+ $wc_vars = WC()->query->query_vars;
40
+
41
+ if ( ! empty( $wc_vars ) ) {
42
+ $query_vars = array(
43
+ // Checkout actions
44
+ 'order-pay' => $this->get_endpoint_translation( 'order-pay', $wc_vars['order-pay'], $language ),
45
+ 'order-received' => $this->get_endpoint_translation( 'order-received', $wc_vars['order-received'], $language ),
46
+
47
+ // My account actions
48
+ 'view-order' => $this->get_endpoint_translation( 'view-order', $wc_vars['view-order'], $language ),
49
+ 'edit-account' => $this->get_endpoint_translation( 'edit-account', $wc_vars['edit-account'], $language ),
50
+ 'edit-address' => $this->get_endpoint_translation( 'edit-address', $wc_vars['edit-address'], $language ),
51
+ 'lost-password' => $this->get_endpoint_translation( 'lost-password', $wc_vars['lost-password'], $language ),
52
+ 'customer-logout' => $this->get_endpoint_translation( 'customer-logout', $wc_vars['customer-logout'], $language ),
53
+ 'add-payment-method' => $this->get_endpoint_translation( 'add-payment-method', $wc_vars['add-payment-method'], $language )
54
+ );
55
+
56
+ if ( isset( $wc_vars['orders'] ) ) {
57
+ $query_vars['orders'] = $this->get_endpoint_translation( 'orders', $wc_vars['orders'], $language );
58
+ }
59
+ if ( isset( $wc_vars['downloads'] ) ) {
60
+ $query_vars['downloads'] = $this->get_endpoint_translation( 'downloads', $wc_vars['downloads'], $language );
61
+ }
62
+ if ( isset( $wc_vars['payment-methods'] ) ) {
63
+ $query_vars['payment-methods'] = $this->get_endpoint_translation( 'payment-methods', $wc_vars['payment-methods'], $language );
64
+ }
65
+ if ( isset( $wc_vars['delete-payment-method'] ) ) {
66
+ $query_vars['delete-payment-method'] = $this->get_endpoint_translation( 'delete-payment-method', $wc_vars['delete-payment-method'], $language );
67
+ }
68
+ if ( isset( $wc_vars['set-default-payment-method'] ) ) {
69
+ $query_vars['set-default-payment-method'] = $this->get_endpoint_translation( 'set-default-payment-method', $wc_vars['set-default-payment-method'], $language );
70
+ }
71
+
72
+ $query_vars = apply_filters( 'wcml_register_endpoints_query_vars', $query_vars, $wc_vars, $this );
73
+
74
+ $query_vars = array_merge( $wc_vars, $query_vars );
75
+ WC()->query->query_vars = $query_vars;
76
+
77
+ }
78
+
79
+ return WC()->query->query_vars;
80
+ }
81
+
82
+ function get_endpoint_translation( $key, $endpoint, $language = null ) {
83
+
84
+ $this->register_endpoint_string( $key, $endpoint );
85
+
86
+ if ( function_exists( 'icl_t' ) ) {
87
+ $trnsl = apply_filters( 'wpml_translate_single_string', $endpoint, 'WooCommerce Endpoints', $key, $language );
88
+
89
+ if ( ! empty( $trnsl ) ) {
90
+ return $trnsl;
91
+ } else {
92
+ return $endpoint;
93
+ }
94
+ } else {
95
+ return $endpoint;
96
+ }
97
+ }
98
+
99
+ public function register_endpoint_string( $key, $endpoint ) {
100
+
101
+ $string = icl_get_string_id( $endpoint, 'WooCommerce Endpoints', $key );
102
+
103
+ if ( ! $string && function_exists( 'icl_register_string' ) ) {
104
+ do_action( 'wpml_register_single_string', 'WooCommerce Endpoints', $key, $endpoint );
105
+ } else {
106
+ $this->endpoints_strings[] = $string;
107
+ }
108
+
109
+ }
110
+
111
+ function rewrite_rule_endpoints( $call, $data ) {
112
+
113
+ if ( $call == 'icl_st_save_translation' && in_array( $data['icl_st_string_id'], $this->endpoints_strings ) ) {
114
+ $this->add_endpoints();
115
+ $this->flush_rules_for_endpoints_translations();
116
+ }
117
+ }
118
+
119
+ function flush_rules_for_endpoints_translations() {
120
+ add_option( 'flush_rules_for_endpoints_translations', true );
121
+ }
122
+
123
+ function maybe_flush_rules() {
124
+ if ( get_option( 'flush_rules_for_endpoints_translations' ) ) {
125
+ delete_option( 'flush_rules_for_endpoints_translations' );
126
+ WC()->query->init_query_vars();
127
+ WC()->query->add_endpoints();
128
+ WC()->query->query_vars = apply_filters( 'wcml_flush_rules_query_vars', WC()->query->query_vars, $this );
129
+
130
+ remove_filter( 'gettext_with_context', array(
131
+ $this->woocommerce_wpml->strings,
132
+ 'category_base_in_strings_language'
133
+ ), 99, 3 );
134
+ if ( (int) get_option( 'page_on_front' ) !== wc_get_page_id( 'myaccount' ) ) {
135
+ flush_rewrite_rules( false );
136
+ }
137
+ add_filter( 'gettext_with_context', array(
138
+ $this->woocommerce_wpml->strings,
139
+ 'category_base_in_strings_language'
140
+ ), 99, 3 );
141
+ delete_option( 'flush_rules_for_endpoints_translations' );
142
+ }
143
+ }
144
+
145
+ function update_rewrite_rules( $value, $old_value ) {
146
+ $this->add_endpoints();
147
+ $this->flush_rules_for_endpoints_translations();
148
+
149
+ return $value;
150
+ }
151
+
152
+ function add_endpoints() {
153
+ if ( ! isset( $this->endpoints_strings ) ) {
154
+ return;
155
+ }
156
+
157
+ global $wpdb;
158
+ //add endpoints and flush rules
159
+ foreach ( $this->endpoints_strings as $string_id ) {
160
+
161
+ $string_translations = icl_get_string_translations_by_id( $string_id );
162
+
163
+ foreach ( $string_translations as $string ) {
164
+ add_rewrite_endpoint( $string['value'], EP_ROOT | EP_PAGES );
165
+ }
166
+ }
167
+
168
+ }
169
+
170
+ function endpoint_permalink_filter( $p, $pid ) {
171
+ global $post, $wp;
172
+
173
+ if ( isset( $post->ID ) && ! is_admin() && version_compare( WOOCOMMERCE_VERSION, '2.2', '>=' ) && defined( 'ICL_SITEPRESS_VERSION' ) && ! ICL_PLUGIN_INACTIVE ) {
174
+ global $sitepress;
175
+
176
+ $current_lang = $sitepress->get_current_language();
177
+ $page_lang = $sitepress->get_language_for_element( $post->ID, 'post_page' );
178
+
179
+ if (
180
+ (
181
+ $current_lang != $page_lang &&
182
+ apply_filters( 'translate_object_id', $pid, 'page', false, $page_lang ) == $post->ID
183
+ ) ||
184
+ apply_filters( 'wcml_endpoint_force_permalink_filter', false, $current_lang, $page_lang )
185
+ ) {
186
+
187
+ $endpoints = WC()->query->get_query_vars();
188
+
189
+ foreach ( $endpoints as $key => $endpoint ) {
190
+ if ( isset( $wp->query_vars[ $key ] ) ) {
191
+ if ( 'order-pay' === $key ) {
192
+ $endpoint = get_option( 'woocommerce_checkout_pay_endpoint' );
193
+ $p .= isset( $_SERVER['QUERY_STRING'] ) ? '?' . $_SERVER['QUERY_STRING'] : '';
194
+ } elseif ( 'order-received' === $key ) {
195
+ $endpoint = get_option( 'woocommerce_checkout_order_received_endpoint' );
196
+ } elseif ( 'customer-logout' === $key ) {
197
+ $endpoint = get_option( 'woocommerce_logout_endpoint' );
198
+ } else {
199
+ $endpoint = get_option( 'woocommerce_myaccount_' . str_replace( '-', '_', $key ) . '_endpoint', $endpoint );
200
+ }
201
+
202
+ $endpoint = apply_filters( 'wcml_endpoint_permalink_filter', $endpoint, $key );
203
+
204
+ $p = $this->get_endpoint_url( $this->get_endpoint_translation( $key, $endpoint, $current_lang ), $wp->query_vars[ $key ], $p, $page_lang );
205
+ }
206
+ }
207
+ }
208
+ }
209
+
210
+ return $p;
211
+ }
212
+
213
+ function get_endpoint_url( $endpoint, $value = '', $permalink = '', $page_lang = false ) {
214
+ global $sitepress;
215
+
216
+ if ( $page_lang ) {
217
+ $edit_address_shipping = $this->get_translated_edit_address_slug( 'shipping', $page_lang );
218
+ $edit_address_billing = $this->get_translated_edit_address_slug( 'billing', $page_lang );
219
+
220
+ if ( $edit_address_shipping == urldecode( $value ) ) {
221
+ $value = $this->get_translated_edit_address_slug( 'shipping', $sitepress->get_current_language() );
222
+ } elseif ( $edit_address_billing == urldecode( $value ) ) {
223
+ $value = $this->get_translated_edit_address_slug( 'billing', $sitepress->get_current_language() );
224
+ }
225
+
226
+ }
227
+
228
+
229
+ if ( get_option( 'permalink_structure' ) ) {
230
+ if ( strstr( $permalink, '?' ) ) {
231
+ $query_string = '?' . parse_url( $permalink, PHP_URL_QUERY );
232
+ $permalink = current( explode( '?', $permalink ) );
233
+ } else {
234
+ $query_string = '';
235
+ }
236
+ $url = trailingslashit( $permalink ) . $endpoint . '/' . $value . $query_string;
237
+ } else {
238
+ $url = add_query_arg( $endpoint, $value, $permalink );
239
+ }
240
+
241
+ return $url;
242
+ }
243
+
244
+
245
+ function get_translated_edit_address_slug( $slug, $language = false ) {
246
+
247
+ $strings_language = $this->woocommerce_wpml->strings->get_string_language( $slug, 'woocommerce', 'edit-address-slug: ' . $slug );
248
+
249
+ if ( $strings_language == $language ) {
250
+ return $slug;
251
+ }
252
+
253
+ $translated_slug = apply_filters( 'wpml_translate_single_string', $slug, 'woocommerce', 'edit-address-slug: ' . $slug, $language );
254
+
255
+ if ( $translated_slug == $slug ) {
256
+
257
+ if ( $language ) {
258
+ $translated_slug = $this->woocommerce_wpml->strings->get_translation_from_woocommerce_mo_file( 'edit-address-slug' . chr( 4 ) . $slug, $language );
259
+ } else {
260
+ $translated_slug = _x( $slug, 'edit-address-slug', 'woocommerce' );
261
+ }
262
+
263
+ }
264
+
265
+ return $translated_slug;
266
+ }
267
+
268
+ public function update_original_endpoints_strings() {
269
+
270
+ foreach ( WC()->query->query_vars as $endpoint_key => $endpoint ) {
271
+
272
+ $this->register_endpoint_string( $endpoint_key, $endpoint );
273
+
274
+ }
275
+
276
+ }
277
+
278
+ public function translate_endpoints_in_rewrite_rules( $value ) {
279
+
280
+ if ( ! empty( $value ) ) {
281
+
282
+ foreach ( WC()->query->query_vars as $endpoint_key => $endpoint_translation ) {
283
+ if ( $endpoint_key == $endpoint_translation ) {
284
+ continue;
285
+ }
286
+
287
+ $buff_value = array();
288
+
289
+ foreach ( $value as $k => $v ) {
290
+ $k = preg_replace( '/(\/)?' . $endpoint_key . '(\/)?(\(\/\(\.\*\)\)\?\/\?\$)/', '$1' . $endpoint_translation . '$2$3', $k );
291
+ $buff_value[ $k ] = $v;
292
+ }
293
+ $value = $buff_value;
294
+ }
295
+ }
296
+
297
+ return $value;
298
+ }
299
+
300
+
301
+ }
inc/class-wcml-endpoints.php CHANGED
@@ -1,52 +1,143 @@
1
  <?php
2
 
3
- class WCML_Endpoints{
4
 
5
  /** @var woocommerce_wpml */
6
  private $woocommerce_wpml;
7
- var $endpoints_strings = array();
8
-
9
- function __construct( $woocommerce_wpml ){
 
 
 
 
 
 
 
 
 
 
 
 
 
10
 
11
- $this->woocommerce_wpml =& $woocommerce_wpml;
12
- add_action( 'icl_ajx_custom_call', array( $this, 'rewrite_rule_endpoints' ), 11, 2 );
13
- add_action( 'woocommerce_update_options', array( $this, 'add_endpoints' ) );
14
- add_filter( 'pre_update_option_rewrite_rules', array( $this, 'update_rewrite_rules' ), 100, 2 );
15
- add_filter( 'wpml_sl_blacklist_requests', array( $this, 'reserved_requests' ), 10, 2 );
16
 
17
- add_filter( 'page_link', array( $this, 'endpoint_permalink_filter' ), 10, 2 ); //after WPML
 
 
18
 
19
- if( !is_admin() ){
20
- //endpoints hooks
21
- $this->maybe_flush_rules();
22
- $this->register_endpoints_translations();
23
- add_filter('pre_get_posts', array($this, 'check_if_endpoint_exists'));
24
- }
 
25
 
26
- add_filter( 'woocommerce_get_endpoint_url', array( $this, 'filter_get_endpoint_url' ), 10, 4 );
 
 
 
 
 
27
 
28
- add_filter( 'woocommerce_settings_saved', array( $this, 'update_original_endpoints_strings') );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
29
 
30
- add_filter( 'option_rewrite_rules', array( $this, 'translate_endpoints_in_rewrite_rules' ), 0, 1 ); // high priority
31
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
32
 
33
- public function reserved_requests( $requests, SitePress $sitepress ) {
34
  $cache_key = 'reserved_requests';
35
  $cache_group = 'wpml-endpoints';
36
 
37
- $found = null;
38
  $reserved_requests = wp_cache_get( $cache_key, $cache_group, false, $found );
39
-
40
- if ( ! $found || ! $reserved_requests ) {
 
 
 
 
 
 
 
41
  $reserved_requests = array();
42
 
43
- $current_language = $sitepress->get_current_language();
44
- $languages = $sitepress->get_active_languages();
45
  $languages_codes = array_keys( $languages );
46
  foreach ( $languages_codes as $language_code ) {
47
- $sitepress->switch_lang( $language_code );
 
 
48
 
49
- $my_account_page_id = get_option( 'woocommerce_myaccount_page_id' );
50
  if ( $my_account_page_id ) {
51
  $my_account_page = get_post( $my_account_page_id );
52
  if ( $my_account_page ) {
@@ -56,14 +147,15 @@ class WCML_Endpoints{
56
  $reserved_requests[] = '/^' . $account_base . '/'; // regex version
57
 
58
  foreach ( $this->woocommerce_wpml->get_wc_query_vars() as $key => $endpoint ) {
59
- $translated_endpoint = $this->get_endpoint_translation( $key, $endpoint, $language_code );
 
60
 
61
  $reserved_requests[] = $account_base . '/' . $translated_endpoint;
62
  }
63
  }
64
  }
65
  }
66
- $sitepress->switch_lang( $current_language );
67
 
68
  if ( $reserved_requests ) {
69
  wp_cache_set( $cache_key, $reserved_requests, $cache_group );
@@ -77,311 +169,144 @@ class WCML_Endpoints{
77
  return $requests;
78
  }
79
 
80
- function register_endpoints_translations( $language = null ){
81
-
82
- if( !class_exists( 'WooCommerce' ) || !defined( 'ICL_SITEPRESS_VERSION' ) || ICL_PLUGIN_INACTIVE || version_compare( WOOCOMMERCE_VERSION, '2.2', '<' ) ) return false;
83
-
84
- $wc_vars = WC()->query->query_vars;
85
-
86
- if ( !empty( $wc_vars ) ){
87
- $query_vars = array(
88
- // Checkout actions
89
- 'order-pay' => $this->get_endpoint_translation( 'order-pay', $wc_vars['order-pay'], $language ),
90
- 'order-received' => $this->get_endpoint_translation( 'order-received', $wc_vars['order-received'], $language ),
91
-
92
- // My account actions
93
- 'view-order' => $this->get_endpoint_translation( 'view-order', $wc_vars['view-order'], $language ),
94
- 'edit-account' => $this->get_endpoint_translation( 'edit-account', $wc_vars['edit-account'], $language ),
95
- 'edit-address' => $this->get_endpoint_translation( 'edit-address', $wc_vars['edit-address'], $language ),
96
- 'lost-password' => $this->get_endpoint_translation( 'lost-password', $wc_vars['lost-password'], $language ),
97
- 'customer-logout' => $this->get_endpoint_translation( 'customer-logout', $wc_vars['customer-logout'], $language ),
98
- 'add-payment-method' => $this->get_endpoint_translation( 'add-payment-method', $wc_vars['add-payment-method'], $language )
99
- );
100
-
101
- if( isset( $wc_vars['orders'] ) ) $query_vars[ 'orders' ] = $this->get_endpoint_translation( 'orders', $wc_vars['orders'], $language );
102
- if( isset( $wc_vars['downloads'] ) ) $query_vars[ 'downloads' ] = $this->get_endpoint_translation( 'downloads', $wc_vars['downloads'], $language );
103
- if( isset( $wc_vars['payment-methods'] ) ) $query_vars[ 'payment-methods' ] = $this->get_endpoint_translation( 'payment-methods', $wc_vars['payment-methods'], $language );
104
- if( isset( $wc_vars['delete-payment-method'] ) ) $query_vars[ 'delete-payment-method' ] = $this->get_endpoint_translation( 'delete-payment-method', $wc_vars['delete-payment-method'], $language );
105
- if( isset( $wc_vars['set-default-payment-method'] ) ) $query_vars[ 'set-default-payment-method' ] = $this->get_endpoint_translation( 'set-default-payment-method', $wc_vars['set-default-payment-method'], $language );
106
-
107
- $query_vars = apply_filters( 'wcml_register_endpoints_query_vars', $query_vars, $wc_vars, $this );
108
-
109
- $query_vars = array_merge( $wc_vars , $query_vars );
110
- WC()->query->query_vars = $query_vars;
111
-
112
- }
113
-
114
- return WC()->query->query_vars;
115
- }
116
-
117
- function get_endpoint_translation( $key, $endpoint, $language = null ){
118
-
119
- $this->register_endpoint_string( $key, $endpoint );
120
-
121
- if( function_exists('icl_t') ){
122
- $trnsl = apply_filters( 'wpml_translate_single_string', $endpoint, 'WooCommerce Endpoints', $key, $language );
123
-
124
- if( !empty( $trnsl ) ){
125
- return $trnsl;
126
- }else{
127
- return $endpoint;
128
- }
129
- }else{
130
- return $endpoint;
131
- }
132
- }
133
-
134
- public function register_endpoint_string( $key, $endpoint ){
135
-
136
- $string = icl_get_string_id( $endpoint, 'WooCommerce Endpoints', $key );
137
-
138
- if( !$string && function_exists( 'icl_register_string' ) ){
139
- do_action( 'wpml_register_single_string', 'WooCommerce Endpoints', $key, $endpoint );
140
- }else{
141
- $this->endpoints_strings[] = $string;
142
- }
143
-
144
- }
145
 
146
- function rewrite_rule_endpoints( $call, $data ){
147
-
148
- if( $call == 'icl_st_save_translation' && in_array( $data['icl_st_string_id'], $this->endpoints_strings ) ){
149
- $this->add_endpoints();
150
- $this->flush_rules_for_endpoints_translations();
151
- }
152
- }
153
-
154
- function flush_rules_for_endpoints_translations( ){
155
- add_option( 'flush_rules_for_endpoints_translations', true );
156
- }
157
-
158
- function maybe_flush_rules(){
159
- if( get_option( 'flush_rules_for_endpoints_translations' ) ){
160
- delete_option( 'flush_rules_for_endpoints_translations' );
161
- WC()->query->init_query_vars();
162
- WC()->query->add_endpoints();
163
- WC()->query->query_vars = apply_filters( 'wcml_flush_rules_query_vars', WC()->query->query_vars, $this );
164
-
165
- remove_filter( 'gettext_with_context', array( $this->woocommerce_wpml->strings, 'category_base_in_strings_language' ), 99, 3 );
166
- if ( (int) get_option( 'page_on_front' ) !== wc_get_page_id( 'myaccount' ) ) {
167
- flush_rewrite_rules( false );
168
- }
169
- add_filter( 'gettext_with_context', array( $this->woocommerce_wpml->strings, 'category_base_in_strings_language' ), 99, 3 );
170
- delete_option( 'flush_rules_for_endpoints_translations' );
171
- }
172
- }
173
-
174
- function update_rewrite_rules( $value, $old_value ){
175
- $this->add_endpoints();
176
- $this->flush_rules_for_endpoints_translations();
177
-
178
- return $value;
179
- }
180
-
181
- function add_endpoints(){
182
- if( !isset( $this->endpoints_strings ) )
183
- return;
184
-
185
- global $wpdb;
186
- //add endpoints and flush rules
187
- foreach( $this->endpoints_strings as $string_id ){
188
-
189
- $string_translations = icl_get_string_translations_by_id( $string_id );
190
-
191
- foreach( $string_translations as $string ){
192
- add_rewrite_endpoint( $string['value'], EP_ROOT | EP_PAGES );
193
- }
194
- }
195
-
196
- }
197
-
198
- function endpoint_permalink_filter( $p, $pid ){
199
- global $post;
200
-
201
- if( isset($post->ID) && !is_admin() && version_compare( WOOCOMMERCE_VERSION, '2.2', '>=' ) && defined( 'ICL_SITEPRESS_VERSION' ) && !ICL_PLUGIN_INACTIVE ){
202
- global $wp,$sitepress;
203
-
204
- $current_lang = $sitepress->get_current_language();
205
- $page_lang = $sitepress->get_language_for_element( $post->ID, 'post_page');
206
-
207
- if(
208
- (
209
- $current_lang != $page_lang &&
210
- apply_filters( 'translate_object_id', $pid, 'page', false, $page_lang ) == $post->ID
211
- ) ||
212
- apply_filters( 'wcml_endpoint_force_permalink_filter', false, $current_lang, $page_lang )
213
- ){
214
-
215
- $endpoints = WC()->query->get_query_vars();
216
-
217
- foreach( $endpoints as $key => $endpoint ){
218
- if( isset($wp->query_vars[$key]) ){
219
- if( 'order-pay' === $key ){
220
- $endpoint = get_option( 'woocommerce_checkout_pay_endpoint' );
221
- $p .= isset( $_SERVER[ 'QUERY_STRING' ] ) ? '?'.$_SERVER[ 'QUERY_STRING' ] : '';
222
- }elseif( 'order-received' === $key ){
223
- $endpoint = get_option( 'woocommerce_checkout_order_received_endpoint' );
224
- }elseif( 'customer-logout' === $key ){
225
- $endpoint = get_option( 'woocommerce_logout_endpoint' );
226
- }else{
227
- $endpoint = get_option( 'woocommerce_myaccount_'.str_replace( '-','_',$key).'_endpoint', $endpoint );
228
- }
229
-
230
- $endpoint = apply_filters( 'wcml_endpoint_permalink_filter', $endpoint, $key );
231
-
232
- $p = $this->get_endpoint_url( $this->get_endpoint_translation( $key, $endpoint, $current_lang ), $wp->query_vars[ $key ], $p, $page_lang );
233
- }
234
- }
235
- }
236
- }
237
 
238
- return $p;
239
- }
240
 
241
- function get_endpoint_url($endpoint, $value = '', $permalink = '', $page_lang = false ){
242
- global $sitepress;
243
 
244
- if( $page_lang ){
245
- $edit_address_shipping = $this->get_translated_edit_address_slug( 'shipping', $page_lang );
246
- $edit_address_billing = $this->get_translated_edit_address_slug( 'billing', $page_lang );
247
-
248
- if( $edit_address_shipping == urldecode( $value ) ){
249
- $value = $this->get_translated_edit_address_slug( 'shipping', $sitepress->get_current_language() );
250
- }elseif( $edit_address_billing == urldecode( $value ) ){
251
- $value = $this->get_translated_edit_address_slug( 'billing', $sitepress->get_current_language() );
252
- }
253
-
254
- }
255
 
 
 
 
256
 
257
- if ( get_option( 'permalink_structure' ) ) {
258
- if ( strstr( $permalink, '?' ) ) {
259
- $query_string = '?' . parse_url( $permalink, PHP_URL_QUERY );
260
- $permalink = current( explode( '?', $permalink ) );
261
- } else {
262
- $query_string = '';
263
- }
264
- $url = trailingslashit( $permalink ) . $endpoint . '/' . $value . $query_string;
265
- } else {
266
- $url = add_query_arg( $endpoint, $value, $permalink );
267
- }
268
- return $url;
269
- }
270
 
271
- /*
272
- * We need check special case - when you manually put in URL default not translated endpoint it not generated 404 error
273
- */
274
- function check_if_endpoint_exists($q){
275
- global $wp_query;
276
 
277
- $my_account_id = wc_get_page_id('myaccount');
278
 
279
- $current_id = $q->query_vars['page_id'];
280
- if(!$current_id){
281
- $current_id = $q->queried_object_id;
282
- }
283
 
284
- if( !$q->is_404 && $current_id == $my_account_id && $q->is_page ){
285
 
286
- $uri_vars = array_filter( explode( '/', $_SERVER['REQUEST_URI']) );
287
- $endpoints = WC()->query->get_query_vars();
288
- $endpoint_in_url = urldecode( end( $uri_vars ) );
289
 
290
- $endpoints['shipping'] = urldecode( $this->get_translated_edit_address_slug( 'shipping' ) );
291
- $endpoints['billing'] = urldecode( $this->get_translated_edit_address_slug( 'billing' ) );
 
 
 
292
 
293
- $endpoint_not_pagename = isset( $q->query['pagename'] ) && urldecode( $q->query['pagename'] ) != $endpoint_in_url;
294
- $endpoint_url_not_in_endpoints = !in_array( $endpoint_in_url,$endpoints );
295
- $uri_vars_not_in_query_vars = !in_array( urldecode( prev( $uri_vars ) ) ,$q->query_vars );
296
 
297
- if( $endpoint_not_pagename && $endpoint_url_not_in_endpoints && is_numeric( $endpoint_in_url ) && $uri_vars_not_in_query_vars ){
298
- $wp_query->set_404();
299
- status_header(404);
300
- include( get_query_template( '404' ) );
301
- die();
302
- }
303
 
304
- }
305
 
306
- }
307
-
308
- function get_translated_edit_address_slug( $slug, $language = false ){
309
- global $woocommerce_wpml;
310
 
311
- $strings_language = $woocommerce_wpml->strings->get_string_language( $slug, 'woocommerce', 'edit-address-slug: '.$slug );
 
312
 
313
- if( $strings_language == $language ){
314
- return $slug;
315
- }
316
 
317
- $translated_slug = apply_filters( 'wpml_translate_single_string', $slug, 'woocommerce', 'edit-address-slug: '.$slug, $language );
 
 
 
 
 
 
 
318
 
319
- if( $translated_slug == $slug ){
320
 
321
- if( $language ){
322
- $translated_slug = $woocommerce_wpml->strings->get_translation_from_woocommerce_mo_file( 'edit-address-slug'. chr(4) .$slug, $language );
323
- }else{
324
- $translated_slug = _x( $slug, 'edit-address-slug', 'woocommerce' );
325
- }
326
 
327
- }
 
 
 
 
 
 
 
328
 
329
- return $translated_slug;
330
- }
331
 
332
- function filter_get_endpoint_url( $url, $endpoint, $value, $permalink ) {
333
 
334
- // return translated edit account slugs
335
  remove_filter( 'woocommerce_get_endpoint_url', array( $this, 'filter_get_endpoint_url' ), 10, 4 );
336
- if ( isset( WC()->query->query_vars['edit-address'] ) && WC()->query->query_vars['edit-address'] == $endpoint && in_array( $value, array(
337
- 'shipping',
338
- 'billing'
339
- ) )
340
- ) {
341
- $url = wc_get_endpoint_url( 'edit-address', $this->get_translated_edit_address_slug( $value ) );
342
- } elseif ( $endpoint === get_option( 'woocommerce_myaccount_lost_password_endpoint' ) ) {
343
- $translated_lost_password_endpoint = apply_filters( 'wpml_translate_single_string', $endpoint, 'WooCommerce Endpoints', 'lost-password' );
344
 
345
- $wc_account_page_url = wc_get_page_permalink( 'myaccount' );
346
- $url = wc_get_endpoint_url( $translated_lost_password_endpoint, '', $wc_account_page_url );
347
 
348
- }
349
  add_filter( 'woocommerce_get_endpoint_url', array( $this, 'filter_get_endpoint_url' ), 10, 4 );
350
 
351
  return $url;
352
  }
353
 
354
- public function update_original_endpoints_strings(){
355
 
356
- foreach( WC()->query->query_vars as $endpoint_key => $endpoint ){
 
 
357
 
358
- $this->register_endpoint_string( $endpoint_key, $endpoint );
359
-
360
- }
361
-
362
- }
 
363
 
364
- public function translate_endpoints_in_rewrite_rules( $value ) {
 
365
 
366
- if ( ! empty( $value ) ) {
 
367
 
368
- foreach ( WC()->query->query_vars as $endpoint_key => $endpoint_translation ) {
369
- if ( $endpoint_key == $endpoint_translation ) {
370
- continue;
371
- }
 
 
372
 
373
- $buff_value = array();
374
 
375
- foreach ( $value as $k => $v ) {
376
- $k = preg_replace( '/(\/)?' . $endpoint_key . '(\/)?(\(\/\(\.\*\)\)\?\/\?\$)/', '$1' . $endpoint_translation . '$2$3', $k );
377
- $buff_value[ $k ] = $v;
378
- }
379
- $value = $buff_value;
380
  }
381
  }
382
 
383
- return $value;
384
  }
385
 
386
-
387
  }
1
  <?php
2
 
3
+ class WCML_Endpoints {
4
 
5
  /** @var woocommerce_wpml */
6
  private $woocommerce_wpml;
7
+ /**
8
+ * @var SitePress
9
+ */
10
+ private $sitepress;
11
+ /**
12
+ * @var wpdb
13
+ */
14
+ private $wpdb;
15
+
16
+ var $endpoints_strings = array();
17
+
18
+ function __construct( woocommerce_wpml $woocommerce_wpml, SitePress $sitepress, wpdb $wpdb ) {
19
+ $this->woocommerce_wpml = $woocommerce_wpml;
20
+ $this->sitepress = $sitepress;
21
+ $this->wpdb = $wpdb;
22
+ }
23
 
24
+ public function add_hooks() {
 
 
 
 
25
 
26
+ if ( class_exists( 'WPML_Endpoints_Support_Factory' ) ) {
27
+ add_action( 'init', array( $this, 'migrate_ones_string_translations' ), 9 );
28
+ add_action( 'wpml_after_add_endpoints_translations', array( $this, 'add_wc_endpoints_translations' ) );
29
 
30
+ add_filter( 'wpml_endpoint_permalink_filter', array( $this, 'endpoint_permalink_filter' ), 10, 2 );
31
+ add_filter( 'wpml_endpoint_url_value', array( $this, 'filter_endpoint_url_value' ), 10, 2 );
32
+ add_filter( 'wpml_current_ls_language_url_endpoint', array( $this, 'add_endpoint_to_current_ls_language_url' ), 10, 4 );
33
+ }else{
34
+ $legacy_endpoints = new WCML_Endpoints_Legacy( $this->woocommerce_wpml );
35
+ $legacy_endpoints->add_hooks();
36
+ }
37
 
38
+ add_filter( 'wpml_sl_blacklist_requests', array( $this, 'reserved_requests' ) );
39
+ add_filter( 'woocommerce_get_endpoint_url', array( $this, 'filter_get_endpoint_url' ), 10, 4 );
40
+ if ( ! is_admin() ) {
41
+ add_filter( 'pre_get_posts', array( $this, 'check_if_endpoint_exists' ) );
42
+ }
43
+ }
44
 
45
+ public function migrate_ones_string_translations() {
46
+
47
+ if ( ! get_option( 'wcml_endpoints_context_updated' ) ) {
48
+
49
+ $endpoint_keys = array(
50
+ 'order-pay',
51
+ 'order-received',
52
+ 'view-order',
53
+ 'edit-account',
54
+ 'edit-address',
55
+ 'lost-password',
56
+ 'customer-logout',
57
+ 'add-payment-method',
58
+ 'set-default-payment-method',
59
+ 'delete-payment-method',
60
+ 'payment-methods',
61
+ 'downloads',
62
+ 'orders'
63
+ );
64
+
65
+ foreach ( $endpoint_keys as $endpoint_key ) {
66
+
67
+ $existing_string_id = $this->wpdb->get_var(
68
+ $this->wpdb->prepare( "SELECT id FROM {$this->wpdb->prefix}icl_strings
69
+ WHERE context = %s AND name = %s",
70
+ WPML_Endpoints_Support::STRING_CONTEXT, $endpoint_key )
71
+ );
72
+
73
+ if( $existing_string_id ){
74
+
75
+ $existing_wcml_string_id = $this->wpdb->get_var(
76
+ $this->wpdb->prepare( "SELECT id FROM {$this->wpdb->prefix}icl_strings
77
+ WHERE context = %s AND name = %s",
78
+ 'WooCommerce Endpoints', $endpoint_key )
79
+ );
80
+
81
+ if( $existing_wcml_string_id ){
82
+ $wcml_string_translations = icl_get_string_translations_by_id( $existing_wcml_string_id );
83
+
84
+ foreach( $wcml_string_translations as $language_code => $translation_data ){
85
+ icl_add_string_translation( $existing_string_id, $language_code, $translation_data['value'], ICL_STRING_TRANSLATION_COMPLETE );
86
+ }
87
 
88
+ wpml_unregister_string_multi( $existing_wcml_string_id );
89
+ }
90
+ }else{
91
+
92
+ $this->wpdb->query(
93
+ $this->wpdb->prepare( "UPDATE {$this->wpdb->prefix}icl_strings
94
+ SET context = %s
95
+ WHERE context = 'WooCommerce Endpoints' AND name = %s",
96
+ WPML_Endpoints_Support::STRING_CONTEXT, $endpoint_key )
97
+ );
98
+
99
+ // update domain_name_context_md5 value
100
+ $string_id = $this->wpdb->get_var( $this->wpdb->prepare( "SELECT id FROM {$this->wpdb->prefix}icl_strings WHERE context = %s AND name = %s", WPML_Endpoints_Support::STRING_CONTEXT, $endpoint_key ) );
101
+
102
+ if ( $string_id ) {
103
+ $this->wpdb->query(
104
+ $this->wpdb->prepare( "UPDATE {$this->wpdb->prefix}icl_strings
105
+ SET domain_name_context_md5 = %s
106
+ WHERE id = %d",
107
+ md5( $endpoint_key, WPML_Endpoints_Support::STRING_CONTEXT ), $string_id )
108
+ );
109
+ }
110
+ }
111
+ }
112
+ update_option( 'wcml_endpoints_context_updated', true );
113
+ }
114
+ }
115
 
116
+ public function reserved_requests( $requests ) {
117
  $cache_key = 'reserved_requests';
118
  $cache_group = 'wpml-endpoints';
119
 
120
+ $found = null;
121
  $reserved_requests = wp_cache_get( $cache_key, $cache_group, false, $found );
122
+ $is_page_display_as_translated = $this->sitepress->is_display_as_translated_post_type( 'page' );
123
+
124
+ if (
125
+ ! $is_page_display_as_translated &&
126
+ (
127
+ ! $found ||
128
+ ! $reserved_requests
129
+ )
130
+ ) {
131
  $reserved_requests = array();
132
 
133
+ $current_language = $this->sitepress->get_current_language();
134
+ $languages = $this->sitepress->get_active_languages();
135
  $languages_codes = array_keys( $languages );
136
  foreach ( $languages_codes as $language_code ) {
137
+ $this->sitepress->switch_lang( $language_code );
138
+
139
+ $my_account_page_id = wc_get_page_id( 'myaccount' );
140
 
 
141
  if ( $my_account_page_id ) {
142
  $my_account_page = get_post( $my_account_page_id );
143
  if ( $my_account_page ) {
147
  $reserved_requests[] = '/^' . $account_base . '/'; // regex version
148
 
149
  foreach ( $this->woocommerce_wpml->get_wc_query_vars() as $key => $endpoint ) {
150
+
151
+ $translated_endpoint = $this->get_endpoint_translation( $endpoint, $language_code );
152
 
153
  $reserved_requests[] = $account_base . '/' . $translated_endpoint;
154
  }
155
  }
156
  }
157
  }
158
+ $this->sitepress->switch_lang( $current_language );
159
 
160
  if ( $reserved_requests ) {
161
  wp_cache_set( $cache_key, $reserved_requests, $cache_group );
169
  return $requests;
170
  }
171
 
172
+ public function add_wc_endpoints_translations( $language ) {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
173
 
174
+ if ( ! class_exists( 'WooCommerce' ) || ! defined( 'ICL_SITEPRESS_VERSION' ) || ICL_PLUGIN_INACTIVE || version_compare( WOOCOMMERCE_VERSION, '2.2', '<' ) ) {
175
+ return false;
176
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
177
 
178
+ $wc_vars = WC()->query->query_vars;
 
179
 
180
+ if ( ! empty( $wc_vars ) ) {
 
181
 
182
+ foreach ( $wc_vars as $key => $endpoint ){
183
+ $endpoint_translation = $this->get_endpoint_translation( $endpoint, $language );
184
+ $query_vars[ $endpoint_translation ] = $endpoint_translation;
185
+ }
 
 
 
 
 
 
 
186
 
187
+ $query_vars = apply_filters( 'wcml_register_endpoints_query_vars', $query_vars, $wc_vars, $this );
188
+ WC()->query->query_vars = array_merge( $wc_vars, $query_vars );
189
+ }
190
 
191
+ }
 
 
 
 
 
 
 
 
 
 
 
 
192
 
193
+ public function get_endpoint_translation( $endpoint, $language = null ) {
194
+ return apply_filters( 'wpml_get_endpoint_translation', $endpoint, $endpoint, $language );
195
+ }
 
 
196
 
197
+ public function endpoint_permalink_filter( $data, $endpoint_key ) {
198
 
199
+ $link = $data[0];
200
+ $endpoint = $data[1];
 
 
201
 
202
+ $endpoint = apply_filters( 'wcml_endpoint_permalink_filter', $endpoint, $endpoint_key );
203
 
204
+ return array( $link, $endpoint );
205
+ }
 
206
 
207
+ /*
208
+ * We need check special case - when you manually put in URL default not translated endpoint it not generated 404 error
209
+ */
210
+ public function check_if_endpoint_exists( $q ) {
211
+ global $wp_query;
212
 
213
+ $my_account_id = wc_get_page_id( 'myaccount' );
 
 
214
 
215
+ $current_id = $q->query_vars['page_id'];
216
+ if ( ! $current_id ) {
217
+ $current_id = $q->queried_object_id;
218
+ }
 
 
219
 
220
+ if ( ! $q->is_404 && $current_id == $my_account_id && $q->is_page ) {
221
 
222
+ $uri_vars = array_filter( explode( '/', $_SERVER['REQUEST_URI'] ) );
223
+ $endpoints = WC()->query->get_query_vars();
224
+ $endpoint_in_url = urldecode( end( $uri_vars ) );
 
225
 
226
+ $endpoints['shipping'] = urldecode( $this->get_translated_edit_address_slug( 'shipping' ) );
227
+ $endpoints['billing'] = urldecode( $this->get_translated_edit_address_slug( 'billing' ) );
228
 
229
+ $endpoint_not_pagename = isset( $q->query['pagename'] ) && urldecode( $q->query['pagename'] ) != $endpoint_in_url;
230
+ $endpoint_url_not_in_endpoints = ! in_array( $endpoint_in_url, $endpoints );
231
+ $uri_vars_not_in_query_vars = ! in_array( urldecode( prev( $uri_vars ) ), $q->query_vars );
232
 
233
+ if ( $endpoint_not_pagename && $endpoint_url_not_in_endpoints && is_numeric( $endpoint_in_url ) && $uri_vars_not_in_query_vars ) {
234
+ $wp_query->set_404();
235
+ status_header( 404 );
236
+ include( get_query_template( '404' ) );
237
+ die();
238
+ }
239
+ }
240
+ }
241
 
242
+ private function get_translated_edit_address_slug( $slug, $language = false ) {
243
 
244
+ $strings_language = $this->woocommerce_wpml->strings->get_string_language( $slug, 'woocommerce', 'edit-address-slug: ' . $slug );
245
+ if ( $strings_language == $language ) {
246
+ return $slug;
247
+ }
 
248
 
249
+ $translated_slug = apply_filters( 'wpml_translate_single_string', $slug, 'woocommerce', 'edit-address-slug: ' . $slug, $language );
250
+ if ( $translated_slug == $slug ) {
251
+ if ( $language ) {
252
+ $translated_slug = $this->woocommerce_wpml->strings->get_translation_from_woocommerce_mo_file( 'edit-address-slug' . chr( 4 ) . $slug, $language );
253
+ } else {
254
+ $translated_slug = _x( $slug, 'edit-address-slug', 'woocommerce' );
255
+ }
256
+ }
257
 
258
+ return $translated_slug;
259
+ }
260
 
261
+ public function filter_get_endpoint_url( $url, $endpoint, $value, $permalink ) {
262
 
 
263
  remove_filter( 'woocommerce_get_endpoint_url', array( $this, 'filter_get_endpoint_url' ), 10, 4 );
 
 
 
 
 
 
 
 
264
 
265
+ $translated_endpoint = $this->get_endpoint_translation( $endpoint );
266
+ $url = wc_get_endpoint_url( $translated_endpoint, $value, $this->sitepress->convert_url( $permalink ) );
267
 
 
268
  add_filter( 'woocommerce_get_endpoint_url', array( $this, 'filter_get_endpoint_url' ), 10, 4 );
269
 
270
  return $url;
271
  }
272
 
273
+ public function filter_endpoint_url_value( $value, $page_lang ) {
274
 
275
+ if ( $page_lang ) {
276
+ $edit_address_shipping = $this->get_translated_edit_address_slug( 'shipping', $page_lang );
277
+ $edit_address_billing = $this->get_translated_edit_address_slug( 'billing', $page_lang );
278
 
279
+ if ( $edit_address_shipping == urldecode( $value ) ) {
280
+ $value = $this->get_translated_edit_address_slug( 'shipping', $this->sitepress->get_current_language() );
281
+ } elseif ( $edit_address_billing == urldecode( $value ) ) {
282
+ $value = $this->get_translated_edit_address_slug( 'billing', $this->sitepress->get_current_language() );
283
+ }
284
+ }
285
 
286
+ return $value;
287
+ }
288
 
289
+ public function add_endpoint_to_current_ls_language_url( $url, $post_lang, $data, $current_endpoint ){
290
+ global $post;
291
 
292
+ if (
293
+ $current_endpoint &&
294
+ $post &&
295
+ $post_lang !== $data['code'] &&
296
+ 'page' == get_option( 'show_on_front' )
297
+ ) {
298
 
299
+ $myaccount_page_id = wc_get_page_id( 'myaccount' );
300
 
301
+ if (
302
+ $myaccount_page_id === (int) get_option( 'page_on_front' ) &&
303
+ $post->ID === $myaccount_page_id
304
+ ) {
305
+ $url = apply_filters( 'wpml_get_endpoint_url', $current_endpoint['key'], $current_endpoint['value'], $url );
306
  }
307
  }
308
 
309
+ return $url;
310
  }
311
 
 
312
  }
inc/class-wcml-fix-copied-custom-fields-wpml353.php DELETED
@@ -1,40 +0,0 @@
1
- <?php
2
-
3
- class WCML_Fix_Copied_Custom_Fields_WPML353{
4
-
5
- public function __construct(){
6
- //@TODO review after WPML 3.6
7
- if ( is_admin() && version_compare( ICL_SITEPRESS_VERSION, '3.5.3', '>=' ) && version_compare( ICL_SITEPRESS_VERSION, '3.6', '<' ) ) {
8
- add_action( 'added_post_meta', array(
9
- $this,
10
- 'fix_copied_custom_fields'
11
- ), 10, 4 );
12
- }
13
-
14
- }
15
-
16
- public function fix_copied_custom_fields( $mid, $object_id, $meta_key, $_meta_value ) {
17
- global $wpdb;
18
-
19
- if ( in_array( get_post_type( $object_id ), array( 'product', 'product_variation' ) ) ) {
20
-
21
- $meta_keys_to_fix = array(
22
- '_price',
23
- '_regular_price',
24
- '_sale_price',
25
- '_sku'
26
- );
27
-
28
- if ( in_array( $meta_key, $meta_keys_to_fix ) ) {
29
-
30
- if ( is_null( $_meta_value ) ) {
31
- $wpdb->update( $wpdb->postmeta, array( 'meta_value' => '' ), array( 'meta_id' => $mid ) );
32
- }
33
-
34
- }
35
-
36
- }
37
-
38
- }
39
-
40
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
inc/class-wcml-languages-upgrader.php CHANGED
@@ -140,15 +140,8 @@ class WCML_Languages_Upgrader{
140
  $version = WC_VERSION;
141
  }
142
 
143
- if( version_compare( $version, '2.5.0', '<') ){
144
- $repo = 'https://github.com/woothemes/woocommerce-language-packs/raw/v';
145
- return $repo . $version . '/packages/' . $locale . '.zip';
146
-
147
- }else{
148
- $repo = 'https://downloads.wordpress.org/translation/plugin/woocommerce/';
149
- return $repo . $version . '/' . $locale . '.zip';
150
- }
151
-
152
  }
153
 
154
  /*
@@ -287,7 +280,7 @@ class WCML_Languages_Upgrader{
287
 
288
  public function load_js(){
289
 
290
- wp_register_script( 'wcml-lang-notice', WCML_PLUGIN_URL . '/res/js/languages_notice' . WCML_JS_MIN . '.js', array( 'jquery' ), WCML_VERSION );
291
  wp_enqueue_script( 'wcml-lang-notice');
292
 
293
  wp_localize_script( 'wcml-lang-notice', 'wcml_language_upgrade_notices',
@@ -298,4 +291,4 @@ class WCML_Languages_Upgrader{
298
 
299
  }
300
 
301
- }
140
  $version = WC_VERSION;
141
  }
142
 
143
+ $repo = 'https://downloads.wordpress.org/translation/plugin/woocommerce/';
144
+ return $repo . $version . '/' . $locale . '.zip';
 
 
 
 
 
 
 
145
  }
146
 
147
  /*
280
 
281
  public function load_js(){
282
 
283
+ wp_register_script( 'wcml-lang-notice', WCML_PLUGIN_URL . '/res/js/languages_notice' . WCML_JS_MIN . '.js', array( 'jquery' ), WCML_VERSION, true );
284
  wp_enqueue_script( 'wcml-lang-notice');
285
 
286
  wp_localize_script( 'wcml-lang-notice', 'wcml_language_upgrade_notices',
291
 
292
  }
293
 
294
+ }
inc/class-wcml-orders.php CHANGED
@@ -187,7 +187,12 @@ class WCML_Orders {
187
  }
188
  }elseif( $item instanceof WC_Order_Item_Shipping ){
189
  if( $item->get_method_id() ){
190
- $shipping_id = $item->get_method_id() . $item->get_instance_id();
 
 
 
 
 
191
  $item->set_method_title(
192
  $this->woocommerce_wpml->shipping->translate_shipping_method_title(
193
  $item->get_method_title(),
@@ -395,17 +400,17 @@ class WCML_Orders {
395
 
396
  public function filter_downloadable_product_items( $files, $item, $object ){
397
 
398
- $order_language = get_post_meta( WooCommerce_Functions_Wrapper::get_order_id( $object ), 'wpml_language', true );
399
 
400
- if( $item['variation_id'] > 0 ){
401
- $item['variation_id'] = apply_filters( 'translate_object_id', $item['variation_id'], 'product_variation', false, $order_language );
402
  }else{
403
- $item['product_id'] = apply_filters( 'translate_object_id', $item['product_id'], 'product', false, $order_language );
404
  }
405
 
406
  remove_filter( 'woocommerce_get_item_downloads', array( $this, 'filter_downloadable_product_items' ), 10, 3 );
407
 
408
- $files = WooCommerce_Functions_Wrapper::get_item_downloads( $object, $item );
409
 
410
  add_filter( 'woocommerce_get_item_downloads', array( $this, 'filter_downloadable_product_items' ), 10, 3 );
411
 
187
  }
188
  }elseif( $item instanceof WC_Order_Item_Shipping ){
189
  if( $item->get_method_id() ){
190
+
191
+ $shipping_id = $item->get_method_id();
192
+ if( method_exists( $item ,'get_instance_id' ) ){
193
+ $shipping_id .= $item->get_instance_id();
194
+ }
195
+
196
  $item->set_method_title(
197
  $this->woocommerce_wpml->shipping->translate_shipping_method_title(
198
  $item->get_method_title(),
400
 
401
  public function filter_downloadable_product_items( $files, $item, $object ){
402
 
403
+ $order_language = get_post_meta( $object->get_id(), 'wpml_language', true );
404
 
405
+ if( $item->get_variation_id() > 0 ){
406
+ $item->set_variation_id( apply_filters( 'translate_object_id', $item->get_variation_id(), 'product_variation', false, $order_language ) );
407
  }else{
408
+ $item->set_product_id( apply_filters( 'translate_object_id', $item->get_product_id(), 'product', false, $order_language ) );
409
  }
410
 
411
  remove_filter( 'woocommerce_get_item_downloads', array( $this, 'filter_downloadable_product_items' ), 10, 3 );
412
 
413
+ $files = $item->get_item_downloads();
414
 
415
  add_filter( 'woocommerce_get_item_downloads', array( $this, 'filter_downloadable_product_items' ), 10, 3 );
416
 
inc/class-wcml-products.php CHANGED
@@ -2,40 +2,36 @@
2
 
3
  class WCML_Products{
4
 
5
- /**
6
- * @var woocommerce_wpml
7
- */
8
  private $woocommerce_wpml;
9
- /**
10
- * @var SitePress
11
- */
12
  private $sitepress;
13
- /**
14
- * @var wpdb
15
- */
16
- private $wpdb;/**
17
- * @var WPML_WP_Cache
18
- */
19
  private $wpml_cache;
20
 
21
-
22
  /**
23
  * WCML_Products constructor.
24
  *
25
  * @param woocommerce_wpml $woocommerce_wpml
26
  * @param SitePress $sitepress
 
27
  * @param wpdb $wpdb
28
  * @param WPML_WP_Cache $wpml_cache
29
  */
30
- public function __construct( woocommerce_wpml $woocommerce_wpml, SitePress $sitepress, wpdb $wpdb, WPML_WP_Cache $wpml_cache = null ) {
31
- $this->woocommerce_wpml = $woocommerce_wpml;
32
- $this->sitepress = $sitepress;
33
- $this->wpdb = $wpdb;
 
34
 
35
- $cache_group = 'WCML_Products';
36
- $this->wpml_cache = is_null( $wpml_cache ) ? new WPML_WP_Cache( $cache_group ) : $wpml_cache;
37
 
38
- }
39
 
40
  public function add_hooks() {
41
 
@@ -78,49 +74,37 @@ class WCML_Products{
78
  add_filter( 'woocommerce_pre_customer_bought_product', array( $this, 'is_customer_bought_product' ), 10, 4 );
79
  }
80
 
81
- // Check if original product
82
- public function is_original_product( $product_id ){
83
- $cache_key = $product_id;
84
- $cache_group = 'is_original_product';
85
- $temp_is_original = wp_cache_get($cache_key, $cache_group);
86
-
87
- if($temp_is_original) return $temp_is_original;
88
-
89
- $is_original = $this->wpdb->get_var(
90
- $this->wpdb->prepare(
91
- "SELECT source_language_code IS NULL
92
- FROM {$this->wpdb->prefix}icl_translations
93
- WHERE element_id=%d AND element_type=%s",
94
- $product_id, 'post_'.get_post_type( $product_id ) )
95
- );
96
-
97
- wp_cache_set( $cache_key, $is_original, $cache_group );
98
-
99
- return $is_original;
100
- }
101
 
102
- // Get original product language
 
 
 
 
103
  public function get_original_product_language( $product_id ){
104
- $cache_key = $product_id;
105
- $cache_group = 'original_product_language';
106
- $temp_language = wp_cache_get( $cache_key, $cache_group );
107
- if($temp_language) return $temp_language;
108
 
109
- $language = $this->wpdb->get_var( $this->wpdb->prepare( "
110
- SELECT t2.language_code FROM {$this->wpdb->prefix}icl_translations as t1
111
- LEFT JOIN {$this->wpdb->prefix}icl_translations as t2 ON t1.trid = t2.trid
112
- WHERE t1.element_id=%d AND t1.element_type=%s AND t2.source_language_code IS NULL", $product_id, 'post_'.get_post_type($product_id) ) );
113
 
114
- wp_cache_set( $cache_key, $language, $cache_group );
115
- return $language;
116
  }
117
 
 
 
 
 
 
118
  public function get_original_product_id( $product_id ){
119
 
120
- $original_product_language = $this->get_original_product_language( $product_id );
121
- $original_product_id = apply_filters( 'translate_object_id', $product_id, get_post_type( $product_id ), true, $original_product_language );
122
 
123
- return $original_product_id;
124
  }
125
 
126
  public function is_variable_product( $product_id ){
@@ -375,8 +359,8 @@ class WCML_Products{
375
  foreach( $found_products as $post => $formatted_product_name ) {
376
  $parent = wp_get_post_parent_id( $post );
377
  if( ( isset( $_COOKIE [ '_wcml_dashboard_order_language' ] )
378
- && ( ( !$parent && $this->sitepress->get_language_for_element( $post, 'post_product') == $_COOKIE [ '_wcml_dashboard_order_language' ] )
379
- || ( $parent && $this->sitepress->get_language_for_element( $parent, 'post_product') == $_COOKIE [ '_wcml_dashboard_order_language' ] ) )
380
  )
381
  ||
382
  ( ! isset( $_COOKIE [ '_wcml_dashboard_order_language' ] )
@@ -423,12 +407,11 @@ class WCML_Products{
423
 
424
  if ( $current_language == $this->sitepress->get_default_language() ) {
425
  $menu_order = $this->wpdb->get_var( $this->wpdb->prepare("SELECT menu_order FROM {$this->wpdb->posts} WHERE ID = %d", $product_id ) );
426
- $trid = $this->sitepress->get_element_trid($product_id, 'post_product');
427
- $translations = $this->sitepress->get_element_translations($trid, 'post_product');
428
 
429
  foreach( $translations as $translation ){
430
- if( $translation->element_id != $product_id ){
431
- $this->wpdb->update( $this->wpdb->posts, array( 'menu_order' => $menu_order ), array( 'ID' => $translation->element_id ) );
432
  }
433
  }
434
  }
@@ -454,25 +437,6 @@ class WCML_Products{
454
  return $elements;
455
  }
456
 
457
- // Check if user can translate product
458
- public function user_can_translate_product( $trid, $language_code ){
459
- global $iclTranslationManagement;
460
-
461
- $current_translator = $iclTranslationManagement->get_current_translator();
462
- $job_id = $this->wpdb->get_var( $this->wpdb->prepare("
463
- SELECT tj.job_id FROM {$this->wpdb->prefix}icl_translate_job tj
464
- JOIN {$this->wpdb->prefix}icl_translation_status ts ON tj.rid = ts.rid
465
- JOIN {$this->wpdb->prefix}icl_translations t ON ts.translation_id = t.translation_id
466
- WHERE t.trid = %d AND t.language_code='%s'
467
- ORDER BY tj.job_id DESC LIMIT 1
468
- ", $trid, $language_code ) );
469
-
470
- if( $job_id && wpml_check_user_is_translator( $this->sitepress->get_source_language_by_trid( $trid ), $language_code ) ){
471
- return true;
472
- }
473
- return false;
474
- }
475
-
476
  public function filter_related_products_args( $args ){
477
  if( $this->woocommerce_wpml->settings[ 'enable_multi_currency' ] == WCML_MULTI_CURRENCIES_INDEPENDENT &&
478
  isset( $this->woocommerce_wpml->settings[ 'display_custom_prices' ] ) &&
@@ -603,7 +567,7 @@ class WCML_Products{
603
 
604
  if ( $sku_found ) {
605
 
606
- $product_trid = $this->sitepress->get_element_trid( $product_id, 'post_' . get_post_type( $product_id ) );
607
 
608
  $products = $this->wpdb->get_results(
609
  $this->wpdb->prepare(
@@ -622,7 +586,7 @@ class WCML_Products{
622
  $sku_found = false;
623
 
624
  foreach ( (array) $products as $product ) {
625
- $trid = $this->sitepress->get_element_trid( $product->ID, 'post_' . get_post_type( $product_id ) );
626
  if ( $product_trid !== $trid ) {
627
  $sku_found = true;
628
  break;
2
 
3
  class WCML_Products{
4
 
5
+ /** @var woocommerce_wpml */
 
 
6
  private $woocommerce_wpml;
7
+ /** @var SitePress */
 
 
8
  private $sitepress;
9
+ /** @var WPML_Post_Translation */
10
+ private $post_translations;
11
+ /** @var wpdb */
12
+ private $wpdb;
13
+ /** @var WPML_WP_Cache */
 
14
  private $wpml_cache;
15
 
 
16
  /**
17
  * WCML_Products constructor.
18
  *
19
  * @param woocommerce_wpml $woocommerce_wpml
20
  * @param SitePress $sitepress
21
+ * @param WPML_Post_Translation $post_translations
22
  * @param wpdb $wpdb
23
  * @param WPML_WP_Cache $wpml_cache
24
  */
25
+ public function __construct( woocommerce_wpml $woocommerce_wpml, SitePress $sitepress, WPML_Post_Translation $post_translations, wpdb $wpdb, WPML_WP_Cache $wpml_cache = null ) {
26
+ $this->woocommerce_wpml = $woocommerce_wpml;
27
+ $this->sitepress = $sitepress;
28
+ $this->post_translations = $post_translations;
29
+ $this->wpdb = $wpdb;
30
 
31
+ $cache_group = 'WCML_Products';
32
+ $this->wpml_cache = is_null( $wpml_cache ) ? new WPML_WP_Cache( $cache_group ) : $wpml_cache;
33
 
34
+ }
35
 
36
  public function add_hooks() {
37
 
74
  add_filter( 'woocommerce_pre_customer_bought_product', array( $this, 'is_customer_bought_product' ), 10, 4 );
75
  }
76
 
77
+ /**
78
+ * @param int|string $product_id
79
+ *
80
+ * @return bool
81
+ */
82
+ public function is_original_product( $product_id ) {
83
+ return null === $this->post_translations->get_source_lang_code( $product_id );
84
+ }
 
 
 
 
 
 
 
 
 
 
 
 
85
 
86
+ /**
87
+ * @param int|string $product_id
88
+ *
89
+ * @return null|string
90
+ */
91
  public function get_original_product_language( $product_id ){
 
 
 
 
92
 
93
+ $original_product_id = $this->get_original_product_id( $product_id );
 
 
 
94
 
95
+ return $this->post_translations->get_element_lang_code( $original_product_id );
 
96
  }
97
 
98
+ /**
99
+ * @param int|string $product_id
100
+ *
101
+ * @return int|string
102
+ */
103
  public function get_original_product_id( $product_id ){
104
 
105
+ $original_product_id = $this->post_translations->get_original_element( $product_id );
 
106
 
107
+ return $original_product_id ? $original_product_id : $product_id;
108
  }
109
 
110
  public function is_variable_product( $product_id ){
359
  foreach( $found_products as $post => $formatted_product_name ) {
360
  $parent = wp_get_post_parent_id( $post );
361
  if( ( isset( $_COOKIE [ '_wcml_dashboard_order_language' ] )
362
+ && ( ( !$parent && $this->post_translations->get_element_lang_code( $post ) == $_COOKIE [ '_wcml_dashboard_order_language' ] )
363
+ || ( $parent && $this->post_translations->get_element_lang_code( $parent ) == $_COOKIE [ '_wcml_dashboard_order_language' ] ) )
364
  )
365
  ||
366
  ( ! isset( $_COOKIE [ '_wcml_dashboard_order_language' ] )
407
 
408
  if ( $current_language == $this->sitepress->get_default_language() ) {
409
  $menu_order = $this->wpdb->get_var( $this->wpdb->prepare("SELECT menu_order FROM {$this->wpdb->posts} WHERE ID = %d", $product_id ) );
410
+ $translations = $this->post_translations->get_element_translations( $product_id );
 
411
 
412
  foreach( $translations as $translation ){
413
+ if( $translation !== $product_id ){
414
+ $this->wpdb->update( $this->wpdb->posts, array( 'menu_order' => $menu_order ), array( 'ID' => $translation ) );
415
  }
416
  }
417
  }
437
  return $elements;
438
  }
439
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
440
  public function filter_related_products_args( $args ){
441
  if( $this->woocommerce_wpml->settings[ 'enable_multi_currency' ] == WCML_MULTI_CURRENCIES_INDEPENDENT &&
442
  isset( $this->woocommerce_wpml->settings[ 'display_custom_prices' ] ) &&
567
 
568
  if ( $sku_found ) {
569
 
570
+ $product_trid = $this->post_translations->get_element_trid( $product_id );
571
 
572
  $products = $this->wpdb->get_results(
573
  $this->wpdb->prepare(
586
  $sku_found = false;
587
 
588
  foreach ( (array) $products as $product ) {
589
+ $trid = $this->post_translations->get_element_trid( $product->ID );
590
  if ( $product_trid !== $trid ) {
591
  $sku_found = true;
592
  break;
inc/class-wcml-resources.php CHANGED
@@ -65,7 +65,7 @@ class WCML_Resources {
65
  }
66
 
67
  public static function load_taxonomy_translation_scripts(){
68
- wp_register_script( 'wcml-taxonomy-translation-scripts', WCML_PLUGIN_URL . '/res/js/taxonomy_translation' . WCML_JS_MIN . '.js', array( 'jquery' ), WCML_VERSION );
69
  wp_enqueue_script( 'wcml-taxonomy-translation-scripts' );
70
  }
71
 
@@ -73,18 +73,14 @@ class WCML_Resources {
73
 
74
  if ( self::$is_wpml_wcml_page ) {
75
 
76
- wp_register_script( 'wcml-scripts', WCML_PLUGIN_URL . '/res/js/scripts' . WCML_JS_MIN . '.js', array(
77
- 'jquery',
78
- 'jquery-ui-core',
79
- 'jquery-ui-resizable'
80
- ), WCML_VERSION );
81
 
82
  self::load_taxonomy_translation_scripts();
83
 
84
- wp_register_script( 'jquery-cookie', WCML_PLUGIN_URL . '/res/js/jquery.cookie' . WCML_JS_MIN . '.js', array('jquery'), WCML_VERSION );
85
- wp_register_script( 'wcml-dialogs', WCML_PLUGIN_URL . '/res/js/dialogs' . WCML_JS_MIN . '.js', array('jquery', 'jquery-ui-core', 'jquery-ui-dialog'), WCML_VERSION );
86
- wp_register_script( 'wcml-troubleshooting', WCML_PLUGIN_URL . '/res/js/troubleshooting' . WCML_JS_MIN . '.js', array('jquery'), WCML_VERSION );
87
- wp_register_script( 'wcml-translation-interface-dialog-warning', WCML_PLUGIN_URL . '/res/js/trnsl_interface_dialog_warning' . WCML_JS_MIN . '.js', array('jquery'), WCML_VERSION );
88
 
89
  wp_enqueue_script( 'wcml-scripts' );
90
  wp_enqueue_script( 'wp-color-picker');
@@ -103,12 +99,12 @@ class WCML_Resources {
103
  }
104
 
105
  if ( self::$page == WPML_TM_FOLDER . '/menu/main.php' ) {
106
- wp_register_script( 'wpml_tm', WCML_PLUGIN_URL . '/res/js/wpml_tm' . WCML_JS_MIN . '.js', array('jquery'), WCML_VERSION );
107
  wp_enqueue_script( 'wpml_tm' );
108
  }
109
 
110
  if ( self::$pagenow == 'widgets.php' ) {
111
- wp_register_script( 'wcml_widgets', WCML_PLUGIN_URL . '/res/js/widgets' . WCML_JS_MIN . '.js', array('jquery'), WCML_VERSION );
112
  wp_enqueue_script( 'wcml_widgets' );
113
  }
114
 
@@ -138,14 +134,12 @@ class WCML_Resources {
138
 
139
  if ( !is_admin() && self::$pagenow != 'wp-login.php' ) {
140
 
141
- wp_register_script( 'wcml-front-scripts', WCML_PLUGIN_URL . '/res/js/front-scripts' . WCML_JS_MIN . '.js', array(
142
- 'jquery'
143
- ), WCML_VERSION );
144
  wp_enqueue_script( 'wcml-front-scripts' );
145
 
146
  $referer = isset( $_SERVER[ 'HTTP_REFERER' ] ) ? $_SERVER[ 'HTTP_REFERER' ] : '';
147
 
148
- wp_register_script( 'cart-widget', WCML_PLUGIN_URL . '/res/js/cart_widget' . WCML_JS_MIN . '.js', array('jquery'), WCML_VERSION );
149
  wp_enqueue_script( 'cart-widget' );
150
  wp_localize_script( 'cart-widget', 'actions', array(
151
  'is_lang_switched' => self::$sitepress->get_language_from_url( $referer ) != self::$sitepress->get_current_language() ? 1 : 0,
@@ -161,14 +155,14 @@ class WCML_Resources {
161
  true
162
  );
163
 
164
- wp_register_script( 'wcml-messages', WCML_PLUGIN_URL . '/res/js/wcml-messages' . WCML_JS_MIN . '.js', array('jquery'), WCML_VERSION );
165
  wp_enqueue_script( 'wcml-messages' );
166
  }
167
 
168
  $is_attr_page = apply_filters( 'wcml_is_attributes_page', self::$page == 'product_attributes' && isset( $_GET[ 'post_type' ] ) && $_GET[ 'post_type' ] == 'product' );
169
 
170
  if( $is_attr_page ){
171
- wp_register_script( 'wcml-attributes', WCML_PLUGIN_URL . '/res/js/wcml-attributes' . WCML_JS_MIN . '.js', array( 'jquery' ), WCML_VERSION );
172
  wp_enqueue_script( 'wcml-attributes' );
173
  }
174
 
@@ -176,7 +170,7 @@ class WCML_Resources {
176
 
177
  self::load_tooltip_resources();
178
  wp_enqueue_media();
179
- wp_register_script( 'wcml-editor', WCML_PLUGIN_URL . '/res/js/wcml-translation-editor' . WCML_JS_MIN . '.js', array('jquery', 'jquery-ui-core'), WCML_VERSION);
180
  wp_enqueue_script( 'wcml-editor' );
181
  wp_localize_script( 'wcml-editor', 'wcml_settings',
182
  array(
@@ -192,7 +186,7 @@ class WCML_Resources {
192
 
193
  if ( isset( $_GET['post_type'] ) && 'product' === $_GET['post_type'] && 'edit.php' === self::$pagenow ) {
194
  self::load_tooltip_resources();
195
- wp_enqueue_script( 'products-screen-options', WCML_PLUGIN_URL . '/res/js/products-screen-option.js', array( 'jquery', 'wcml-tooltip-init' ), WCML_VERSION );
196
  wp_localize_script( 'products-screen-options', 'products_screen_option', array( 'nonce' => wp_create_nonce( 'products-screen-option-action' ) ) );
197
  }
198
  }
@@ -201,7 +195,7 @@ class WCML_Resources {
201
 
202
  if ( class_exists( 'WooCommerce' ) && function_exists( 'WC' ) ) {
203
  wp_register_script( 'jquery-tiptip', WC()->plugin_url() . '/assets/js/jquery-tiptip/jquery.tipTip.min.js', array('jquery'), WC_VERSION, true );
204
- wp_register_script( 'wcml-tooltip-init', WCML_PLUGIN_URL . '/res/js/tooltip_init' . WCML_JS_MIN . '.js', array('jquery'), WCML_VERSION );
205
  wp_enqueue_script( 'jquery-tiptip' );
206
  wp_enqueue_script( 'wcml-tooltip-init' );
207
  wp_enqueue_style( 'woocommerce_admin_styles', WC()->plugin_url() . '/assets/css/admin.css', array(), WC_VERSION );
@@ -212,7 +206,7 @@ class WCML_Resources {
212
  public static function load_lock_fields_js() {
213
  global $pagenow;
214
 
215
- wp_register_script( 'wcml-lock-script', WCML_PLUGIN_URL . '/res/js/lock_fields' . WCML_JS_MIN . '.js', array('jquery'), WCML_VERSION );
216
  wp_enqueue_script( 'wcml-lock-script' );
217
 
218
  $file_path_sync = self::$woocommerce_wpml->settings['file_path_sync'];
@@ -276,4 +270,4 @@ class WCML_Resources {
276
  '<a data-action="product-translation-dialog" class="js-wcml-dialog-trigger" data-id="' . $original_id . '" data-job_id="" data-language="' . $language . '">' .
277
  __( 'WooCommerce Multilingual products translator', 'woocommerce-multilingual' ) . '</a>' ) . '</h3>';
278
  }
279
- }
65
  }
66
 
67
  public static function load_taxonomy_translation_scripts(){
68
+ wp_register_script( 'wcml-taxonomy-translation-scripts', WCML_PLUGIN_URL . '/res/js/taxonomy_translation' . WCML_JS_MIN . '.js', array( 'jquery' ), WCML_VERSION, true );
69
  wp_enqueue_script( 'wcml-taxonomy-translation-scripts' );
70
  }
71
 
73
 
74
  if ( self::$is_wpml_wcml_page ) {
75
 
76
+ wp_register_script( 'wcml-scripts', WCML_PLUGIN_URL . '/res/js/scripts' . WCML_JS_MIN . '.js', array( 'jquery', 'jquery-ui-core', 'jquery-ui-resizable' ), WCML_VERSION, true );
 
 
 
 
77
 
78
  self::load_taxonomy_translation_scripts();
79
 
80
+ wp_register_script( 'jquery-cookie', WCML_PLUGIN_URL . '/res/js/jquery.cookie' . WCML_JS_MIN . '.js', array( 'jquery' ), WCML_VERSION, true );
81
+ wp_register_script( 'wcml-dialogs', WCML_PLUGIN_URL . '/res/js/dialogs' . WCML_JS_MIN . '.js', array( 'jquery', 'jquery-ui-core', 'jquery-ui-dialog' ), WCML_VERSION, true );
82
+ wp_register_script( 'wcml-troubleshooting', WCML_PLUGIN_URL . '/res/js/troubleshooting' . WCML_JS_MIN . '.js', array( 'jquery' ), WCML_VERSION, true );
83
+ wp_register_script( 'wcml-translation-interface-dialog-warning', WCML_PLUGIN_URL . '/res/js/trnsl_interface_dialog_warning' . WCML_JS_MIN . '.js', array( 'jquery' ), WCML_VERSION, true );
84
 
85
  wp_enqueue_script( 'wcml-scripts' );
86
  wp_enqueue_script( 'wp-color-picker');
99
  }
100
 
101
  if ( self::$page == WPML_TM_FOLDER . '/menu/main.php' ) {
102
+ wp_register_script( 'wpml_tm', WCML_PLUGIN_URL . '/res/js/wpml_tm' . WCML_JS_MIN . '.js', array( 'jquery' ), WCML_VERSION, true );
103
  wp_enqueue_script( 'wpml_tm' );
104
  }
105
 
106
  if ( self::$pagenow == 'widgets.php' ) {
107
+ wp_register_script( 'wcml_widgets', WCML_PLUGIN_URL . '/res/js/widgets' . WCML_JS_MIN . '.js', array( 'jquery' ), WCML_VERSION, true );
108
  wp_enqueue_script( 'wcml_widgets' );
109
  }
110
 
134
 
135
  if ( !is_admin() && self::$pagenow != 'wp-login.php' ) {
136
 
137
+ wp_register_script( 'wcml-front-scripts', WCML_PLUGIN_URL . '/res/js/front-scripts' . WCML_JS_MIN . '.js', array( 'jquery' ), WCML_VERSION, true );
 
 
138
  wp_enqueue_script( 'wcml-front-scripts' );
139
 
140
  $referer = isset( $_SERVER[ 'HTTP_REFERER' ] ) ? $_SERVER[ 'HTTP_REFERER' ] : '';
141
 
142
+ wp_register_script( 'cart-widget', WCML_PLUGIN_URL . '/res/js/cart_widget' . WCML_JS_MIN . '.js', array( 'jquery' ), WCML_VERSION, true );
143
  wp_enqueue_script( 'cart-widget' );
144
  wp_localize_script( 'cart-widget', 'actions', array(
145
  'is_lang_switched' => self::$sitepress->get_language_from_url( $referer ) != self::$sitepress->get_current_language() ? 1 : 0,
155
  true
156
  );
157
 
158
+ wp_register_script( 'wcml-messages', WCML_PLUGIN_URL . '/res/js/wcml-messages' . WCML_JS_MIN . '.js', array( 'jquery' ), WCML_VERSION, true );
159
  wp_enqueue_script( 'wcml-messages' );
160
  }
161
 
162
  $is_attr_page = apply_filters( 'wcml_is_attributes_page', self::$page == 'product_attributes' && isset( $_GET[ 'post_type' ] ) && $_GET[ 'post_type' ] == 'product' );
163
 
164
  if( $is_attr_page ){
165
+ wp_register_script( 'wcml-attributes', WCML_PLUGIN_URL . '/res/js/wcml-attributes' . WCML_JS_MIN . '.js', array( 'jquery' ), WCML_VERSION, true );
166
  wp_enqueue_script( 'wcml-attributes' );
167
  }
168
 
170
 
171
  self::load_tooltip_resources();
172
  wp_enqueue_media();
173
+ wp_register_script( 'wcml-editor', WCML_PLUGIN_URL . '/res/js/wcml-translation-editor' . WCML_JS_MIN . '.js', array( 'jquery', 'jquery-ui-core' ), WCML_VERSION, true );
174
  wp_enqueue_script( 'wcml-editor' );
175
  wp_localize_script( 'wcml-editor', 'wcml_settings',
176
  array(
186
 
187
  if ( isset( $_GET['post_type'] ) && 'product' === $_GET['post_type'] && 'edit.php' === self::$pagenow ) {
188
  self::load_tooltip_resources();
189
+ wp_enqueue_script( 'products-screen-options', WCML_PLUGIN_URL . '/res/js/products-screen-option.js', array( 'jquery', 'wcml-tooltip-init' ), WCML_VERSION, true );
190
  wp_localize_script( 'products-screen-options', 'products_screen_option', array( 'nonce' => wp_create_nonce( 'products-screen-option-action' ) ) );
191
  }
192
  }
195
 
196
  if ( class_exists( 'WooCommerce' ) && function_exists( 'WC' ) ) {
197
  wp_register_script( 'jquery-tiptip', WC()->plugin_url() . '/assets/js/jquery-tiptip/jquery.tipTip.min.js', array('jquery'), WC_VERSION, true );
198
+ wp_register_script( 'wcml-tooltip-init', WCML_PLUGIN_URL . '/res/js/tooltip_init' . WCML_JS_MIN . '.js', array( 'jquery' ), WCML_VERSION, true );
199
  wp_enqueue_script( 'jquery-tiptip' );
200
  wp_enqueue_script( 'wcml-tooltip-init' );
201
  wp_enqueue_style( 'woocommerce_admin_styles', WC()->plugin_url() . '/assets/css/admin.css', array(), WC_VERSION );
206
  public static function load_lock_fields_js() {
207
  global $pagenow;
208
 
209
+ wp_register_script( 'wcml-lock-script', WCML_PLUGIN_URL . '/res/js/lock_fields' . WCML_JS_MIN . '.js', array( 'jquery' ), WCML_VERSION, true );
210
  wp_enqueue_script( 'wcml-lock-script' );
211
 
212
  $file_path_sync = self::$woocommerce_wpml->settings['file_path_sync'];
270
  '<a data-action="product-translation-dialog" class="js-wcml-dialog-trigger" data-id="' . $original_id . '" data-job_id="" data-language="' . $language . '">' .
271
  __( 'WooCommerce Multilingual products translator', 'woocommerce-multilingual' ) . '</a>' ) . '</h3>';
272
  }
273
+ }
inc/class-wcml-store-pages.php CHANGED
@@ -42,7 +42,6 @@ class WCML_Store_Pages{
42
  if(!is_admin()){
43
  add_filter('pre_get_posts', array($this, 'shop_page_query'), 9);
44
  add_filter('icl_ls_languages', array($this, 'translate_ls_shop_url'));
45
- add_filter('parse_request', array($this, 'adjust_shop_page'));
46
  }
47
 
48
  add_filter( 'woocommerce_create_page_id', array( $this, 'check_store_page_id'), 10 ,3 );
@@ -283,24 +282,6 @@ class WCML_Store_Pages{
283
  return $languages;
284
  }
285
 
286
- function adjust_shop_page($q) {
287
-
288
- $is_wc_prior_3_3 = $this->sitepress->get_wp_api()->version_compare( $this->sitepress->get_wp_api()->constant( 'WC_VERSION' ), '3.3', '<' );
289
-
290
- if ( $is_wc_prior_3_3 && $this->sitepress->get_default_language() != $this->sitepress->get_current_language() ) {
291
- if (!empty($q->query_vars['pagename'])) {
292
- $shop_page = get_post( wc_get_page_id('shop') );
293
- // we should explode by / for children page
294
- $query_var_page = explode('/',$q->query_vars['pagename']);
295
- if (isset($shop_page->post_name) && ( ( $shop_page->post_name == $query_var_page[count($query_var_page)-1]) || ( $shop_page->post_name == strtolower($query_var_page[count($query_var_page)-1]) ) ) ) {
296
- unset($q->query_vars['page']);
297
- unset($q->query_vars['pagename']);
298
- $q->query_vars['post_type'] = 'product';
299
- }
300
- }
301
- }
302
- }
303
-
304
  function create_missing_store_pages_with_redirect(){
305
  $this->create_missing_store_pages();
306
 
@@ -343,7 +324,7 @@ class WCML_Store_Pages{
343
  $this->switch_lang( $mis_lang );
344
 
345
  foreach ($check_pages as $page) {
346
- $orig_id = get_option($page);
347
  $trid = $this->sitepress->get_element_trid($orig_id,'post_page');
348
  $translations = $this->sitepress->get_element_translations($trid,'post_page',true);
349
 
@@ -351,16 +332,16 @@ class WCML_Store_Pages{
351
  $orig_page = get_post($orig_id);
352
 
353
  switch( $page ){
354
- case 'woocommerce_shop_page_id':
355
  $page_title = $mis_lang !== 'en' ? __( 'Shop', 'woocommerce-multilingual') : 'Shop';
356
  break;
357
- case 'woocommerce_cart_page_id':
358
  $page_title = $mis_lang !== 'en' ? __( 'Cart', 'woocommerce-multilingual') : 'Cart';
359
  break;
360
- case 'woocommerce_checkout_page_id':
361
  $page_title = $mis_lang !== 'en' ? __( 'Checkout', 'woocommerce-multilingual') : 'Checkout';
362
  break;
363
- case 'woocommerce_myaccount_page_id':
364
  $page_title = $mis_lang !== 'en' ? __( 'My Account', 'woocommerce-multilingual') : 'My Account';
365
  break;
366
  default:
@@ -381,7 +362,7 @@ class WCML_Store_Pages{
381
  $new_page_id = wp_insert_post($args);
382
 
383
  if( isset($translations[$mis_lang]->element_id) && get_post_status($translations[$mis_lang]->element_id) == 'trash' && $mis_lang == $default_language){
384
- update_option($page, $new_page_id);
385
  }
386
 
387
  if( isset($translations[$mis_lang]->element_id) && !is_null($translations[$mis_lang]->element_id)){
@@ -399,13 +380,9 @@ class WCML_Store_Pages{
399
 
400
  private function switch_lang( $lang_code = false ){
401
 
402
- $st_prior_2_6 = version_compare( $this->sitepress->get_wp_api()->constant( 'WPML_ST_VERSION' ), '2.6.0', '<' );
403
 
404
- if( !$st_prior_2_6 ){
405
- $is_mo_loading_disabled = WPML_Theme_Localization_Type::USE_ST_AND_NO_MO_FILES === $this->sitepress->get_setting('theme_localization_type' );
406
- }
407
-
408
- if( $st_prior_2_6 || !$is_mo_loading_disabled ){
409
  $this->woocommerce_wpml->locale->switch_locale( $lang_code );
410
  }else{
411
  $this->sitepress->switch_lang( $lang_code );
@@ -424,7 +401,7 @@ class WCML_Store_Pages{
424
  $pages_in_progress = array();
425
 
426
  foreach ($check_pages as $page) {
427
- $page_id = get_option($page);
428
  $page_obj = get_post($page_id);
429
  if(!$page_id || !$page_obj || $page_obj->post_status != 'publish' ){
430
  return 'non_exist';
@@ -436,7 +413,7 @@ class WCML_Store_Pages{
436
  $missing_lang_codes = array();
437
 
438
  foreach ($check_pages as $page) {
439
- $store_page_id = get_option($page);
440
  $trid = $this->sitepress->get_element_trid($store_page_id,'post_page');
441
  $translations = $this->sitepress->get_element_translations($trid,'post_page',true);
442
  $pages_in_progress_miss_lang = '';
@@ -488,16 +465,22 @@ class WCML_Store_Pages{
488
  * Filters WooCommerce checkout link.
489
  */
490
  function get_checkout_page_url(){
491
- return get_permalink(apply_filters( 'translate_object_id',get_option('woocommerce_checkout_page_id'), 'page', true));
492
  }
493
 
494
  function get_wc_pages(){
495
- return apply_filters('wcml_wc_installed_pages', array(
496
  'woocommerce_shop_page_id',
497
  'woocommerce_cart_page_id',
498
  'woocommerce_checkout_page_id',
499
  'woocommerce_myaccount_page_id'
500
  ));
 
 
 
 
 
 
501
  }
502
 
503
  function after_set_default_language( $code, $previous_code ){
@@ -507,11 +490,10 @@ class WCML_Store_Pages{
507
  $pages = $this->get_wc_pages();
508
 
509
  foreach( $pages as $page ){
510
-
511
- if( $page_id = get_option($page) ){
512
  $trnsl_id = apply_filters( 'translate_object_id', $page_id, 'page', false, $code );
513
  if( !is_null( $trnsl_id ) ){
514
- $wpdb->update( $wpdb->options, array( 'option_value' => $trnsl_id ), array( 'option_name' => $page ) );
515
  }
516
  }
517
 
@@ -597,7 +579,7 @@ class WCML_Store_Pages{
597
  $pages = $this->get_wc_pages();
598
  $current_page_id = get_the_ID();
599
  foreach( $pages as $page ){
600
- $page_id = get_option( $page );
601
  if( $page_id && $page_id === $current_page_id ){
602
  $is_shop_page = true;
603
  break;
42
  if(!is_admin()){
43
  add_filter('pre_get_posts', array($this, 'shop_page_query'), 9);
44
  add_filter('icl_ls_languages', array($this, 'translate_ls_shop_url'));
 
45
  }
46
 
47
  add_filter( 'woocommerce_create_page_id', array( $this, 'check_store_page_id'), 10 ,3 );
282
  return $languages;
283
  }
284
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
285
  function create_missing_store_pages_with_redirect(){
286
  $this->create_missing_store_pages();
287
 
324
  $this->switch_lang( $mis_lang );
325
 
326
  foreach ($check_pages as $page) {
327
+ $orig_id = wc_get_page_id( $page );
328
  $trid = $this->sitepress->get_element_trid($orig_id,'post_page');
329
  $translations = $this->sitepress->get_element_translations($trid,'post_page',true);
330
 
332
  $orig_page = get_post($orig_id);
333
 
334
  switch( $page ){
335
+ case 'shop':
336
  $page_title = $mis_lang !== 'en' ? __( 'Shop', 'woocommerce-multilingual') : 'Shop';
337
  break;
338
+ case 'cart':
339
  $page_title = $mis_lang !== 'en' ? __( 'Cart', 'woocommerce-multilingual') : 'Cart';
340
  break;
341
+ case 'checkout':
342
  $page_title = $mis_lang !== 'en' ? __( 'Checkout', 'woocommerce-multilingual') : 'Checkout';
343
  break;
344
+ case 'myaccount':
345
  $page_title = $mis_lang !== 'en' ? __( 'My Account', 'woocommerce-multilingual') : 'My Account';
346
  break;
347
  default:
362
  $new_page_id = wp_insert_post($args);
363
 
364
  if( isset($translations[$mis_lang]->element_id) && get_post_status($translations[$mis_lang]->element_id) == 'trash' && $mis_lang == $default_language){
365
+ update_option( 'woocommerce_'.$page.'_page_id', $new_page_id);
366
  }
367
 
368
  if( isset($translations[$mis_lang]->element_id) && !is_null($translations[$mis_lang]->element_id)){
380
 
381
  private function switch_lang( $lang_code = false ){
382
 
383
+ $is_mo_loading_disabled = WPML_Theme_Localization_Type::USE_ST_AND_NO_MO_FILES === $this->sitepress->get_setting('theme_localization_type' );
384
 
385
+ if( !$is_mo_loading_disabled ){
 
 
 
 
386
  $this->woocommerce_wpml->locale->switch_locale( $lang_code );
387
  }else{
388
  $this->sitepress->switch_lang( $lang_code );
401
  $pages_in_progress = array();
402
 
403
  foreach ($check_pages as $page) {
404
+ $page_id = wc_get_page_id( $page );
405
  $page_obj = get_post($page_id);
406
  if(!$page_id || !$page_obj || $page_obj->post_status != 'publish' ){
407
  return 'non_exist';
413
  $missing_lang_codes = array();
414
 
415
  foreach ($check_pages as $page) {
416
+ $store_page_id = wc_get_page_id( $page );
417
  $trid = $this->sitepress->get_element_trid($store_page_id,'post_page');
418
  $translations = $this->sitepress->get_element_translations($trid,'post_page',true);
419
  $pages_in_progress_miss_lang = '';
465
  * Filters WooCommerce checkout link.
466
  */
467
  function get_checkout_page_url(){
468
+ return get_permalink(apply_filters( 'translate_object_id', wc_get_page_id( 'checkout' ), 'page', true));
469
  }
470
 
471
  function get_wc_pages(){
472
+ $pages = apply_filters('wcml_wc_installed_pages', array(
473
  'woocommerce_shop_page_id',
474
  'woocommerce_cart_page_id',
475
  'woocommerce_checkout_page_id',
476
  'woocommerce_myaccount_page_id'
477
  ));
478
+
479
+ foreach ( $pages as &$page ) {
480
+ $page = preg_replace( '/(woocommerce_)(.*)(_page_id)/', "$2", $page );
481
+ }
482
+
483
+ return $pages;
484
  }
485
 
486
  function after_set_default_language( $code, $previous_code ){
490
  $pages = $this->get_wc_pages();
491
 
492
  foreach( $pages as $page ){
493
+ if( $page_id = wc_get_page_id( $page ) ){
 
494
  $trnsl_id = apply_filters( 'translate_object_id', $page_id, 'page', false, $code );
495
  if( !is_null( $trnsl_id ) ){
496
+ $wpdb->update( $wpdb->options, array( 'option_value' => $trnsl_id ), array( 'option_name' => 'woocommerce_'.$page.'_page_id' ) );
497
  }
498
  }
499
 
579
  $pages = $this->get_wc_pages();
580
  $current_page_id = get_the_ID();
581
  foreach( $pages as $page ){
582
+ $page_id = wc_get_page_id( $page );
583
  if( $page_id && $page_id === $current_page_id ){
584
  $is_shop_page = true;
585
  break;
inc/class-wcml-terms.php CHANGED
@@ -31,9 +31,6 @@ class WCML_Terms{
31
  add_action( 'updated_woocommerce_term_meta', array( $this, 'sync_term_order' ), 100, 4 );
32
 
33
  add_filter( 'wp_get_object_terms', array( $this->sitepress, 'get_terms_filter' ) );
34
-
35
- add_action( 'icl_save_term_translation', array( $this, 'save_wc_term_meta' ), 100, 4 );
36
-
37
  add_action( 'created_term', array( $this, 'translated_terms_status_update' ), 10, 3 );
38
  add_action( 'edit_term', array( $this, 'translated_terms_status_update' ), 10, 3 );
39
  add_action( 'wp_ajax_wcml_update_term_translated_warnings', array(
@@ -57,6 +54,8 @@ class WCML_Terms{
57
 
58
  add_filter( 'pre_option_default_product_cat', array( $this, 'pre_option_default_product_cat' ) );
59
  add_filter( 'update_option_default_product_cat', array( $this, 'update_option_default_product_cat' ), 1, 2 );
 
 
60
  }
61
 
62
  add_action( 'delete_term', array( $this, 'wcml_delete_term' ), 10, 4 );
@@ -80,32 +79,6 @@ class WCML_Terms{
80
  }
81
 
82
  }
83
-
84
- function save_wc_term_meta($original_tax, $result){
85
-
86
-
87
- // WooCommerce before termmeta table migration
88
- $wc_before_term_meta = get_option( 'db_version' ) < 34370;
89
-
90
- // backwards compatibility - before the termmeta table was added
91
- if( $wc_before_term_meta ){
92
-
93
- $term_wc_meta = $this->wpdb->get_results($this->wpdb->prepare("SELECT * FROM {$this->wpdb->woocommerce_termmeta} WHERE woocommerce_term_id=%s", $original_tax->term_id));
94
- foreach ( $term_wc_meta as $wc_meta ){
95
- $wc_original_metakey = $wc_meta->meta_key;
96
- $wc_original_metavalue = $wc_meta->meta_value;
97
- update_woocommerce_term_meta($result['term_id'], $wc_original_metakey, $wc_original_metavalue);
98
- }
99
- // End of backwards compatibility - before the termmeta table was added
100
- }else{
101
-
102
- $term_wc_meta = get_term_meta( $original_tax->term_id, false, true );
103
- foreach ( $term_wc_meta as $key => $values ) {
104
- update_term_meta( $result['term_id'], $key, maybe_unserialize( array_pop( $values ) ) );
105
- }
106
-
107
- }
108
- }
109
 
110
  function show_term_translation_screen_notices(){
111
 
@@ -1021,4 +994,22 @@ class WCML_Terms{
1021
  }
1022
  }
1023
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1024
  }
31
  add_action( 'updated_woocommerce_term_meta', array( $this, 'sync_term_order' ), 100, 4 );
32
 
33
  add_filter( 'wp_get_object_terms', array( $this->sitepress, 'get_terms_filter' ) );
 
 
 
34
  add_action( 'created_term', array( $this, 'translated_terms_status_update' ), 10, 3 );
35
  add_action( 'edit_term', array( $this, 'translated_terms_status_update' ), 10, 3 );
36
  add_action( 'wp_ajax_wcml_update_term_translated_warnings', array(
54
 
55
  add_filter( 'pre_option_default_product_cat', array( $this, 'pre_option_default_product_cat' ) );
56
  add_filter( 'update_option_default_product_cat', array( $this, 'update_option_default_product_cat' ), 1, 2 );
57
+ }else{
58
+ add_action( 'update_term_meta', array( $this, 'update_category_count_meta' ), 10, 4 );
59
  }
60
 
61
  add_action( 'delete_term', array( $this, 'wcml_delete_term' ), 10, 4 );
79
  }
80
 
81
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
82
 
83
  function show_term_translation_screen_notices(){
84
 
994
  }
995
  }
996
 
997
+ public function update_category_count_meta( $meta_id, $object_id, $meta_key, $meta_value ) {
998
+
999
+ if ( 'product_count_product_cat' === $meta_key ) {
1000
+ remove_action( 'update_term_meta', array( $this, 'update_category_count_meta' ), 10, 4 );
1001
+
1002
+ $trid = $this->sitepress->get_element_trid( $object_id, 'tax_product_cat' );
1003
+ $translations = $this->sitepress->get_element_translations( $trid, 'tax_product_cat' );
1004
+
1005
+ foreach ( $translations as $translation ) {
1006
+ if ( $translation->element_id !== $object_id ) {
1007
+ update_term_meta( $translation->element_id, $meta_key, $meta_value, '' );
1008
+ }
1009
+ }
1010
+
1011
+ add_action( 'update_term_meta', array( $this, 'update_category_count_meta' ), 10, 4 );
1012
+ }
1013
+ }
1014
+
1015
  }
inc/class-wcml-tp-support.php CHANGED
@@ -2,316 +2,328 @@
2
 
3
  class WCML_TP_Support {
4
 
5
- /** @var woocommerce_wpml */
6
- private $woocommerce_wpml;
7
- /** @var wpdb */
8
- private $wpdb;
9
- /** @var WPML_Element_Translation_Package */
10
- private $tp;
11
 
12
- /**
13
- * WCML_Attributes constructor.
14
- *
15
- * @param woocommerce_wpml $woocommerce_wpml
16
- * @param wpdb $wpdb
17
- * @param WPML_Element_Translation_Package $tp
18
- */
19
- public function __construct( woocommerce_wpml $woocommerce_wpml, wpdb $wpdb, WPML_Element_Translation_Package $tp ){
20
 
21
- $this->woocommerce_wpml = $woocommerce_wpml;
22
- $this->wpdb = $wpdb;
23
- $this->tp = $tp;
24
- }
25
 
26
- public function add_hooks(){
27
- add_filter( 'wpml_tm_translation_job_data', array( $this, 'append_custom_attributes_to_translation_package' ), 10, 2 );
28
- add_action( 'wpml_translation_job_saved', array( $this, 'save_custom_attribute_translations' ), 10, 2 );
 
 
 
29
 
30
- add_filter( 'wpml_tm_translation_job_data', array( $this, 'append_variation_descriptions_translation_package' ), 10, 2 );
31
- add_action( 'wpml_pro_translation_completed', array( $this, 'save_variation_descriptions_translations' ), 20, 3 ); //after WCML_Products
 
 
 
 
 
 
32
 
33
- add_filter( 'wpml_tm_translation_job_data', array( $this, 'append_slug_to_translation_package' ), 10, 2 );
34
- add_action( 'wpml_translation_job_saved', array( $this, 'save_slug_translations' ), 10, 2 );
35
 
36
- add_filter( 'wpml_tm_translation_job_data', array( $this, 'append_images_to_translation_package' ), 10, 2 );
37
- add_action( 'wpml_translation_job_saved', array( $this, 'save_images_translations' ), 10, 3 );
38
- }
39
-
40
- public function append_custom_attributes_to_translation_package( $package, $post ) {
41
 
42
- if ( $post->post_type === 'product' ) {
43
 
44
- $product = wc_get_product( $post->ID );
45
- $product_type = WooCommerce_Functions_Wrapper::get_product_type( $post->ID );
46
 
47
- if ( ! empty( $product ) && $product_type === 'variable' ) {
 
48
 
49
- $attributes = $product->get_attributes();
50
 
51
- foreach ( $attributes as $attribute_key => $attribute ) {
52
 
53
- if( $this->woocommerce_wpml->attributes->is_a_taxonomy( $attribute ) ){
54
- continue;
55
- }
56
 
57
- $package[ 'contents' ][ 'wc_attribute_name:' . $attribute_key ] = array(
58
- 'translate' => 1,
59
- 'data' => $this->tp->encode_field_data( $attribute[ 'name' ], 'base64' ),
60
- 'format' => 'base64'
61
- );
62
- $values = explode( '|', $attribute[ 'value' ] );
63
- $values = array_map( 'trim', $values );
64
 
65
- foreach ( $values as $value_key => $value ) {
66
- $package[ 'contents' ][ 'wc_attribute_value:' . $value_key . ':' . $attribute_key ] = array(
67
- 'translate' => 1,
68
- 'data' => $this->tp->encode_field_data( $value, 'base64' ),
69
- 'format' => 'base64'
70
- );
71
- }
72
- }
73
- }
74
- }
75
 
76
- return $package;
77
- }
 
 
 
 
 
 
 
 
78
 
79
- public function save_custom_attribute_translations( $post_id, $data ) {
 
80
 
81
- $translated_attributes = array();
82
 
83
- foreach ( $data as $data_key => $value ) {
 
84
 
85
- if ( $value['finished'] && isset( $value['field_type'] ) && strpos( $value['field_type'], 'wc_attribute_' ) === 0 ) {
86
 
87
- if ( strpos( $value['field_type'], 'wc_attribute_name:' ) === 0 ) {
88
 
89
- $exp = explode( ':', $value['field_type'], 2 );
90
- $attribute_key = $exp[1];
91
 
92
- $translated_attributes[ $attribute_key ]['name'] = $value['data'];
 
93
 
94
- } else if ( strpos( $value['field_type'], 'wc_attribute_value:' ) === 0 ) {
95
 
96
- $exp = explode( ':', $value['field_type'], 3 );
97
- $value_key = $exp[1];
98
- $attribute_key = $exp[2];
99
 
100
- $translated_attributes[ $attribute_key ]['values'][ $value_key ] = $value['data'];
 
 
101
 
102
- }
103
 
104
- }
105
 
106
- }
107
 
108
- if ( $translated_attributes ) {
109
 
110
- $product_attributes = get_post_meta( $post_id, '_product_attributes', true );
111
 
112
- $original_post_language = $this->woocommerce_wpml->products->get_original_product_language( $post_id );
113
- $original_post_id = apply_filters( 'translate_object_id', $post_id, 'product', false, $original_post_language );
114
 
115
- $original_attributes = get_post_meta( $original_post_id, '_product_attributes', true );
 
116
 
117
- foreach ( $translated_attributes as $attribute_key => $attribute ) {
118
 
119
- $product_attributes[ $attribute_key ] = array(
120
- 'name' => $attribute['name'],
121
- 'value' => join( ' | ', $attribute['values'] ),
122
- 'is_taxonomy' => 0,
123
- 'is_visible' => $original_attributes[ $attribute_key ]['is_visible'],
124
- 'position' => $original_attributes[ $attribute_key ]['position']
125
- );
126
 
 
 
 
 
 
 
 
127
 
128
- }
129
 
130
- update_post_meta( $post_id, '_product_attributes', $product_attributes );
131
 
132
- }
133
 
134
- }
135
 
136
- public function append_variation_descriptions_translation_package( $package, $post ) {
137
 
138
- if ( $post->post_type == 'product' ) {
139
 
140
- /** @var WC_Product_Variable $product */
141
- $product = wc_get_product( $post->ID );
142
 
143
- $product_type = WooCommerce_Functions_Wrapper::get_product_type( $post->ID );
144
 
145
- if ( ! empty( $product ) && $product_type === 'variable' ) {
 
146
 
147
- $variations = $product->get_available_variations();
148
 
149
- foreach ( $variations as $variation ) {
150
 
151
- if ( ! empty( $variation['variation_description'] ) ) {
152
 
153
- $package['contents'][ 'wc_variation_description:' . $variation['variation_id'] ] = array(
154
- 'translate' => 1,
155
- 'data' => $this->tp->encode_field_data( $variation['variation_description'], 'base64' ),
156
- 'format' => 'base64'
157
- );
158
 
159
- }
160
 
161
- }
 
 
 
 
162
 
163
- }
164
 
165
- }
166
 
167
- return $package;
168
 
169
- }
170
 
171
- public function save_variation_descriptions_translations( $post_id, $data, $job ) {
172
 
173
- $language = $job->language_code;
174
 
175
- foreach ( $data as $data_key => $value ) {
176
 
177
- if ( $value['finished'] && isset( $value['field_type'] ) && strpos( $value['field_type'], 'wc_variation_description:' ) === 0 ) {
178
 
179
- $variation_id = substr( $value['field_type'], strpos( $value['field_type'], ':' ) + 1 );
180
 
181
- if ( is_post_type_translated( 'product_variation' ) ) {
182
 
183
- $translated_variation_id = apply_filters( 'translate_object_id', $variation_id, 'product_variation', false, $language );
184
 
185
- } else {
186
- global $sitepress;
187
- $trid = $sitepress->get_element_trid( $variation_id, 'post_product_variation' );
188
- $translations = $sitepress->get_element_translations( $trid, 'post_product_variation', true, true, true );
189
 
190
- $translated_variation_id = isset( $translations[ $language ] ) ? $translations[ $language ]->element_id : false;
191
 
192
- }
 
 
 
193
 
194
- if ( $translated_variation_id ) {
195
- update_post_meta( $translated_variation_id, '_variation_description', $value['data'] );
196
- }
197
 
 
 
 
198
 
199
- }
200
 
201
- }
202
 
203
- }
204
 
205
- public function append_slug_to_translation_package( $package, $post ) {
206
- if ( $post->post_type == 'product' ) {
207
 
208
- $this->add_to_package( $package, 'slug', urldecode( $post->post_name ) );
209
- }
210
 
211
- return $package;
212
- }
213
 
214
- public function save_slug_translations( $post_id, $data ) {
 
215
 
216
- foreach ( $data as $data_key => $value ) {
217
- if ( $value['finished'] && isset( $value['field_type'] ) && 'slug' === $value['field_type'] ) {
218
- $product = get_post( $post_id );
219
- if ( $product->post_type == 'product' ) {
220
- $new_slug = wp_unique_post_slug( sanitize_title( $value['data'] ), $post_id, $product->post_status, $product->post_type, $product->post_parent );
221
- $this->wpdb->update( $this->wpdb->posts, array( 'post_name' => $new_slug ), array( 'ID' => $post_id ) );
222
- break;
223
- }
224
- }
225
- }
226
- }
227
 
228
- public function append_images_to_translation_package( $package, $post ) {
 
 
 
 
 
 
 
 
 
 
229
 
230
- if ( $post->post_type == 'product' ) {
231
 
232
- $product_images = $this->woocommerce_wpml->media->product_images_ids( $post->ID );
233
- foreach ( $product_images as $image_id ) {
234
- $attachment_data = $this->wpdb->get_row( $this->wpdb->prepare( "SELECT post_title,post_excerpt,post_content FROM {$this->wpdb->posts} WHERE ID = %d", $image_id ) );
235
- if ( ! $attachment_data ) {
236
- continue;
237
- }
238
- $alt_text = get_post_meta( $image_id, '_wp_attachment_image_alt', true );
239
- $alt_text = $alt_text ? $alt_text : '';
240
- $this->add_to_package( $package, 'image-id-' . $image_id . '-title', $attachment_data->post_title );
241
- $this->add_to_package( $package, 'image-id-' . $image_id . '-caption', $attachment_data->post_excerpt );
242
- $this->add_to_package( $package, 'image-id-' . $image_id . '-description', $attachment_data->post_content );
243
- $this->add_to_package( $package, 'image-id-' . $image_id . '-alt-text', $alt_text );
244
 
245
- }
246
- }
247
- return $package;
248
- }
 
 
 
 
 
 
 
 
249
 
250
- public function save_images_translations( $post_id, $data, $job ) {
 
251
 
252
- $language = $job->language_code;
 
253
 
254
- $product_images = $this->woocommerce_wpml->media->product_images_ids( $job->original_doc_id );
255
- foreach ( $product_images as $image_id ) {
256
- $translated_prod_image = apply_filters( 'translate_object_id', $image_id, 'attachment', false, $language );
257
- $image_data = $this->get_image_data( $image_id, $data );
258
- if ( ! empty( $image_data ) ) {
259
 
260
- $translation = array();
261
- if( isset( $image_data['title'] ) ){
262
- $translation['post_title'] = $image_data['title'];
263
- }
264
- if( isset( $image_data['description'] ) ){
265
- $translation['post_content'] = $image_data['description'];
266
- }
267
- if( isset( $image_data['caption'] ) ){
268
- $translation['post_excerpt'] = $image_data['caption'];
269
- }
270
-
271
- if( $translation ){
272
- $this->wpdb->update( $this->wpdb->posts, $translation, array( 'id' => $translated_prod_image ) );
273
- }
274
-
275
- if ( isset( $image_data['alt-text'] ) ) {
276
- update_post_meta( $translated_prod_image, '_wp_attachment_image_alt', $image_data['alt-text'] );
277
- }
278
- }
279
- }
280
- }
281
-
282
- private function get_image_data( $image_id, $data ) {
283
- $image_data = array();
284
-
285
- foreach ( $data as $data_key => $value ) {
286
- if ( $value['finished'] && isset( $value['field_type'] ) ) {
287
- if ( strpos( $value['field_type'], 'image-id-' . $image_id ) === 0 ) {
288
- if ( $value['field_type'] === 'image-id-' . $image_id . '-title' ) {
289
- $image_data['title'] = $value['data'];
290
- }
291
- if ( $value['field_type'] === 'image-id-' . $image_id . '-caption' ) {
292
- $image_data['caption'] = $value['data'];
293
- }
294
- if ( $value['field_type'] === 'image-id-' . $image_id . '-description' ) {
295
- $image_data['description'] = $value['data'];
296
- }
297
- if ( $value['field_type'] === 'image-id-' . $image_id . '-alt-text' ) {
298
- $image_data['alt-text'] = $value['data'];
299
- }
300
- }
301
- }
302
- }
303
-
304
- return $image_data;
305
- }
306
-
307
- private function add_to_package( &$package, $key, $data ) {
308
- $package['contents'][ $key ] = array(
309
- 'translate' => 1,
310
- 'data' => $this->tp->encode_field_data( $data, 'base64' ),
311
- 'format' => 'base64'
312
- );
313
-
314
- }
 
 
 
 
 
 
 
 
315
  }
316
 
317
 
2
 
3
  class WCML_TP_Support {
4
 
5
+ /** @var woocommerce_wpml */
6
+ private $woocommerce_wpml;
7
+ /** @var wpdb */
8
+ private $wpdb;
9
+ /** @var WPML_Element_Translation_Package */
10
+ private $tp;
11
 
12
+ /**
13
+ * WCML_Attributes constructor.
14
+ *
15
+ * @param woocommerce_wpml $woocommerce_wpml
16
+ * @param wpdb $wpdb
17
+ * @param WPML_Element_Translation_Package $tp
18
+ */
19
+ public function __construct( woocommerce_wpml $woocommerce_wpml, wpdb $wpdb, WPML_Element_Translation_Package $tp ) {
20
 
21
+ $this->woocommerce_wpml = $woocommerce_wpml;
22
+ $this->wpdb = $wpdb;
23
+ $this->tp = $tp;
24
+ }
25
 
26
+ public function add_hooks() {
27
+ add_filter( 'wpml_tm_translation_job_data', array(
28
+ $this,
29
+ 'append_custom_attributes_to_translation_package'
30
+ ), 10, 2 );
31
+ add_action( 'wpml_translation_job_saved', array( $this, 'save_custom_attribute_translations' ), 10, 3 );
32
 
33
+ add_filter( 'wpml_tm_translation_job_data', array(
34
+ $this,
35
+ 'append_variation_descriptions_translation_package'
36
+ ), 10, 2 );
37
+ add_action( 'wpml_pro_translation_completed', array(
38
+ $this,
39
+ 'save_variation_descriptions_translations'
40
+ ), 20, 3 ); //after WCML_Products
41
 
42
+ add_filter( 'wpml_tm_translation_job_data', array( $this, 'append_slug_to_translation_package' ), 10, 2 );
43
+ add_action( 'wpml_translation_job_saved', array( $this, 'save_slug_translations' ), 10, 2 );
44
 
45
+ add_filter( 'wpml_tm_translation_job_data', array( $this, 'append_images_to_translation_package' ), 10, 2 );
46
+ add_action( 'wpml_translation_job_saved', array( $this, 'save_images_translations' ), 10, 3 );
47
+ }
 
 
48
 
49
+ public function append_custom_attributes_to_translation_package( $package, $post ) {
50
 
51
+ if ( $post->post_type === 'product' ) {
 
52
 
53
+ $product = wc_get_product( $post->ID );
54
+ $product_type = $product->get_type();
55
 
56
+ if ( ! empty( $product ) ) {
57
 
58
+ $attributes = $product->get_attributes();
59
 
60
+ foreach ( $attributes as $attribute_key => $attribute ) {
 
 
61
 
62
+ if ( $this->woocommerce_wpml->attributes->is_a_taxonomy( $attribute ) ) {
63
+ continue;
64
+ }
 
 
 
 
65
 
66
+ $package['contents'][ 'wc_attribute_name:' . $attribute_key ] = array(
67
+ 'translate' => 1,
68
+ 'data' => $this->tp->encode_field_data( $attribute['name'], 'base64' ),
69
+ 'format' => 'base64'
70
+ );
71
+ $values = explode( '|', $attribute['value'] );
72
+ $values = array_map( 'trim', $values );
 
 
 
73
 
74
+ foreach ( $values as $value_key => $value ) {
75
+ $package['contents'][ 'wc_attribute_value:' . $value_key . ':' . $attribute_key ] = array(
76
+ 'translate' => 1,
77
+ 'data' => $this->tp->encode_field_data( $value, 'base64' ),
78
+ 'format' => 'base64'
79
+ );
80
+ }
81
+ }
82
+ }
83
+ }
84
 
85
+ return $package;
86
+ }
87
 
88
+ public function save_custom_attribute_translations( $post_id, $data, $job ) {
89
 
90
+ $translated_attributes = array();
91
+ $translated_labels = $this->woocommerce_wpml->attributes->get_attr_label_translations( $post_id );
92
 
93
+ foreach ( $data as $data_key => $value ) {
94
 
95
+ if ( $value['finished'] && isset( $value['field_type'] ) && strpos( $value['field_type'], 'wc_attribute_' ) === 0 ) {
96
 
97
+ if ( strpos( $value['field_type'], 'wc_attribute_name:' ) === 0 ) {
 
98
 
99
+ $exp = explode( ':', $value['field_type'], 2 );
100
+ $attribute_key = $exp[1];
101
 
102
+ $translated_attributes[ $attribute_key ]['name'] = $value['data'];
103
 
104
+ } else if ( strpos( $value['field_type'], 'wc_attribute_value:' ) === 0 ) {
 
 
105
 
106
+ $exp = explode( ':', $value['field_type'], 3 );
107
+ $value_key = $exp[1];
108
+ $attribute_key = $exp[2];
109
 
110
+ $translated_attributes[ $attribute_key ]['values'][ $value_key ] = $value['data'];
111
 
112
+ }
113
 
114
+ }
115
 
116
+ }
117
 
118
+ if ( $translated_attributes ) {
119
 
120
+ $product_attributes = get_post_meta( $post_id, '_product_attributes', true );
 
121
 
122
+ $original_post_language = $this->woocommerce_wpml->products->get_original_product_language( $post_id );
123
+ $original_post_id = apply_filters( 'translate_object_id', $post_id, 'product', false, $original_post_language );
124
 
125
+ $original_attributes = get_post_meta( $original_post_id, '_product_attributes', true );
126
 
127
+ foreach ( $translated_attributes as $attribute_key => $attribute ) {
 
 
 
 
 
 
128
 
129
+ $product_attributes[ $attribute_key ] = array(
130
+ 'name' => $attribute['name'],
131
+ 'value' => join( ' | ', $attribute['values'] ),
132
+ 'is_taxonomy' => 0,
133
+ 'is_visible' => $original_attributes[ $attribute_key ]['is_visible'],
134
+ 'position' => $original_attributes[ $attribute_key ]['position']
135
+ );
136
 
137
+ $translated_labels[ $job->language_code ][ $attribute_key ] = $attribute['name'];
138
 
139
+ }
140
 
141
+ update_post_meta( $post_id, '_product_attributes', $product_attributes );
142
 
143
+ update_post_meta( $post_id, 'attr_label_translations', $translated_labels );
144
 
145
+ }
146
 
147
+ }
148
 
149
+ public function append_variation_descriptions_translation_package( $package, $post ) {
 
150
 
151
+ if ( $post->post_type == 'product' ) {
152
 
153
+ /** @var WC_Product_Variable $product */
154
+ $product = wc_get_product( $post->ID );
155
 
156
+ $allowed_variations_types = apply_filters( 'wcml_xliff_allowed_variations_types', array( 'variable' ) );
157
 
158
+ if ( ! empty( $product ) && in_array( $product->get_type(), $allowed_variations_types, true ) ) {
159
 
160
+ $variations = $product->get_available_variations();
161
 
162
+ foreach ( $variations as $variation ) {
 
 
 
 
163
 
164
+ if ( ! empty( $variation['variation_description'] ) ) {
165
 
166
+ $package['contents'][ 'wc_variation_description:' . $variation['variation_id'] ] = array(
167
+ 'translate' => 1,
168
+ 'data' => $this->tp->encode_field_data( get_post_meta( $variation['variation_id'], '_variation_description', true ), 'base64' ),
169
+ 'format' => 'base64'
170
+ );
171
 
172
+ }
173
 
174
+ }
175
 
176
+ }
177
 
178
+ }
179
 
180
+ return $package;
181
 
182
+ }
183
 
184
+ public function save_variation_descriptions_translations( $post_id, $data, $job ) {
185
 
186
+ $language = $job->language_code;
187
 
188
+ foreach ( $data as $data_key => $value ) {
189
 
190
+ if ( $value['finished'] && isset( $value['field_type'] ) && strpos( $value['field_type'], 'wc_variation_description:' ) === 0 ) {
191
 
192
+ $variation_id = substr( $value['field_type'], strpos( $value['field_type'], ':' ) + 1 );
193
 
194
+ if ( is_post_type_translated( 'product_variation' ) ) {
 
 
 
195
 
196
+ $translated_variation_id = apply_filters( 'translate_object_id', $variation_id, 'product_variation', false, $language );
197
 
198
+ } else {
199
+ global $wpml_post_translations;
200
+ $translations = $wpml_post_translations->get_element_translations( $variation_id );
201
+ $translated_variation_id = isset( $translations[ $language ] ) ? $translations[ $language ] : false;
202
 
203
+ }
 
 
204
 
205
+ if ( $translated_variation_id ) {
206
+ update_post_meta( $translated_variation_id, '_variation_description', $value['data'] );
207
+ }
208
 
 
209
 
210
+ }
211
 
212
+ }
213
 
214
+ }
 
215
 
216
+ public function append_slug_to_translation_package( $package, $post ) {
217
+ if ( $post->post_type == 'product' ) {
218
 
219
+ $this->add_to_package( $package, 'slug', urldecode( $post->post_name ) );
220
+ }
221
 
222
+ return $package;
223
+ }
224
 
225
+ public function save_slug_translations( $post_id, $data ) {
 
 
 
 
 
 
 
 
 
 
226
 
227
+ foreach ( $data as $data_key => $value ) {
228
+ if ( $value['finished'] && isset( $value['field_type'] ) && 'slug' === $value['field_type'] ) {
229
+ $product = get_post( $post_id );
230
+ if ( $product->post_type == 'product' ) {
231
+ $new_slug = wp_unique_post_slug( sanitize_title( $value['data'] ), $post_id, $product->post_status, $product->post_type, $product->post_parent );
232
+ $this->wpdb->update( $this->wpdb->posts, array( 'post_name' => $new_slug ), array( 'ID' => $post_id ) );
233
+ break;
234
+ }
235
+ }
236
+ }
237
+ }
238
 
239
+ public function append_images_to_translation_package( $package, $post ) {
240
 
241
+ if ( $post->post_type == 'product' ) {
 
 
 
 
 
 
 
 
 
 
 
242
 
243
+ $product_images = $this->woocommerce_wpml->media->product_images_ids( $post->ID );
244
+ foreach ( $product_images as $image_id ) {
245
+ $attachment_data = $this->wpdb->get_row( $this->wpdb->prepare( "SELECT post_title,post_excerpt,post_content FROM {$this->wpdb->posts} WHERE ID = %d", $image_id ) );
246
+ if ( ! $attachment_data ) {
247
+ continue;
248
+ }
249
+ $alt_text = get_post_meta( $image_id, '_wp_attachment_image_alt', true );
250
+ $alt_text = $alt_text ? $alt_text : '';
251
+ $this->add_to_package( $package, 'image-id-' . $image_id . '-title', $attachment_data->post_title );
252
+ $this->add_to_package( $package, 'image-id-' . $image_id . '-caption', $attachment_data->post_excerpt );
253
+ $this->add_to_package( $package, 'image-id-' . $image_id . '-description', $attachment_data->post_content );
254
+ $this->add_to_package( $package, 'image-id-' . $image_id . '-alt-text', $alt_text );
255
 
256
+ }
257
+ }
258
 
259
+ return $package;
260
+ }
261
 
262
+ public function save_images_translations( $post_id, $data, $job ) {
 
 
 
 
263
 
264
+ $language = $job->language_code;
265
+
266
+ $product_images = $this->woocommerce_wpml->media->product_images_ids( $job->original_doc_id );
267
+ foreach ( $product_images as $image_id ) {
268
+ $translated_prod_image = apply_filters( 'translate_object_id', $image_id, 'attachment', false, $language );
269
+ $image_data = $this->get_image_data( $image_id, $data );
270
+ if ( ! empty( $image_data ) ) {
271
+
272
+ $translation = array();
273
+ if ( isset( $image_data['title'] ) ) {
274
+ $translation['post_title'] = $image_data['title'];
275
+ }
276
+ if ( isset( $image_data['description'] ) ) {
277
+ $translation['post_content'] = $image_data['description'];
278
+ }
279
+ if ( isset( $image_data['caption'] ) ) {
280
+ $translation['post_excerpt'] = $image_data['caption'];
281
+ }
282
+
283
+ if ( $translation ) {
284
+ $this->wpdb->update( $this->wpdb->posts, $translation, array( 'id' => $translated_prod_image ) );
285
+ }
286
+
287
+ if ( isset( $image_data['alt-text'] ) ) {
288
+ update_post_meta( $translated_prod_image, '_wp_attachment_image_alt', $image_data['alt-text'] );
289
+ }
290
+ }
291
+ }
292
+ }
293
+
294
+ private function get_image_data( $image_id, $data ) {
295
+ $image_data = array();
296
+
297
+ foreach ( $data as $data_key => $value ) {
298
+ if ( $value['finished'] && isset( $value['field_type'] ) ) {
299
+ if ( strpos( $value['field_type'], 'image-id-' . $image_id ) === 0 ) {
300
+ if ( $value['field_type'] === 'image-id-' . $image_id . '-title' ) {
301
+ $image_data['title'] = $value['data'];
302
+ }
303
+ if ( $value['field_type'] === 'image-id-' . $image_id . '-caption' ) {
304
+ $image_data['caption'] = $value['data'];
305
+ }
306
+ if ( $value['field_type'] === 'image-id-' . $image_id . '-description' ) {
307
+ $image_data['description'] = $value['data'];
308
+ }
309
+ if ( $value['field_type'] === 'image-id-' . $image_id . '-alt-text' ) {
310
+ $image_data['alt-text'] = $value['data'];
311
+ }
312
+ }
313
+ }
314
+ }
315
+
316
+ return $image_data;
317
+ }
318
+
319
+ private function add_to_package( &$package, $key, $data ) {
320
+ $package['contents'][ $key ] = array(
321
+ 'translate' => 1,
322
+ 'data' => $this->tp->encode_field_data( $data, 'base64' ),
323
+ 'format' => 'base64'
324
+ );
325
+
326
+ }
327
  }
328
 
329
 
inc/class-wcml-troubleshooting.php CHANGED
@@ -209,40 +209,42 @@ class WCML_Troubleshooting{
209
 
210
  $attr = isset($_POST['attr'])?$_POST['attr']:false;
211
 
212
- $terms = get_terms($attr,'hide_empty=0');
213
- $i = 0;
214
- $languages = $this->sitepress->get_active_languages();
215
- foreach($terms as $term){
216
- foreach($languages as $language){
217
- $tr_id = apply_filters( 'translate_object_id',$term->term_id, $attr, false, $language['code']);
218
-
219
- if(is_null($tr_id)){
220
- $term_args = array();
221
- // hierarchy - parents
222
- if ( is_taxonomy_hierarchical( $attr ) ) {
223
- // fix hierarchy
224
- if ( $term->parent ) {
225
- $original_parent_translated = apply_filters( 'translate_object_id', $term->parent, $attr, false, $language['code'] );
226
- if ( $original_parent_translated ) {
227
- $term_args[ 'parent' ] = $original_parent_translated;
228
- }
229
- }
230
- }
231
-
232
- $term_name = $term->name;
233
- $slug = $term->name.'-'.$language['code'];
234
- $slug = WPML_Terms_Translations::term_unique_slug( $slug, $attr, $language['code'] );
235
- $term_args[ 'slug' ] = $slug;
236
-
237
- $new_term = wp_insert_term( $term_name , $attr, $term_args );
238
- if ( $new_term && !is_wp_error( $new_term ) ) {
239
- $tt_id = $this->sitepress->get_element_trid( $term->term_taxonomy_id, 'tax_' . $attr );
240
- $this->sitepress->set_element_language_details( $new_term[ 'term_taxonomy_id' ], 'tax_' . $attr, $tt_id, $language['code'] );
241
- }
242
- }
243
- }
244
-
245
- }
 
 
246
 
247
  wp_send_json_success();
248
  }
209
 
210
  $attr = isset($_POST['attr'])?$_POST['attr']:false;
211
 
212
+ if ( $attr ) {
213
+ $terms = get_terms( $attr, 'hide_empty=0' );
214
+ $i = 0;
215
+ $languages = $this->sitepress->get_active_languages();
216
+ foreach ( $terms as $term ) {
217
+ foreach ( $languages as $language ) {
218
+ $tr_id = apply_filters( 'translate_object_id', $term->term_id, $attr, false, $language['code'] );
219
+
220
+ if ( is_null( $tr_id ) ) {
221
+ $term_args = array();
222
+ // hierarchy - parents
223
+ if ( is_taxonomy_hierarchical( $attr ) ) {
224
+ // fix hierarchy
225
+ if ( $term->parent ) {
226
+ $original_parent_translated = apply_filters( 'translate_object_id', $term->parent, $attr, false, $language['code'] );
227
+ if ( $original_parent_translated ) {
228
+ $term_args['parent'] = $original_parent_translated;
229
+ }
230
+ }
231
+ }
232
+
233
+ $term_name = $term->name;
234
+ $slug = $term->name . '-' . $language['code'];
235
+ $slug = WPML_Terms_Translations::term_unique_slug( $slug, $attr, $language['code'] );
236
+ $term_args['slug'] = $slug;
237
+
238
+ $new_term = wp_insert_term( $term_name, $attr, $term_args );
239
+ if ( $new_term && ! is_wp_error( $new_term ) ) {
240
+ $tt_id = $this->sitepress->get_element_trid( $term->term_taxonomy_id, 'tax_' . $attr );
241
+ $this->sitepress->set_element_language_details( $new_term['term_taxonomy_id'], 'tax_' . $attr, $tt_id, $language['code'] );
242
+ }
243
+ }
244
+ }
245
+
246
+ }
247
+ }
248
 
249
  wp_send_json_success();
250
  }
inc/class-wcml-url-translation.php CHANGED
@@ -178,29 +178,7 @@ class WCML_Url_Translation {
178
  }
179
 
180
  $slug = $this->get_woocommerce_product_base();
181
-
182
- if ( version_compare( WPML_ST_VERSION, '2.2.6', '>' ) ) {
183
-
184
- // Use new API for WPML ST > 2.2.6
185
- do_action( 'wpml_activate_slug_translation', 'product', $slug );
186
-
187
- } else {
188
-
189
- // force_product_slug_translation_on
190
- $iclsettings = $this->sitepress->get_settings();
191
- if ( empty( $iclsettings['posts_slug_translation']['on'] ) || empty( $iclsettings['posts_slug_translation']['types']['product'] ) ) {
192
- $iclsettings['posts_slug_translation']['on'] = 1;
193
- $iclsettings['posts_slug_translation']['types']['product'] = 1;
194
- $this->sitepress->save_settings( $iclsettings );
195
- }
196
-
197
- $string = icl_get_string_id( $slug, $this->url_strings_context(), $this->url_string_name( 'product' ) );
198
- if ( ! $string ) {
199
- do_action( 'wpml_register_single_string', $this->url_strings_context(), $this->url_string_name( 'product' ), trim( $slug, '/' ) );
200
- }
201
-
202
- }
203
-
204
  }
205
 
206
  function get_woocommerce_product_base() {
@@ -486,16 +464,15 @@ class WCML_Url_Translation {
486
  $taxonomy_obj = get_taxonomy( $taxonomy );
487
 
488
  if ( isset( $taxonomy_obj->rewrite['slug'] ) ) {
489
- $exp = explode( '/', trim( $taxonomy_obj->rewrite['slug'], '/' ) );
490
- $slug = join( '/', array_slice( $exp, 0, count( $exp ) - 1 ) );
491
-
492
  $attribute_slug = preg_replace( "#^$slug/#", '', $taxonomy_obj->rewrite['slug'] );
493
- }
494
 
495
- if ( isset( $slug ) ) {
496
- $string_language = $this->woocommerce_wpml->strings->get_string_language( $slug, $this->url_strings_context(), $this->url_string_name( 'attribute' ) );
 
497
 
498
- if ( $this->sitepress->get_current_language() != $string_language ) {
499
 
500
  $slug_translation = apply_filters( 'wpml_translate_single_string', $slug, $this->url_strings_context(), $this->url_string_name( 'attribute' ) );
501
 
@@ -516,7 +493,7 @@ class WCML_Url_Translation {
516
 
517
  $slug_match = addslashes( ltrim( $attribute_slug, '/' ) );
518
  $pattern = "#(^|\/)" . $slug_match . "/(.*)#";
519
- $replacement = '$1'.$attribute_slug_translation . '/$2';
520
 
521
  $value = $this->replace_bases_in_rewrite_rules( $value, $pattern, $pattern, $replacement );
522
 
@@ -776,10 +753,15 @@ class WCML_Url_Translation {
776
  break;
777
 
778
  default:
779
- $endpoints = WC()->query->query_vars;
780
- $slug = isset( $endpoints[ $base ] ) ? $endpoints[ $base ] : false;
 
 
 
 
 
781
  $return['name'] = sprintf( __( 'Endpoint: %s', 'woocommerce-multilingual' ), $base );
782
- $string_id = icl_get_string_id( $slug, 'WooCommerce Endpoints', $base );
783
  break;
784
  }
785
 
@@ -802,15 +784,29 @@ class WCML_Url_Translation {
802
  return $return;
803
 
804
  }
 
 
 
 
 
 
805
 
806
- function get_source_slug_language( $base ) {
 
 
 
 
 
807
 
808
  if ( $base == 'shop' ) {
809
- $source_language = $this->sitepress->get_language_for_element( get_option( 'woocommerce_shop_page_id' ), 'post_page' );
810
  } elseif ( in_array( $base, array( 'product', 'product_cat', 'product_tag', 'attribute' ) ) ) {
811
  $source_language = $this->woocommerce_wpml->strings->get_string_language( $base, $this->url_strings_context(), $this->url_string_name( $base ) );
 
 
 
812
  } else {
813
- $source_language = $this->woocommerce_wpml->strings->get_string_language( $base, 'WooCommerce Endpoints', $base );
814
  }
815
 
816
  return $source_language;
@@ -829,7 +825,7 @@ class WCML_Url_Translation {
829
  $language = $_POST['language'];
830
 
831
  if ( $original_base == 'shop' ) {
832
- $original_shop_id = get_option( 'woocommerce_shop_page_id' );
833
  $translated_shop_id = apply_filters( 'translate_object_id', $original_shop_id, 'page', false, $language );
834
 
835
  if ( ! is_null( $translated_shop_id ) ) {
@@ -848,12 +844,15 @@ class WCML_Url_Translation {
848
  do_action( 'wpml_register_single_string', $this->url_strings_context(), $this->url_string_name( 'attribute_slug', $slug ), $slug );
849
  $string_id = icl_get_string_id( $original_base_value, $this->url_strings_context(), $this->url_string_name( 'attribute_slug', $slug ) );
850
  } else {
851
- $string_id = icl_get_string_id( $original_base_value, 'WooCommerce Endpoints', $original_base );
852
  if ( ! $string_id && function_exists( 'icl_register_string' ) ) {
853
- $string_id = icl_register_string( 'WooCommerce Endpoints', $original_base, $original_base_value );
 
 
 
 
 
854
  }
855
- $this->woocommerce_wpml->endpoints->add_endpoints();
856
- $this->woocommerce_wpml->endpoints->flush_rules_for_endpoints_translations();
857
  }
858
 
859
  icl_add_string_translation( $string_id, $language, $base_translation, ICL_STRING_TRANSLATION_COMPLETE );
@@ -924,13 +923,7 @@ class WCML_Url_Translation {
924
  $product_slug = $this->woocommerce_wpml->strings->product_permalink_slug();
925
  }
926
 
927
- if ( version_compare( WPML_ST_VERSION, '2.3', '>=' ) ) {
928
- $translated_slug = apply_filters( 'wpml_get_translated_slug', $product_slug, 'product', $language );
929
- } elseif ( apply_filters( 'wpml_slug_translation_available', false ) ) {
930
- $translated_slug = apply_filters( 'wpml_get_translated_slug', 'product', $language );
931
- } else {
932
- $translated_slug = apply_filters( 'wpml_translate_single_string', $product_slug, $this->url_strings_context(), $this->url_string_name( 'product' ) );
933
- }
934
 
935
  return $translated_slug;
936
  }
178
  }
179
 
180
  $slug = $this->get_woocommerce_product_base();
181
+ do_action( 'wpml_activate_slug_translation', 'product', $slug );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
182
  }
183
 
184
  function get_woocommerce_product_base() {
464
  $taxonomy_obj = get_taxonomy( $taxonomy );
465
 
466
  if ( isset( $taxonomy_obj->rewrite['slug'] ) ) {
467
+ $exp = explode( '/', trim( $taxonomy_obj->rewrite['slug'], '/' ) );
468
+ $slug = join( '/', array_slice( $exp, 0, count( $exp ) - 1 ) );
 
469
  $attribute_slug = preg_replace( "#^$slug/#", '', $taxonomy_obj->rewrite['slug'] );
 
470
 
471
+ $current_language = $this->sitepress->get_current_language();
472
+ $slug_language = $this->woocommerce_wpml->strings->get_string_language( $slug, $this->url_strings_context(), $this->url_string_name( 'attribute' ) );
473
+ $attribute_slug_language = $this->woocommerce_wpml->strings->get_string_language( $attribute_slug, $this->url_strings_context(), $this->url_string_name( 'attribute_slug', $attribute_slug ) );
474
 
475
+ if ( $current_language !== $attribute_slug_language || $current_language !== $slug_language ) {
476
 
477
  $slug_translation = apply_filters( 'wpml_translate_single_string', $slug, $this->url_strings_context(), $this->url_string_name( 'attribute' ) );
478
 
493
 
494
  $slug_match = addslashes( ltrim( $attribute_slug, '/' ) );
495
  $pattern = "#(^|\/)" . $slug_match . "/(.*)#";
496
+ $replacement = '$1' . $attribute_slug_translation . '/$2';
497
 
498
  $value = $this->replace_bases_in_rewrite_rules( $value, $pattern, $pattern, $replacement );
499
 
753
  break;
754
 
755
  default:
756
+ if ( class_exists( 'WPML_Endpoints_Support' ) ) {
757
+ $slug = $base;
758
+ } else {
759
+ $endpoints = WC()->query->query_vars;
760
+ $slug = isset( $endpoints[ $base ] ) ? $endpoints[ $base ] : false;
761
+ }
762
+
763
  $return['name'] = sprintf( __( 'Endpoint: %s', 'woocommerce-multilingual' ), $base );
764
+ $string_id = icl_get_string_id( $slug, $this->get_endpoint_string_context(), $base );
765
  break;
766
  }
767
 
784
  return $return;
785
 
786
  }
787
+
788
+ private function get_endpoint_string_context(){
789
+
790
+ return class_exists( 'WPML_Endpoints_Support' ) ? WPML_Endpoints_Support::STRING_CONTEXT : 'WooCommerce Endpoints';
791
+
792
+ }
793
 
794
+ /**
795
+ * @param string $base
796
+ *
797
+ * @return string
798
+ */
799
+ public function get_source_slug_language( $base ) {
800
 
801
  if ( $base == 'shop' ) {
802
+ $source_language = $this->sitepress->get_language_for_element( wc_get_page_id( 'shop' ), 'post_page' );
803
  } elseif ( in_array( $base, array( 'product', 'product_cat', 'product_tag', 'attribute' ) ) ) {
804
  $source_language = $this->woocommerce_wpml->strings->get_string_language( $base, $this->url_strings_context(), $this->url_string_name( $base ) );
805
+ } elseif ( strpos( $base, 'attribute_slug-' ) === 0 ) {
806
+ $slug = preg_replace( '#^attribute_slug-#', '', $base );
807
+ $source_language = $this->woocommerce_wpml->strings->get_string_language( $base, $this->url_strings_context(), $this->url_string_name( 'attribute_slug', $slug ) );
808
  } else {
809
+ $source_language = $this->woocommerce_wpml->strings->get_string_language( $base, $this->get_endpoint_string_context(), $base );
810
  }
811
 
812
  return $source_language;
825
  $language = $_POST['language'];
826
 
827
  if ( $original_base == 'shop' ) {
828
+ $original_shop_id = wc_get_page_id( 'shop' );
829
  $translated_shop_id = apply_filters( 'translate_object_id', $original_shop_id, 'page', false, $language );
830
 
831
  if ( ! is_null( $translated_shop_id ) ) {
844
  do_action( 'wpml_register_single_string', $this->url_strings_context(), $this->url_string_name( 'attribute_slug', $slug ), $slug );
845
  $string_id = icl_get_string_id( $original_base_value, $this->url_strings_context(), $this->url_string_name( 'attribute_slug', $slug ) );
846
  } else {
847
+ $string_id = icl_get_string_id( $original_base_value, $this->get_endpoint_string_context(), $original_base );
848
  if ( ! $string_id && function_exists( 'icl_register_string' ) ) {
849
+ $string_id = icl_register_string( $this->get_endpoint_string_context(), $original_base, $original_base_value );
850
+ }
851
+
852
+ if( method_exists( $this->woocommerce_wpml->endpoints, 'add_endpoints' ) ){
853
+ $this->woocommerce_wpml->endpoints->add_endpoints();
854
+ $this->woocommerce_wpml->endpoints->flush_rules_for_endpoints_translations();
855
  }
 
 
856
  }
857
 
858
  icl_add_string_translation( $string_id, $language, $base_translation, ICL_STRING_TRANSLATION_COMPLETE );
923
  $product_slug = $this->woocommerce_wpml->strings->product_permalink_slug();
924
  }
925
 
926
+ $translated_slug = apply_filters( 'wpml_get_translated_slug', $product_slug, 'product', $language );
 
 
 
 
 
 
927
 
928
  return $translated_slug;
929
  }
inc/class-wcml-wc-gateways.php CHANGED
@@ -2,6 +2,8 @@
2
 
3
  class WCML_WC_Gateways{
4
 
 
 
5
  private $current_language;
6
  private $sitepress;
7
 
@@ -30,6 +32,10 @@ class WCML_WC_Gateways{
30
  if( is_admin() && $pagenow == 'admin.php' && isset( $_GET[ 'page' ] ) && $_GET[ 'page' ] == 'wc-settings' && isset( $_GET[ 'tab' ] ) && $_GET[ 'tab' ] == 'checkout' ){
31
  add_action( 'admin_footer', array($this, 'show_language_links_for_gateways' ) );
32
  $this->register_and_set_gateway_strings_language();
 
 
 
 
33
  }
34
 
35
  }
@@ -177,6 +183,10 @@ class WCML_WC_Gateways{
177
 
178
  $this->woocommerce_wpml->strings->set_string_language( $string_value, $context, $gateway_string_name, $language );
179
  }
 
 
 
 
180
  }
181
 
182
  }
@@ -192,4 +202,27 @@ class WCML_WC_Gateways{
192
  return apply_filters( 'wcml_gateway_text_keys_to_translate', $text_keys );
193
  }
194
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
195
  }
2
 
3
  class WCML_WC_Gateways{
4
 
5
+ const WCML_BACS_ACCOUNTS_CURRENCIES_OPTION = 'wcml_bacs_accounts_currencies';
6
+
7
  private $current_language;
8
  private $sitepress;
9
 
32
  if( is_admin() && $pagenow == 'admin.php' && isset( $_GET[ 'page' ] ) && $_GET[ 'page' ] == 'wc-settings' && isset( $_GET[ 'tab' ] ) && $_GET[ 'tab' ] == 'checkout' ){
33
  add_action( 'admin_footer', array($this, 'show_language_links_for_gateways' ) );
34
  $this->register_and_set_gateway_strings_language();
35
+
36
+ if( isset( $_GET[ 'section' ] ) && 'bacs' === $_GET[ 'section' ] ){
37
+ add_action( 'admin_footer', array( $this, 'append_currency_selector_to_bacs_account_settings' ) );
38
+ }
39
  }
40
 
41
  }
183
 
184
  $this->woocommerce_wpml->strings->set_string_language( $string_value, $context, $gateway_string_name, $language );
185
  }
186
+
187
+ if( 'woocommerce_bacs' === $gateway && isset( $_POST['bacs-currency'] ) ){
188
+ update_option( self::WCML_BACS_ACCOUNTS_CURRENCIES_OPTION, filter_var_array( $_POST['bacs-currency'], FILTER_SANITIZE_STRING ) );
189
+ }
190
  }
191
 
192
  }
202
  return apply_filters( 'wcml_gateway_text_keys_to_translate', $text_keys );
203
  }
204
 
205
+ public function append_currency_selector_to_bacs_account_settings() {
206
+
207
+ $active_currencies = $this->woocommerce_wpml->multi_currency->get_currency_codes();
208
+ $default_currency = get_option( 'woocommerce_currency' );
209
+ $bacs_settings = get_option( 'woocommerce_bacs_accounts', array() );
210
+ $bacs_accounts_currencies = get_option( self::WCML_BACS_ACCOUNTS_CURRENCIES_OPTION, array() );
211
+ $template_loader = new WPML_Twig_Template_Loader( array( $this->sitepress->get_wp_api()->constant( 'WCML_PLUGIN_PATH' ) . '/templates/multi-currency/' ) );
212
+ $currencies_dropdown_ui = new WCML_Currencies_Dropdown_UI( $template_loader );
213
+
214
+ foreach ( $bacs_settings as $id => $account_settings ) {
215
+ $currencies_output[ $id ] = $currencies_dropdown_ui->get( $active_currencies, isset( $bacs_accounts_currencies[ $id ] ) ? $bacs_accounts_currencies[ $id ] : $default_currency );
216
+ }
217
+
218
+ $default_dropdown = $currencies_dropdown_ui->get( $active_currencies, $default_currency );
219
+
220
+ wp_enqueue_script( 'wcml-bacs-accounts-currencies', WCML_PLUGIN_URL . '/res/js/bacs-accounts-currencies' . WCML_JS_MIN . '.js', array( 'jquery' ), WCML_VERSION, true );
221
+ wp_localize_script( 'wcml-bacs-accounts-currencies', 'wcml_data', array(
222
+ 'currencies_dropdown' => $currencies_output,
223
+ 'label' => __( 'Currency', 'woocommerce-multilingual' ),
224
+ 'default_dropdown' => $default_dropdown
225
+ ) );
226
+ }
227
+
228
  }
inc/class-wcml-wc-shipping.php CHANGED
@@ -37,19 +37,20 @@ class WCML_WC_Shipping{
37
 
38
  foreach ( $shipping_methods as $shipping_method ) {
39
 
40
- if( isset( $shipping_method->id ) ){
41
- $shipping_method_id = $shipping_method->id;
42
- }else{
43
- continue;
44
- }
45
-
46
- if( ( defined('WC_VERSION') && version_compare( WC_VERSION , '2.6', '<' ) ) ){
47
- add_filter( 'woocommerce_settings_api_sanitized_fields_'.$shipping_method_id, array( $this, 'register_shipping_strings' ) );
48
- }else{
49
- add_filter( 'woocommerce_shipping_' . $shipping_method_id . '_instance_settings_values', array( $this, 'register_zone_shipping_strings' ),9,2 );
50
- }
51
-
52
- add_filter( 'option_woocommerce_'.$shipping_method_id.'_settings', array( $this, 'translate_shipping_strings' ), 9, 2 );
 
53
  }
54
  }
55
 
@@ -74,23 +75,6 @@ class WCML_WC_Shipping{
74
  return $instance_settings;
75
  }
76
 
77
- function register_shipping_strings( $fields ){
78
- $shipping = WC_Shipping::instance();
79
-
80
- foreach( $shipping->get_shipping_methods() as $shipping_method ){
81
- if( isset( $_POST['woocommerce_'.$shipping_method->id.'_enabled'] ) ){
82
- $shipping_method_id = $shipping_method->id;
83
- break;
84
- }
85
- }
86
-
87
- if( isset( $shipping_method_id ) ){
88
- $this->register_shipping_title( $shipping_method_id, $fields['title'] );
89
- }
90
-
91
- return $fields;
92
- }
93
-
94
  function register_shipping_title( $shipping_method_id, $title ){
95
  do_action( 'wpml_register_single_string', 'woocommerce', $shipping_method_id .'_shipping_method_title', $title );
96
  }
@@ -112,12 +96,12 @@ class WCML_WC_Shipping{
112
  }
113
 
114
  function translate_shipping_methods_in_package( $available_methods ){
 
115
  foreach($available_methods as $key => $method){
116
- $shipping_id = $method->method_id . $method->instance_id;
117
- $available_methods[$key]->label = $this->translate_shipping_method_title( $method->label, $shipping_id );
118
  }
119
 
120
- return $available_methods;
121
  }
122
 
123
  /**
37
 
38
  foreach ( $shipping_methods as $shipping_method ) {
39
 
40
+ if ( isset( $shipping_method->id ) ) {
41
+ $shipping_method_id = $shipping_method->id;
42
+ } else {
43
+ continue;
44
+ }
45
+
46
+ add_filter( 'woocommerce_shipping_' . $shipping_method_id . '_instance_settings_values', array(
47
+ $this,
48
+ 'register_zone_shipping_strings'
49
+ ), 9, 2 );
50
+ add_filter( 'option_woocommerce_' . $shipping_method_id . '_settings', array(
51
+ $this,
52
+ 'translate_shipping_strings'
53
+ ), 9, 2 );
54
  }
55
  }
56
 
75
  return $instance_settings;
76
  }
77
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
78
  function register_shipping_title( $shipping_method_id, $title ){
79
  do_action( 'wpml_register_single_string', 'woocommerce', $shipping_method_id .'_shipping_method_title', $title );
80
  }
96
  }
97
 
98
  function translate_shipping_methods_in_package( $available_methods ){
99
+
100
  foreach($available_methods as $key => $method){
101
+ $available_methods[$key]->label = $this->translate_shipping_method_title( $method->label, $key );
 
102
  }
103
 
104
+ return apply_filters( 'wcml_translated_package_rates', $available_methods );
105
  }
106
 
107
  /**
inc/class-wcml-wc-strings.php CHANGED
@@ -77,11 +77,11 @@ class WCML_WC_Strings {
77
  }
78
 
79
  if ( $product && is_object( $product ) ) {
80
- $product_id = WooCommerce_Functions_Wrapper::get_product_id( $product );
81
  } elseif ( is_numeric( $product_obj ) ) {
82
  $product_id = $product_obj;
83
  } elseif ( $product_obj ) {
84
- $product_id = WooCommerce_Functions_Wrapper::get_product_id( $product_obj );
85
  }
86
 
87
  $name = $this->woocommerce_wpml->attributes->filter_attribute_name( $name, $product_id, true );
@@ -158,7 +158,7 @@ class WCML_WC_Strings {
158
  function translated_checkout_product_title( $title, $product ) {
159
 
160
  if ( $product ) {
161
- $tr_product_id = apply_filters( 'translate_object_id', WooCommerce_Functions_Wrapper::get_product_id( $product ), 'product', true, $this->current_language );
162
  $title = get_the_title( $tr_product_id );
163
  }
164
 
77
  }
78
 
79
  if ( $product && is_object( $product ) ) {
80
+ $product_id = $product->get_id();
81
  } elseif ( is_numeric( $product_obj ) ) {
82
  $product_id = $product_obj;
83
  } elseif ( $product_obj ) {
84
+ $product_id = $product_obj->get_id();
85
  }
86
 
87
  $name = $this->woocommerce_wpml->attributes->filter_attribute_name( $name, $product_id, true );
158
  function translated_checkout_product_title( $title, $product ) {
159
 
160
  if ( $product ) {
161
+ $tr_product_id = apply_filters( 'translate_object_id', $product->get_id(), 'product', true, $this->current_language );
162
  $title = get_the_title( $tr_product_id );
163
  }
164
 
inc/class-wcml-woocommerce-rest-api-support.php DELETED
@@ -1,414 +0,0 @@
1
- <?php
2
- // Should only be used for WooCommerce versions prior 2.6
3
- class WCML_WooCommerce_Rest_API_Support{
4
-
5
- private $woocommerce_wpml;
6
- /**
7
- * @var SitePress
8
- */
9
- private $sitepress;
10
- private $sitepress_settings;
11
-
12
- function __construct( &$woocommerce_wpml, &$sitepress ){
13
-
14
- $this->woocommerce_wpml =& $woocommerce_wpml;
15
- $this->sitepress =& $sitepress;
16
- $this->sitepress_settings = $this->sitepress->get_settings();
17
-
18
- add_action( 'parse_request', array( $this, 'use_canonical_home_url' ), -10 );
19
- add_action( 'init', array( $this, 'init' ) );
20
-
21
- add_filter( 'woocommerce_api_query_args', array($this, 'add_lang_parameter'), 10, 2 );
22
- add_filter( 'woocommerce_api_dispatch_args', array($this, 'dispatch_args_filter'), 10, 2 );
23
-
24
- add_filter( 'woocommerce_api_order_response' , array( $this, 'filter_order_items_by_language' ), 10, 4 );
25
- add_action( 'woocommerce_api_create_order' , array( $this, 'set_order_language' ), 10, 2 );
26
-
27
-
28
- add_action( 'woocommerce_api_create_product', array( $this, 'set_product_language' ), 10 , 2 );
29
- add_action( 'woocommerce_api_create_product', array( $this, 'set_product_custom_prices' ), 10 , 2 );
30
- add_action( 'woocommerce_api_product_response', array( $this, 'append_product_language_and_translations' ) );
31
- add_action( 'woocommerce_api_product_response', array( $this, 'append_product_secondary_prices' ) );
32
-
33
- add_action( 'woocommerce_api_edit_product', array( $this, 'sync_product_with_translations' ), 10, 2 );
34
- }
35
-
36
- public function init(){
37
-
38
- //remove rewrite rules filtering for PayPal IPN url
39
- if( strstr($_SERVER['REQUEST_URI'],'WC_Gateway_Paypal') && $this->sitepress_settings[ 'urls' ][ 'directory_for_default_language' ] ) {
40
- remove_filter('option_rewrite_rules', array($this->sitepress, 'rewrite_rules_filter'));
41
- }
42
-
43
- }
44
-
45
- // Use url without the language parameter. Needed for the signature match.
46
- public function use_canonical_home_url(){
47
- global $wp;
48
-
49
- if(!empty($wp->query_vars['wc-api-version'])) {
50
- global $wpml_url_filters;
51
- $wpml_url_filters->remove_global_hooks();
52
- remove_filter('home_url', array($wpml_url_filters, 'home_url_filter'), -10, 4);
53
-
54
- }
55
-
56
- }
57
-
58
- public function add_lang_parameter( $args, $request_args ){
59
-
60
- if( isset( $request_args['lang'] ) ) {
61
- $args['lang'] = $request_args['lang'];
62
- }
63
-
64
- return $args;
65
- }
66
-
67
- public function dispatch_args_filter( $args, $callback ){
68
- global $wp;
69
-
70
- $route = $wp->query_vars['wc-api-route'];
71
-
72
-
73
- if( isset( $args['filter']['lang'] ) ){
74
-
75
- $lang = $args['filter']['lang'];
76
-
77
- $active_languages = $this->sitepress->get_active_languages();
78
-
79
- if ( !isset($active_languages[$lang]) && $lang != 'all' ) {
80
- throw new WC_API_Exception( '404', sprintf( __( 'Invalid language parameter: %s' ), $lang ), '404' );
81
- }
82
-
83
- if ( $lang != $this->sitepress->get_default_language() ) {
84
- if ( $lang != 'all' ) {
85
-
86
- $this->sitepress->switch_lang( $lang );
87
-
88
- }else{
89
-
90
- switch($route){
91
- case '/products':
92
- // Remove filters for the post query
93
- remove_action( 'query_vars', array( $this->sitepress, 'query_vars' ) );
94
- global $wpml_query_filter;
95
- remove_filter( 'posts_join', array( $wpml_query_filter, 'posts_join_filter' ), 10 );
96
- remove_filter( 'posts_where', array( $wpml_query_filter, 'posts_where_filter' ), 10 );
97
- break;
98
-
99
- case '/products/categories':
100
- // Remove WPML language filters for the terms query
101
- remove_filter('terms_clauses', array($this->sitepress,'terms_clauses'));
102
- remove_filter( 'get_term', array( $this->sitepress, 'get_term_adjust_id' ), 1 );
103
- break;
104
-
105
- }
106
-
107
- }
108
- }
109
-
110
- if( $route == '/orders'){
111
- add_filter( 'woocommerce_order_get_items', array( $this, 'get_order_items_in_the_current_language' ) );
112
- }
113
-
114
-
115
- }
116
-
117
-
118
- return $args;
119
-
120
- }
121
-
122
- /**
123
- * Filter orders content in the current language
124
- */
125
- public function get_order_items_in_the_current_language( $items ){
126
-
127
- $lang = get_query_var('lang');
128
- $wc_taxonomies = wc_get_attribute_taxonomies();
129
- $attributes = array();
130
- foreach( $wc_taxonomies as $taxonomy ){
131
- $attributes[] = 'pa_' . $taxonomy->attribute_name;
132
- }
133
-
134
- foreach( $items as $key => $item ){
135
-
136
- if( isset( $item['product_id'] ) ) {
137
- $translated_product_id = apply_filters( 'translate_object_id', $item['product_id'], 'product', true, $lang );
138
- $items[$key]['product_id'] = $translated_product_id;
139
- $items[$key]['item_meta']['_product_id'] = $translated_product_id;
140
- $items[$key]['name'] = get_post_field( 'post_title', $translated_product_id );
141
- foreach ( $item['item_meta_array'] as $k => $m ) {
142
- if ( $m->key == '_product_id' ) {
143
- $items[$key]['item_meta_array'][$k]->value = $translated_product_id;
144
- }
145
- }
146
- }
147
-
148
- // Variations included
149
- if( !empty( $item['variation_id'] ) ){
150
- $translated_variation_id = apply_filters('translate_object_id', $item['variation_id'], 'product_variation', true, $lang);
151
- $items[$key]['variation_id'] = $translated_variation_id;
152
- $items[$key]['item_meta']['_variation_id'] = $translated_variation_id;
153
- foreach( $attributes as $attribute_name ){
154
- if( isset( $item['item_meta'][$attribute_name] ) ){
155
-
156
- foreach( $item['item_meta'][$attribute_name] as $idx => $attr ){
157
- $term = get_term_by('slug', $attr, $attribute_name);
158
- $translated_term_id = apply_filters('translate_object_id', $term->term_id, $attribute_name, true, $lang);
159
- $translated_term = get_term_by('id', $translated_term_id, $attribute_name);
160
- $items[$key]['item_meta'][$attribute_name][$idx] = $translated_term->slug;
161
- }
162
-
163
- }
164
-
165
- if( isset( $item[$attribute_name] ) ){
166
- $term = get_term_by('slug', $item[$attribute_name], $attribute_name);
167
- $translated_term_id = apply_filters('translate_object_id', $term->term_id, $attribute_name, true, $lang);
168
- $translated_term = get_term_by('id', $translated_term_id, $attribute_name);
169
- $items[$key][$attribute_name] = $translated_term->slug;
170
- }
171
- }
172
-
173
- foreach( $item['item_meta_array'] as $k => $m){
174
- if($m->key == '_variation_id'){
175
-
176
- $items[$key]['item_meta_array'][$k]->value = $translated_variation_id;
177
-
178
- } elseif( in_array( $m->key, $attributes ) ){
179
-
180
- $term = get_term_by('slug', $m->value, $m->key);
181
- $translated_term_id = apply_filters('translate_object_id', $term->term_id, $m->key, true, $lang);
182
- $translated_term = get_term_by('id', $translated_term_id, $m->key);
183
- $items[$key]['item_meta_array'][$k]->value = $translated_term->slug;
184
-
185
- }
186
- }
187
-
188
-
189
- }
190
-
191
- }
192
-
193
- return $items;
194
-
195
- }
196
-
197
- /**
198
- * Filters the items of an order according to a given languages
199
- *
200
- * @param $order_data
201
- * @param $order
202
- * @param $fields
203
- * @param $server
204
- * @return mixed
205
- */
206
- public function filter_order_items_by_language( $order_data, $order, $fields, $server ){
207
-
208
- $lang = get_query_var('lang');
209
-
210
- $order_lang = get_post_meta($order->ID, 'wpml_language');
211
-
212
- if( $order_lang != $lang ){
213
-
214
- foreach( $order_data['line_items'] as $k => $item ){
215
-
216
- if( isset( $item['product_id'] ) ){
217
-
218
- $translated_product_id = apply_filters( 'translate_object_id', $item['product_id'], 'product', true, $lang );
219
- if( $translated_product_id ){
220
- $translated_product = get_post( $translated_product_id );
221
- $order_data['line_items'][$k]['product_id'] = $translated_product_id;
222
- if( $translated_product->post_type == 'product_variation' ){
223
- $post_parent = get_post( $translated_product->post_parent );
224
- $post_name = $post_parent->post_title;
225
- } else {
226
- $post_name = $translated_product->post_title;
227
- }
228
- $order_data['line_items'][$k]['name'] = $post_name;
229
- }
230
-
231
- }
232
-
233
- }
234
-
235
- }
236
-
237
- return $order_data;
238
- }
239
-
240
-
241
- /**
242
- * Sets the language for a new order
243
- *
244
- * @param $order_id
245
- * @param $data
246
- *
247
- * @throws WC_API_Exception
248
- */
249
- public function set_order_language( $order_id, $data ){
250
-
251
- if( isset( $data['lang'] ) ){
252
-
253
- $active_languages = $this->sitepress->get_active_languages();
254
- if( !isset( $active_languages[$data['lang']] ) ){
255
- throw new WC_API_Exception( '404', sprintf( __( 'Invalid language parameter: %s' ), $data['lang'] ), '404' );
256
- }
257
-
258
- update_post_meta( $order_id, 'wpml_language', $data['lang']);
259
-
260
- }
261
-
262
- }
263
-
264
- /**
265
- * Sets the product information according to the provided language
266
- *
267
- * @param $id
268
- * @param $data
269
- *
270
- * @throws WC_API_Exception
271
- *
272
- */
273
- public function set_product_language( $id, $data ){
274
-
275
- if( isset( $data['lang'] )){
276
- $active_languages = $this->sitepress->get_active_languages();
277
- if( !isset( $active_languages[$data['lang']] ) ){
278
- throw new WC_API_Exception( '404', sprintf( __( 'Invalid language parameter: %s' ), $data['lang'] ), '404' );
279
- }
280
- if( isset( $data['translation_of'] ) ){
281
- $trid = $this->sitepress->get_element_trid( $data['translation_of'], 'post_product' );
282
- if( empty($trid) ){
283
- throw new WC_API_Exception( '404', sprintf( __( 'Source product id not found: %s' ), $data['translation_of'] ), '404' );
284
- }
285
- }else{
286
- $trid = null;
287
- }
288
- $this->sitepress->set_element_language_details( $id, 'post_product', $trid, $data['lang'] );
289
- }
290
-
291
- }
292
-
293
- /**
294
- * Sets custom prices in secondary currencies for products
295
- *
296
- * @param $id
297
- * @param @data
298
- *
299
- */
300
- public function set_product_custom_prices( $id, $data ){
301
-
302
- if( !empty($this->woocommerce_wpml->multi_currency) ){
303
-
304
- if( (!empty($data['custom_prices'])) && (empty($data['translation_of']))){
305
- update_post_meta( $id, '_wcml_custom_prices_status', 1);
306
-
307
- foreach( $data['custom_prices'] as $currency => $prices ){
308
-
309
- $prices_uscore = array();
310
- foreach( $prices as $k => $p){
311
- $prices_uscore['_' . $k] = $p;
312
- }
313
-
314
- $this->woocommerce_wpml->multi_currency->custom_prices->update_custom_prices( $id, $prices_uscore, $currency );
315
-
316
- }
317
-
318
- }
319
- }
320
-
321
- }
322
-
323
- /**
324
- * Synchronizes product fields with its translations
325
- *
326
- * @param $id
327
- * @param $data
328
- */
329
- public function sync_product_with_translations( $id, $data ){
330
-
331
- // Force the WPML sync on post update for the changes
332
- // that don't trigger wp_save_post. e.g. stock
333
- if(
334
- !isset( $data['title']) ||
335
- !isset( $data['name']) ||
336
- !isset( $data['status']) ||
337
- !isset( $data['short_description']) ||
338
- !isset( $data['description'])
339
- ){
340
- $post = get_post( $id );
341
- wp_update_post( array( 'ID' => $id, 'post_title' => wc_clean( $post->post_title ) ) ); // triggers WPML sync
342
- }
343
- }
344
-
345
- /**
346
- * Appends the language and translation information to the get_product response
347
- *
348
- * @param $product_data
349
- */
350
- public function append_product_language_and_translations( $product_data ){
351
-
352
- $product_data['translations'] = array();
353
-
354
- $trid = $this->sitepress->get_element_trid( $product_data['id'], 'post_product' );
355
- $translations = $this->sitepress->get_element_translations( $trid, 'post_product');
356
- foreach( $translations as $translation ){
357
- if( $translation->element_id == $product_data['id'] ){
358
- $product_language = $translation->language_code;
359
- }else{
360
- $product_data['translations'][$translation->language_code] = $translation->element_id;
361
- }
362
- }
363
-
364
- $product_data['lang'] = $product_language;
365
-
366
- return $product_data;
367
- }
368
-
369
- /**
370
- * Appends the secondary prices information to the get_product response
371
- *
372
- * @param $product_data
373
- */
374
- public function append_product_secondary_prices( $product_data ){
375
-
376
- if( !empty($this->woocommerce_wpml->multi_currency) && !empty($this->woocommerce_wpml->settings['currencies_order']) ){
377
-
378
- $product_data['multi-currency-prices'] = array();
379
-
380
- $custom_prices_on = get_post_meta( $product_data['id'], '_wcml_custom_prices_status', true);
381
-
382
- foreach( $this->woocommerce_wpml->settings['currencies_order'] as $currency ){
383
-
384
- if( $currency != get_option('woocommerce_currency') ){
385
-
386
- if( $custom_prices_on ){
387
-
388
- $custom_prices = (array) $this->woocommerce_wpml->multi_currency->custom_prices->get_product_custom_prices( $product_data['id'], $currency );
389
- foreach( $custom_prices as $key => $price){
390
- $product_data['multi-currency-prices'][$currency][ preg_replace('#^_#', '', $key) ] = $price;
391
-
392
- }
393
-
394
- } else {
395
- $product_data['multi-currency-prices'][$currency]['regular_price'] =
396
- $this->woocommerce_wpml->multi_currency->prices->raw_price_filter( $product_data['regular_price'], $currency );
397
- if( !empty($product_data['sale_price']) ){
398
- $product_data['multi-currency-prices'][$currency]['sale_price'] =
399
- $this->woocommerce_wpml->multi_currency->prices->raw_price_filter( $product_data['sale_price'], $currency );
400
- }
401
- }
402
-
403
- }
404
-
405
- }
406
-
407
- }
408
-
409
- return $product_data;
410
- }
411
-
412
- }
413
-
414
- ?>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
inc/currencies/class-wcml-custom-prices.php CHANGED
@@ -35,7 +35,7 @@ class WCML_Custom_Prices{
35
  }
36
 
37
  public function get_product_custom_prices( $product_id, $currency = false ){
38
- global $wpdb, $sitepress;
39
 
40
  if( empty( $currency ) ){
41
  $currency = $this->woocommerce_wpml->multi_currency->get_client_currency();
@@ -51,19 +51,7 @@ class WCML_Custom_Prices{
51
  $cache_custom_prices = wp_cache_get( $cache_key, $cache_group, false, $cache_found );
52
  if( $cache_found ) return $cache_custom_prices;
53
 
54
-
55
- $original_product_id = $product_id;
56
- $post_type = get_post_type($product_id);
57
- $product_translations = $sitepress->get_element_translations($sitepress->get_element_trid($product_id, 'post_'.$post_type), 'post_'.$post_type);
58
- foreach($product_translations as $translation){
59
- if( $translation->original ){
60
- $original_product_id = $translation->element_id;
61
- break;
62
- }
63
- }
64
-
65
- $product_meta = get_post_custom($original_product_id);
66
-
67
  $custom_prices = false;
68
 
69
  if( !empty( $product_meta['_wcml_custom_prices_status'][0] ) ){
@@ -309,7 +297,7 @@ class WCML_Custom_Prices{
309
 
310
  private function load_custom_prices_js_css(){
311
  wp_register_style( 'wpml-wcml-prices', WCML_PLUGIN_URL . '/res/css/wcml-prices.css', null, WCML_VERSION );
312
- wp_register_script( 'wcml-tm-scripts-prices', WCML_PLUGIN_URL . '/res/js/prices' . WCML_JS_MIN . '.js', array( 'jquery' ), WCML_VERSION );
313
 
314
  wp_enqueue_style('wpml-wcml-prices');
315
  wp_enqueue_script('wcml-tm-scripts-prices');
@@ -408,14 +396,17 @@ class WCML_Custom_Prices{
408
  $date_to = isset( $_POST[ '_custom_sale_price_dates_to' ][ $code ] ) ? strtotime( $_POST[ '_custom_sale_price_dates_to' ][ $code ] ) : '';
409
  $schedule = $_POST[ '_wcml_schedule' ][ $code ];
410
 
411
- $custom_prices = apply_filters( 'wcml_update_custom_prices_values',
412
- array( '_regular_price' => $regular_price,
413
- '_sale_price' => $sale_price,
414
- '_wcml_schedule' => $schedule,
415
- '_sale_price_dates_from' => $date_from,
416
- '_sale_price_dates_to' => $date_to ),
417
- $code
418
- );
 
 
 
419
  $product_price = $this->update_custom_prices( $post_id, $custom_prices , $code );
420
 
421
  do_action( 'wcml_after_save_custom_prices', $post_id, $product_price, $custom_prices, $code );
@@ -526,4 +517,4 @@ class WCML_Custom_Prices{
526
  return $on_sale;
527
  }
528
 
529
- }
35
  }
36
 
37
  public function get_product_custom_prices( $product_id, $currency = false ){
38
+ global $wpdb;
39
 
40
  if( empty( $currency ) ){
41
  $currency = $this->woocommerce_wpml->multi_currency->get_client_currency();
51
  $cache_custom_prices = wp_cache_get( $cache_key, $cache_group, false, $cache_found );
52
  if( $cache_found ) return $cache_custom_prices;
53
 
54
+ $product_meta = get_post_custom( $this->woocommerce_wpml->products->get_original_product_id( $product_id ) );
 
 
 
 
 
 
 
 
 
 
 
 
55
  $custom_prices = false;
56
 
57
  if( !empty( $product_meta['_wcml_custom_prices_status'][0] ) ){
297
 
298
  private function load_custom_prices_js_css(){
299
  wp_register_style( 'wpml-wcml-prices', WCML_PLUGIN_URL . '/res/css/wcml-prices.css', null, WCML_VERSION );
300
+ wp_register_script( 'wcml-tm-scripts-prices', WCML_PLUGIN_URL . '/res/js/prices' . WCML_JS_MIN . '.js', array( 'jquery' ), WCML_VERSION, true );
301
 
302
  wp_enqueue_style('wpml-wcml-prices');
303
  wp_enqueue_script('wcml-tm-scripts-prices');
396
  $date_to = isset( $_POST[ '_custom_sale_price_dates_to' ][ $code ] ) ? strtotime( $_POST[ '_custom_sale_price_dates_to' ][ $code ] ) : '';
397
  $schedule = $_POST[ '_wcml_schedule' ][ $code ];
398
 
399
+ $custom_prices = apply_filters( 'wcml_update_custom_prices_values',
400
+ array(
401
+ '_regular_price' => $regular_price,
402
+ '_sale_price' => $sale_price,
403
+ '_wcml_schedule' => $schedule,
404
+ '_sale_price_dates_from' => $date_from,
405
+ '_sale_price_dates_to' => $date_to
406
+ ),
407
+ $code,
408
+ $post_id
409
+ );
410
  $product_price = $this->update_custom_prices( $post_id, $custom_prices , $code );
411
 
412
  do_action( 'wcml_after_save_custom_prices', $post_id, $product_price, $custom_prices, $code );
517
  return $on_sale;
518
  }
519
 
520
+ }
inc/currencies/class-wcml-multi-currency-configuration.php CHANGED
@@ -167,6 +167,19 @@ class WCML_Multi_Currency_Configuration
167
 
168
  $currency_code = $options['code'];
169
 
 
 
 
 
 
 
 
 
 
 
 
 
 
170
  if (!isset(self::$multi_currency->currencies[$currency_code])) {
171
  self::add_currency($currency_code);
172
  }
167
 
168
  $currency_code = $options['code'];
169
 
170
+ self::$multi_currency->currencies_payment_gateways->set_enabled( $currency_code, isset( $options['gateways_enabled'] ) ? true : false );
171
+
172
+ if ( isset( $options['gateways_settings'] ) ) {
173
+
174
+ $payment_gateways = self::$multi_currency->currencies_payment_gateways->get_gateways();
175
+
176
+ foreach ( $options['gateways_settings'] as $code => $gateways_settings ) {
177
+ if ( isset( $payment_gateways[ $code ] ) ) {
178
+ $payment_gateways[ $code ]->save_setting( $currency_code, $gateways_settings );
179
+ }
180
+ }
181
+ }
182
+
183
  if (!isset(self::$multi_currency->currencies[$currency_code])) {
184
  self::add_currency($currency_code);
185
  }
inc/currencies/class-wcml-multi-currency-orders.php CHANGED
@@ -139,7 +139,7 @@ class WCML_Multi_Currency_Orders {
139
 
140
  $the_order = new WC_Order( get_the_ID() );
141
  if ( $the_order ) {
142
- $order_currency = WooCommerce_Functions_Wrapper::get_order_currency( $the_order );
143
 
144
  if ( ! $order_currency && isset( $_COOKIE['_wcml_order_currency'] ) ) {
145
  $order_currency = $_COOKIE['_wcml_order_currency'];
@@ -290,10 +290,11 @@ class WCML_Multi_Currency_Orders {
290
 
291
  if ( $item instanceof WC_Order_Item_Product ) {
292
 
293
- $original_product_id = $this->woocommerce_wpml->products->get_original_product_id( $item->get_product_id() );
294
-
295
  if ( 'line_item' === $item->get_type() ) {
296
 
 
 
 
297
  $converted_price = get_post_meta( $original_product_id, '_price_' . $order_currency, true );
298
 
299
  if ( ! $converted_price ) {
@@ -324,7 +325,8 @@ class WCML_Multi_Currency_Orders {
324
  }
325
  } else {
326
 
327
- $original_product_id = $this->woocommerce_wpml->products->get_original_product_id( $item[ 'product_id' ] );
 
328
 
329
  $converted_price = $converted_subtotal_price = $converted_total_price = get_post_meta( $original_product_id, '_price_' . $order_currency, true );
330
 
@@ -421,7 +423,7 @@ class WCML_Multi_Currency_Orders {
421
  // handle currency in order emails before handled in woocommerce
422
  public function fix_currency_before_order_email( $order ) {
423
 
424
- $order_currency = WooCommerce_Functions_Wrapper::get_order_currency( $order );
425
 
426
  if ( ! $order_currency ) {
427
  return;
139
 
140
  $the_order = new WC_Order( get_the_ID() );
141
  if ( $the_order ) {
142
+ $order_currency = $the_order->get_currency();
143
 
144
  if ( ! $order_currency && isset( $_COOKIE['_wcml_order_currency'] ) ) {
145
  $order_currency = $_COOKIE['_wcml_order_currency'];
290
 
291
  if ( $item instanceof WC_Order_Item_Product ) {
292
 
 
 
293
  if ( 'line_item' === $item->get_type() ) {
294
 
295
+ $product_id = $item->get_variation_id() ? $item->get_variation_id() : $item->get_product_id();
296
+ $original_product_id = $this->woocommerce_wpml->products->get_original_product_id( $product_id );
297
+
298
  $converted_price = get_post_meta( $original_product_id, '_price_' . $order_currency, true );
299
 
300
  if ( ! $converted_price ) {
325
  }
326
  } else {
327
 
328
+ $product_id = $item['variation_id'] ? $item['variation_id'] : $item['product_id'];
329
+ $original_product_id = $this->woocommerce_wpml->products->get_original_product_id( $product_id );
330
 
331
  $converted_price = $converted_subtotal_price = $converted_total_price = get_post_meta( $original_product_id, '_price_' . $order_currency, true );
332
 
423
  // handle currency in order emails before handled in woocommerce
424
  public function fix_currency_before_order_email( $order ) {
425
 
426
+ $order_currency = $order->get_currency();
427
 
428
  if ( ! $order_currency ) {
429
  return;
inc/currencies/class-wcml-multi-currency-prices.php CHANGED
@@ -254,6 +254,12 @@ class WCML_Multi_Currency_Prices {
254
 
255
  }
256
 
 
 
 
 
 
 
257
  public function convert_price_amount( $amount, $currency = false ) {
258
 
259
  if ( empty( $currency ) ) {
@@ -262,20 +268,59 @@ class WCML_Multi_Currency_Prices {
262
 
263
  if ( $currency != get_option( 'woocommerce_currency' ) ) {
264
 
265
- $exchange_rates = $this->multi_currency->get_exchange_rates();
266
 
267
- if ( isset( $exchange_rates[ $currency ] ) && is_numeric( $amount ) ) {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
268
  $amount = $amount * $exchange_rates[ $currency ];
 
 
 
269
 
270
- // exception - currencies_without_cents
271
- if ( in_array( $currency, $this->multi_currency->get_currencies_without_cents() ) ) {
272
- $amount = $this->round_up( $amount );
273
- }
274
 
275
- } else {
276
- $amount = 0;
 
277
  }
278
 
 
 
279
  }
280
 
281
  return $amount;
254
 
255
  }
256
 
257
+ /**
258
+ * @param float|int $amount
259
+ * @param bool|string $currency
260
+ *
261
+ * @return float|int
262
+ */
263
  public function convert_price_amount( $amount, $currency = false ) {
264
 
265
  if ( empty( $currency ) ) {
268
 
269
  if ( $currency != get_option( 'woocommerce_currency' ) ) {
270
 
271
+ $amount = $this->calculate_exchange_rate_price( $amount, $currency, '*' );
272
 
273
+ }
274
+
275
+ return $amount;
276
+
277
+ }
278
+
279
+ /**
280
+ * @param float|int $amount
281
+ * @param string $from_currency
282
+ * @param string $to_currency
283
+ *
284
+ * @return float|int
285
+ */
286
+ public function convert_price_amount_by_currencies( $amount, $from_currency, $to_currency ){
287
+
288
+ if( $to_currency !== get_option( 'woocommerce_currency' ) ){
289
+ $amount = $this->calculate_exchange_rate_price( $amount, $to_currency, '*' );
290
+ }else{
291
+ $amount = $this->calculate_exchange_rate_price( $amount, $from_currency, '/' );
292
+ }
293
+
294
+ return $amount;
295
+ }
296
+
297
+ /**
298
+ * @param float|int $amount
299
+ * @param string $currency
300
+ * @param string $operator
301
+ *
302
+ * @return float|int
303
+ */
304
+ private function calculate_exchange_rate_price( $amount, $currency, $operator ){
305
+
306
+ $exchange_rates = $this->multi_currency->get_exchange_rates();
307
+
308
+ if ( isset( $exchange_rates[ $currency ] ) && is_numeric( $amount ) ) {
309
+
310
+ if( '*' === $operator ){
311
  $amount = $amount * $exchange_rates[ $currency ];
312
+ }elseif( '/' === $operator ){
313
+ $amount = $amount / $exchange_rates[ $currency ];
314
+ }
315
 
 
 
 
 
316
 
317
+ // exception - currencies_without_cents
318
+ if ( in_array( $currency, $this->multi_currency->get_currencies_without_cents() ) ) {
319
+ $amount = $this->round_up( $amount );
320
  }
321
 
322
+ } else {
323
+ $amount = 0;
324
  }
325
 
326
  return $amount;
inc/currencies/class-wcml-multi-currency-shipping-legacy.php DELETED
@@ -1,58 +0,0 @@
1
- <?php
2
-
3
- /**
4
- * Class WCML_Multi_Currency_Shipping_Legacy
5
- *
6
- * This code is only required for versions of WooCommerce prior 2.6.0
7
- *
8
- */
9
- class WCML_Multi_Currency_Shipping_Legacy{
10
-
11
- public function __construct() {
12
-
13
- add_filter( 'option_woocommerce_free_shipping_settings', array( $this, 'adjust_min_amount_required' ) );
14
- add_filter( 'woocommerce_package_rates', array($this, 'shipping_taxes_filter'));
15
-
16
- }
17
-
18
- public function shipping_taxes_filter($methods){
19
-
20
- global $woocommerce;
21
- $woocommerce->shipping->load_shipping_methods();
22
- $shipping_methods = $woocommerce->shipping->get_shipping_methods();
23
-
24
- foreach($methods as $k => $method){
25
-
26
- // exceptions
27
- if(
28
- isset($shipping_methods[$method->id]) &&
29
- isset($shipping_methods[$method->id]->settings['type']) &&
30
- $shipping_methods[$method->id]->settings['type'] == 'percent'
31
- || preg_match('/^table_rate-[0-9]+ : [0-9]+$/', $k)
32
- ){
33
- continue;
34
- }
35
-
36
-
37
- foreach($method->taxes as $j => $tax){
38
-
39
- $methods[$k]->taxes[$j] = apply_filters('wcml_shipping_price_amount', $methods[$k]->taxes[$j]);
40
-
41
- }
42
-
43
- }
44
-
45
- return $methods;
46
- }
47
-
48
- // Before WooCommerce 2.6
49
- public function adjust_min_amount_required($options){
50
-
51
- if( !empty( $options['min_amount'] ) ){
52
- $options['min_amount'] = apply_filters( 'wcml_shipping_free_min_amount', $options['min_amount'] );
53
- }
54
-
55
- return $options;
56
- }
57
-
58
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
inc/currencies/class-wcml-multi-currency-shipping.php CHANGED
@@ -19,15 +19,10 @@ class WCML_Multi_Currency_Shipping{
19
  public function add_hooks(){
20
 
21
  // shipping method cost settings
22
- if( $this->sitepress->get_wp_api()->version_compare( $this->sitepress->get_wp_api()->constant( 'WC_VERSION' ), '2.6.0', '>=' ) ) {
23
- $rates = $this->wpdb->get_results( "SELECT * FROM {$this->wpdb->prefix}woocommerce_shipping_zone_methods WHERE method_id IN('flat_rate', 'local_pickup', 'free_shipping')" );
24
- foreach ( $rates as $method ) {
25
- $option_name = sprintf( 'woocommerce_%s_%d_settings', $method->method_id, $method->instance_id );
26
- add_filter( 'option_' . $option_name, array($this, 'convert_shipping_method_cost_settings') );
27
- }
28
- }else{
29
- // Before WooCommerce 2.6
30
- new WCML_Multi_Currency_Shipping_Legacy();
31
  }
32
 
33
  // Used for table rate shipping compatibility class
19
  public function add_hooks(){
20
 
21
  // shipping method cost settings
22
+ $rates = $this->wpdb->get_results( "SELECT * FROM {$this->wpdb->prefix}woocommerce_shipping_zone_methods WHERE method_id IN('flat_rate', 'local_pickup', 'free_shipping')" );
23
+ foreach ( $rates as $method ) {
24
+ $option_name = sprintf( 'woocommerce_%s_%d_settings', $method->method_id, $method->instance_id );
25
+ add_filter( 'option_' . $option_name, array($this, 'convert_shipping_method_cost_settings') );
 
 
 
 
 
26
  }
27
 
28
  // Used for table rate shipping compatibility class
inc/currencies/class-wcml-multi-currency.php CHANGED
@@ -75,6 +75,11 @@ class WCML_Multi_Currency{
75
  */
76
  public $exchange_rate_services;
77
 
 
 
 
 
 
78
  /**
79
  * @var bool
80
  */
@@ -122,12 +127,14 @@ class WCML_Multi_Currency{
122
  $this->currency_switcher->add_hooks();
123
  $this->currency_switcher_ajax = new WCML_Currency_Switcher_Ajax( $woocommerce_wpml );
124
 
125
- $this->exchange_rate_services = new WCML_Exchange_Rates( $this->woocommerce_wpml, $wp_locale );
126
  $this->exchange_rate_services->initialize_settings();
127
  $this->exchange_rate_services->add_actions();
128
  $this->exchange_rate_services->add_service( 'fixerio', new WCML_Exchange_Rates_Fixerio() );
129
  $this->exchange_rate_services->add_service( 'currencylayer', new WCML_Exchange_Rates_Currencylayer() );
130
 
 
 
131
 
132
  if( defined('W3TC') ){
133
  $this->W3TC = new WCML_W3TC_Multi_Currency();
@@ -389,7 +396,7 @@ class WCML_Multi_Currency{
389
  $original_product_language = $this->woocommerce_wpml->products->get_original_product_language( $current_product_id );
390
  $default = false;
391
 
392
- if( WooCommerce_Functions_Wrapper::get_product_type ($current_product_id ) === 'variable' ){
393
  foreach( $product_obj->get_children() as $child ){
394
  if( !get_post_meta( apply_filters( 'translate_object_id', $child , get_post_type( $child ), true, $original_product_language ), '_wcml_custom_prices_status', true ) ){
395
  $default = true;
75
  */
76
  public $exchange_rate_services;
77
 
78
+ /**
79
+ * @var WCML_Currencies_Payment_Gateways
80
+ */
81
+ public $currencies_payment_gateways;
82
+
83
  /**
84
  * @var bool
85
  */
127
  $this->currency_switcher->add_hooks();
128
  $this->currency_switcher_ajax = new WCML_Currency_Switcher_Ajax( $woocommerce_wpml );
129
 
130
+ $this->exchange_rate_services = new WCML_Exchange_Rates( $this->woocommerce_wpml, $wp_locale );
131
  $this->exchange_rate_services->initialize_settings();
132
  $this->exchange_rate_services->add_actions();
133
  $this->exchange_rate_services->add_service( 'fixerio', new WCML_Exchange_Rates_Fixerio() );
134
  $this->exchange_rate_services->add_service( 'currencylayer', new WCML_Exchange_Rates_Currencylayer() );
135
 
136
+ $this->currencies_payment_gateways = new WCML_Currencies_Payment_Gateways( $this->woocommerce_wpml, $sitepress->get_wp_api() );
137
+ $this->currencies_payment_gateways->add_hooks();
138
 
139
  if( defined('W3TC') ){
140
  $this->W3TC = new WCML_W3TC_Multi_Currency();
396
  $original_product_language = $this->woocommerce_wpml->products->get_original_product_language( $current_product_id );
397
  $default = false;
398
 
399
+ if( $product_obj->get_type() === 'variable' ){
400
  foreach( $product_obj->get_children() as $child ){
401
  if( !get_post_meta( apply_filters( 'translate_object_id', $child , get_post_type( $child ), true, $original_product_language ), '_wcml_custom_prices_status', true ) ){
402
  $default = true;
inc/currencies/currency-switcher/class-wcml-currency-switcher-templates.php CHANGED
@@ -417,7 +417,7 @@ class WCML_Currency_Switcher_Templates {
417
  $this->enqueued_templates[] = $slug;
418
 
419
  foreach ( $template->get_scripts() as $k => $url ) {
420
- wp_enqueue_script( $template->get_resource_handler( $k ), $url, array(), WCML_VERSION );
421
  }
422
 
423
  foreach ( $template->get_styles() as $k => $url ) {
417
  $this->enqueued_templates[] = $slug;
418
 
419
  foreach ( $template->get_scripts() as $k => $url ) {
420
+ wp_enqueue_script( $template->get_resource_handler( $k ), $url, array(), WCML_VERSION, true );
421
  }
422
 
423
  foreach ( $template->get_styles() as $k => $url ) {
inc/template-classes/class-wcml-currencies-dropdown-ui.php ADDED
@@ -0,0 +1,29 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class WCML_Currencies_Dropdown_UI {
4
+
5
+ private $template_loader;
6
+ private $template;
7
+
8
+ function __construct( WPML_Twig_Template_Loader $template_loader ) {
9
+ $this->template_loader = $template_loader;
10
+ }
11
+
12
+ public function get( $active_currencies, $selected_currency ) {
13
+ $model = array(
14
+ 'active_currencies' => $active_currencies,
15
+ 'selected_currency' => $selected_currency,
16
+ );
17
+
18
+ return $this->get_template()->show( $model, 'currencies-dropdown.twig' );
19
+ }
20
+
21
+ private function get_template() {
22
+ if ( null === $this->template ) {
23
+ $this->template = $this->template_loader->get_template();
24
+ }
25
+
26
+ return $this->template;
27
+ }
28
+
29
+ }
inc/template-classes/class-wcml-plugins-wrap.php CHANGED
@@ -25,32 +25,29 @@ class WCML_Plugins_Wrap {
25
 
26
  $model = array(
27
  'link_url' => admin_url('admin.php?page=wpml-wcml'),
28
- 'old_wpml' => defined('ICL_SITEPRESS_VERSION') && version_compare( ICL_SITEPRESS_VERSION, '3.4', '<' ),
29
  'tracking_link' => $this->tracking_link->generate( 'https://wpml.org/shop/account/', false, 'account' ),
30
  'install_wpml_link' => $this->woocommerce_wpml->dependencies->required_plugin_install_link( 'wpml' ),
31
  'icl_version' => defined('ICL_SITEPRESS_VERSION'),
32
  'icl_setup' => $this->sitepress ? $this->sitepress->setup() : false,
33
- 'media_version' => defined( 'WPML_MEDIA_VERSION' ),
34
  'tm_version' => defined( 'WPML_TM_VERSION' ),
35
  'st_version' => defined( 'WPML_ST_VERSION' ),
36
  'wc' => class_exists('WooCommerce') ,
37
- 'old_wc' => class_exists('WooCommerce') && version_compare( WC_VERSION, '2.0', '<'),
38
  'wc_link' => 'http://wordpress.org/extend/plugins/woocommerce/',
39
  'strings' => array(
40
  'title' => __('WooCommerce Multilingual', 'woocommerce-multilingual'),
41
  'required'=> __('Required plugins', 'woocommerce-multilingual'),
42
  'plugins'=> __('Plugins Status', 'woocommerce-multilingual'),
43
  'depends'=> __('WooCommerce Multilingual depends on several plugins to work. If any required plugin is missing, you should install and activate it.', 'woocommerce-multilingual'),
44
- 'old_wpml_link'=> sprintf( __( 'WooCommerce Multilingual is enabled but not effective. It is not compatible with <a href="%s">WPML</a> versions prior 2.0.5.', 'woocommerce-multilingual' ), $this->tracking_link->generate( 'https://wpml.org/' ) ),
45
  'update_wpml'=> __( 'Update WPML', 'woocommerce-multilingual' ),
46
  'upgrade_wpml'=> __( 'Upgrade WPML', 'woocommerce-multilingual' ),
47
  'get_wpml'=> __( 'Get WPML', 'woocommerce-multilingual' ),
48
- 'get_wpml_media'=> __( 'Get WPML Media', 'woocommerce-multilingual' ),
49
  'get_wpml_tm'=> __( 'Get WPML Translation Management', 'woocommerce-multilingual' ),
50
  'get_wpml_st'=> __( 'Get WPML String Translation', 'woocommerce-multilingual' ),
51
  'new_design_wpml_link'=> sprintf( __( 'You are using WooCommerce Multilingual %s. This version includes an important UI redesign for the configuration screens and it requires <a href="%s">WPML %s</a> or higher. Everything still works on the front end now but, in order to configure options for WooCommerce Multilingual, you need to upgrade WPML.', 'woocommerce-multilingual' ), WCML_VERSION, $this->tracking_link->generate( 'https://wpml.org/' ), '3.4' ),
52
  'wpml' => '<strong>WPML</strong>',
53
- 'media' => '<strong>WPML Media</strong>',
54
  'tm' => '<strong>WPML Translation Management</strong>',
55
  'st' => '<strong>WPML String Translation</strong>',
56
  'wc' => '<strong>WooCommerce</strong>',
@@ -59,7 +56,7 @@ class WCML_Plugins_Wrap {
59
  'not_setup' => __( '%s is not set up.', 'woocommerce-multilingual' ),
60
  'not_inst' => __( '%s is either not installed or not active.', 'woocommerce-multilingual' ),
61
  'wpml_not_inst' => sprintf( __( '%s is either not installed or not active.', 'woocommerce-multilingual' ),'<strong><a title="' . esc_attr__('The WordPress Multilingual Plugin', 'woocommerce-multilingual') .'" href="' . $this->tracking_link->generate( 'https://wpml.org/' ) . '">WPML</a></strong>' ),
62
- 'old_wc' => sprintf( __( '%1$s is installed, but with incorrect version. You need %1$s %2$s or higher. ', 'woocommerce-multilingual' ), '<strong>WooCommerce</strong>', '2.0' ),
63
  'download_wc' => __( 'Download WooCommerce', 'woocommerce-multilingual' ),
64
  )
65
  );
25
 
26
  $model = array(
27
  'link_url' => admin_url('admin.php?page=wpml-wcml'),
28
+ 'old_wpml' => defined('ICL_SITEPRESS_VERSION') && version_compare( ICL_SITEPRESS_VERSION, '4.0', '<' ),
29
  'tracking_link' => $this->tracking_link->generate( 'https://wpml.org/shop/account/', false, 'account' ),
30
  'install_wpml_link' => $this->woocommerce_wpml->dependencies->required_plugin_install_link( 'wpml' ),
31
  'icl_version' => defined('ICL_SITEPRESS_VERSION'),
32
  'icl_setup' => $this->sitepress ? $this->sitepress->setup() : false,
 
33
  'tm_version' => defined( 'WPML_TM_VERSION' ),
34
  'st_version' => defined( 'WPML_ST_VERSION' ),
35
  'wc' => class_exists('WooCommerce') ,
36
+ 'old_wc' => class_exists('WooCommerce') && version_compare( WC_VERSION, '3.3.0', '<'),
37
  'wc_link' => 'http://wordpress.org/extend/plugins/woocommerce/',
38
  'strings' => array(
39
  'title' => __('WooCommerce Multilingual', 'woocommerce-multilingual'),
40
  'required'=> __('Required plugins', 'woocommerce-multilingual'),
41
  'plugins'=> __('Plugins Status', 'woocommerce-multilingual'),
42
  'depends'=> __('WooCommerce Multilingual depends on several plugins to work. If any required plugin is missing, you should install and activate it.', 'woocommerce-multilingual'),
43
+ 'old_wpml_link'=> sprintf( __( 'WooCommerce Multilingual is enabled but not effective. It is not compatible with <a href="%s">WPML</a> versions prior 4.0', 'woocommerce-multilingual' ), $this->tracking_link->generate( 'https://wpml.org/' ) ),
44
  'update_wpml'=> __( 'Update WPML', 'woocommerce-multilingual' ),
45
  'upgrade_wpml'=> __( 'Upgrade WPML', 'woocommerce-multilingual' ),
46
  'get_wpml'=> __( 'Get WPML', 'woocommerce-multilingual' ),
 
47
  'get_wpml_tm'=> __( 'Get WPML Translation Management', 'woocommerce-multilingual' ),
48
  'get_wpml_st'=> __( 'Get WPML String Translation', 'woocommerce-multilingual' ),
49
  'new_design_wpml_link'=> sprintf( __( 'You are using WooCommerce Multilingual %s. This version includes an important UI redesign for the configuration screens and it requires <a href="%s">WPML %s</a> or higher. Everything still works on the front end now but, in order to configure options for WooCommerce Multilingual, you need to upgrade WPML.', 'woocommerce-multilingual' ), WCML_VERSION, $this->tracking_link->generate( 'https://wpml.org/' ), '3.4' ),
50
  'wpml' => '<strong>WPML</strong>',
 
51
  'tm' => '<strong>WPML Translation Management</strong>',
52
  'st' => '<strong>WPML String Translation</strong>',
53
  'wc' => '<strong>WooCommerce</strong>',
56
  'not_setup' => __( '%s is not set up.', 'woocommerce-multilingual' ),
57
  'not_inst' => __( '%s is either not installed or not active.', 'woocommerce-multilingual' ),
58
  'wpml_not_inst' => sprintf( __( '%s is either not installed or not active.', 'woocommerce-multilingual' ),'<strong><a title="' . esc_attr__('The WordPress Multilingual Plugin', 'woocommerce-multilingual') .'" href="' . $this->tracking_link->generate( 'https://wpml.org/' ) . '">WPML</a></strong>' ),
59
+ 'old_wc' => sprintf( __( '%1$s is installed, but with incorrect version. You need %1$s %2$s or higher. ', 'woocommerce-multilingual' ), '<strong>WooCommerce</strong>', '3.3.0' ),
60
  'download_wc' => __( 'Download WooCommerce', 'woocommerce-multilingual' ),
61
  )
62
  );
inc/template-classes/class-wcml-products-ui.php CHANGED
@@ -37,7 +37,6 @@ class WCML_Products_UI extends WPML_Templates_Factory {
37
  'strings' => array(
38
  'image' => __( 'Image', 'woocommerce-multilingual' ),
39
  'product' => __( 'Product', 'woocommerce-multilingual' ),
40
- 'type' => __( 'Type', 'woocommerce-multilingual' ),
41
  'date' => __( 'Date', 'woocommerce-multilingual' ),
42
  'categories' => __( 'Categories', 'woocommerce-multilingual' ),
43
  'no_products' => __( 'No products found', 'woocommerce-multilingual' ),
@@ -116,6 +115,10 @@ class WCML_Products_UI extends WPML_Templates_Factory {
116
  )
117
  );
118
 
 
 
 
 
119
  return $model;
120
  }
121
 
@@ -183,13 +186,15 @@ class WCML_Products_UI extends WPML_Templates_Factory {
183
 
184
  $products[ $key ]->categories_list = $this->get_categories_list( $product->ID, $this->get_cat_url() );
185
 
186
- $prod = wc_get_product( $product->ID );
187
- $products[ $key ]->icon_class = WooCommerce_Functions_Wrapper::get_product_type( $product->ID );
 
188
 
189
- if ( $prod->is_virtual() ) {
190
- $products[ $key ]->icon_class = 'virtual';
191
- } else if ( $prod->is_downloadable() ) {
192
- $products[ $key ]->icon_class = 'downloadable';
 
193
  }
194
 
195
  if ( $product->post_status == "publish" ) {
@@ -203,6 +208,15 @@ class WCML_Products_UI extends WPML_Templates_Factory {
203
  return array( 'products' => $products, 'products_count' => $products_info[ 'products_count' ] );
204
  }
205
 
 
 
 
 
 
 
 
 
 
206
  public function get_product_info_from_self_edit_mode(){
207
 
208
  if ( isset( $_GET[ 'prid' ] ) ) {
37
  'strings' => array(
38
  'image' => __( 'Image', 'woocommerce-multilingual' ),
39
  'product' => __( 'Product', 'woocommerce-multilingual' ),
 
40
  'date' => __( 'Date', 'woocommerce-multilingual' ),
41
  'categories' => __( 'Categories', 'woocommerce-multilingual' ),
42
  'no_products' => __( 'No products found', 'woocommerce-multilingual' ),
115
  )
116
  );
117
 
118
+ if ( $this->is_show_type_column() ) {
119
+ $model['strings']['type'] = __( 'Type', 'woocommerce-multilingual' );
120
+ }
121
+
122
  return $model;
123
  }
124
 
186
 
187
  $products[ $key ]->categories_list = $this->get_categories_list( $product->ID, $this->get_cat_url() );
188
 
189
+ if ( $this->is_show_type_column() ) {
190
+ $prod = wc_get_product( $product->ID );
191
+ $products[ $key ]->icon_class = $prod->get_type();
192
 
193
+ if ( $prod->is_virtual() ) {
194
+ $products[ $key ]->icon_class = 'virtual';
195
+ } else if ( $prod->is_downloadable() ) {
196
+ $products[ $key ]->icon_class = 'downloadable';
197
+ }
198
  }
199
 
200
  if ( $product->post_status == "publish" ) {
208
  return array( 'products' => $products, 'products_count' => $products_info[ 'products_count' ] );
209
  }
210
 
211
+ /**
212
+ * @return bool
213
+ */
214
+ private function is_show_type_column() {
215
+
216
+ return $this->sitepress->get_wp_api()->version_compare( $this->sitepress->get_wp_api()->constant( 'WC_VERSION' ), '3.4.0', '<' ) ||
217
+ apply_filters( 'wcml_show_type_column', false );
218
+ }
219
+
220
  public function get_product_info_from_self_edit_mode(){
221
 
222
  if ( isset( $_GET[ 'prid' ] ) ) {
inc/template-classes/class-wcml-troubleshooting-ui.php CHANGED
@@ -71,8 +71,12 @@ class WCML_Troubleshooting_UI extends WPML_Templates_Factory {
71
  );
72
 
73
  foreach( $all_products_taxonomies as $key => $taxonomy ){
74
- $all_products_taxonomies[ $key ]->terms_count = wp_count_terms( $key );
75
- $all_products_taxonomies[ $key ]->tax_key = $key;
 
 
 
 
76
  }
77
 
78
  return $all_products_taxonomies;
71
  );
72
 
73
  foreach( $all_products_taxonomies as $key => $taxonomy ){
74
+ if( is_taxonomy_translated( $key ) ) {
75
+ $all_products_taxonomies[ $key ]->terms_count = wp_count_terms( $key );
76
+ $all_products_taxonomies[ $key ]->tax_key = $key;
77
+ }else{
78
+ unset( $all_products_taxonomies[$key]);
79
+ }
80
  }
81
 
82
  return $all_products_taxonomies;
inc/template-classes/multi-currency/class-wcml-custom-currency-options.php CHANGED
@@ -35,6 +35,8 @@ class WCML_Custom_Currency_Options extends WPML_Templates_Factory {
35
  $exchange_rates_service = '';
36
  }
37
 
 
 
38
  $model = array(
39
 
40
  'args' => $this->args,
@@ -92,25 +94,34 @@ class WCML_Custom_Currency_Options extends WPML_Templates_Factory {
92
  'label' => __( 'Autosubtract amount', 'woocommerce-multilingual' ),
93
  'only_numeric' => __( 'Only numeric', 'woocommerce-multilingual' )
94
  ),
95
-
 
 
 
 
 
96
  'number_error' => __( 'Please enter a valid number', 'woocommerce-multilingual' ),
97
  'cancel' => __( 'Cancel', 'woocommerce-multilingual' ),
98
  'save' => __( 'Save', 'woocommerce-multilingual' )
99
-
100
-
101
  ),
102
 
103
- 'automatic_rates' => $exchange_rates_automatic,
104
- 'automatic_rates_tip' => sprintf( __('Exchange rate updated automatically from %s', 'woocommerce-multilingual' ), $exchange_rates_service ),
105
- 'current_currency' => $current_currency
106
-
107
-
 
108
  );
109
 
110
  return $model;
111
  }
112
 
 
 
 
 
113
  public function render(){
 
114
  echo $this->get_view();
115
  }
116
 
35
  $exchange_rates_service = '';
36
  }
37
 
38
+ $tracking_link = new WCML_Tracking_Link();
39
+
40
  $model = array(
41
 
42
  'args' => $this->args,
94
  'label' => __( 'Autosubtract amount', 'woocommerce-multilingual' ),
95
  'only_numeric' => __( 'Only numeric', 'woocommerce-multilingual' )
96
  ),
97
+ 'payment_gateways' => array(
98
+ 'label' => __( 'Payment Gateways', 'woocommerce-multilingual' ),
99
+ 'settings_label' => sprintf( __( 'Custom settings for %s', 'woocommerce-multilingual' ), $current_currency ),
100
+ 'learn_url' => $tracking_link->generate( 'https://wpml.org/?page_id=290080#payment-gateways-settings', 'payment-gateways-settings', 'documentation' ),
101
+ 'learn_txt' => __( 'Learn more', 'woocommerce-multilingual' ),
102
+ ),
103
  'number_error' => __( 'Please enter a valid number', 'woocommerce-multilingual' ),
104
  'cancel' => __( 'Cancel', 'woocommerce-multilingual' ),
105
  'save' => __( 'Save', 'woocommerce-multilingual' )
 
 
106
  ),
107
 
108
+ 'automatic_rates' => $exchange_rates_automatic,
109
+ 'automatic_rates_tip' => sprintf( __( 'Exchange rate updated automatically from %s', 'woocommerce-multilingual' ), $exchange_rates_service ),
110
+ 'current_currency' => $current_currency,
111
+ 'active_currencies' => $this->woocommerce_wpml->multi_currency->get_currencies( true ),
112
+ 'payment_gateways_enabled' => $this->woocommerce_wpml->multi_currency->currencies_payment_gateways->is_enabled( $current_currency ),
113
+ 'payment_gateways' => $this->woocommerce_wpml->multi_currency->currencies_payment_gateways->get_gateways()
114
  );
115
 
116
  return $model;
117
  }
118
 
119
+ public function enqueue_resources(){
120
+ wp_enqueue_style( 'otgsSwitcher' );
121
+ }
122
+
123
  public function render(){
124
+ $this->enqueue_resources();
125
  echo $this->get_view();
126
  }
127
 
inc/template-classes/multi-currency/class-wcml-multi-currency-ui.php CHANGED
@@ -62,27 +62,27 @@ class WCML_Multi_Currency_UI extends WPML_Templates_Factory {
62
  $exchange_rates_ui = new WCML_Exchange_Rates_UI( $this->woocommerce_wpml );
63
 
64
  $model = array(
65
- 'strings' => array(
66
- 'headers' => array(
67
- 'enable_disable' => __( 'Enable/disable', 'woocommerce-multilingual' ),
68
- 'currencies' => __( 'Currencies', 'woocommerce-multilingual' ),
69
- ),
70
- 'add_currency_button' => __( 'Add currency', 'woocommerce-multilingual' ),
71
- 'currencies_table' => array(
72
- 'head_currency' => __('Currency', 'woocommerce-multilingual'),
73
- 'head_rate' => __('Rate', 'woocommerce-multilingual'),
74
- 'default' => __( 'default', 'woocommerce-multilingual' ),
75
- 'edit' => __( 'Edit', 'woocommerce-multilingual' ),
76
- 'default_currency' => __( 'Default currency', 'woocommerce-multilingual' ),
77
- 'default_cur_tip' => __( 'Switch to this currency when switching language in the front-end', 'woocommerce-multilingual' ),
78
- 'keep_currency' => __( 'Keep', 'woocommerce-multilingual' ),
79
- 'delete' => __( 'Delete', 'woocommerce-multilingual' ),
80
- 'help_title' => __( 'Currencies to display for each language', 'woocommerce-multilingual' ),
81
- 'enable_for' => __('Enable %s for %s', 'woocommerce-multilingual'),
82
- 'disable_for' => __('Disable %s for %s', 'woocommerce-multilingual')
83
- )
84
-
85
- ),
86
  'currencies' => $this->currencies,
87
  'currencies_positions' => $currencies_positions,
88
  'wc_currency' => $this->wc_currency,
@@ -265,11 +265,11 @@ class WCML_Multi_Currency_UI extends WPML_Templates_Factory {
265
  $args['currency_name'] = $args['wc_currencies'][$args['currency_code']];
266
  $args['currency_symbol'] = get_woocommerce_currency_symbol( $args['currency_code'] );
267
  $args['currency'] = $currency;
268
- $args['title'] = sprintf( __( 'Update settings for %s', 'woocommerce-multilingual' ), $args['currency_name'] . ' (' . $args['currency_symbol'] . ')' );
269
 
270
  $args['current_currency'] = $args['currency_code'];
271
 
272
- new WCML_Custom_Currency_Options($args, $this->woocommerce_wpml);
273
 
274
  }
275
 
62
  $exchange_rates_ui = new WCML_Exchange_Rates_UI( $this->woocommerce_wpml );
63
 
64
  $model = array(
65
+ 'strings' => array(
66
+ 'headers' => array(
67
+ 'enable_disable' => __( 'Enable/disable', 'woocommerce-multilingual' ),
68
+ 'currencies' => __( 'Currencies', 'woocommerce-multilingual' ),
69
+ ),
70
+ 'add_currency_button' => __( 'Add currency', 'woocommerce-multilingual' ),
71
+ 'currencies_table' => array(
72
+ 'head_currency' => __( 'Currency', 'woocommerce-multilingual' ),
73
+ 'head_rate' => __( 'Rate', 'woocommerce-multilingual' ),
74
+ 'default' => __( 'default', 'woocommerce-multilingual' ),
75
+ 'edit' => __( 'Edit', 'woocommerce-multilingual' ),
76
+ 'default_currency' => __( 'Default currency', 'woocommerce-multilingual' ),
77
+ 'default_cur_tip' => __( 'Switch to this currency when switching language in the front-end', 'woocommerce-multilingual' ),
78
+ 'keep_currency' => __( 'Keep', 'woocommerce-multilingual' ),
79
+ 'delete' => __( 'Delete', 'woocommerce-multilingual' ),
80
+ 'help_title' => __( 'Currencies to display for each language', 'woocommerce-multilingual' ),
81
+ 'enable_for' => __( 'Enable %s for %s', 'woocommerce-multilingual' ),
82
+ 'disable_for' => __( 'Disable %s for %s', 'woocommerce-multilingual' )
83
+ ),
84
+ 'settings' => __( 'Settings', 'woocommerce-multilingual' )
85
+ ),
86
  'currencies' => $this->currencies,
87
  'currencies_positions' => $currencies_positions,
88
  'wc_currency' => $this->wc_currency,
265
  $args['currency_name'] = $args['wc_currencies'][$args['currency_code']];
266
  $args['currency_symbol'] = get_woocommerce_currency_symbol( $args['currency_code'] );
267
  $args['currency'] = $currency;
268
+ $args['title'] = sprintf( __( 'Currency settings for %s', 'woocommerce-multilingual' ), $args['currency_name'] . ' (' . $args['currency_symbol'] . ')' );
269
 
270
  $args['current_currency'] = $args['currency_code'];
271
 
272
+ new WCML_Custom_Currency_Options( $args, $this->woocommerce_wpml );
273
 
274
  }
275
 
inc/template-classes/status/class-wcml-status-config-warnings-ui.php CHANGED
@@ -59,36 +59,28 @@ class WCML_Status_Config_Warnings_UI extends WPML_Templates_Factory {
59
  $miss_slug_lang = array();
60
 
61
  if ( ! empty( $slug_settings['on'] ) ) {
62
- $slug = $this->woocommerce_wpml->strings->product_permalink_slug();
63
-
64
- if (has_filter('wpml_slug_translation_available')) {
65
-
66
- if (version_compare(WPML_ST_VERSION, '2.2.6', '>')) {
67
- $slug_translation_languages = apply_filters('wpml_get_slug_translation_languages', array(), 'product');
68
-
69
-
70
- } else {
71
- $slug_translation_languages = apply_filters('wpml_get_slug_translation_languages', array(), $slug);
72
- }
73
-
74
- } else {
75
- $string_id = icl_get_string_id($slug, $this->woocommerce_wpml->url_translation->url_strings_context(), $this->woocommerce_wpml->url_translation->url_string_name('product'));
76
- $slug_translations = icl_get_string_translations_by_id($string_id);
77
- }
78
-
79
-
80
- $string_language = $this->woocommerce_wpml->strings->get_string_language($slug, $this->woocommerce_wpml->url_translation->url_strings_context(), $this->woocommerce_wpml->url_translation->url_string_name('product'));
81
-
82
- foreach ($this->sitepress->get_active_languages() as $lang_info) {
83
- if (
84
- (
85
- (isset($slug_translations) && !array_key_exists($lang_info['code'], $slug_translations)) ||
86
- (isset($slug_translation_languages) && !in_array($lang_info['code'], $slug_translation_languages))
87
- ) && $lang_info['code'] != $string_language
88
- ) {
89
- $miss_slug_lang[] = $lang_info;
90
- }
91
- }
92
  }
93
 
94
  return $miss_slug_lang;
59
  $miss_slug_lang = array();
60
 
61
  if ( ! empty( $slug_settings['on'] ) ) {
62
+ $slug = $this->woocommerce_wpml->strings->product_permalink_slug();
63
+
64
+ if ( has_filter( 'wpml_slug_translation_available' ) ) {
65
+ $slug_translation_languages = apply_filters( 'wpml_get_slug_translation_languages', array(), 'product' );
66
+ } else {
67
+ $string_id = icl_get_string_id( $slug, $this->woocommerce_wpml->url_translation->url_strings_context(), $this->woocommerce_wpml->url_translation->url_string_name( 'product' ) );
68
+ $slug_translations = icl_get_string_translations_by_id( $string_id );
69
+ }
70
+
71
+
72
+ $string_language = $this->woocommerce_wpml->strings->get_string_language( $slug, $this->woocommerce_wpml->url_translation->url_strings_context(), $this->woocommerce_wpml->url_translation->url_string_name( 'product' ) );
73
+
74
+ foreach ( $this->sitepress->get_active_languages() as $lang_info ) {
75
+ if (
76
+ (
77
+ ( isset( $slug_translations ) && ! array_key_exists( $lang_info['code'], $slug_translations ) ) ||
78
+ ( isset( $slug_translation_languages ) && ! in_array( $lang_info['code'], $slug_translation_languages ) )
79
+ ) && $lang_info['code'] != $string_language
80
+ ) {
81
+ $miss_slug_lang[] = $lang_info;
82
+ }
83
+ }
 
 
 
 
 
 
 
 
84
  }
85
 
86
  return $miss_slug_lang;
inc/template-classes/store-urls/class-wcml-store-urls-edit-base-ui.php CHANGED
@@ -52,7 +52,7 @@ class WCML_Store_URLs_Edit_Base_UI extends WPML_Templates_Factory {
52
  $args = array();
53
 
54
  if( $this->base == 'shop' ){
55
- $original_shop_id = get_option('woocommerce_shop_page_id' );
56
  $translated_base = apply_filters( 'translate_object_id',$original_shop_id , 'page', false, $this->language );
57
  if( !is_null($translated_base)){
58
  $args['translated_base_value'] = urldecode(get_post($translated_base)->post_name);
52
  $args = array();
53
 
54
  if( $this->base == 'shop' ){
55
+ $original_shop_id = wc_get_page_id( 'shop' );
56
  $translated_base = apply_filters( 'translate_object_id',$original_shop_id , 'page', false, $this->language );
57
  if( !is_null($translated_base)){
58
  $args['translated_base_value'] = urldecode(get_post($translated_base)->post_name);
inc/template-classes/store-urls/class-wcml-store-urls-translation-statuses-ui.php CHANGED
@@ -60,7 +60,7 @@ class WCML_Store_URLs_Translation_Statuses_UI extends WPML_Templates_Factory {
60
  foreach( $languages as $key => $language ){
61
 
62
  if( $this->base == 'shop' ){
63
- $translated_base = apply_filters( 'translate_object_id', get_option('woocommerce_shop_page_id' ), 'page', false, $language['code'] );
64
 
65
  }else{
66
  $translated_base_info = $this->woocommerce_wpml->url_translation->get_base_translation( $this->base,$language['code'] );
60
  foreach( $languages as $key => $language ){
61
 
62
  if( $this->base == 'shop' ){
63
+ $translated_base = apply_filters( 'translate_object_id', wc_get_page_id( 'shop' ), 'page', false, $language['code'] );
64
 
65
  }else{
66
  $translated_base_info = $this->woocommerce_wpml->url_translation->get_base_translation( $this->base,$language['code'] );
inc/template-classes/store-urls/class-wcml-store-urls-ui.php CHANGED
@@ -25,7 +25,7 @@ class WCML_Store_URLs_UI extends WPML_Templates_Factory {
25
  ),
26
  'shop_base' => array(
27
  'flag' => $this->sitepress->get_flag_url( $this->woocommerce_wpml->url_translation->get_source_slug_language( 'shop' ) ),
28
- 'orig_value' => get_post( get_option('woocommerce_shop_page_id' ) )->post_name,
29
  'statuses' => $this->get_base_translations_statuses( 'shop', $this->active_languages ),
30
  ),
31
  'product_base' => array(
@@ -82,6 +82,9 @@ class WCML_Store_URLs_UI extends WPML_Templates_Factory {
82
 
83
  $endpoints_info = array();
84
  foreach( WC()->query->query_vars as $key => $endpoint ){
 
 
 
85
 
86
  $endpoints_info[ $key ][ 'key' ] = $key;
87
  $endpoints_info[ $key ][ 'orig_value' ] = $endpoint;
25
  ),
26
  'shop_base' => array(
27
  'flag' => $this->sitepress->get_flag_url( $this->woocommerce_wpml->url_translation->get_source_slug_language( 'shop' ) ),
28
+ 'orig_value' => get_post( wc_get_page_id( 'shop' ) )->post_name,
29
  'statuses' => $this->get_base_translations_statuses( 'shop', $this->active_languages ),
30
  ),
31
  'product_base' => array(
82
 
83
  $endpoints_info = array();
84
  foreach( WC()->query->query_vars as $key => $endpoint ){
85
+ if ( class_exists( 'WPML_Endpoints_Support' ) ) {
86
+ $key = $endpoint;
87
+ }
88
 
89
  $endpoints_info[ $key ][ 'key' ] = $key;
90
  $endpoints_info[ $key ][ 'orig_value' ] = $endpoint;
inc/translation-editor/class-wcml-downloadable-products.php CHANGED
@@ -69,7 +69,7 @@ class WCML_Downloadable_Products{
69
  $wcml_js_min = $this->sitepress->get_wp_api()->constant( 'WCML_JS_MIN' );
70
 
71
  wp_register_style( 'wpml-wcml-files', $wcml_plugin_url . '/res/css/wcml-files.css', null, $wcml_version );
72
- wp_register_script( 'wcml-scripts-files', $wcml_plugin_url . '/res/js/files' . $wcml_js_min . '.js', array( 'jquery' ), $wcml_version );
73
 
74
  wp_enqueue_style('wpml-wcml-files');
75
  wp_enqueue_script('wcml-scripts-files');
@@ -125,4 +125,4 @@ class WCML_Downloadable_Products{
125
 
126
  return $files_data;
127
  }
128
- }
69
  $wcml_js_min = $this->sitepress->get_wp_api()->constant( 'WCML_JS_MIN' );
70
 
71
  wp_register_style( 'wpml-wcml-files', $wcml_plugin_url . '/res/css/wcml-files.css', null, $wcml_version );
72
+ wp_register_script( 'wcml-scripts-files', $wcml_plugin_url . '/res/js/files' . $wcml_js_min . '.js', array( 'jquery' ), $wcml_version, true );
73
 
74
  wp_enqueue_style('wpml-wcml-files');
75
  wp_enqueue_script('wcml-scripts-files');
125
 
126
  return $files_data;
127
  }
128
+ }
inc/translation-editor/class-wcml-editor-ui-product-job.php CHANGED
@@ -40,8 +40,8 @@ class WCML_Editor_UI_Product_Job extends WPML_Editor_UI_Job {
40
  $this->job_details = $job_details;
41
  $this->product = wc_get_product( $job_details[ 'job_id' ] );
42
  $this->original_post = get_post( $job_details[ 'job_id' ] );
43
- $this->product_id = WooCommerce_Functions_Wrapper::get_product_id( $this->product );
44
- $this->product_type = WooCommerce_Functions_Wrapper::get_product_type( $this->product_id );
45
 
46
  $source_lang = $this->sitepress->get_language_for_element( $job_details[ 'job_id' ], 'post_product' );
47
  $target_lang = $job_details[ 'target'];
@@ -52,7 +52,7 @@ class WCML_Editor_UI_Product_Job extends WPML_Editor_UI_Job {
52
  $job_details[ 'job_id' ],
53
  'wc_product', __( 'Product', 'woocommerce-multilingual' ),
54
  $this->original_post->post_title,
55
- get_post_permalink( WooCommerce_Functions_Wrapper::get_product_id( $this->product ) ),
56
  $source_lang,
57
  $target_lang,
58
  $translation_complete,
@@ -144,7 +144,7 @@ class WCML_Editor_UI_Product_Job extends WPML_Editor_UI_Job {
144
  $group = new WPML_Editor_UI_Field_Group( '', true );
145
  $attribute_field = new WPML_Editor_UI_Single_Line_Field( $attr_key . '_name', __( 'Name', 'woocommerce-multilingual' ), $this->data, false );
146
  $group->add_field( $attribute_field );
147
- $attribute_field = new WPML_Editor_UI_TextArea_Field( $attr_key , __( 'Value(s)', 'woocommerce-multilingual' ), $this->data, false );
148
  $group->add_field( $attribute_field );
149
  $attributes_section->add_field( $group );
150
  }
@@ -529,11 +529,11 @@ class WCML_Editor_UI_Product_Job extends WPML_Editor_UI_Job {
529
  if( $custom_fields ){
530
  foreach( $custom_fields as $custom_field ) {
531
  $orig_custom_field_values = get_post_meta( $element_id, $custom_field );
532
- $translated_custom_field_values = array();
533
  $trnsl_mid_ids = array();
534
 
535
  if ( $translation_id ) {
536
- $translated_custom_field_values = get_post_meta( $translation_id, $custom_field );
537
  $trnsl_mid_ids = $this->woocommerce_wpml->products->get_mid_ids_by_key( $translation_id, $custom_field );
538
  }
539
 
@@ -547,31 +547,35 @@ class WCML_Editor_UI_Product_Job extends WPML_Editor_UI_Job {
547
 
548
  if( count( $orig_custom_field_values ) == 1 ){
549
  $element_data[ $custom_field ] = array( 'original' => $orig_custom_field_value );
550
- $element_data[ $custom_field ][ 'translation' ] = ( $translation_id && isset( $translated_custom_field_values[ $val_key ] ) ) ? $translated_custom_field_values[ $val_key ] : '';
551
  }else{
552
 
553
  $custom_field_key = $custom_field.':'. ( isset( $trnsl_mid_ids[ $val_key ] ) ? $trnsl_mid_ids[ $val_key ] : 'new_'. $val_key );
554
 
555
  $element_data[ $custom_field ][ $custom_field_key ] = array( 'original' => $orig_custom_field_value );
556
- $element_data[ $custom_field ][ $custom_field_key ][ 'translation' ] = ($translation_id && isset( $translated_custom_field_values[ $val_key ] ) ) ? $translated_custom_field_values[ $val_key ] : '';
557
  }
558
 
559
  }else{
560
 
561
- $custom_fields_values = array_values( array_filter( maybe_unserialize( get_post_meta($this->product_id, $custom_field, true ) ) ) );
 
562
 
563
- if( $custom_fields_values ){
564
- if ( $translation_id ) {
565
- $translated_custom_field_values = array_values( array_filter( maybe_unserialize( get_post_meta( $translation_id, $custom_field , true ) ) ) );
566
- }
567
- foreach( $custom_fields_values as $custom_field_index => $custom_field_val ){
568
 
569
- $translated_custom_field_value = isset( $translated_custom_field_values[ $custom_field_index ] )? $translated_custom_field_values[ $custom_field_index ] : '';
 
 
570
 
571
- $element_data = $this->add_single_custom_field_content_value( $element_data, $custom_field, $custom_field_index, $custom_field_val, $translated_custom_field_value );
572
-
573
- }
574
- }
 
 
 
 
 
575
  }
576
  }
577
  }
40
  $this->job_details = $job_details;
41
  $this->product = wc_get_product( $job_details[ 'job_id' ] );
42
  $this->original_post = get_post( $job_details[ 'job_id' ] );
43
+ $this->product_id = $this->product->get_id();
44
+ $this->product_type = $this->product->get_type();
45
 
46
  $source_lang = $this->sitepress->get_language_for_element( $job_details[ 'job_id' ], 'post_product' );
47
  $target_lang = $job_details[ 'target'];
52
  $job_details[ 'job_id' ],
53
  'wc_product', __( 'Product', 'woocommerce-multilingual' ),
54
  $this->original_post->post_title,
55
+ get_post_permalink( $this->product->get_id() ),
56
  $source_lang,
57
  $target_lang,
58
  $translation_complete,
144
  $group = new WPML_Editor_UI_Field_Group( '', true );
145
  $attribute_field = new WPML_Editor_UI_Single_Line_Field( $attr_key . '_name', __( 'Name', 'woocommerce-multilingual' ), $this->data, false );
146
  $group->add_field( $attribute_field );
147
+ $attribute_field = new WPML_Editor_UI_TextArea_Field( (string)$attr_key , __( 'Value(s)', 'woocommerce-multilingual' ), $this->data, false );
148
  $group->add_field( $attribute_field );
149
  $attributes_section->add_field( $group );
150
  }
529
  if( $custom_fields ){
530
  foreach( $custom_fields as $custom_field ) {
531
  $orig_custom_field_values = get_post_meta( $element_id, $custom_field );
532
+ $translated_custom_field_value = array();
533
  $trnsl_mid_ids = array();
534
 
535
  if ( $translation_id ) {
536
+ $translated_custom_field_value = get_post_meta( $translation_id, $custom_field );
537
  $trnsl_mid_ids = $this->woocommerce_wpml->products->get_mid_ids_by_key( $translation_id, $custom_field );
538
  }
539
 
547
 
548
  if( count( $orig_custom_field_values ) == 1 ){
549
  $element_data[ $custom_field ] = array( 'original' => $orig_custom_field_value );
550
+ $element_data[ $custom_field ][ 'translation' ] = ( $translation_id && isset( $translated_custom_field_value[ $val_key ] ) ) ? $translated_custom_field_value[ $val_key ] : '';
551
  }else{
552
 
553
  $custom_field_key = $custom_field.':'. ( isset( $trnsl_mid_ids[ $val_key ] ) ? $trnsl_mid_ids[ $val_key ] : 'new_'. $val_key );
554
 
555
  $element_data[ $custom_field ][ $custom_field_key ] = array( 'original' => $orig_custom_field_value );
556
+ $element_data[ $custom_field ][ $custom_field_key ][ 'translation' ] = ($translation_id && isset( $translated_custom_field_value[ $val_key ] ) ) ? $translated_custom_field_value[ $val_key ] : '';
557
  }
558
 
559
  }else{
560
 
561
+ $custom_fields = maybe_unserialize( get_post_meta( $this->product_id, $custom_field, true ) );
562
+ $translated_custom_fields = array();
563
 
564
+ if ( $custom_fields ) {
 
 
 
 
565
 
566
+ if ( $translation_id ) {
567
+ $translated_custom_fields = maybe_unserialize( get_post_meta( $translation_id, $custom_field, true ) );
568
+ }
569
 
570
+ $i = 0;
571
+ foreach ( $custom_fields as $key => $field_value ) {
572
+ if ( ! empty( $field_value ) ) {
573
+ $translated_custom_field_value = isset( $translated_custom_fields[ $key ] ) ? $translated_custom_fields[ $key ] : '';
574
+ $element_data = $this->add_single_custom_field_content_value( $element_data, $custom_field, $i, $field_value, $translated_custom_field_value );
575
+ $i ++;
576
+ }
577
+ }
578
+ }
579
  }
580
  }
581
  }
inc/translation-editor/class-wcml-synchronize-product-data.php CHANGED
@@ -10,6 +10,8 @@ class WCML_Synchronize_Product_Data{
10
  * @var SitePress
11
  */
12
  private $sitepress;
 
 
13
  /** @var wpdb */
14
  private $wpdb;
15
 
@@ -19,13 +21,15 @@ class WCML_Synchronize_Product_Data{
19
  *
20
  * @param woocommerce_wpml $woocommerce_wpml
21
  * @param SitePress $sitepress
 
22
  * @param wpdb $wpdb
23
  */
24
- public function __construct( woocommerce_wpml $woocommerce_wpml, SitePress $sitepress, wpdb $wpdb ) {
25
- $this->woocommerce_wpml = $woocommerce_wpml;
26
- $this->sitepress = $sitepress;
27
- $this->wpdb = $wpdb;
28
- }
 
29
 
30
  public function add_hooks(){
31
  if( is_admin() ){
@@ -43,12 +47,13 @@ class WCML_Synchronize_Product_Data{
43
  add_action( 'wpml_translation_update', array( $this, 'icl_connect_translations_action' ) );
44
 
45
  add_action( 'deleted_term_relationships', array( $this, 'delete_term_relationships_update_term_count' ), 10, 2 );
46
-
47
- add_action( 'woocommerce_product_set_visibility', array( $this, 'sync_product_translations_visibility' ) );
48
  }
49
 
50
- add_action( 'woocommerce_reduce_order_stock', array( $this, 'sync_product_stocks_reduce' ) );
51
- add_action( 'woocommerce_restore_order_stock', array( $this, 'sync_product_stocks_restore' ) );
 
 
 
52
 
53
  add_action( 'woocommerce_product_set_stock_status', array($this, 'sync_stock_status_for_translations' ), 100, 2);
54
  add_action( 'woocommerce_variation_set_stock_status', array($this, 'sync_stock_status_for_translations' ), 10, 2);
@@ -112,13 +117,10 @@ class WCML_Synchronize_Product_Data{
112
  $this->woocommerce_wpml->products->update_order_for_product_translations( $original_product_id );
113
 
114
  // pick posts to sync
115
- $trid = $this->sitepress->get_element_trid( $original_product_id, 'post_product' );
116
- $translations = $this->sitepress->get_element_translations( $trid, 'post_product', false, true );
117
 
118
  foreach( $translations as $translation ) {
119
- if ( !$translation->original ) {
120
- $this->sync_product_data( $original_product_id, $translation->element_id, $translation->language_code );
121
- }
122
  }
123
 
124
  //save custom options for variations
@@ -162,44 +164,51 @@ class WCML_Synchronize_Product_Data{
162
  wc_delete_product_transients( $tr_product_id );
163
  }
164
 
165
- public function sync_product_taxonomies( $original_product_id, $tr_product_id, $lang ){
166
- $taxonomies = get_object_taxonomies( 'product' );
167
- remove_filter( 'terms_clauses', array( $this->sitepress, 'terms_clauses' ), 10, 4 );
168
- foreach( $taxonomies as $taxonomy ) {
169
-
170
- $terms = wp_get_object_terms( $original_product_id, $taxonomy );
171
- $tt_ids = array();
172
- $tt_names = array();
173
- if ($terms) {
174
- foreach ($terms as $term) {
175
- if ( in_array( $term->taxonomy, array( 'product_type', 'product_visibility' ) ) ) {
176
- $tt_names[] = $term->name;
177
- continue;
178
- }
179
- $tt_ids[] = $term->term_id;
180
- }
 
 
 
 
 
 
 
181
 
182
- if ( ! $this->woocommerce_wpml->terms->is_translatable_wc_taxonomy( $taxonomy ) ) {
183
- wp_set_post_terms( $tr_product_id, $tt_names, $taxonomy );
184
- }else{
185
- $this->wcml_update_term_count_by_ids( $tt_ids, $lang, $taxonomy, $tr_product_id );
186
- }
187
- }
188
- }
189
- add_filter( 'terms_clauses', array( $this->sitepress, 'terms_clauses' ), 10, 4 );
190
- }
 
 
191
 
192
  public function delete_term_relationships_update_term_count( $object_id, $tt_ids ){
193
 
194
  if( get_post_type( $object_id ) == 'product' ){
195
 
196
- $language_details = $this->sitepress->get_element_language_details( $object_id, 'post_product' );
197
- $translations = $this->sitepress->get_element_translations( $language_details->trid, 'post_product', false, true );
198
 
199
  foreach( $translations as $translation ) {
200
- if ( !$translation->original ) {
201
- $this->wcml_update_term_count_by_ids( $tt_ids, $translation->language_code );
202
- }
203
  }
204
  }
205
 
@@ -290,102 +299,71 @@ class WCML_Synchronize_Product_Data{
290
 
291
  }
292
 
293
- public function sync_product_stocks_reduce( $order ){
294
- return $this->sync_product_stocks( $order, 'reduce' );
295
- }
296
-
297
- public function sync_product_stocks_restore( $order ){
298
- return $this->sync_product_stocks( $order, 'restore' );
299
- }
300
-
301
- /**
302
- * @param $order WC_Order
303
- * @param $action
304
- */
305
- public function sync_product_stocks( $order, $action ){
306
-
307
- foreach( $order->get_items() as $item ) {
308
-
309
- if( $item instanceof WC_Order_Item_Product ){
310
-
311
- $variation_id = $item->get_variation_id();
312
- $product_id = $item->get_product_id();
313
- $qty = $item->get_quantity();
314
- }else{
315
- $variation_id = isset( $item[ 'variation_id' ] ) ? $item[ 'variation_id' ] : 0;
316
- $product_id = $item[ 'product_id' ];
317
- $qty = $item[ 'qty' ];
318
- }
319
-
320
- $is_original = $this->woocommerce_wpml->products->is_original_product( $product_id );
321
 
322
- if ( $is_original && $this->sitepress->get_wp_api()->version_compare( $this->sitepress->get_wp_api()->constant( 'WC_VERSION' ), '3.0.0', '>=' ) ) {
323
- return;
324
- }
325
 
326
- $qty = apply_filters( 'wcml_order_item_quantity', $qty, $order, $item );
327
 
328
- if( $variation_id > 0 ){
329
- $trid = $this->sitepress->get_element_trid( $variation_id, 'post_product_variation' );
330
- $translations = $this->sitepress->get_element_translations( $trid, 'post_product_variation' );
331
- $ld = $this->sitepress->get_element_language_details( $variation_id, 'post_product_variation' );
332
- } else {
333
- $trid = $this->sitepress->get_element_trid( $product_id, 'post_product' );
334
- $translations = $this->sitepress->get_element_translations( $trid, 'post_product' );
335
- $ld = $this->sitepress->get_element_language_details( $product_id, 'post_product' );
336
- }
337
 
338
- // Process for non-current languages
339
- foreach( $translations as $translation ){
340
- if ( !$is_original || $ld->language_code != $translation->language_code ) {
341
-
342
- $translation_product_id = $translation->element_id;
343
- //check if product exist
344
- if ( get_post_type( $translation->element_id ) === 'product_variation' ) {
345
- if ( ! get_post( wp_get_post_parent_id( $translation->element_id ) ) ) {
346
- continue;
347
- }
348
- $translation_product_id = wp_get_post_parent_id( $translation->element_id );
349
- }
350
 
351
- $_product = wc_get_product( $translation->element_id );
 
 
 
352
 
353
- $managing_stock = $_product && $_product->exists() && $_product->managing_stock();
354
 
355
- $total_sales = get_post_meta( $translation_product_id, 'total_sales', true );
 
 
356
 
357
- if ( $action === 'reduce' ) {
358
- $total_sales += $qty;
359
 
360
- if( $managing_stock ){
361
- WooCommerce_Functions_Wrapper::reduce_stock( $translation->element_id, $qty );
362
- }
363
- } else {
364
- $total_sales -= $qty;
 
 
365
 
366
- if( $managing_stock ){
367
- WooCommerce_Functions_Wrapper::increase_stock( $translation->element_id, $qty );
368
- }
369
- }
370
 
371
- update_post_meta( $translation_product_id, 'total_sales', $total_sales );
 
 
 
 
 
 
 
 
372
 
373
- $this->wc_taxonomies_recount_after_stock_change( (int)$translation_product_id );
374
- }
375
- }
376
- }
377
- }
378
 
379
- public function sync_stock_status_for_translations( $id, $status ) {
380
 
381
- $type = get_post_type( $id );
382
- $trid = $this->sitepress->get_element_trid( $id, 'post_' . $type );
383
- $translations = $this->sitepress->get_element_translations( $trid, 'post_' . $type, true );
384
 
385
- foreach ( $translations as $translation ) {
386
- if ( $id !== (int) $translation->element_id ) {
387
- update_post_meta( $translation->element_id, '_stock_status', $status );
388
- $this->wc_taxonomies_recount_after_stock_change( (int) $translation->element_id );
389
  }
390
  }
391
  }
@@ -427,13 +405,10 @@ class WCML_Synchronize_Product_Data{
427
  public function set_schedule_for_translations( $deprecated, $post ){
428
 
429
  if( $this->woocommerce_wpml->products->is_original_product( $post->ID ) ) {
430
- $trid = $this->sitepress->get_element_trid( $post->ID, 'post_product');
431
- $translations = $this->sitepress->get_element_translations( $trid, 'post_product', true);
432
  foreach( $translations as $translation ) {
433
- if( !$translation->original ){
434
- wp_clear_scheduled_hook( 'publish_future_post', array( $translation->element_id ) );
435
- wp_schedule_single_event( strtotime( get_gmt_from_date( $post->post_date) . ' GMT' ), 'publish_future_post', array( $translation->element_id ) );
436
- }
437
  }
438
  }
439
  }
@@ -442,24 +417,12 @@ class WCML_Synchronize_Product_Data{
442
 
443
  if( get_post_type( $tr_product_id ) == 'product' ){
444
 
445
- $trid = $this->sitepress->get_element_trid( $tr_product_id, 'post_product' );
446
- $translations = $this->sitepress->get_element_translations( $trid, 'post_product' );
447
 
448
- foreach( $translations as $translation ){
449
- if( $translation->original ){
450
- $original_product_id = $translation->element_id;
451
- }
452
  }
453
-
454
- if( !isset( $original_product_id ) ){
455
- return;
456
- }
457
-
458
- $lang = $this->sitepress->get_language_for_element( $tr_product_id, 'post_product' );
459
- $this->sync_product_data( $original_product_id, $tr_product_id, $lang );
460
-
461
  }
462
-
463
  }
464
 
465
  public function icl_make_duplicate( $master_post_id, $lang, $postarr, $id ){
@@ -471,28 +434,27 @@ class WCML_Synchronize_Product_Data{
471
  }
472
  }
473
 
474
- public function woocommerce_product_quick_edit_save( $product ){
475
-
476
- $product_id = WooCommerce_Functions_Wrapper::get_product_id( $product );
477
- $is_original = $this->woocommerce_wpml->products->is_original_product( $product_id );
478
- $trid = $this->sitepress->get_element_trid( $product_id, 'post_product' );
479
-
480
- if( $trid ){
481
- $translations = $this->sitepress->get_element_translations( $trid, 'post_product' );
482
- if( $translations ){
483
- foreach( $translations as $translation ){
484
- if( $is_original ){
485
- if( !$translation->original ){
486
- $this->sync_product_data( $product_id, $translation->element_id, $translation->language_code );
487
- $this->sync_date_and_parent( $product_id, $translation->element_id, $translation->language_code );
488
- }
489
- }elseif( $translation->original ){
490
- $this->sync_product_data( $translation->element_id, $product_id, $this->sitepress->get_language_for_element( $product_id, 'post_product' ) );
491
- $this->sync_date_and_parent( $translation->element_id, $product_id, $this->sitepress->get_language_for_element( $product_id, 'post_product' ) );
492
- }
493
- }
494
- }
495
- }
496
  }
497
 
498
  //duplicate product post meta
@@ -550,9 +512,11 @@ class WCML_Synchronize_Product_Data{
550
  foreach( $post_fields as $post_field_key => $post_field ){
551
 
552
  if( 1 === preg_match( '/field-' . $custom_field . '-.*?/', $post_field_key ) ){
553
- $custom_fields = array_filter( get_post_meta( $original_product_id, $custom_field, true ) );
554
- $custom_fields_values = array_values( $custom_fields );
555
- $custom_fields_keys = array_keys( $custom_fields );
 
 
556
  foreach ( $custom_fields_values as $custom_field_index => $custom_field_value ) {
557
  $custom_fields_values =
558
  $this->get_translated_custom_field_values(
@@ -564,8 +528,9 @@ class WCML_Synchronize_Product_Data{
564
  );
565
  }
566
 
567
- $custom_fields_translated = array();
568
- foreach ( $custom_fields_values as $index => $value ) {
 
569
  $custom_fields_translated[ $custom_fields_keys[ $index ] ] = $value;
570
  }
571
 
@@ -732,28 +697,29 @@ class WCML_Synchronize_Product_Data{
732
  }
733
 
734
  public function sync_product_translations_visibility( $product_id ) {
 
 
735
 
736
- if ( $this->woocommerce_wpml->products->is_original_product( $product_id ) ) {
737
-
738
- $trid = $this->sitepress->get_element_trid( $product_id, 'post_product' );
739
- $translations = $this->sitepress->get_element_translations( $trid, 'post_product' );
740
-
741
- if ( $translations ) {
742
 
743
- $product = wc_get_product( $product_id );
744
- $terms = array();
745
  if ( $product->is_featured() ) {
746
  $terms[] = 'featured';
747
  }
 
748
 
749
- foreach ( $translations as $translation ) {
750
- if ( ! $translation->original ) {
751
- wp_set_post_terms( $translation->element_id, $terms, 'product_visibility', false );
752
- }
 
 
 
753
  }
754
  }
755
  }
756
-
757
  }
758
 
 
759
  }
10
  * @var SitePress
11
  */
12
  private $sitepress;
13
+ /** @var WPML_Post_Translation */
14
+ private $post_translations;
15
  /** @var wpdb */
16
  private $wpdb;
17
 
21
  *
22
  * @param woocommerce_wpml $woocommerce_wpml
23
  * @param SitePress $sitepress
24
+ * @param WPML_Post_Translation $post_translations
25
  * @param wpdb $wpdb
26
  */
27
+ public function __construct( woocommerce_wpml $woocommerce_wpml, SitePress $sitepress, WPML_Post_Translation $post_translations, wpdb $wpdb ) {
28
+ $this->woocommerce_wpml = $woocommerce_wpml;
29
+ $this->sitepress = $sitepress;
30
+ $this->post_translations = $post_translations;
31
+ $this->wpdb = $wpdb;
32
+ }
33
 
34
  public function add_hooks(){
35
  if( is_admin() ){
47
  add_action( 'wpml_translation_update', array( $this, 'icl_connect_translations_action' ) );
48
 
49
  add_action( 'deleted_term_relationships', array( $this, 'delete_term_relationships_update_term_count' ), 10, 2 );
 
 
50
  }
51
 
52
+ add_action( 'woocommerce_product_set_visibility', array( $this, 'sync_product_translations_visibility' ) );
53
+
54
+ add_action( 'woocommerce_product_set_stock', array( $this, 'sync_product_stock' ) );
55
+ add_action( 'woocommerce_variation_set_stock', array( $this, 'sync_product_stock' ) );
56
+ add_action( 'woocommerce_recorded_sales', array( $this, 'sync_product_total_sales' ) );
57
 
58
  add_action( 'woocommerce_product_set_stock_status', array($this, 'sync_stock_status_for_translations' ), 100, 2);
59
  add_action( 'woocommerce_variation_set_stock_status', array($this, 'sync_stock_status_for_translations' ), 10, 2);
117
  $this->woocommerce_wpml->products->update_order_for_product_translations( $original_product_id );
118
 
119
  // pick posts to sync
120
+ $translations = $this->post_translations->get_element_translations( $original_product_id, false, true );
 
121
 
122
  foreach( $translations as $translation ) {
123
+ $this->sync_product_data( $original_product_id, $translation, $this->post_translations->get_element_lang_code( $translation ) );
 
 
124
  }
125
 
126
  //save custom options for variations
164
  wc_delete_product_transients( $tr_product_id );
165
  }
166
 
167
+ public function sync_product_taxonomies( $original_product_id, $tr_product_id, $lang ) {
168
+
169
+ $taxonomies = get_object_taxonomies( 'product' );
170
+ $taxonomy_exceptions = array( 'product_type', 'product_visibility' );
171
+ $sync_taxonomies = $this->sitepress->get_setting( 'sync_post_taxonomies' );
172
+
173
+ remove_filter( 'terms_clauses', array( $this->sitepress, 'terms_clauses' ), 10 );
174
+ foreach ( $taxonomies as $taxonomy ) {
175
+ if (
176
+ $sync_taxonomies ||
177
+ in_array( $taxonomy, $taxonomy_exceptions )
178
+ ) {
179
+ $terms = wp_get_object_terms( $original_product_id, $taxonomy );
180
+ $tt_ids = array();
181
+ $tt_names = array();
182
+ if ( $terms ) {
183
+ foreach ( $terms as $term ) {
184
+ if ( in_array( $term->taxonomy, $taxonomy_exceptions ) ) {
185
+ $tt_names[] = $term->name;
186
+ continue;
187
+ }
188
+ $tt_ids[] = $term->term_id;
189
+ }
190
 
191
+ if ( ! $this->woocommerce_wpml->terms->is_translatable_wc_taxonomy( $taxonomy ) ) {
192
+ wp_set_post_terms( $tr_product_id, $tt_names, $taxonomy );
193
+ } else {
194
+ $this->wcml_update_term_count_by_ids( $tt_ids, $lang, $taxonomy, $tr_product_id );
195
+ }
196
+ }
197
+ }
198
+ }
199
+
200
+ add_filter( 'terms_clauses', array( $this->sitepress, 'terms_clauses' ), 10, 3 );
201
+ }
202
 
203
  public function delete_term_relationships_update_term_count( $object_id, $tt_ids ){
204
 
205
  if( get_post_type( $object_id ) == 'product' ){
206
 
207
+ $original_product_id = $this->post_translations->get_original_element( $object_id );
208
+ $translations = $this->post_translations->get_element_translations( $original_product_id, false, true );
209
 
210
  foreach( $translations as $translation ) {
211
+ $this->wcml_update_term_count_by_ids( $tt_ids, $this->post_translations->get_element_lang_code( $translation ) );
 
 
212
  }
213
  }
214
 
299
 
300
  }
301
 
302
+ /**
303
+ * @param $product
304
+ */
305
+ public function sync_product_stock( $product ) {
306
+ $stock = $product->get_stock_quantity();
307
+ $product_id = $product->get_id();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
308
 
309
+ remove_action( 'woocommerce_product_set_stock', array( $this, 'sync_product_stock' ) );
310
+ remove_action( 'woocommerce_variation_set_stock', array( $this, 'sync_product_stock' ) );
 
311
 
312
+ $translations = $this->post_translations->get_element_translations( $product_id );
313
 
314
+ foreach( $translations as $translation ){
315
+ if( $product_id !== $translation ){
316
+ $_product = wc_get_product( $translation );
317
+ wc_update_product_stock( $_product, $stock );
318
+ }
319
+ }
 
 
 
320
 
321
+ add_action( 'woocommerce_product_set_stock', array( $this, 'sync_product_stock' ) );
322
+ add_action( 'woocommerce_variation_set_stock', array( $this, 'sync_product_stock' ) );
323
+ }
 
 
 
 
 
 
 
 
 
324
 
325
+ /**
326
+ * @param int $order_id
327
+ */
328
+ public function sync_product_total_sales( $order_id ) {
329
 
330
+ $order = wc_get_order( $order_id );
331
 
332
+ if ( ! $order || $order->get_data_store()->get_recorded_sales( $order ) ) {
333
+ return;
334
+ }
335
 
336
+ foreach ( $order->get_items() as $item ) {
 
337
 
338
+ if ( $item instanceof WC_Order_Item_Product ) {
339
+ $product_id = $item->get_product_id();
340
+ $qty = $item->get_quantity();
341
+ } else {
342
+ $product_id = $item['product_id'];
343
+ $qty = $item['qty'];
344
+ }
345
 
346
+ $qty = apply_filters( 'wcml_order_item_quantity', $qty, $order, $item );
 
 
 
347
 
348
+ $translations = $this->post_translations->get_element_translations( $product_id );
349
+ $data_store = WC_Data_Store::load( 'product' );
350
+ foreach ( $translations as $translation ) {
351
+ if ( $product_id !== $translation ) {
352
+ $data_store->update_product_sales( $translation, absint( $qty ), 'increase' );
353
+ }
354
+ }
355
+ }
356
+ }
357
 
358
+ public function sync_stock_status_for_translations( $product_id, $status ) {
 
 
 
 
359
 
360
+ if( $this->woocommerce_wpml->products->is_original_product( $product_id ) ) {
361
 
362
+ $translations = $this->post_translations->get_element_translations( $product_id, false, true );
 
 
363
 
364
+ foreach ( $translations as $translation ) {
365
+ update_post_meta( $translation, '_stock_status', $status );
366
+ $this->wc_taxonomies_recount_after_stock_change( $translation );
 
367
  }
368
  }
369
  }
405
  public function set_schedule_for_translations( $deprecated, $post ){
406
 
407
  if( $this->woocommerce_wpml->products->is_original_product( $post->ID ) ) {
408
+ $translations = $this->post_translations->get_element_translations( $post->ID, false, true );
 
409
  foreach( $translations as $translation ) {
410
+ wp_clear_scheduled_hook( 'publish_future_post', array( $translation ) );
411
+ wp_schedule_single_event( strtotime( get_gmt_from_date( $post->post_date) . ' GMT' ), 'publish_future_post', array( $translation ) );
 
 
412
  }
413
  }
414
  }
417
 
418
  if( get_post_type( $tr_product_id ) == 'product' ){
419
 
420
+ $original_product_id = $this->post_translations->get_original_element( $tr_product_id );
 
421
 
422
+ if( $original_product_id ){
423
+ $this->sync_product_data( $original_product_id, $tr_product_id, $this->post_translations->get_element_lang_code( $tr_product_id ) );
 
 
424
  }
 
 
 
 
 
 
 
 
425
  }
 
426
  }
427
 
428
  public function icl_make_duplicate( $master_post_id, $lang, $postarr, $id ){
434
  }
435
  }
436
 
437
+ public function woocommerce_product_quick_edit_save( $product ) {
438
+
439
+ $product_id = $product->get_id();
440
+ $is_original = $this->woocommerce_wpml->products->is_original_product( $product_id );
441
+ $original_product_id = $this->woocommerce_wpml->products->get_original_product_id( $product_id );
442
+
443
+ $translations = $this->post_translations->get_element_translations( $product_id );
444
+
445
+ if ( $translations ) {
446
+ foreach ( $translations as $translation ) {
447
+ if ( $is_original && $product_id !== $translation ) {
448
+ $language_code = $this->post_translations->get_element_lang_code( $translation );
449
+ $this->sync_product_data( $product_id, $translation, $language_code );
450
+ $this->sync_date_and_parent( $product_id, $translation, $language_code );
451
+ } elseif ( $original_product_id === $translation ) {
452
+ $language_code = $this->post_translations->get_element_lang_code( $product_id );
453
+ $this->sync_product_data( $translation, $product_id, $language_code );
454
+ $this->sync_date_and_parent( $translation, $product_id, $language_code );
455
+ }
456
+ }
457
+ }
 
458
  }
459
 
460
  //duplicate product post meta
512
  foreach( $post_fields as $post_field_key => $post_field ){
513
 
514
  if( 1 === preg_match( '/field-' . $custom_field . '-.*?/', $post_field_key ) ){
515
+ $custom_fields = get_post_meta( $original_product_id, $custom_field, true );
516
+ $filtered_custom_fields = array_filter( $custom_fields );
517
+ $custom_fields_values = array_values( $filtered_custom_fields );
518
+ $custom_fields_keys = array_keys( $filtered_custom_fields );
519
+
520
  foreach ( $custom_fields_values as $custom_field_index => $custom_field_value ) {
521
  $custom_fields_values =
522
  $this->get_translated_custom_field_values(
528
  );
529
  }
530
 
531
+ $custom_fields_translated = $custom_fields;
532
+
533
+ foreach( $custom_fields_values as $index => $value ){
534
  $custom_fields_translated[ $custom_fields_keys[ $index ] ] = $value;
535
  }
536
 
697
  }
698
 
699
  public function sync_product_translations_visibility( $product_id ) {
700
+ $translations = $this->post_translations->get_element_translations( $product_id );
701
+ if ( $translations ) {
702
 
703
+ $product = wc_get_product( $product_id );
704
+ $terms = array();
 
 
 
 
705
 
706
+ if ( $this->woocommerce_wpml->products->is_original_product( $product_id ) ) {
 
707
  if ( $product->is_featured() ) {
708
  $terms[] = 'featured';
709
  }
710
+ }
711
 
712
+ if ( 'outofstock' === $product->get_stock_status() ) {
713
+ $terms[] = 'outofstock';
714
+ }
715
+
716
+ foreach ( $translations as $translation ) {
717
+ if( $product_id !== $translation ){
718
+ wp_set_post_terms( $translation, $terms, 'product_visibility', false );
719
  }
720
  }
721
  }
 
722
  }
723
 
724
+
725
  }
inc/translation-editor/class-wcml-synchronize-variations-data.php CHANGED
@@ -202,7 +202,7 @@ class WCML_Synchronize_Variations_Data{
202
 
203
  public function sync_variations_taxonomies( $original_variation_id, $tr_variation_id, $lang ){
204
 
205
- remove_filter( 'terms_clauses', array( $this->sitepress, 'terms_clauses' ), 10, 4 );
206
 
207
  if( $this->woocommerce_wpml->sync_product_data->check_if_product_fields_sync_needed( $original_variation_id, $tr_variation_id, 'taxonomies' ) ){
208
 
@@ -239,7 +239,7 @@ class WCML_Synchronize_Variations_Data{
239
  }
240
  }
241
 
242
- add_filter( 'terms_clauses', array( $this->sitepress, 'terms_clauses' ), 10, 4 );
243
  }
244
 
245
  public function duplicate_variation_data( $original_variation_id, $variation_id, $data, $lang, $trbl ){
202
 
203
  public function sync_variations_taxonomies( $original_variation_id, $tr_variation_id, $lang ){
204
 
205
+ remove_filter( 'terms_clauses', array( $this->sitepress, 'terms_clauses' ), 10 );
206
 
207
  if( $this->woocommerce_wpml->sync_product_data->check_if_product_fields_sync_needed( $original_variation_id, $tr_variation_id, 'taxonomies' ) ){
208
 
239
  }
240
  }
241
 
242
+ add_filter( 'terms_clauses', array( $this->sitepress, 'terms_clauses' ), 10, 3 );
243
  }
244
 
245
  public function duplicate_variation_data( $original_variation_id, $variation_id, $data, $lang, $trbl ){
inc/translation-editor/class-wcml-translation-editor.php CHANGED
@@ -100,7 +100,7 @@ class WCML_Translation_Editor{
100
  }
101
 
102
  $post_type = get_post_type( $post->ID );
103
- $checkout_page_id = get_option( 'woocommerce_checkout_page_id' );
104
 
105
  if ( $post_type === 'product' || is_page( $checkout_page_id ) ){
106
  $output = '';
@@ -141,7 +141,7 @@ class WCML_Translation_Editor{
141
 
142
  public function add_languages_column( $columns ){
143
 
144
- if ( array_key_exists( 'icl_translations', $columns ) || ( version_compare( WOOCOMMERCE_VERSION, '2.3', '<' ) ) ){
145
  return $columns;
146
  }
147
  $active_languages = $this->sitepress->get_active_languages();
100
  }
101
 
102
  $post_type = get_post_type( $post->ID );
103
+ $checkout_page_id = wc_get_page_id( 'checkout' );
104
 
105
  if ( $post_type === 'product' || is_page( $checkout_page_id ) ){
106
  $output = '';
141
 
142
  public function add_languages_column( $columns ){
143
 
144
+ if ( array_key_exists( 'icl_translations', $columns ) ){
145
  return $columns;
146
  }
147
  $active_languages = $this->sitepress->get_active_languages();
inc/translation-editor/class-wcml-wc-admin-duplicate-product.php CHANGED
@@ -17,20 +17,15 @@ class WCML_WC_Admin_Duplicate_Product{
17
  $this->sitepress = $sitepress;
18
  $this->wpdb = $wpdb;
19
 
20
- if( ( defined('WC_VERSION') && version_compare( WC_VERSION , '3.0.0', '<' ) ) ) {
21
- add_action('woocommerce_duplicate_product', array( $this, 'woocommerce_duplicate_product'), 10, 2);
22
- }else{
23
- add_action( 'woocommerce_product_duplicate', array( $this, 'woocommerce_duplicate_product' ), 10, 2 );
24
- }
25
-
26
  }
27
 
28
  public function woocommerce_duplicate_product( $new_id, $post ){
29
  $duplicated_products = array();
30
 
31
- $product_id = WooCommerce_Functions_Wrapper::get_product_id( $post );
32
  if( !is_numeric( $new_id ) ){
33
- $new_id = WooCommerce_Functions_Wrapper::get_product_id( $new_id );
34
  }
35
 
36
  //duplicate original first
@@ -107,13 +102,8 @@ class WCML_WC_Admin_Duplicate_Product{
107
 
108
  $product = wc_get_product( $post_to_duplicate->ID );
109
  $wc_duplicate_product_instance = new WC_Admin_Duplicate_Product();;
110
-
111
- if( WooCommerce_Functions_Wrapper::is_deprecated() ){
112
- $new_orig_id = $wc_duplicate_product_instance->duplicate_product( $product );
113
- }else{
114
- $duplicate = $wc_duplicate_product_instance->product_duplicate( $product );
115
- $new_orig_id = $duplicate->get_id();
116
- }
117
 
118
  return $new_orig_id;
119
  }
17
  $this->sitepress = $sitepress;
18
  $this->wpdb = $wpdb;
19
 
20
+ add_action( 'woocommerce_product_duplicate', array( $this, 'woocommerce_duplicate_product' ), 10, 2 );
 
 
 
 
 
21
  }
22
 
23
  public function woocommerce_duplicate_product( $new_id, $post ){
24
  $duplicated_products = array();
25
 
26
+ $product_id = $post->get_id();
27
  if( !is_numeric( $new_id ) ){
28
+ $new_id = $new_id->get_id();
29
  }
30
 
31
  //duplicate original first
102
 
103
  $product = wc_get_product( $post_to_duplicate->ID );
104
  $wc_duplicate_product_instance = new WC_Admin_Duplicate_Product();;
105
+ $duplicate = $wc_duplicate_product_instance->product_duplicate( $product );
106
+ $new_orig_id = $duplicate->get_id();
 
 
 
 
 
107
 
108
  return $new_orig_id;
109
  }
inc/woocommerce-functions-wrapper.php DELETED
@@ -1,91 +0,0 @@
1
- <?php
2
-
3
- class WooCommerce_Functions_Wrapper{
4
-
5
- public static function is_deprecated(){
6
-
7
- if( version_compare( WC_VERSION , '3.0.0', '<' ) ){
8
- return true;
9
- }
10
- return false;
11
- }
12
-
13
- public static function get_product_id( $product ){
14
- if( self::is_deprecated() ){
15
- return $product->id;
16
- }
17
- return $product->get_id();
18
- }
19
-
20
- public static function get_product_type( $product_id ){
21
- if( self::is_deprecated() ){
22
- $product = wc_get_product( $product_id );
23
- return $product->product_type;
24
- }
25
- return WC_Product_Factory::get_product_type( $product_id );
26
- }
27
-
28
- public static function reduce_stock( $product_id, $qty ){
29
- if( self::is_deprecated() ){
30
- $product = wc_get_product( $product_id );
31
- return $product->reduce_stock( $qty );
32
- }
33
- $data_store = WC_Data_Store::load( 'product' );
34
- return $data_store->update_product_stock( $product_id, $qty, 'decrease' );
35
- }
36
-
37
- public static function increase_stock( $product_id, $qty ){
38
- if( self::is_deprecated() ){
39
- $product = wc_get_product( $product_id );
40
- return $product->increase_stock( $qty );
41
- }
42
- $data_store = WC_Data_Store::load( 'product' );
43
- return $data_store->update_product_stock( $product_id, $qty, 'increase' );
44
- }
45
-
46
- public static function set_stock( $product_id, $qty ){
47
- if( self::is_deprecated() ){
48
- $product = wc_get_product( $product_id );
49
- return $product->set_stock( $qty );
50
- }
51
- return wc_update_product_stock( $product_id, $qty );
52
- }
53
-
54
- /**
55
- * @param WC_Abstract_Legacy_Order|WC_Abstract_Order $order
56
- *
57
- * @return string
58
- */
59
- public static function get_order_currency( $order ){
60
- if( self::is_deprecated() ){
61
- return $order->get_order_currency();
62
- }
63
- return $order->get_currency();
64
- }
65
-
66
- /**
67
- * @param WC_Abstract_Legacy_Order|WC_Abstract_Order $object
68
- * @param array|WC_Order_Item_Product $item
69
- *
70
- * @return mixed
71
- */
72
- public static function get_item_downloads( $object, $item ){
73
- if( self::is_deprecated() ){
74
- return $object->get_item_downloads( $item );
75
- }
76
- return $item->get_item_downloads( );
77
- }
78
-
79
- /**
80
- * @param WC_Abstract_Legacy_Order|WC_Abstract_Order $order
81
- *
82
- * @return int
83
- */
84
- public static function get_order_id( $order ){
85
- if( self::is_deprecated() ){
86
- /** @noinspection Annotator */
87
- return $order->id;
88
- }
89
- return $order->get_id();
90
- }
91
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
locale/woocommerce-multilingual-ar.mo CHANGED
Binary file
locale/woocommerce-multilingual-de_DE.mo CHANGED
Binary file
locale/woocommerce-multilingual-el.mo CHANGED
Binary file
locale/woocommerce-multilingual-es_ES.mo CHANGED
Binary file
locale/woocommerce-multilingual-fr_FR.mo CHANGED
Binary file
locale/woocommerce-multilingual-he_IL.mo CHANGED
Binary file
locale/woocommerce-multilingual-it_IT.mo CHANGED
Binary file
locale/woocommerce-multilingual-ja.mo CHANGED
Binary file
locale/woocommerce-multilingual-ko_KR.mo CHANGED
Binary file
locale/woocommerce-multilingual-nl_NL.mo CHANGED
Binary file
locale/woocommerce-multilingual-pl_PL.mo CHANGED
Binary file
locale/woocommerce-multilingual-pt_BR.mo CHANGED
Binary file
locale/woocommerce-multilingual-pt_PT.mo CHANGED
Binary file
locale/woocommerce-multilingual-ru_RU.mo CHANGED
Binary file
locale/woocommerce-multilingual-sv_SE.mo CHANGED
Binary file
locale/woocommerce-multilingual-uk.mo CHANGED
Binary file
locale/woocommerce-multilingual-uk_UA.mo DELETED
Binary file
locale/woocommerce-multilingual-vi.mo CHANGED
Binary file
locale/woocommerce-multilingual-zh_CN.mo CHANGED
Binary file
locale/woocommerce-multilingual-zh_TW.mo CHANGED
Binary file
readme.txt CHANGED
@@ -4,8 +4,8 @@ Donate link: http://wpml.org/documentation/related-projects/woocommerce-multilin
4
  Tags: CMS, woocommerce, commerce, ecommerce, e-commerce, products, WPML, multilingual, e-shop, shop
5
  License: GPLv2
6
  Requires at least: 3.9
7
- Tested up to: 4.9.8
8
- Stable tag: 4.3.7
9
 
10
  Allows running fully multilingual e-commerce sites using WooCommerce and WPML.
11
 
@@ -46,7 +46,7 @@ When you need help, go to [WooCommerce Multilingual support forum](http://wpml.o
46
 
47
  = Downloads =
48
 
49
- This version of WooCommerce Multilingual works with WooCommerce > 2.1
50
 
51
  You will also need [WPML](http://wpml.org), together with the String Translation and the Translation Management modules, which are part of the [Multilingual CMS](http://wpml.org/purchase/) package.
52
 
@@ -54,9 +54,9 @@ You will also need [WPML](http://wpml.org), together with the String Translation
54
 
55
  WooCommerce Multilingual checks that the following versions of WPML and their components are active:
56
 
57
- * WPML Multilingual CMS - 3.4
58
- * WPML String Translation - 2.0
59
- * WPML Translation Management - 2.2
60
 
61
  Without having all these running, WooCommerce Multilingual will not be able to run.
62
 
@@ -68,10 +68,10 @@ Without having all these running, WooCommerce Multilingual will not be able to r
68
  * PHP version 5.6 or later
69
  * MySQL version 5.6 or later
70
 
71
- * WooCommerce 2.1 or later
72
- * WPML Multilingual CMS 3.4 or later
73
- * WPML String Translation 2.0 or later
74
- * WPML Translation Management 2.2 or later
75
 
76
  = WordPress automatic installation =
77
  In your WordPress dashboard, go to the Plugins section and click 'Add new'.
@@ -140,9 +140,50 @@ WooCommerce Multilingual is compatible with all major WooCommerce extensions. We
140
 
141
  == Changelog ==
142
 
143
- = 4.3.7 =
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
144
  * Fix broken logic with Table Rate Shipping when product uses class with "break and abort" rule
145
  * Custom attributes terms not copied to diplicated translation after update values in original
 
 
 
 
 
146
  * Fixed issue which was changing the current language of the site when saving an order
147
  * Better compatibility class for LiteSpeed Cache that doesn't require changing the URL
148
  * Fixed issue with serialized data in term meta table
@@ -197,6 +238,7 @@ WooCommerce Multilingual is compatible with all major WooCommerce extensions. We
197
 
198
  = 4.3.3 =
199
  * Fixed small issue in WC Bookings where block cost in other currencies is not saved correctly
 
200
  * Fix compatibility issue with WC Product Addons and not displayed label in secondary language
201
  * Return back duplication logic for product image and gallery
202
  * Fix warning in secondary language if you don't have any wc pages
@@ -255,6 +297,7 @@ WooCommerce Multilingual is compatible with all major WooCommerce extensions. We
255
  * Added filter for oder_item_quantity
256
  * Fix issue in endpoints when set My Account as homepage
257
  * WooCommerce Dynamic Pricing: Fix Order total rules by category
 
258
 
259
  = 4.2.9 =
260
  * Fix wrong qty in cart page for same product and different language
@@ -338,6 +381,24 @@ WooCommerce Multilingual is compatible with all major WooCommerce extensions. We
338
  * Fixed an incompatibility issue with WooCommerce Bookings: the layout of the conformation prompt from switching the cart was broken.
339
  * Serialized custom fields were translated incorrectly using the WooCommerce Multilingual Translation Editor
340
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
341
  = 4.2.1 =
342
  * Added the ability to set custom currencies for orders created via the REST API
343
  * Filter by translation status displays wrong results on WooCommerce Multilingual products list page
@@ -345,6 +406,7 @@ WooCommerce Multilingual is compatible with all major WooCommerce extensions. We
345
  * Missing Woocommerce pages were created in default language
346
  * Fatal error while custom call not active currency switcher template
347
  * Duplicating from WooCommerce resulted in losing language data for the original product
 
348
  * PHP errors were shown on the admin dashboard when no orders existed and displaying errors was on
349
  * A fatal error (undefiend get_current_screen) was occurring in some conditions on the WP admin side
350
  * Cart widget shows wrong product names
@@ -363,6 +425,7 @@ WooCommerce Multilingual is compatible with all major WooCommerce extensions. We
363
  * Checkout Field Editor compatibility fix
364
  * Fixed issue with displaying custom prices in Bundles Products
365
  * Add filter for 'woocommerce_subscriptions_product_price'
 
366
  * The `wcml_raw_price_amount` filter could not be used to convert to a different currency than the current user currency
367
 
368
  = 4.2.0 =
@@ -377,9 +440,12 @@ WooCommerce Multilingual is compatible with all major WooCommerce extensions. We
377
  * A fatal error occurred when using old WordPress versions (before 4.4.0) - rest_get_url_prefix didn't exist
378
  * The admin orders page was loading slower than necessary
379
  * A PHP fatal error was occurring when using the Adventure Tours extension
 
380
  * For translated products, the product variation names were displayed in the old format (before WooCommerce 3.0)
381
  * The prices in the secondary currencies for products in secondary languages for products read via the REST API were incorrect
382
  * CSS for the currency switcher was loaded when the multi-currency was not enabled
 
 
383
  * Fixed a javascript error on the shop page
384
  * It was not possible to use the clear cart feature with enabled WPML Ajax cookies only
385
  * WooCommerce Product Bundles: Bundled items filtering by variation was not synced with translations
4
  Tags: CMS, woocommerce, commerce, ecommerce, e-commerce, products, WPML, multilingual, e-shop, shop
5
  License: GPLv2
6
  Requires at least: 3.9
7
+ Tested up to: 5.0.3
8
+ Stable tag: 4.4.0
9
 
10
  Allows running fully multilingual e-commerce sites using WooCommerce and WPML.
11
 
46
 
47
  = Downloads =
48
 
49
+ This version of WooCommerce Multilingual works with WooCommerce > 3.3.0
50
 
51
  You will also need [WPML](http://wpml.org), together with the String Translation and the Translation Management modules, which are part of the [Multilingual CMS](http://wpml.org/purchase/) package.
52
 
54
 
55
  WooCommerce Multilingual checks that the following versions of WPML and their components are active:
56
 
57
+ * WPML Multilingual CMS - 4.0
58
+ * WPML String Translation - 2.8
59
+ * WPML Translation Management - 2.6
60
 
61
  Without having all these running, WooCommerce Multilingual will not be able to run.
62
 
68
  * PHP version 5.6 or later
69
  * MySQL version 5.6 or later
70
 
71
+ * WooCommerce 3.3.0 or later
72
+ * WPML Multilingual CMS 4.0 or later
73
+ * WPML String Translation 2.8 or later
74
+ * WPML Translation Management 2.6 or later
75
 
76
  = WordPress automatic installation =
77
  In your WordPress dashboard, go to the Plugins section and click 'Add new'.
140
 
141
  == Changelog ==
142
 
143
+ = 4.4.0 =
144
+ * Added the ability to associate BACS accounts with currencies
145
+ * Fix and removed duplicated entries in code
146
+ * Hide reviews in other languages link, if there are no reviews in product
147
+ * Update WCML Logo
148
+ * Added support for wpml endpoints
149
+ * Removed Product Type Column from WCML backend and added compatibility with the WC Product Type Column plugin
150
+ * Fix low_stock_amount not synchronized to translations
151
+ * Fix custom attribute with number in name not appears to translation in Translation editor
152
+ * Fix not applied price rule for WooCommerce Table Rate Shipping in second currency
153
+ * Fix translated custom field wrongly saved to translation if contains array of strings
154
+ * Endless loop when using troubleshooting action to duplicate terms
155
+ * Fixed an issue with Elementor PRO products block showing all categories in the translated page.
156
+ * Fixed Xliff doesn't contains variation descriptions for WooCommerce Subscriptions
157
+ * Fixed compatibility issue with Flatsome theme
158
+ * Fix issue with custom product attribute title when trying to upload translation with XLIFF file
159
+ * Fixed cart validate for specific situations
160
+ * Added filter for translated package rates
161
+ * Added WPML switcher buttons library for Multi Currency in backend
162
+ * Fix loading Jquery to any place in code and in header
163
+ * Added fix for variation product "become" out-of-stock when translating using native screen
164
+ * Removed backward compatibility filters for terms synchronization
165
+ * Fixed attribute slug language always set to English
166
+ * Wrong path in Bookings compatibility class
167
+ * Fixed a fatal error occuring with older versions of WooCommerce (3.3.5)
168
+ * Fixed confirming order as complete from the order edit screen, does not decrement the second language stock qty
169
+ * Product category data always synchronizes on save of the translation and does not respect WPML option to sync taxonomies
170
+ * Fixed call to undefined method WPML_URL_Filters::remove_global_hooks with WPML < 3.6.0
171
+ * Fixed compatibility class name for wc product addons
172
+ * Fixed manual order creation does not respect manual prices
173
+ * Fix email language for the order as complete emails
174
+ * Fixed Composite Products compatibility - Price not rounding to the nearest integer
175
+ * Fixed missing custom attribute in XLIFF file / Pro Translation
176
+ * Fix Endpoint error to prevent 404 in some cases
177
+ * Fixed accepted arguments for terms_clause
178
+ * Resolved an exception causing an error message in the cart in some setups
179
+ * Fixed missed synchronization of 'outofstock' visibility term between product translations
180
  * Fix broken logic with Table Rate Shipping when product uses class with "break and abort" rule
181
  * Custom attributes terms not copied to diplicated translation after update values in original
182
+ * WP Fastest Cache compatibility - fixed currency switcher problem
183
+ * Added ability to set custom prices for secondary currencies in WC Product Add-Ons
184
+ * Update minimum requirements
185
+
186
+ = 4.3.7 =
187
  * Fixed issue which was changing the current language of the site when saving an order
188
  * Better compatibility class for LiteSpeed Cache that doesn't require changing the URL
189
  * Fixed issue with serialized data in term meta table
238
 
239
  = 4.3.3 =
240
  * Fixed small issue in WC Bookings where block cost in other currencies is not saved correctly
241
+ * Fix an error due to a bug in upgrade logic
242
  * Fix compatibility issue with WC Product Addons and not displayed label in secondary language
243
  * Return back duplication logic for product image and gallery
244
  * Fix warning in secondary language if you don't have any wc pages
297
  * Added filter for oder_item_quantity
298
  * Fix issue in endpoints when set My Account as homepage
299
  * WooCommerce Dynamic Pricing: Fix Order total rules by category
300
+ * Relevanssi compatibility - add missing terms for translated product
301
 
302
  = 4.2.9 =
303
  * Fix wrong qty in cart page for same product and different language
381
  * Fixed an incompatibility issue with WooCommerce Bookings: the layout of the conformation prompt from switching the cart was broken.
382
  * Serialized custom fields were translated incorrectly using the WooCommerce Multilingual Translation Editor
383
 
384
+ = 4.2.3 =
385
+ * A fatal error occurred when deactivating WPML with WooCommerce Multilingual being active
386
+
387
+ = 4.2.2 =
388
+ * My account Bookings list page displays bookings in all languages
389
+ * Updating variable product does not refresh product visibility terms
390
+ * Currency switcher doesn't reload the product page if # is present in the URL
391
+ * Fixed a PHP fatal error that was occurring when using WooCommerce Multilingual together with Sensei
392
+ * The 'featured' product field was not synchronized across product translations
393
+ * When updating a translation, the product translation slug was overwritten if product contains page builders fields
394
+ * The 'reset password' form in a secondary language pointed to a 404 error
395
+ * "product/%product_cat%" product permalink doesn't work for products without category assigned in second language if "Uncategorized" string not translated in String Translation module
396
+ * WC Subscriptions compatibility error
397
+ * It was not possible to set the custom price value in secondary currencies as '0'
398
+ * It was not possible to translate attribute slugs if the attributes base was not translated
399
+ * Currency switcher styles were not loaded when using only a shortcode currency switcher
400
+ * The customer order email was sent in default language when the 'Processing' button was clicked on the back-end
401
+
402
  = 4.2.1 =
403
  * Added the ability to set custom currencies for orders created via the REST API
404
  * Filter by translation status displays wrong results on WooCommerce Multilingual products list page
406
  * Missing Woocommerce pages were created in default language
407
  * Fatal error while custom call not active currency switcher template
408
  * Duplicating from WooCommerce resulted in losing language data for the original product
409
+ * Coupon with category restriction removed when switching language on cart page
410
  * PHP errors were shown on the admin dashboard when no orders existed and displaying errors was on
411
  * A fatal error (undefiend get_current_screen) was occurring in some conditions on the WP admin side
412
  * Cart widget shows wrong product names
425
  * Checkout Field Editor compatibility fix
426
  * Fixed issue with displaying custom prices in Bundles Products
427
  * Add filter for 'woocommerce_subscriptions_product_price'
428
+ * Fixed compatibi;ity issue with coupos not applied correctly in a subscription product
429
  * The `wcml_raw_price_amount` filter could not be used to convert to a different currency than the current user currency
430
 
431
  = 4.2.0 =
440
  * A fatal error occurred when using old WordPress versions (before 4.4.0) - rest_get_url_prefix didn't exist
441
  * The admin orders page was loading slower than necessary
442
  * A PHP fatal error was occurring when using the Adventure Tours extension
443
+ * A product addon was added to the cart more then once in combination with Bookings
444
  * For translated products, the product variation names were displayed in the old format (before WooCommerce 3.0)
445
  * The prices in the secondary currencies for products in secondary languages for products read via the REST API were incorrect
446
  * CSS for the currency switcher was loaded when the multi-currency was not enabled
447
+ * Visual Composer field value not updated in WooCommerce Multilingual translation editor after update original
448
+ * Wrong count of not translated products on WooCommerce Multilingual Status tab
449
  * Fixed a javascript error on the shop page
450
  * It was not possible to use the clear cart feature with enabled WPML Ajax cookies only
451
  * WooCommerce Product Bundles: Bundled items filtering by variation was not synced with translations
res/css/currency-switcher.css CHANGED
@@ -1 +1 @@
1
- ul.wcml_currency_switcher{padding:0 !important;margin:0 !important;list-style-type:none !important;position:relative}ul.wcml_currency_switcher li{cursor:pointer;border:1px solid #cdcdcd}ul.wcml_currency_switcher.curr_list_vertical{border-top:1px solid #cdcdcd;display:inline-block}ul.wcml_currency_switcher.curr_list_horizontal li{float:left;position:relative;padding:2px 5px;margin-left:1px}ul.wcml_currency_switcher.curr_list_horizontal li:first-child{margin-left:0}ul.wcml_currency_switcher.curr_list_vertical li{border-top-width:0;cursor:pointer;padding:3px 10px;margin:0}ul.dropdown.wcml_currency_switcher{position:relative;padding:0;margin:0 !important;list-style-type:none}ul.dropdown.wcml_currency_switcher li span{position:relative;padding-right:-webkit-calc(10px + .7em + .7em);padding-right:calc(10px + .7em + .7em);display:block;padding:5px 10px;line-height:1}ul.dropdown.wcml_currency_switcher li span:after{content:'';vertical-align:middle;display:inline-block;border:.35em solid transparent;border-top:.5em solid;position:absolute;right:10px;top:-webkit-calc(50% - .175em);top:calc(50% - .175em)}ul.dropdown.wcml_currency_switcher ul.wcml-cs-submenu{visibility:hidden;position:absolute;top:100%;right:0;left:0;border-top:1px solid #cdcdcd;padding:0;margin:0;list-style-type:none;z-index:101}.exchange-rates-online-wrap,.service-details-wrap{padding-left:24px}.rtl .exchange-rates-online-wrap,.rtl .service-details-wrap{padding-left:0;padding-right:24px}.exchange-rate-service-website{text-decoration:none}.exchange-rate-service-website .dashicons-external{font-size:14px;width:14px;height:14px;vertical-align:-4px}
1
+ ul.wcml_currency_switcher{padding:0 !important;margin:0 !important;list-style-type:none !important;position:relative}ul.wcml_currency_switcher li{cursor:pointer;border:1px solid #cdcdcd}ul.wcml_currency_switcher.curr_list_vertical{border-top:1px solid #cdcdcd;display:inline-block}ul.wcml_currency_switcher.curr_list_horizontal li{float:left;position:relative;padding:2px 5px;margin-left:1px}ul.wcml_currency_switcher.curr_list_horizontal li:first-child{margin-left:0}ul.wcml_currency_switcher.curr_list_vertical li{border-top-width:0;cursor:pointer;padding:3px 10px;margin:0}ul.dropdown.wcml_currency_switcher{position:relative;padding:0;margin:0 !important;list-style-type:none}ul.dropdown.wcml_currency_switcher li span{position:relative;padding-right:calc(10px + .7em + .7em);display:block;padding:5px 10px;line-height:1}ul.dropdown.wcml_currency_switcher li span:after{content:'';vertical-align:middle;display:inline-block;border:.35em solid transparent;border-top:.5em solid;position:absolute;right:10px;top:calc(50% - .175em)}ul.dropdown.wcml_currency_switcher ul.wcml-cs-submenu{visibility:hidden;position:absolute;top:100%;right:0;left:0;border-top:1px solid #cdcdcd;padding:0;margin:0;list-style-type:none;z-index:101}.exchange-rates-online-wrap,.service-details-wrap{padding-left:24px}.rtl .exchange-rates-online-wrap,.rtl .service-details-wrap{padding-left:0;padding-right:24px}.exchange-rate-service-website{text-decoration:none}.exchange-rate-service-website .dashicons-external{font-size:14px;width:14px;height:14px;vertical-align:-4px}
res/css/dialogs.css CHANGED
@@ -1 +1 @@
1
- .wcml-slug-dialog .translated_value,.wcml-slug-dialog .original_value,.wcml-slug-dialog .wpml-header-original,.wcml-slug-dialog .wpml-header-translation{width:-webkit-calc(50% - 30px - 5px);width:calc(50% - 30px - 5px)}
1
+ .wcml-slug-dialog .translated_value,.wcml-slug-dialog .original_value,.wcml-slug-dialog .wpml-header-original,.wcml-slug-dialog .wpml-header-translation{width:calc(50% - 30px - 5px)}
res/css/management.css CHANGED
@@ -1 +1 @@
1
- .wcml-wrap{border:1px solid #CCCCCC;padding:15px;background-color:#ffffff}.wcml-wrap:before,.wcml-wrap:after{content:" ";display:table}.wcml-wrap:after{clear:both}.dis_base{opacity:0.5}.display-block{display:block}.wcml-wrap{margin-bottom:20px;min-width:900px}.wcml-wrap .wpml-tabs{margin-top:0}.wcml-wrap .otgs-ico-yes,.wcml-wrap .otgs-ico-ok{color:#51a351}.wcml-wrap .otgs-ico-no,.wcml-wrap .otgs-ico-warning,.wcml-wrap .otgs-ico-delete{color:#9d261d}.wcml-wrap .otgs-ico-edit{color:#3a87ad}.wcml-wrap .otgs-ico-in-progress{color:#ffb800}@media (max-width: 1199px){.wcml-wrap .tablenav.top{height:auto}.wcml-wrap .tablenav.top.wcml-product-translation-filtering .alignright,.wcml-wrap .tablenav.top.wcml-product-translation-filtering .alignleft{float:none;margin-bottom:5px}}[class*="otgs-ico"]:before{font-size:16px}.wcml-tabs{min-width:930px}.wcml-tabs:before,.wcml-tabs:after{content:" ";display:table}.wcml-tabs:after{clear:both}.wcml-tabs .nav-tab{margin-top:5px}@media (max-width: 1350px){.wcml-tabs .nav-tab{margin-left:.2em}}.wcml-tabs .nav-tab [class*="otgs-ico"]:before{font-size:18px}.wcml-section{clear:both;padding:0 0 15px 0;margin:0 0 15px 0;border-bottom:1px solid #ededed;min-width:900px}.wcml-section:after{content:'';display:table;clear:both}.wcml-section:last-of-type{border:none;margin:0}.explanation-text{color:#999}h4+.explanation-text{margin-top:-1.1em;margin-bottom:1.33em}.wcml-section-content .wcml-section-content-inner:not(:last-child){margin:0 0 20px 0;padding:0 0 10px 0;border-bottom:1px solid #ededed}.wcml-section-header{width:310px;float:left}.wcml-section-header h3{font-weight:normal;font-size:1.4em;margin-top:0.7em}.wcml-section-header h3 .wcml-tip:before{vertical-align:top}.wcml-section-content{float:left;width:680px;margin-left:30px}.wcml-section-content-wide{width:-webkit-calc(100% - 360px);width:calc(100% - 360px)}.wcml_products{margin:20px 0;position:relative}.button-wrap,.widefat td .button-wrap{text-align:right;margin:10px 0}.currency_action_update{display:inline-block}.wcml-co-dialog.hidden{display:none}.wcml-co-dialog .wpml-form-row label{width:215px;text-align:left}.wcml-co-dialog input,.wcml-co-dialog select{width:145px}.wcml-co-dialog .currency_code label{width:100px;vertical-align:top}.wcml-co-dialog .currency_code select{width:auto;max-width:-webkit-calc(100% - 165px);max-width:calc(100% - 165px)}.wcml-co-dialog .wcml-co-exchange-rate label{width:100px;vertical-align:top}.wcml-co-dialog .wcml-co-exchange-rate input{margin:0 !important;width:75px}.wcml-co-dialog .wcml-co-exchange-rate .wcml-co-set-rate{display:inline-block;padding:4px 15px 7px 15px;max-width:265px}.wcml-co-dialog .wcml-co-exchange-rate small{display:block;margin-top:5px}.wcml-co-dialog .wcml-co-help-link{margin-top:7px}.wcml-co-dialog .wcml-co-preview label{width:120px;vertical-align:middle}.wcml-co-dialog .wcml-co-preview .wcml-co-preview-value{display:inline-block;padding:7px 15px;border:1px solid #555;font-size:1.4em;font-weight:bold;vertical-align:middle;margin:15px 0}table.widefat.currency_table{float:left;width:320px;border-right:none}table.widefat.currency_table td.wcml-col-currency,table.widefat.currency_table td.wcml-col-rate{padding-top:7px;padding-bottom:0;vertical-align:top}table.widefat.currency_table td.wcml-col-currency .truncate{max-width:120px;display:block}table.widefat.currency_table td.wcml-col-currency small{display:block}table.widefat.currency_table td.wcml-col-edit a{position:relative;top:-3px}table.widefat.currency_table td.wcml-col-rate{font-size:.85em}table.widefat.currency_table td.wcml-col-rate .truncate{max-width:75px;display:block}table.widefat.currency_delete_table{float:left;width:50px;border-left:none;clear:none}table.widefat.currency_delete_table td.wcml-col-delete{vertical-align:middle;text-align:center}table.widefat.currency_delete_table td.wcml-col-delete:first-child{border-left:1px solid #e5e5e5}.currency_value .wcml-error,.wcml-error{font-size:10px;color:#f00;display:inline-block}.trbl_variables_products{padding:10px;border:1px solid #8cceea;background-color:#eff8fc;border-radius:5px}.trbl_variables_products label span{font-weight:bold}.wcml_trbl_warning{padding:10px;margin-bottom:10px;border:1px solid #f00;background-color:#ffb7b7;border-radius:5px 5px}#wcml_sync_variations{background-color:#21759b;background-image:-webkit-linear-gradient(top, #2a95c5, #21759b);background-image:linear-gradient(to bottom, #2a95c5, #21759b);border-color:#21759b;border-bottom-color:#1e6a8d;box-shadow:inset 0 1px 0 rgba(120,200,230,0.5);color:#fff;text-decoration:none;text-shadow:0 1px 0 rgba(0,0,0,0.1)}.wcml_duplicate_product_notice td{border-bottom:none !important}.wcml_product_status_text,.prod_parent_text{font-style:italic;color:#9A9A9A}.wcml_no_found_text{text-align:center}.currency_languages{position:relative;text-align:center}.currency_languages:first-child{border-left:1px solid #e5e5e5}.currency_languages ul{margin:0;text-align:center}.currency_languages ul li{margin:0;display:none}.currency_languages ul li.on{display:inline-block}table.widefat.currency_lang_table{border-left:none;border-right:none}table.widefat.currency_lang_table thead tr{height:28px}table.widefat.currency_lang_table thead td{border-bottom:0;text-align:center;padding-top:3px;padding-bottom:1px;font-size:1em}table.widefat.currency_lang_table thead th{padding-top:0;padding-bottom:0;text-align:center}.currency_wrap{width:-webkit-calc(100% - 320px - 50px);width:calc(100% - 320px - 50px);float:left;margin-bottom:10px}.currency_inner{overflow-x:auto;overflow-y:visible}.currency_table,.currency_lang_table,.currency_delete_table{clear:none}.currency_table thead tr,.currency_lang_table thead tr,.currency_delete_table thead tr{height:56px}.currency_table tr,.currency_lang_table tr,.currency_delete_table tr{height:50px}.currency_lang_table th{text-align:center}.currency_lang_table td{vertical-align:middle}.currency_lang_table.widefat td{padding-right:0;padding-left:0}.default_currency select{font-size:9px;height:24px;margin:0;margin-right:2px;padding:2px 0}.default_currency td{border-top:1px solid #e5e5e5}.default_currency .inf_message{font-size:10px;font-style:italic;color:#9A9A9A}#wcml_currencies_order{display:block;overflow:hidden;width:100%}#wcml_currencies_order li{float:left;margin:2px 4px 2px 0;padding:2px 8px;border:1px solid #DFDFDF;border-radius:2px;background:-webkit-linear-gradient(bottom, #ECECEC, #F9F9F9) repeat scroll 0 0 #F1F1F1;background:linear-gradient(to top, #ECECEC, #F9F9F9) repeat scroll 0 0 #F1F1F1;cursor:move}.wcml_currencies_order_ajx_resp{font-weight:500;margin:0 5px;padding:1px 4px 2px;border-radius:3px;white-space:nowrap;color:#46b450;background-color:rgba(92,255,102,0.15)}.wcml-cs-list{font-size:inherit;width:100%;border-collapse:collapse;border:lightgrey 1px solid;vertical-align:middle}.wcml-cs-list thead tr{border:lightgrey 1px solid}.wcml-cs-list th,.wcml-cs-list td{text-align:center;padding:5px}.wcml-cs-list .wcml-cs-cell-preview{text-align:start}.wcml-cs-list .wcml-cs-actions{width:60px}.wcml-cs-list .wcml-cs-actions a{display:inline-block;width:20px;cursor:pointer}.wcml-currency-preview-wrapper{background-color:#fff;padding:15px 10px 10px;border:1px solid #ccc;width:100%;min-width:150px;min-height:120px;box-sizing:border-box;position:relative;display:-webkit-box !important;display:-ms-flexbox !important;display:flex !important;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center}.wcml-currency-preview-wrapper .wcml-currency-preview-label{position:absolute;top:5px;left:10px;z-index:101;display:inline-block;padding:2px;background:rgba(255,255,255,0.9)}.wcml-currency-preview-wrapper .spinner{position:absolute;bottom:5px;right:0;z-index:101}.wcml-cs-dialog .wcml-currency-switcher-options-form input{max-width:100%}@media (min-width: 1000px){.wcml-cs-dialog .wcml-currency-switcher-options-form{display:-webkit-box;display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;-webkit-box-align:start;-ms-flex-align:start;align-items:flex-start}.wcml-cs-dialog .wcml-currency-switcher-options-form .wcml-currency-switcher-options{width:60%;-webkit-box-ordinal-group:2;-ms-flex-order:1;order:1;box-sizing:border-box}.wcml-cs-dialog .wcml-currency-switcher-options-form .wcml-currency-switcher-options>h4:first-child{margin-top:0}.wcml-cs-dialog .wcml-currency-switcher-options-form .wcml-currency-preview-wrapper{width:40%;box-sizing:border-box;-webkit-box-ordinal-group:3;-ms-flex-order:2;order:2}.wcml-cs-dialog .wcml-currency-switcher-options-form .wcml-currency-preview-wrapper>div{display:block}}@media (max-width: 999px){.wcml-cs-dialog .wcml-currency-switcher-options-form .wcml-currency-preview-wrapper{margin:-17px -15px 30px -15px;width:-webkit-calc(100% + 2 * 15px);width:calc(100% + 2 * 15px);border-left:0;border-right:0;z-index:10}}.wcml-cs-panel-colors table{width:100%;max-width:600px;font-size:inherit}.wcml-cs-panel-colors table th{text-align:start}.wcml-cs-panel-colors table td{vertical-align:top}.wcml-cs-panel-colors .wp-color-result,.wcml-cs-panel-colors .wp-color-result.button{padding-left:50px;position:relative}@media screen and (max-width: 782px){.wcml-cs-panel-colors .wp-color-result,.wcml-cs-panel-colors .wp-color-result.button{height:22px}}.wcml-cs-panel-colors .wp-color-result:after,.wcml-cs-panel-colors .wp-color-result.button:after{background:transparent;border-radius:0;border-left:0;padding:0;right:0;left:0;position:absolute;content:''}.wcml-cs-panel-colors .wp-color-result.wp-picker-open:after,.wcml-cs-panel-colors .wp-color-result.button.wp-picker-open:after{content:''}.wcml-cs-panel-colors .wp-color-result:not(.wp-picker-open):after,.wcml-cs-panel-colors .wp-color-result.button:not(.wp-picker-open):after{font-family:otgs-icons;content:'\69';color:#333;text-shadow:1px 1px 2px rgba(255,255,255,0.4);font-size:16px;min-width:0}.wcml-cs-panel-colors .wp-color-result.button .wp-color-result-text{display:none !important}.wcml-cs-panel-colors .wp-color-result.button:after{top:-2px}.wcml-cs-panel-colors .wp-picker-container input[type="text"].wp-color-picker{display:inline !important;margin-right:6px}.wcml_product_name{line-height:20px}.wcml_prod_filters{float:left}.wcml_miss_lang p:first-child{float:left}#display_custom_prices_select{display:inline-block;width:100%}.edit_slug_input,.edit_slug_hide_link{display:none}.wcml-tip{cursor:help;color:#555}.wcml-products a{cursor:pointer}@media (max-width: 782px){.column-product_cat,.column-product_tag,.column-product_type{display:none}}.wcml-link-troubleshooting{margin-top:7px}.wcml-status-list li{padding-left:25px;margin-bottom:30px}.wcml-status-list li ul li{margin-bottom:3.5px}.wcml-status-list.wcml-tax-translation-list li{margin-bottom:5px;line-height:26px}.wcml-status-list.wcml-plugins-status-list li{margin-bottom:10px}.wcml-status-list [class*="otgs-ico"]:not(.otgs-ico-help){margin-left:-25px;margin-right:5px;vertical-align:baseline}.wcml-status-list .button-secondary{vertical-align:middle}.wcml-status-list small{display:block}.wcml-lang-list{margin:7px 0}.wcml-lang-list .wpml-title-flag{margin-left:-25px;margin-right:5px}.wcml-dismiss-warning{position:relative;float:right;padding:0;text-decoration:none;outline:none}.wcml-dismiss-warning:active{outline:none}.wcml-notice{background:#fff;box-shadow:0 1px 1px 0 rgba(0,0,0,0.1);margin:5px 0 15px;padding:1px 12px;position:relative}.wcml-notice p{margin:.5em 0;padding:2px}.otgs-is-dismissible{position:relative;padding-right:38px}.otgs-is-dismissible .notice-dismiss{text-decoration:none}.otgs-is-dismissible p [class*="button-"]{margin:-5px 5px}.wcml_tt_spinner{margin-right:15px;display:none}.wcml-product-attributes-selector{text-align:center;margin-bottom:25px}@media (max-width: 1280px){.wcml-product-attributes-selector{margin-left:.2em}}.wcml-product-attributes-selector select{min-width:200px}.wcml-product-custom-taxonomies-selector{text-align:center;margin-bottom:25px}.wcml_attributes_wrap #wpml_tt_taxonomy_translation_wrap>label,.wcml_custom_taxonomies_wrap #wpml_tt_taxonomy_translation_wrap>label{display:none}
1
+ .wcml-wrap{border:1px solid #CCCCCC;padding:15px;background-color:#ffffff}.wcml-wrap:before,.wcml-wrap:after{content:" ";display:table}.wcml-wrap:after{clear:both}.dis_base{opacity:0.5}.display-block{display:block}.wcml-wrap{margin-bottom:20px}.wcml-wrap .wpml-tabs{margin-top:0}.wcml-wrap .otgs-ico-yes,.wcml-wrap .otgs-ico-ok{color:#51a351}.wcml-wrap .otgs-ico-no,.wcml-wrap .otgs-ico-warning,.wcml-wrap .otgs-ico-delete{color:#9d261d}.wcml-wrap .otgs-ico-edit{color:#3a87ad}.wcml-wrap .otgs-ico-in-progress{color:#ffb800}@media (max-width: 1199px){.wcml-wrap .tablenav.top{height:auto}.wcml-wrap .tablenav.top.wcml-product-translation-filtering .alignright,.wcml-wrap .tablenav.top.wcml-product-translation-filtering .alignleft{float:none;margin-bottom:5px}}[class*="otgs-ico"]:before{font-size:16px}.wcml-tabs:before,.wcml-tabs:after{content:" ";display:table}.wcml-tabs:after{clear:both}.wcml-tabs .nav-tab{margin-top:5px}@media (max-width: 1350px){.wcml-tabs .nav-tab{margin-left:.2em}}.wcml-tabs .nav-tab [class*="otgs-ico"]:before{font-size:18px}.wcml-section{clear:both;padding:0 0 15px 0;margin:0 0 15px 0;border-bottom:1px solid #ededed}.wcml-section:after{content:'';display:table;clear:both}.wcml-section:last-of-type{border:none;margin:0}@media (max-width: 480px){.wcml-section .button{max-width:100%;white-space:normal;line-height:1.3;padding-top:7px;padding-bottom:8px;height:auto}}.explanation-text{color:#999}h4+.explanation-text{margin-top:-1.1em;margin-bottom:1.33em}.wcml-section-content .wcml-section-content-inner:not(:last-child){margin:0 0 20px 0;padding:0 0 10px 0;border-bottom:1px solid #ededed}.wcml-section-header h3{font-weight:normal;font-size:1.4em;margin-top:0.7em}.wcml-section-header h3 .wcml-tip:before{vertical-align:top}@media (min-width: 1200px){.wcml-section-header{width:310px;float:left}.wcml-section-content{float:left;width:600px;max-width:100%;margin-left:30px}.wcml-section-content-wide{width:calc(100% - 360px)}}.wcml_products{margin:20px 0;position:relative}.button-wrap,.widefat td .button-wrap{text-align:right;margin:10px 0}.currency_action_update{display:inline-block}.wcml-co-dialog.hidden{display:none}.wcml-co-dialog .wpml-form-row label,.wcml-co-dialog .wpml-form-row input,.wcml-co-dialog .wpml-form-row select{margin:3px 15px}.wcml-co-dialog .wpml-form-row label{width:215px;text-align:start}.wcml-co-dialog .wpml-form-row input,.wcml-co-dialog .wpml-form-row select{width:145px}.wcml-co-dialog .currency_code label{width:100px;vertical-align:top}.wcml-co-dialog .currency_code select{width:auto;max-width:calc(100% - 165px)}.wcml-co-dialog .wcml-co-exchange-rate label{width:100px;vertical-align:top}.wcml-co-dialog .wcml-co-exchange-rate input{margin:0 !important;width:75px}.wcml-co-dialog .wcml-co-exchange-rate .wcml-co-set-rate{display:inline-block;padding:4px 15px 7px 15px;max-width:265px}.wcml-co-dialog .wcml-co-exchange-rate small{display:block;margin-top:5px}.wcml-co-dialog .wcml-co-help-link{margin-top:7px}.wcml-co-dialog .wcml-co-preview label{width:120px;vertical-align:middle}.wcml-co-dialog .wcml-co-preview .wcml-co-preview-value{display:inline-block;padding:7px 15px;border:1px solid #555;font-size:1.4em;font-weight:bold;vertical-align:middle;margin:15px 0}.wcml-co-dialog .label-header{margin:20px 15px 7px 15px;display:block}.wcml-co-dialog .wcml-gateways-switcher{margin:7px 15px 30px}.wcml-co-dialog .wcml-gateways-switcher .otgs-toggle-group{display:inline-flex;-webkit-margin-end:15px;margin-inline-end:15px}.wcml-co-dialog .wcml-gateways{margin-bottom:30px}.wcml-co-dialog .wcml-gateways .wpml-form-row label{width:130px}.wcml-co-dialog .wcml-gateways .wpml-form-row input,.wcml-co-dialog .wcml-gateways .wpml-form-row select{width:auto}.wcml-co-dialog .wcml-gateways .wpml-form-row input+.wcml-tip,.wcml-co-dialog .wcml-gateways .wpml-form-row select+.wcml-tip{-webkit-margin-start:-12px;margin-inline-start:-12px}.wcml-co-dialog .wcml-gateways .explanation-text{display:block;margin:0 15px}table.widefat.currency_table{float:left;width:255px;border-right:none}@media (max-width: 782px){table.widefat.currency_table{width:120px}}table.widefat.currency_table td.wcml-col-currency,table.widefat.currency_table td.wcml-col-rate{padding-top:7px;padding-bottom:0;vertical-align:top}table.widefat.currency_table td.wcml-col-currency .truncate{max-width:100px;display:block}table.widefat.currency_table td.wcml-col-currency small{display:block}table.widefat.currency_table td.wcml-col-edit a{position:relative;top:-3px}table.widefat.currency_table td.wcml-col-rate{font-size:.85em;-webkit-padding-start:3px;padding-inline-start:3px}table.widefat.currency_table td.wcml-col-rate .truncate{max-width:75px;display:block}@media (max-width: 782px){table.widefat.currency_table .wcml-col-rate{display:none}}table.widefat.currency_settings_table{float:left;width:80px;border-left:none;clear:none}table.widefat.currency_settings_table td.wcml-col-delete,table.widefat.currency_settings_table td.wcml-col-edit{vertical-align:middle;text-align:center}table.widefat.currency_settings_table td.wcml-col-delete:first-child,table.widefat.currency_settings_table td.wcml-col-edit:first-child{border-left:1px solid #e5e5e5}.currency_value .wcml-error,.wcml-error{font-size:10px;color:#f00;display:inline-block}.trbl_variables_products{padding:10px;border:1px solid #8cceea;background-color:#eff8fc;border-radius:5px}.trbl_variables_products label span{font-weight:bold}.wcml_trbl_warning{padding:10px;margin-bottom:10px;border:1px solid #f00;background-color:#ffb7b7;border-radius:5px 5px}#wcml_sync_variations{background-color:#21759b;background-image:linear-gradient(to bottom, #2a95c5, #21759b);border-color:#21759b;border-bottom-color:#1e6a8d;box-shadow:inset 0 1px 0 rgba(120,200,230,0.5);color:#fff;text-decoration:none;text-shadow:0 1px 0 rgba(0,0,0,0.1)}.wcml_duplicate_product_notice td{border-bottom:none !important}.wcml_product_status_text,.prod_parent_text{font-style:italic;color:#9A9A9A}.wcml_no_found_text{text-align:center}.currency_languages{position:relative;text-align:center}.currency_languages:first-child{border-left:1px solid #e5e5e5}.currency_languages ul{margin:0;text-align:center}.currency_languages ul li{margin:0;display:none}.currency_languages ul li.on{display:inline-block}.currencies-table-content{display:inline-block;min-width:291px}@media (min-width: 1200px){.currencies-table-content{min-width:600px}}.currencies-table-content::after{display:table;clear:both;content:''}table.widefat.currency_lang_table{border-left:none;border-right:none}table.widefat.currency_lang_table thead .currency-lang-flags{height:23px}table.widefat.currency_lang_table thead tr{height:45px}table.widefat.currency_lang_table thead td{border-bottom:0;text-align:center;padding:3px 10px 1px 0;font-size:1em}table.widefat.currency_lang_table thead th{padding-top:0;padding-bottom:0;text-align:center}.currency_wrap{width:100%;max-width:calc(100% - 255px - 80px);min-width:70px;float:left;margin-bottom:10px;position:relative}.currency_wrap::after{content:'';position:absolute;top:1px;bottom:1px;right:0;width:15px;background:linear-gradient(to right, transparent, #fff)}@media (max-width: 782px){.currency_wrap{max-width:calc(100% - 121px - 80px)}}.currency_inner{overflow-x:auto;overflow-y:visible}.currency_table,.currency_lang_table,.currency_settings_table{clear:none}.currency_table thead tr,.currency_lang_table thead tr,.currency_settings_table thead tr{height:68px}.currency_table tr,.currency_lang_table tr,.currency_settings_table tr{height:50px}@media (max-width: 782px){.currency_table .default_currency,.currency_lang_table .default_currency,.currency_settings_table .default_currency{height:55px}}.currency_lang_table th{text-align:center}.currency_lang_table td{vertical-align:middle}.currency_lang_table.widefat td{padding-right:0;padding-left:0}@media (max-width: 782px){#wpbody .currency_lang_table select{font-size:10px}.currency_lang_table [class*='otgs-ico']::before{font-size:27px}}.default_currency select{font-size:9px;height:24px;margin:0;margin-right:2px;padding:2px 0}.default_currency td{border-top:1px solid #e5e5e5}.default_currency .inf_message{font-size:10px;font-style:italic;color:#9A9A9A}#wcml_currencies_order{display:block;overflow:hidden;width:100%}#wcml_currencies_order li{float:left;margin:2px 4px 2px 0;padding:2px 8px;border:1px solid #DFDFDF;border-radius:2px;background:linear-gradient(to top, #ECECEC, #F9F9F9) repeat scroll 0 0 #F1F1F1;cursor:move}.wcml_currencies_order_ajx_resp{font-weight:500;margin:0 5px;padding:1px 4px 2px;border-radius:3px;white-space:nowrap;color:#46b450;background-color:rgba(92,255,102,0.15)}.wcml-cs-list{font-size:inherit;width:100%;border-collapse:collapse;border:lightgrey 1px solid;vertical-align:middle}.wcml-cs-list thead tr{border:lightgrey 1px solid}.wcml-cs-list th,.wcml-cs-list td{text-align:center;padding:5px}.wcml-cs-list .wcml-cs-cell-preview{text-align:start}.wcml-cs-list .wcml-cs-actions{width:60px}.wcml-cs-list .wcml-cs-actions a{display:inline-block;width:20px;cursor:pointer}@media (max-width: 480px){.wcml-cs-list{display:block}.wcml-cs-list thead{display:none}.wcml-cs-list tbody,.wcml-cs-list tr:not(.wcml-cs-empty-row),.wcml-cs-list td{display:block !important;box-sizing:border-box}.wcml-cs-list tr::after{display:table;content:'';clear:both}.wcml-cs-list tr+tr{margin-top:30px}.wcml-cs-list .wcml-cs-cell-preview{width:100%}.wcml-cs-list .wcml-cs-widget-name,.wcml-cs-list .wcml-cs-actions{width:50%;float:left}.wcml-cs-list .wcml-cs-widget-name{text-align:start}.wcml-cs-list .wcml-cs-actions{text-align:end}}.wcml-currency-preview-wrapper{background-color:#fff;padding:15px 10px 10px;border:1px solid #ccc;width:100%;min-width:150px;min-height:120px;box-sizing:border-box;position:relative;display:flex !important;align-items:center;justify-content:center}.wcml-currency-preview-wrapper .wcml-currency-preview-label{position:absolute;top:5px;left:10px;z-index:101;display:inline-block;padding:2px;background:rgba(255,255,255,0.9)}.wcml-currency-preview-wrapper .spinner{position:absolute;bottom:5px;right:0;z-index:101}.wcml-cs-dialog .wcml-currency-switcher-options-form input{max-width:100%}@media (min-width: 1000px){.wcml-cs-dialog .wcml-currency-switcher-options-form{display:flex;flex-wrap:wrap;align-items:flex-start}.wcml-cs-dialog .wcml-currency-switcher-options-form .wcml-currency-switcher-options{width:60%;order:1;box-sizing:border-box}.wcml-cs-dialog .wcml-currency-switcher-options-form .wcml-currency-switcher-options>h4:first-child{margin-top:0}.wcml-cs-dialog .wcml-currency-switcher-options-form .wcml-currency-preview-wrapper{width:40%;box-sizing:border-box;order:2}.wcml-cs-dialog .wcml-currency-switcher-options-form .wcml-currency-preview-wrapper>div{display:block}}@media (max-width: 999px){.wcml-cs-dialog .wcml-currency-switcher-options-form .wcml-currency-preview-wrapper{margin:-17px -15px 30px -15px;width:calc(100% + 2 * 15px);border-left:0;border-right:0;z-index:10}}.wcml-cs-panel-colors table{width:100%;max-width:600px;font-size:inherit}.wcml-cs-panel-colors table th{text-align:start}.wcml-cs-panel-colors table td{vertical-align:top}.wcml-cs-panel-colors .wp-color-result,.wcml-cs-panel-colors .wp-color-result.button{padding-left:50px;position:relative}@media screen and (max-width: 782px){.wcml-cs-panel-colors .wp-color-result,.wcml-cs-panel-colors .wp-color-result.button{height:22px}}.wcml-cs-panel-colors .wp-color-result:after,.wcml-cs-panel-colors .wp-color-result.button:after{background:transparent;border-radius:0;border-left:0;padding:0;right:0;left:0;position:absolute;content:''}.wcml-cs-panel-colors .wp-color-result.wp-picker-open:after,.wcml-cs-panel-colors .wp-color-result.button.wp-picker-open:after{content:''}.wcml-cs-panel-colors .wp-color-result:not(.wp-picker-open):after,.wcml-cs-panel-colors .wp-color-result.button:not(.wp-picker-open):after{font-family:otgs-icons;content:'\69';color:#333;text-shadow:1px 1px 2px rgba(255,255,255,0.4);font-size:16px;min-width:0}.wcml-cs-panel-colors .wp-color-result.button .wp-color-result-text{display:none !important}.wcml-cs-panel-colors .wp-color-result.button:after{top:-2px}.wcml-cs-panel-colors .wp-picker-container input[type="text"].wp-color-picker{display:inline !important;margin-right:6px}.wcml_product_name{line-height:20px}.wcml_prod_filters{float:left}.wcml_miss_lang p:first-child{float:left}#display_custom_prices_select{display:inline-block;width:100%}.edit_slug_input,.edit_slug_hide_link{display:none}.wcml-tip{cursor:help;color:#555}.wcml-products a{cursor:pointer}@media (max-width: 782px){.column-product_cat,.column-product_tag,.column-product_type{display:none}}.wcml-link-troubleshooting{margin-top:7px}.wcml-status-list li{padding-left:25px;margin-bottom:30px}.wcml-status-list li ul li{margin-bottom:3.5px}.wcml-status-list.wcml-tax-translation-list li{margin-bottom:5px;line-height:26px}.wcml-status-list.wcml-plugins-status-list li{margin-bottom:10px}.wcml-status-list [class*="otgs-ico"]:not(.otgs-ico-help){margin-left:-25px;margin-right:5px;vertical-align:baseline}.wcml-status-list .button-secondary{vertical-align:middle}.wcml-status-list small{display:block}.wcml-lang-list{margin:7px 0}.wcml-lang-list .wpml-title-flag{margin-left:-25px;margin-right:5px}.wcml-dismiss-warning{position:relative;float:right;padding:0;text-decoration:none;outline:none}.wcml-dismiss-warning:active{outline:none}.wcml-notice{background:#fff;box-shadow:0 1px 1px 0 rgba(0,0,0,0.1);margin:5px 0 15px;padding:1px 12px;position:relative}.wcml-notice p{margin:.5em 0;padding:2px}.otgs-is-dismissible{position:relative;padding-right:38px}.otgs-is-dismissible .notice-dismiss{text-decoration:none}.otgs-is-dismissible p [class*="button-"]{margin:-5px 5px}.wcml_tt_spinner{margin-right:15px;display:none}.wcml-product-attributes-selector{text-align:center;margin-bottom:25px}@media (max-width: 1280px){.wcml-product-attributes-selector{margin-left:.2em}}.wcml-product-attributes-selector select{min-width:200px}.wcml-product-custom-taxonomies-selector{text-align:center;margin-bottom:25px}.wcml_attributes_wrap #wpml_tt_taxonomy_translation_wrap>label,.wcml_custom_taxonomies_wrap #wpml_tt_taxonomy_translation_wrap>label{display:none}
res/css/wcml-setup.css CHANGED
@@ -1 +1 @@
1
- .wcml-setup .wcml-setup-actions .button-primary{background:#21759b;border-color:#1d6586;box-shadow:inset 0 1px 0 rgba(255,255,255,0.25),0 1px 0 #1d6586;color:#fff;text-shadow:0 -1px 1px #1d6586,1px 0 1px #1d6586,0 1px 1px #1d6586,-1px 0 1px #1d6586}.wcml-setup .wcml-setup-actions .button-primary:hover,.wcml-setup .wcml-setup-actions .button-primary:focus,.wcml-setup .wcml-setup-actions .button-primary:active{background:#1d688a;border-color:#1d6586}body{margin:100px auto 24px;box-shadow:none;background:#f1f1f1;padding:0}#wcml-logo{border:0;margin:0 0 24px;padding:0;text-align:center}#wcml-logo img{max-width:50%}.wcml-setup-content{box-shadow:0 1px 3px rgba(0,0,0,0.13);padding:24px 24px 0;background:#fff;overflow:hidden;zoom:1}.wcml-setup-content p,.wcml-setup-content li,.wcml-setup-content table{font-size:1em;line-height:1.75em;color:#666}.wcml-setup-content h1,.wcml-setup-content h2,.wcml-setup-content h3,.wcml-setup-content table{margin:0 0 24px;border:0;padding:0;color:#666;clear:none}.wcml-setup-content p{margin:0 0 24px}.wcml-setup-content a{color:#21759b}.wcml-setup-content a:focus,.wcml-setup-content a:hover{color:#111}.wcml-setup-content .wcml-setup-pages{width:100%;border-top:1px solid #eee}.wcml-setup-content .wcml-setup-pages thead th{display:none}.wcml-setup-content .wcml-setup-pages .page-name{width:30%;font-weight:700}.wcml-setup-content .wcml-setup-pages td,.wcml-setup-content .wcml-setup-pages th{padding:14px 0;border-bottom:1px solid #eee}.wcml-setup-content .wcml-setup-pages td:first-child{padding-right:9px}.wcml-setup-content .wcml-setup-pages th{padding-top:0}.wcml-setup-content .wcml-setup-pages th:first-child{padding-right:9px}.wcml-setup-content .wcml-setup-pages .page-options p{color:#777;margin:6px 0 0 24px;line-height:1.75em}.wcml-setup-content .wcml-setup-pages .page-options p input{vertical-align:middle;margin:1px 0 0;height:1.75em;width:1.75em;line-height:1.75em}.wcml-setup-content .wcml-setup-pages .page-options p label{line-height:1}.wcml-setup-content .wcml-setup-next-steps{overflow:hidden;margin:0 0 24px}.wcml-setup-content .wcml-setup-next-steps h2{margin-bottom:12px}.wcml-setup-content .wcml-setup-next-steps .wcml-setup-next-steps-first{float:left;width:50%;box-sizing:border-box}.wcml-setup-content .wcml-setup-next-steps .wcml-setup-next-steps-last{float:right;width:50%;box-sizing:border-box}.wcml-setup-content .wcml-setup-next-steps ul{padding:0 2em 0 0;list-style:none;margin:0 0 -0.75em}.wcml-setup-content .wcml-setup-next-steps ul li a{display:block;padding:0 0 0.75em}.wcml-setup-content .wcml-setup-next-steps ul .setup-product a{background-color:#21759b;border-color:#21759b;box-shadow:inset 0 1px 0 rgba(255,255,255,0.2),0 1px 0 rgba(0,0,0,0.15);font-size:1em;height:auto;line-height:1.75em;margin:0 0 .75em;opacity:1;padding:1em;text-align:center;text-shadow:0 -1px 1px #4A4A4A,1px 0 1px #4A4A4A,0 1px 1px #4A4A4A,-1px 0 1px #4A4A4A}.wcml-setup-content .wcml-setup-next-steps ul li a:before{color:#82878c;font:400 20px/1 dashicons;speak:none;display:inline-block;padding:0 10px 0 0;top:1px;position:relative;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;text-decoration:none !important;vertical-align:top}.wcml-setup-content .wcml-setup-next-steps ul .learn-more a:before{content:""}.wcml-setup-content .wcml-setup-next-steps ul .video-walkthrough a:before{content:""}.wcml-setup-content .wcml-setup-next-steps ul .sidekick a:before{content:""}.wcml-setup-content .wcml-setup-next-steps ul .newsletter a:before{content:""}.wcml-setup-content .updated{padding:24px 24px 0;margin:0 0 24px;overflow:hidden;background:#f5f5f5}.wcml-setup-content .updated p{padding:0;margin:0 0 12px}.wcml-setup-content .updated p:last-child{margin:0 0 24px}.wcml-setup-content .wcml-status-list{list-style:none}.wcml-setup-content .wcml-status-list ul li{list-style:none}.wcml-setup-content .wcml-section-header h3{display:none}.wcml-setup-content .no-bullets li{list-style:none}.wcml-setup-content .otgs-ico-no,.wcml-setup-content .otgs-ico-warning,.wcml-setup-content.otgs-ico-delete{color:#9d261d}.wcml-setup-content .otgs-ico-yes,.wcml-setup-content .otgs-ico-ok{color:#51a351}.wcml-setup-content [class*="otgs-ico"]::before{line-height:1.3em !important}@media screen and (max-width: 782px){.wcml-setup-content .form-table tbody th{width:auto}}.wcml-setup-steps{padding:0 0 24px;margin:0;list-style:none;overflow:hidden;color:#ccc;width:100%;display:-ms-inline-flexbox;display:-webkit-inline-box;display:inline-flex}.wcml-setup-steps li{width:25%;float:left;padding:0 0 .8em;margin:0;text-align:center;position:relative;border-bottom:4px solid #ccc;line-height:1.4em}.wcml-setup-steps li:before{content:"";border:4px solid #ccc;border-radius:100%;width:4px;height:4px;position:absolute;bottom:0;left:50%;margin-left:-6px;margin-bottom:-8px;background:#fff}.wcml-setup-steps li.active{border-color:#21759b;color:#21759b}.wcml-setup-steps li.active:before{border-color:#21759b}.wcml-setup-steps li.done{border-color:#21759b;color:#21759b}.wcml-setup-steps li.done:before{border-color:#21759b;background:#21759b}.wcml-setup .wcml-setup-actions:after{content:'';display:table;clear:both}.wcml-setup .wcml-setup-actions .button{float:right;font-size:1.25em;padding:.5em 1em;line-height:1em;margin-right:.5em;height:auto}.wcml-setup .wcml-setup-actions .button-primary{float:right;margin:0;opacity:1}
1
+ .wcml-setup .wcml-setup-actions .button-primary{background:#21759b;border-color:#1d6586;box-shadow:inset 0 1px 0 rgba(255,255,255,0.25),0 1px 0 #1d6586;color:#fff;text-shadow:0 -1px 1px #1d6586,1px 0 1px #1d6586,0 1px 1px #1d6586,-1px 0 1px #1d6586}.wcml-setup .wcml-setup-actions .button-primary:hover,.wcml-setup .wcml-setup-actions .button-primary:focus,.wcml-setup .wcml-setup-actions .button-primary:active{background:#1d688a;border-color:#1d6586}body{margin:100px auto 24px;box-shadow:none;background:#f1f1f1;padding:0}#wcml-logo{border:0;margin:0 0 24px;padding:0;text-align:center}#wcml-logo img{max-width:50%}.wcml-setup-content{box-shadow:0 1px 3px rgba(0,0,0,0.13);padding:24px 24px 0;background:#fff;overflow:hidden;zoom:1}.wcml-setup-content p,.wcml-setup-content li,.wcml-setup-content table{font-size:1em;line-height:1.75em;color:#666}.wcml-setup-content h1,.wcml-setup-content h2,.wcml-setup-content h3,.wcml-setup-content table{margin:0 0 24px;border:0;padding:0;color:#666;clear:none}.wcml-setup-content p{margin:0 0 24px}.wcml-setup-content a{color:#21759b}.wcml-setup-content a:focus,.wcml-setup-content a:hover{color:#111}.wcml-setup-content .wcml-setup-pages{width:100%;border-top:1px solid #eee}.wcml-setup-content .wcml-setup-pages thead th{display:none}.wcml-setup-content .wcml-setup-pages .page-name{width:30%;font-weight:700}.wcml-setup-content .wcml-setup-pages td,.wcml-setup-content .wcml-setup-pages th{padding:14px 0;border-bottom:1px solid #eee}.wcml-setup-content .wcml-setup-pages td:first-child{padding-right:9px}.wcml-setup-content .wcml-setup-pages th{padding-top:0}.wcml-setup-content .wcml-setup-pages th:first-child{padding-right:9px}.wcml-setup-content .wcml-setup-pages .page-options p{color:#777;margin:6px 0 0 24px;line-height:1.75em}.wcml-setup-content .wcml-setup-pages .page-options p input{vertical-align:middle;margin:1px 0 0;height:1.75em;width:1.75em;line-height:1.75em}.wcml-setup-content .wcml-setup-pages .page-options p label{line-height:1}.wcml-setup-content .wcml-setup-next-steps{overflow:hidden;margin:0 0 24px}.wcml-setup-content .wcml-setup-next-steps h2{margin-bottom:12px}.wcml-setup-content .wcml-setup-next-steps .wcml-setup-next-steps-first{float:left;width:50%;box-sizing:border-box}.wcml-setup-content .wcml-setup-next-steps .wcml-setup-next-steps-last{float:right;width:50%;box-sizing:border-box}.wcml-setup-content .wcml-setup-next-steps ul{padding:0 2em 0 0;list-style:none;margin:0 0 -0.75em}.wcml-setup-content .wcml-setup-next-steps ul li a{display:block;padding:0 0 0.75em}.wcml-setup-content .wcml-setup-next-steps ul .setup-product a{background-color:#21759b;border-color:#21759b;box-shadow:inset 0 1px 0 rgba(255,255,255,0.2),0 1px 0 rgba(0,0,0,0.15);font-size:1em;height:auto;line-height:1.75em;margin:0 0 .75em;opacity:1;padding:1em;text-align:center;text-shadow:0 -1px 1px #4A4A4A,1px 0 1px #4A4A4A,0 1px 1px #4A4A4A,-1px 0 1px #4A4A4A}.wcml-setup-content .wcml-setup-next-steps ul li a:before{color:#82878c;font:400 20px/1 dashicons;speak:none;display:inline-block;padding:0 10px 0 0;top:1px;position:relative;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;text-decoration:none !important;vertical-align:top}.wcml-setup-content .wcml-setup-next-steps ul .learn-more a:before{content:""}.wcml-setup-content .wcml-setup-next-steps ul .video-walkthrough a:before{content:""}.wcml-setup-content .wcml-setup-next-steps ul .sidekick a:before{content:""}.wcml-setup-content .wcml-setup-next-steps ul .newsletter a:before{content:""}.wcml-setup-content .updated{padding:24px 24px 0;margin:0 0 24px;overflow:hidden;background:#f5f5f5}.wcml-setup-content .updated p{padding:0;margin:0 0 12px}.wcml-setup-content .updated p:last-child{margin:0 0 24px}.wcml-setup-content .wcml-status-list{list-style:none}.wcml-setup-content .wcml-status-list ul li{list-style:none}.wcml-setup-content .wcml-section-header h3{display:none}.wcml-setup-content .no-bullets li{list-style:none}.wcml-setup-content .otgs-ico-no,.wcml-setup-content .otgs-ico-warning,.wcml-setup-content.otgs-ico-delete{color:#9d261d}.wcml-setup-content .otgs-ico-yes,.wcml-setup-content .otgs-ico-ok{color:#51a351}.wcml-setup-content [class*="otgs-ico"]::before{line-height:1.3em !important}@media screen and (max-width: 782px){.wcml-setup-content .form-table tbody th{width:auto}}.wcml-setup-steps{padding:0 0 24px;margin:0;list-style:none;overflow:hidden;color:#ccc;width:100%;display:inline-flex}.wcml-setup-steps li{width:25%;float:left;padding:0 0 .8em;margin:0;text-align:center;position:relative;border-bottom:4px solid #ccc;line-height:1.4em}.wcml-setup-steps li:before{content:"";border:4px solid #ccc;border-radius:100%;width:4px;height:4px;position:absolute;bottom:0;left:50%;margin-left:-6px;margin-bottom:-8px;background:#fff}.wcml-setup-steps li.active{border-color:#21759b;color:#21759b}.wcml-setup-steps li.active:before{border-color:#21759b}.wcml-setup-steps li.done{border-color:#21759b;color:#21759b}.wcml-setup-steps li.done:before{border-color:#21759b;background:#21759b}.wcml-setup .wcml-setup-actions:after{content:'';display:table;clear:both}.wcml-setup .wcml-setup-actions .button{float:right;font-size:1.25em;padding:.5em 1em;line-height:1em;margin-right:.5em;height:auto}.wcml-setup .wcml-setup-actions .button-primary{float:right;margin:0;opacity:1}
res/images/banner-772x120.png CHANGED
Binary file
res/js/bacs-accounts-currencies.js ADDED
@@ -0,0 +1,20 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ jQuery(document).ready( function() {
2
+
3
+ var bacs_accounts = jQuery('#bacs_accounts');
4
+ var bacs_accounts_tbody = bacs_accounts.find('tbody');
5
+
6
+ bacs_accounts.find('thead tr').append( '<th>'+wcml_data.label+'</th>' );
7
+ bacs_accounts_tbody.find('tr').each( function( index ){
8
+ jQuery(this).append( '<td>'+wcml_data.currencies_dropdown[index]+'</td>');
9
+ jQuery(this).find('.wcml-currencies').attr('name','bacs-currency['+index+']');
10
+ });
11
+ bacs_accounts.find('a.add').on('mouseup', function(){
12
+ setTimeout(function () {
13
+ var size = bacs_accounts_tbody.find('.account').length -1;
14
+ var last_accounts_element = bacs_accounts_tbody.find('tr:last');
15
+ last_accounts_element.append('<td>' + wcml_data.default_dropdown + '</td>');
16
+ last_accounts_element.find('.wcml-currencies').attr('name','bacs-currency['+size+']');
17
+ }, 100);
18
+ });
19
+
20
+ });
res/js/bacs-accounts-currencies.min.js ADDED
@@ -0,0 +1 @@
 
1
+ jQuery(document).ready(function(){var bacs_accounts=jQuery("#bacs_accounts");var bacs_accounts_tbody=bacs_accounts.find("tbody");bacs_accounts.find("thead tr").append("<th>"+wcml_data.label+"</th>");bacs_accounts_tbody.find("tr").each(function(index){jQuery(this).append("<td>"+wcml_data.currencies_dropdown[index]+"</td>");jQuery(this).find(".wcml-currencies").attr("name","bacs-currency["+index+"]")});bacs_accounts.find("a.add").on("mouseup",function(){setTimeout(function(){var size=bacs_accounts_tbody.find(".account").length-1;var last_accounts_element=bacs_accounts_tbody.find("tr:last");last_accounts_element.append("<td>"+wcml_data.default_dropdown+"</td>");last_accounts_element.find(".wcml-currencies").attr("name","bacs-currency["+size+"]")},100)})});
res/js/dialogs.js CHANGED
@@ -48,7 +48,7 @@ jQuery( function($){
48
  position: { my: 'center', at: 'center', of: window },
49
  modal:true,
50
  width: "90%",
51
- height: window_h * 0.7,
52
  resizable:false,
53
  draggable: data.draggable,
54
  beforeOpen: function (event) {
@@ -56,14 +56,17 @@ jQuery( function($){
56
  beforeClose: function (event) {
57
  },
58
  close: function (event) {
59
- $('body').css('overflow-y', self.overflow_y)
 
60
  },
61
  create: function (event) {
 
62
  },
63
  focus: function (event) {
64
  },
65
  open: function (event) {
66
  $('body').css('overflow', 'hidden');
 
67
 
68
  if( data.class === 'wcml-cs-dialog' ){
69
  WCML_Dialog._attachDialogScrollEvent();
@@ -141,11 +144,14 @@ jQuery( function($){
141
  var winH = $(window).height() - 180;
142
  dialog_div.css("max-height", winH);
143
 
144
- dialog_div.dialog("option", "position", {
145
- my: "center",
146
- at: "center",
147
- of: window
148
- });
 
 
 
149
  }
150
 
151
  WCML_Dialog._attachDialogScrollEvent = function() {
48
  position: { my: 'center', at: 'center', of: window },
49
  modal:true,
50
  width: "90%",
51
+ height: "auto",
52
  resizable:false,
53
  draggable: data.draggable,
54
  beforeOpen: function (event) {
56
  beforeClose: function (event) {
57
  },
58
  close: function (event) {
59
+ $('#jquery-ui-style-css').removeAttr('disabled');
60
+ $('body').css('overflow-y', self.overflow_y);
61
  },
62
  create: function (event) {
63
+
64
  },
65
  focus: function (event) {
66
  },
67
  open: function (event) {
68
  $('body').css('overflow', 'hidden');
69
+ $('#jquery-ui-style-css').attr('disabled', 'disabled');
70
 
71
  if( data.class === 'wcml-cs-dialog' ){
72
  WCML_Dialog._attachDialogScrollEvent();
144
  var winH = $(window).height() - 180;
145
  dialog_div.css("max-height", winH);
146
 
147
+ setTimeout(function() {
148
+ dialog_div.dialog("option", "position", {
149
+ my: "center",
150
+ at: "center",
151
+ of: window
152
+ });
153
+ }, 50);
154
+
155
  }
156
 
157
  WCML_Dialog._attachDialogScrollEvent = function() {
res/js/dialogs.min.js CHANGED
@@ -1 +1 @@
1
- var WCML_Dialog=WCML_Dialog||{};jQuery(function($){var dialog_div;WCML_Dialog.dialog=function(dialog_id,data){var self=this;if(typeof dialog_id=="undefined"){dialog_id="generic"}self.overflow_y=$("body").css("overflow-y");$("body").css("overflow-y","hidden");dialog_div=$("#wcml-dialog-"+dialog_id);var title=$("#"+dialog_id).attr("title");if(typeof title=="undefined"){if(data.title!="undefined"){title=data.title}else{title=""}}if(typeof data.class==="undefined"){data.class=""}if(typeof data.draggable==="undefined"){data.draggable=false}if(!dialog_div.length){$(document.body).append($('<div class="wcml-dialog-container" title="'+title+'" id="wcml-dialog-'+dialog_id+'" />'));dialog_div=$("#wcml-dialog-"+dialog_id);var window_h=$(window).height();var dialog_parameters={title:"",autoOpen:false,show:true,dialogClass:"wcml-ui-dialog otgs-ui-dialog "+data.class,position:{my:"center",at:"center",of:window},modal:true,width:"90%",height:window_h*.7,resizable:false,draggable:data.draggable,beforeOpen:function(event){},beforeClose:function(event){},close:function(event){$("body").css("overflow-y",self.overflow_y)},create:function(event){},focus:function(event){},open:function(event){$("body").css("overflow","hidden");if(data.class==="wcml-cs-dialog"){WCML_Dialog._attachDialogScrollEvent()}},refresh:function(event){}};if(typeof data.height!="undefined"&&data.class!="wcml-cs-dialog"){dialog_parameters.height=Math.min(window_h*.7,data.height)}if(typeof data.width!="undefined"&&data.class!="wcml-cs-dialog"){dialog_parameters.width=data.width}if(WCML_Dialog.using_wpdialog){dialog_div.wpdialog(dialog_parameters)}else{dialog_div.dialog(dialog_parameters).on("dialogopen",function(){WCML_Dialog._repositionDialog()})}}var resizeWindowEvent=_.debounce(function(){WCML_Dialog._repositionDialog();if(data.class==="wcml-cs-dialog"){WCML_Dialog._attachDialogScrollEvent()}},200);if(WCML_Dialog.using_wpdialog){dialog_div.wpdialog("open")}else{dialog_div.dialog("open")}if(data.action){var spinner=$('<div class="spinner"></div>');spinner.css({display:"inline-block",visibility:"visible",float:"none"});dialog_div.html(spinner);$.ajax({url:ajaxurl,type:"post",dataType:"json",data:data,success:function(response){dialog_div.html(response.html)}})}if(data.content&&$("#"+data.content).length){dialog_div.html($("#"+data.content).html())}if(typeof WCML_Tooltip!="undefined"){WCML_Tooltip.init()}$(window).resize(resizeWindowEvent);return false};WCML_Dialog._repositionDialog=function(){var winH=$(window).height()-180;dialog_div.css("max-height",winH);dialog_div.dialog("option","position",{my:"center",at:"center",of:window})};WCML_Dialog._attachDialogScrollEvent=function(){var preview=dialog_div.find(".wcml-currency-preview-wrapper"),has_two_columns=dialog_div.width()>900,has_minimal_height=preview.height()+200<dialog_div.height();has_minimal_height=has_minimal_height||has_two_columns&&preview.height()<dialog_div.height();if(has_minimal_height){dialog_div.on("scroll.preview",function(){dialog_div.find(".wcml-currency-preview-wrapper").css({position:"relative",top:dialog_div.scrollTop()})})}else{dialog_div.off("scroll.preview").find(".wcml-currency-preview-wrapper").css({position:"relative",top:0})}};WCML_Dialog._register_open_handler=function(){$(document).on("click",".js-wcml-dialog-trigger",function(e){e.preventDefault();var dialog_id=false;if($(this).data("dialog")){dialog_id=$(this).data("dialog")}else if($(this).data("action")){dialog_id=$(this).data("action")}if(dialog_id){if($(this).data("action")){$(this).data("action",$(this).data("action").replace(/-/g,"_"))}WCML_Dialog.dialog(dialog_id,$(this).data())}});$(document).on("click",".js-wcml-cs-dialog-trigger",function(e){e.preventDefault();var dialog_id=false;if($(this).data("dialog")){dialog_id=$(this).data("dialog")}var data=$(this).data();data.class="wcml-cs-dialog";data.draggable=true;if(dialog_id){WCML_Dialog.dialog(dialog_id,data);WCML_Currency_Switcher_Settings.initColorPicker();WCML_Currency_Switcher_Settings.currency_switcher_preview($("#wcml-dialog-"+dialog_id))}})};WCML_Dialog._register_close_handler=function(){$(document).on("click",".wcml-dialog-close-button",function(e){e.preventDefault();if(typeof tinyMCE!="undefined"){tinyMCE.triggerSave()}$(".wcml-dialog").find(".mce_editor textarea").each(function(){var editor_id=$(this).attr("id");var editor_area=$(this);if(editor_id in tinyMCE.editors){var tinymce_editor=tinyMCE.get(editor_id);if(!tinymce_editor.isHidden()){editor_area.val(tinymce_editor.getContent())}}});var dialog_div=$(this).closest(".wcml-dialog-container");var elem=$(this);elem.attr("disabled","disabled");var data=$(this).data();if(data.action){var spinner=$('<div class="spinner"></div>');spinner.css({visibility:"visible",float:"right"}).prependTo($(".wcml-dialog-footer .alignright"));$.ajax({url:ajaxurl,type:"post",dataType:"json",data:{action:data.action,fields:elem.closest(".wcml-dialog-container").find("form").serialize(),icl_nonce:data.nonce},async:false,success:function(response){if(data.stay){spinner.remove();elem.removeAttr("disabled")}}})}if(!data.stay){elem.trigger("before_close_dialog");if(WCML_Dialog.using_wpdialog){dialog_div.wpdialog("close")}else{dialog_div.dialog("close")}}})};WCML_Dialog.init=function(){$(document).ready(function(){if(typeof $.wp!="undefined"){WCML_Dialog.using_wpdialog=typeof $.wp.wpdialog!="undefined"}else{WCML_Dialog.using_wpdialog=false}WCML_Dialog._register_open_handler();WCML_Dialog._register_close_handler()})};WCML_Dialog.init()});
1
+ var WCML_Dialog=WCML_Dialog||{};jQuery(function(s){var d;WCML_Dialog.dialog=function(i,o){var t=this;void 0===i&&(i="generic"),t.overflow_y=s("body").css("overflow-y"),s("body").css("overflow-y","hidden"),d=s("#wcml-dialog-"+i);var a=s("#"+i).attr("title");if(void 0===a&&(a="undefined"!=o.title?o.title:""),void 0===o.class&&(o.class=""),void 0===o.draggable&&(o.draggable=!1),!d.length){s(document.body).append(s('<div class="wcml-dialog-container" title="'+a+'" id="wcml-dialog-'+i+'" />')),d=s("#wcml-dialog-"+i);var e=s(window).height(),l={title:"",autoOpen:!1,show:!0,dialogClass:"wcml-ui-dialog otgs-ui-dialog "+o.class,position:{my:"center",at:"center",of:window},modal:!0,width:"90%",height:"auto",resizable:!1,draggable:o.draggable,beforeOpen:function(i){},beforeClose:function(i){},close:function(i){s("#jquery-ui-style-css").removeAttr("disabled"),s("body").css("overflow-y",t.overflow_y)},create:function(i){},focus:function(i){},open:function(i){s("body").css("overflow","hidden"),s("#jquery-ui-style-css").attr("disabled","disabled"),"wcml-cs-dialog"===o.class&&WCML_Dialog._attachDialogScrollEvent()},refresh:function(i){}};void 0!==o.height&&"wcml-cs-dialog"!=o.class&&(l.height=Math.min(.7*e,o.height)),void 0!==o.width&&"wcml-cs-dialog"!=o.class&&(l.width=o.width),WCML_Dialog.using_wpdialog?d.wpdialog(l):d.dialog(l).on("dialogopen",function(){WCML_Dialog._repositionDialog()})}var n=_.debounce(function(){WCML_Dialog._repositionDialog(),"wcml-cs-dialog"===o.class&&WCML_Dialog._attachDialogScrollEvent()},200);if(WCML_Dialog.using_wpdialog?d.wpdialog("open"):d.dialog("open"),o.action){var c=s('<div class="spinner"></div>');c.css({display:"inline-block",visibility:"visible",float:"none"}),d.html(c),s.ajax({url:ajaxurl,type:"post",dataType:"json",data:o,success:function(i){d.html(i.html)}})}return o.content&&s("#"+o.content).length&&d.html(s("#"+o.content).html()),"undefined"!=typeof WCML_Tooltip&&WCML_Tooltip.init(),s(window).resize(n),!1},WCML_Dialog._repositionDialog=function(){var i=s(window).height()-180;d.css("max-height",i),setTimeout(function(){d.dialog("option","position",{my:"center",at:"center",of:window})},50)},WCML_Dialog._attachDialogScrollEvent=function(){var i=d.find(".wcml-currency-preview-wrapper"),o=900<d.width(),t=i.height()+200<d.height();(t=t||o&&i.height()<d.height())?d.on("scroll.preview",function(){d.find(".wcml-currency-preview-wrapper").css({position:"relative",top:d.scrollTop()})}):d.off("scroll.preview").find(".wcml-currency-preview-wrapper").css({position:"relative",top:0})},WCML_Dialog._register_open_handler=function(){s(document).on("click",".js-wcml-dialog-trigger",function(i){i.preventDefault();var o=!1;s(this).data("dialog")?o=s(this).data("dialog"):s(this).data("action")&&(o=s(this).data("action")),o&&(s(this).data("action")&&s(this).data("action",s(this).data("action").replace(/-/g,"_")),WCML_Dialog.dialog(o,s(this).data()))}),s(document).on("click",".js-wcml-cs-dialog-trigger",function(i){i.preventDefault();var o=!1;s(this).data("dialog")&&(o=s(this).data("dialog"));var t=s(this).data();t.class="wcml-cs-dialog",t.draggable=!0,o&&(WCML_Dialog.dialog(o,t),WCML_Currency_Switcher_Settings.initColorPicker(),WCML_Currency_Switcher_Settings.currency_switcher_preview(s("#wcml-dialog-"+o)))})},WCML_Dialog._register_close_handler=function(){s(document).on("click",".wcml-dialog-close-button",function(i){i.preventDefault(),"undefined"!=typeof tinyMCE&&tinyMCE.triggerSave(),s(".wcml-dialog").find(".mce_editor textarea").each(function(){var i=s(this).attr("id"),o=s(this);if(i in tinyMCE.editors){var t=tinyMCE.get(i);t.isHidden()||o.val(t.getContent())}});var o=s(this).closest(".wcml-dialog-container"),t=s(this);t.attr("disabled","disabled");var a=s(this).data();if(a.action){var e=s('<div class="spinner"></div>');e.css({visibility:"visible",float:"right"}).prependTo(s(".wcml-dialog-footer .alignright")),s.ajax({url:ajaxurl,type:"post",dataType:"json",data:{action:a.action,fields:t.closest(".wcml-dialog-container").find("form").serialize(),icl_nonce:a.nonce},async:!1,success:function(i){a.stay&&(e.remove(),t.removeAttr("disabled"))}})}a.stay||(t.trigger("before_close_dialog"),WCML_Dialog.using_wpdialog?o.wpdialog("close"):o.dialog("close"))})},WCML_Dialog.init=function(){s(document).ready(function(){void 0!==s.wp?WCML_Dialog.using_wpdialog=void 0!==s.wp.wpdialog:WCML_Dialog.using_wpdialog=!1,WCML_Dialog._register_open_handler(),WCML_Dialog._register_close_handler()})},WCML_Dialog.init()});
res/js/multi-currency.js CHANGED
@@ -1,4 +1,3 @@
1
-
2
  jQuery( function($){
3
 
4
  WCML_Multi_Currency = {
@@ -31,6 +30,9 @@ jQuery( function($){
31
  $(document).on('change','.currency_option_decimal_sep', WCML_Multi_Currency.price_preview);
32
  $(document).on('change','.currency_option_decimals', WCML_Multi_Currency.price_preview);
33
  $(document).on('change','.currency_code select', WCML_Multi_Currency.price_preview);
 
 
 
34
 
35
  $(document).on('keypress', '.currency_option_decimals', function (event) {
36
  // 8 for backspace, 0 for null values, 48-57 for 0-9 numbers
@@ -81,10 +83,18 @@ jQuery( function($){
81
  select_currency: function(){
82
  var parent = $(this).closest('.wcml_currency_options');
83
  var close_button = parent.find('.wcml-dialog-close-button');
 
 
 
 
 
84
  close_button.attr('data-currency', $(this).val());
85
  close_button.attr('data-symbol', $(this).find('option:selected').attr('data-symbol'));
86
- parent.find('.this-currency').html( $(this).val() );
87
 
 
 
 
 
88
  },
89
 
90
  delete_currency: function(e){
@@ -122,7 +132,7 @@ jQuery( function($){
122
  success: function(response) {
123
  $('#currency_row_' + currency).remove();
124
  $('#currency_row_langs_' + currency).remove();
125
- $('#currency_row_del_' + currency).remove();
126
 
127
  $('#wcml_currencies_order .wcml_currencies_order_'+ currency).remove();
128
 
@@ -186,12 +196,6 @@ jQuery( function($){
186
  var tr = $('#currency-table tr.wcml-row-currency:last').clone();
187
  tr.attr('id', 'currency_row_' + currency);
188
 
189
- var edit_link = tr.find('.wcml-col-edit a');
190
- edit_link.attr('data-content', 'wcml_currency_options_' + currency);
191
- edit_link.attr('data-currency', currency);
192
- edit_link.data('dialog', 'wcml_currency_options_' + currency);
193
- edit_link.removeClass('hidden');
194
-
195
  $('#currency-table').find('tr.default_currency').before( tr );
196
 
197
  var tr = $('.empty-currency-language-row').clone();
@@ -213,21 +217,33 @@ jQuery( function($){
213
  //add to orders list
214
  $('#wcml_currencies_order').append('<li class="wcml_currencies_order_'+currency+' ui-sortable-handle" cur="'+currency+'">'+response.currency_name_formatted+'</li>');
215
 
216
- var tr = $('#currency-delete-table tr.wcml-row-currency-del:last').clone();
217
- tr.attr('id', 'currency_row_del_' + currency);
218
 
219
- var del_link = tr.find('.delete_currency');
 
 
 
 
 
 
 
 
 
220
  del_link.removeClass('hidden');
221
  del_link.attr('data-currency', currency);
222
  del_link.attr('data-currency_name', response.currency_name);
223
  del_link.attr('data-currency_symbol', response.currency_symbol);
224
- $('#currency-delete-table').find('tr.default_currency').before( tr );
225
 
226
  }
227
 
228
  $('#currency_row_' + currency + ' .wcml-col-currency').html(response.currency_name_formatted);
229
  $('#currency_row_' + currency + ' .wcml-col-rate').html(response.currency_meta_info);
230
 
 
 
 
 
 
231
  $('#wcml_currency_options_' + currency).remove();
232
  $('#wcml_mc_options').before(response.currency_options);
233
 
@@ -237,8 +253,17 @@ jQuery( function($){
237
  $('#online-exchange-rates-no-currencies').hide();
238
  $('#online-exchange-rates-no-currencies').next().show();
239
  }
240
- }
241
 
 
 
 
 
 
 
 
 
 
 
242
  })
243
 
244
  return false;
@@ -511,6 +536,40 @@ jQuery( function($){
511
 
512
  },
513
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
514
  read_form_fields_status: function(){
515
  this.mc_form_status = $('#wcml_mc_options').serialize();
516
  },
 
1
  jQuery( function($){
2
 
3
  WCML_Multi_Currency = {
30
  $(document).on('change','.currency_option_decimal_sep', WCML_Multi_Currency.price_preview);
31
  $(document).on('change','.currency_option_decimals', WCML_Multi_Currency.price_preview);
32
  $(document).on('change','.currency_code select', WCML_Multi_Currency.price_preview);
33
+ $(document).on('change','.wcml-gateways-enabled', WCML_Multi_Currency.display_gateways);
34
+ $(document).on('change','#wcml_currency_options_gateway_code_paypal', WCML_Multi_Currency.preset_paypal_email);
35
+ $(document).on('change','#wcml_currency_options_gateway_code_stripe', WCML_Multi_Currency.preset_stripe_settings);
36
 
37
  $(document).on('keypress', '.currency_option_decimals', function (event) {
38
  // 8 for backspace, 0 for null values, 48-57 for 0-9 numbers
83
  select_currency: function(){
84
  var parent = $(this).closest('.wcml_currency_options');
85
  var close_button = parent.find('.wcml-dialog-close-button');
86
+ var previous_currency = parent.find('.this-currency').text();
87
+ var gateways = parent.find('.wcml-gateways-switcher');
88
+ var gateways_currency_select = parent.find('.wcml-gateways select[name*="[currency]"] option[value="'+previous_currency+'"]');
89
+ var gateway_new_label_text = gateways.find('label.otgs-on-off-switch').text().replace( previous_currency, $(this).val() );
90
+
91
  close_button.attr('data-currency', $(this).val());
92
  close_button.attr('data-symbol', $(this).find('option:selected').attr('data-symbol'));
 
93
 
94
+ parent.find('.this-currency').html( $(this).val() );
95
+ gateways.find('label.otgs-on-off-switch').text( gateway_new_label_text );
96
+ gateways_currency_select.val( $(this).val() );
97
+ gateways_currency_select.html( $(this).val() );
98
  },
99
 
100
  delete_currency: function(e){
132
  success: function(response) {
133
  $('#currency_row_' + currency).remove();
134
  $('#currency_row_langs_' + currency).remove();
135
+ $('#wcml-row-currency-actions-' + currency).remove();
136
 
137
  $('#wcml_currencies_order .wcml_currencies_order_'+ currency).remove();
138
 
196
  var tr = $('#currency-table tr.wcml-row-currency:last').clone();
197
  tr.attr('id', 'currency_row_' + currency);
198
 
 
 
 
 
 
 
199
  $('#currency-table').find('tr.default_currency').before( tr );
200
 
201
  var tr = $('.empty-currency-language-row').clone();
217
  //add to orders list
218
  $('#wcml_currencies_order').append('<li class="wcml_currencies_order_'+currency+' ui-sortable-handle" cur="'+currency+'">'+response.currency_name_formatted+'</li>');
219
 
 
 
220
 
221
+ var settings_row = $('#currency-settings-table tr.wcml-row-currencies-actions:last').clone();
222
+ settings_row.attr('id', 'wcml-row-currency-actions-' + currency);
223
+
224
+ var edit_link = settings_row.find('.wcml-col-edit a');
225
+ edit_link.attr('data-content', 'wcml_currency_options_' + currency);
226
+ edit_link.attr('data-currency', currency);
227
+ edit_link.data('dialog', 'wcml_currency_options_' + currency);
228
+ edit_link.removeClass('hidden');
229
+
230
+ var del_link = settings_row.find('.delete_currency');
231
  del_link.removeClass('hidden');
232
  del_link.attr('data-currency', currency);
233
  del_link.attr('data-currency_name', response.currency_name);
234
  del_link.attr('data-currency_symbol', response.currency_symbol);
235
+ $('#currency-settings-table').find('tr.default_currency').before( settings_row );
236
 
237
  }
238
 
239
  $('#currency_row_' + currency + ' .wcml-col-currency').html(response.currency_name_formatted);
240
  $('#currency_row_' + currency + ' .wcml-col-rate').html(response.currency_meta_info);
241
 
242
+ var gateways_switcher = $('#wcml_currency_options_' + currency).find('.wcml-gateways-switcher');
243
+ if( 0 == gateways_switcher.length ){
244
+ gateways_switcher = $('#wcml_currency_options_').find('.wcml-gateways-switcher').clone();
245
+ }
246
+
247
  $('#wcml_currency_options_' + currency).remove();
248
  $('#wcml_mc_options').before(response.currency_options);
249
 
253
  $('#online-exchange-rates-no-currencies').hide();
254
  $('#online-exchange-rates-no-currencies').next().show();
255
  }
 
256
 
257
+ var currency_options_dialog = $('#wcml_currency_options_' + currency);
258
+ var is_gateway_switcher_checked = currency_options_dialog.find('.wcml-gateways-switcher input[type="checkbox"]:checked').length > 0;
259
+ currency_options_dialog.find('.wcml-gateways-switcher').remove();
260
+ currency_options_dialog.find('.wcml-gateways').before(gateways_switcher);
261
+ if( is_gateway_switcher_checked ){
262
+ currency_options_dialog.find('.wcml-gateways-switcher input[type="checkbox"]').attr('checked', 'checked');
263
+ }else{
264
+ currency_options_dialog.find('.wcml-gateways-switcher input[type="checkbox"]').removeAttr('checked');
265
+ }
266
+ }
267
  })
268
 
269
  return false;
536
 
537
  },
538
 
539
+ display_gateways: function(){
540
+
541
+ if ($(this).attr('checked') == 'checked') {
542
+ $('.wcml-gateways').slideDown();
543
+ WCML_Tooltip.init();
544
+ } else {
545
+ $('.wcml-gateways').slideUp();
546
+ }
547
+ },
548
+
549
+ preset_paypal_email: function(){
550
+
551
+ var paypal_value_input = $('input[name="currency_options[gateways_settings][paypal][value]"]');
552
+ var paypal_warning = $('.paypal-gateway-warning');
553
+
554
+ paypal_value_input.val( $(this).find(":selected").data('email') );
555
+
556
+ if( $(this).find(":selected").data('is-valid') ){
557
+ paypal_warning.hide();
558
+ paypal_value_input.removeAttr('readonly');
559
+ }else{
560
+ paypal_warning.show();
561
+ paypal_value_input.val('');
562
+ paypal_value_input.attr('readonly','readonly');
563
+ }
564
+ },
565
+
566
+ preset_stripe_settings: function(){
567
+
568
+ $('input[name="currency_options[gateways_settings][stripe][publishable_key]"]').val( $(this).find(":selected").data('publishable-key') );
569
+ $('input[name="currency_options[gateways_settings][stripe][secret_key]"]').val( $(this).find(":selected").data('secret-key') );
570
+
571
+ },
572
+
573
  read_form_fields_status: function(){
574
  this.mc_form_status = $('#wcml_mc_options').serialize();
575
  },
res/js/multi-currency.min.js CHANGED
@@ -1 +1 @@
1
- jQuery(function($){WCML_Multi_Currency={_currency_languages_saving:0,init:function(){$(document).ready(function(){WCML_Multi_Currency.setup_multi_currency_toggle();$(document).on("change",".currency_code select",WCML_Multi_Currency.select_currency);$(document).on("click",".delete_currency",WCML_Multi_Currency.delete_currency);$(document).on("click",".wcml_currency_options .currency_options_save",WCML_Multi_Currency.save_currency);$(document).on("click",".js-display-tooltip",WCML_Multi_Currency.tooltip);$(document).on("click",".currency_languages a.otgs-ico-no",WCML_Multi_Currency.enable_currency_for_language);$(document).on("click",".currency_languages a.otgs-ico-yes",WCML_Multi_Currency.disable_currency_for_language);$(document).on("change",".default_currency select",WCML_Multi_Currency.change_default_currency);WCML_Multi_Currency.setup_currencies_sorting();$(document).on("change",".currency_option_position",WCML_Multi_Currency.price_preview);$(document).on("change",".currency_option_thousand_sep",WCML_Multi_Currency.price_preview);$(document).on("change",".currency_option_decimal_sep",WCML_Multi_Currency.price_preview);$(document).on("change",".currency_option_decimals",WCML_Multi_Currency.price_preview);$(document).on("change",".currency_code select",WCML_Multi_Currency.price_preview);$(document).on("keypress",".currency_option_decimals",function(event){if(event.which!=8&&event.which!=0&&event.which<48||event.which>57){event.preventDefault()}});$(document).on("keyup",".wcml-exchange-rate",WCML_Multi_Currency.exchange_rate_check);if($("#wcml_mc_options").length){WCML_Multi_Currency.wcml_mc_form_submitted=false;WCML_Multi_Currency.read_form_fields_status();window.onbeforeunload=function(e){if(!WCML_Multi_Currency.wcml_mc_form_submitted&&WCML_Multi_Currency.form_fields_changed()||WCML_Multi_Currency.is_update_currency_lang_in_progress()){return $("#wcml_warn_message").val()}};$("#wcml_mc_options").on("submit",function(){WCML_Multi_Currency.wcml_mc_form_submitted=true})}})},setup_multi_currency_toggle:function(){$("#multi_currency_independent").change(function(){if($(this).attr("checked")=="checked"){$("#currency-switcher, #currency-switcher-widget, #currency-switcher-product, #multi-currency-per-language-details, #online-exchange-rates").fadeIn()}else{$("#currency-switcher, #currency-switcher-widget, #currency-switcher-product, #multi-currency-per-language-details, #online-exchange-rates").fadeOut()}})},select_currency:function(){var parent=$(this).closest(".wcml_currency_options");var close_button=parent.find(".wcml-dialog-close-button");close_button.attr("data-currency",$(this).val());close_button.attr("data-symbol",$(this).find("option:selected").attr("data-symbol"));parent.find(".this-currency").html($(this).val())},delete_currency:function(e){e.preventDefault();var is_return=false;var currency=$(this).data("currency");var currency_name=$(this).data("currency_name");var currency_symbol=$(this).data("currency_symbol");$(".currency_lang_table .wcml-row-currency-lang:first .currency_languages").each(function(){if(!WCML_Multi_Currency.check_currency_language($(this).find("li").data("lang"),currency)){is_return=true;return false}});if(is_return){return}$("#currency_row_"+currency+" .currency_action_update").hide();var ajaxLoader=$('<span class="spinner" style="visibility: visible;margin:0;">');$(this).hide();$(this).parent().append(ajaxLoader).show();$.ajax({type:"post",url:ajaxurl,data:{action:"wcml_delete_currency",wcml_nonce:$("#del_currency_nonce").val(),code:currency},success:function(response){$("#currency_row_"+currency).remove();$("#currency_row_langs_"+currency).remove();$("#currency_row_del_"+currency).remove();$("#wcml_currencies_order .wcml_currencies_order_"+currency).remove();$("#wcml_currency_options_code_").prepend('<option data-symbol="'+currency_symbol+'" value="'+currency+'">'+currency_name+"</option>");$("#wcml_currency_options_code_").val(currency).trigger("change");$("#currency-lang-table").find("tr.default_currency select").each(function(){$(this).find("option[value='"+currency+"']").remove()});$(".wcml-ui-dialog").each(function(){WCML_Currency_Switcher_Settings.currency_switcher_preview($(this))});if($(".wcml-row-currency").length==1){$("#online-exchange-rates-no-currencies").next().hide();$("#online-exchange-rates-no-currencies").show()}},done:function(){ajaxLoader.remove()}});return false},save_currency:function(){var parent=$(this).closest(".wcml-dialog-container");var chk_autosub=WCML_Multi_Currency.check_on_numeric(parent,".abstract_amount");if(chk_autosub){return false}$(".wcml-currency-options-dialog :submit, .wcml-currency-options-dialog :button").prop("disabled",true);var currency=parent.find('[name="currency_options[code]"]').val();var ajaxLoader=$('<span class="spinner" style="visibility:visible;position:absolute;margin-left:10px;"></span>');ajaxLoader.show();$(this).parent().prepend(ajaxLoader);$.ajax({url:ajaxurl,type:"POST",dataType:"json",data:parent.find('[name^="currency_options"]').serialize()+"&action=wcml_save_currency&wcml_nonce="+jQuery("#wcml_save_currency_nonce").val(),success:function(response){parent.find(".wcml-dialog-close-button").trigger("click");$(".wcml-ui-dialog").each(function(){WCML_Currency_Switcher_Settings.currency_switcher_preview($(this))});if($("#currency_row_"+currency).length==0){var tr=$("#currency-table tr.wcml-row-currency:last").clone();tr.attr("id","currency_row_"+currency);var edit_link=tr.find(".wcml-col-edit a");edit_link.attr("data-content","wcml_currency_options_"+currency);edit_link.attr("data-currency",currency);edit_link.data("dialog","wcml_currency_options_"+currency);edit_link.removeClass("hidden");$("#currency-table").find("tr.default_currency").before(tr);var tr=$(".empty-currency-language-row").clone();tr.attr("id","currency_row_langs_"+currency);$("#currency-lang-table").find("tr.default_currency").before(tr);tr.removeClass("hidden empty-currency-language-row");tr.find(".on a").each(function(){$(this).attr("data-currency",currency);$(this).attr("title",$(this).attr("title").replace("%code%",response.currency_name));$(this).attr("data-title-alt",$(this).attr("data-title-alt").replace("%code%",response.currency_name))});$("#currency-lang-table").find("tr.default_currency select").each(function(){$(this).append('<option value="'+currency+'">'+currency+"</option>")});$("#wcml_currencies_order").append('<li class="wcml_currencies_order_'+currency+' ui-sortable-handle" cur="'+currency+'">'+response.currency_name_formatted+"</li>");var tr=$("#currency-delete-table tr.wcml-row-currency-del:last").clone();tr.attr("id","currency_row_del_"+currency);var del_link=tr.find(".delete_currency");del_link.removeClass("hidden");del_link.attr("data-currency",currency);del_link.attr("data-currency_name",response.currency_name);del_link.attr("data-currency_symbol",response.currency_symbol);$("#currency-delete-table").find("tr.default_currency").before(tr)}$("#currency_row_"+currency+" .wcml-col-currency").html(response.currency_name_formatted);$("#currency_row_"+currency+" .wcml-col-rate").html(response.currency_meta_info);$("#wcml_currency_options_"+currency).remove();$("#wcml_mc_options").before(response.currency_options);$('#wcml_currency_options_code_ option[value="'+currency+'"]').remove();if($("#online-exchange-rates-no-currencies").is(":visible")){$("#online-exchange-rates-no-currencies").hide();$("#online-exchange-rates-no-currencies").next().show()}}});return false},check_on_numeric:function(parent,elem){var messageContainer=$('<span class="wcml-error">');if(!WCML_Multi_Currency.is_number(parent.find(elem).val())){if(parent.find(elem).parent().find(".wcml-error").size()==0){parent.find(elem).parent().append(messageContainer);messageContainer.text(parent.find(elem).data("message"))}return true}else{if(parent.find(elem).parent().find(".wcml-error").size()>0){parent.find(elem).parent().find(".wcml-error").remove()}return false}},tooltip:function(){var $thiz=$(this);$(".wp-pointer").fadeOut(100);$(this).pointer({content:"<h3>"+$thiz.data("header")+"</h3><p>"+$thiz.data("content")+"</p>",position:{edge:"left",align:"center",offset:"15 0"}}).pointer("open")},enable_currency_for_language:function(e){if(WCML_Multi_Currency.is_update_currency_lang_in_progress())return false;e.preventDefault();$(this).addClass("spinner").removeClass("otgs-ico-no").css("visibility","visible");var index=$(this).closest("tr")[0].rowIndex;$('.default_currency select[rel="'+$(this).data("language")+'"]').append('<option value="'+$(this).data("currency")+'">'+$(this).data("currency")+"</option>");WCML_Multi_Currency.update_currency_lang($(this),1,0);var title_alt=$(this).data("title-alt");$(this).data("title-alt",$(this).attr("title"));$(this).attr("title",title_alt)},disable_currency_for_language:function(e){if(WCML_Multi_Currency.is_update_currency_lang_in_progress())return false;e.preventDefault();$(this).addClass("spinner").removeClass("otgs-ico-yes").css("visibility","visible");var lang=$(this).data("language");if(!WCML_Multi_Currency.check_currency_language(lang)){$(this).removeClass("spinner").addClass("otgs-ico-yes");return}var index=$(this).closest("tr")[0].rowIndex;if($('.currency_languages select[rel="'+$(this).data("language")+'"]').val()==$(this).data("currency")){WCML_Multi_Currency.update_currency_lang($(this),0,1)}else{WCML_Multi_Currency.update_currency_lang($(this),0,0)}$('.default_currency select[rel="'+$(this).data("language")+'"] option[value="'+$(this).data("currency")+'"]').remove();var title_alt=$(this).data("title-alt");$(this).data("title-alt",$(this).attr("title"));$(this).attr("title",title_alt)},check_currency_language:function(lang,currency){var elem=$('#currency-lang-table a.otgs-ico-yes[data-language="'+lang+'"]');if(currency){elem=$('#currency-lang-table a.otgs-ico-yes[data-language="'+lang+'"]').not($('[data-currency="'+currency+'"]'))}if(elem.length==0){alert($("#wcml_warn_disable_language_massage").val());return false}return true},is_update_currency_lang_in_progress:function(){var is=typeof WCML_Multi_Currency._update_currency_lang_sync_flag!="undefined"&&WCML_Multi_Currency._update_currency_lang_sync_flag==1;return is},set_update_currency_lang_in_progress:function(val){WCML_Multi_Currency._update_currency_lang_sync_flag=val},update_currency_lang:function(elem,value,upd_def){WCML_Multi_Currency._currency_languages_saving++;$("#wcml_mc_options :submit").attr("disabled","disabled");$('input[name="wcml_mc_options"]').attr("disabled","disabled");var lang=elem.data("language");var code=elem.data("currency");discard=true;WCML_Multi_Currency.set_update_currency_lang_in_progress(1);$.ajax({type:"post",url:ajaxurl,data:{action:"wcml_update_currency_lang",value:value,lang:lang,code:code,wcml_nonce:$("#update_currency_lang_nonce").val()},success:function(){if(upd_def){WCML_Multi_Currency.update_default_currency(lang,0)}},complete:function(){$('input[name="wcml_mc_options"]').removeAttr("disabled");discard=false;elem.removeClass("spinner").css("visibility","visible");if(value){elem.addClass("otgs-ico-yes")}else{elem.addClass("otgs-ico-no")}WCML_Multi_Currency._currency_languages_saving--;if(WCML_Multi_Currency._currency_languages_saving==0){$("#wcml_mc_options :submit").removeAttr("disabled")}WCML_Multi_Currency.set_update_currency_lang_in_progress(0)}})},change_default_currency:function(){WCML_Multi_Currency.update_default_currency($(this).attr("rel"),$(this).val(),$(this))},update_default_currency:function(lang,code,select){$("#wcml_mc_options_submit").attr("disabled","disabled");if(select){var ajaxLoader=$('<span class="spinner" style="visibility: visible;float:none;position: absolute">');select.parent().append(ajaxLoader)}discard=true;$.ajax({type:"post",url:ajaxurl,data:{action:"wcml_update_default_currency",lang:lang,code:code,wcml_nonce:$("#wcml_update_default_currency_nonce").val()},complete:function(){discard=false;$("#wcml_mc_options_submit").removeAttr("disabled");if(select){select.parent().find(".spinner").remove()}}})},is_number:function(n){return!isNaN(parseFloat(n))&&isFinite(n)},setup_currencies_sorting:function(){$("#wcml_currencies_order").sortable({update:function(){var currencies_order=[];$("#wcml_currencies_order").find("li").each(function(){currencies_order.push($(this).attr("cur"))});$.ajax({type:"POST",url:ajaxurl,dataType:"json",data:{action:"wcml_currencies_order",wcml_nonce:$("#wcml_currencies_order_order_nonce").val(),order:currencies_order.join(";")},success:function(resp){if(resp.success){fadeInAjxResp(".wcml_currencies_order_ajx_resp",resp.data.message);$(".wcml-ui-dialog").each(function(){WCML_Currency_Switcher_Settings.currency_switcher_preview($(this))})}}})}})},price_preview:function(){var parent=$(this).closest(".wcml_currency_options");var position=parent.find(".currency_option_position").val();var thousand_sep=parent.find(".currency_option_thousand_sep").val();var thousand_sep=parent.find(".currency_option_thousand_sep").val();var decimal_sep=parent.find(".currency_option_decimal_sep").val();var symbol=$(this).closest(".wcml_currency_options").find(".wcml-dialog-close-button").attr("data-symbol");var decimals="56789".substr(0,parent.find(".currency_option_decimals").val());if(decimals==""){decimal_sep=""}var format="";switch(position){case"left":format="{symbol}1{thousand_sep}234{decimal_sep}{decimals}";break;case"right":format="1{thousand_sep}234{decimal_sep}{decimals}{symbol}";break;case"left_space":format="{symbol}&nbsp;1{thousand_sep}234{decimal_sep}{decimals}";break;case"right_space":format="1{thousand_sep}234{decimal_sep}{decimals}&nbsp;{symbol}";break}var preview=format.replace(/\{symbol\}/,symbol).replace(/\{thousand_sep\}/,thousand_sep).replace(/\{decimal_sep\}/,decimal_sep).replace(/\{decimals\}/,decimals);parent.find(".wcml-co-preview-value").html(preview);return false},read_form_fields_status:function(){this.mc_form_status=$("#wcml_mc_options").serialize()},form_fields_changed:function(){return this.mc_form_status!=$("#wcml_mc_options").serialize()},exchange_rate_check:function(e){if(typeof KeyEvent=="undefined"){var KeyEvent={DOM_SUBTRACT:109,DOM_DASH:189,DOM_E:69}}if($(this).val()<=0||!WCML_Multi_Currency.is_number($(this).val())||e.keyCode==KeyEvent.DOM_SUBTRACT||e.keyCode==KeyEvent.DOM_DASH||e.keyCode==KeyEvent.DOM_E){$(".wcml-co-set-rate .wcml-error").fadeIn();$(".currency_options_save").attr("disabled","disabled")}else{$(".wcml-co-set-rate .wcml-error").fadeOut();$(".currency_options_save").removeAttr("disabled")}}};WCML_Multi_Currency.init()});
1
+ jQuery(function(u){WCML_Multi_Currency={_currency_languages_saving:0,init:function(){u(document).ready(function(){WCML_Multi_Currency.setup_multi_currency_toggle(),u(document).on("change",".currency_code select",WCML_Multi_Currency.select_currency),u(document).on("click",".delete_currency",WCML_Multi_Currency.delete_currency),u(document).on("click",".wcml_currency_options .currency_options_save",WCML_Multi_Currency.save_currency),u(document).on("click",".js-display-tooltip",WCML_Multi_Currency.tooltip),u(document).on("click",".currency_languages a.otgs-ico-no",WCML_Multi_Currency.enable_currency_for_language),u(document).on("click",".currency_languages a.otgs-ico-yes",WCML_Multi_Currency.disable_currency_for_language),u(document).on("change",".default_currency select",WCML_Multi_Currency.change_default_currency),WCML_Multi_Currency.setup_currencies_sorting(),u(document).on("change",".currency_option_position",WCML_Multi_Currency.price_preview),u(document).on("change",".currency_option_thousand_sep",WCML_Multi_Currency.price_preview),u(document).on("change",".currency_option_decimal_sep",WCML_Multi_Currency.price_preview),u(document).on("change",".currency_option_decimals",WCML_Multi_Currency.price_preview),u(document).on("change",".currency_code select",WCML_Multi_Currency.price_preview),u(document).on("change",".wcml-gateways-enabled",WCML_Multi_Currency.display_gateways),u(document).on("change","#wcml_currency_options_gateway_code_paypal",WCML_Multi_Currency.preset_paypal_email),u(document).on("change","#wcml_currency_options_gateway_code_stripe",WCML_Multi_Currency.preset_stripe_settings),u(document).on("keypress",".currency_option_decimals",function(e){(8!=e.which&&0!=e.which&&e.which<48||57<e.which)&&e.preventDefault()}),u(document).on("keyup",".wcml-exchange-rate",WCML_Multi_Currency.exchange_rate_check),u("#wcml_mc_options").length&&(WCML_Multi_Currency.wcml_mc_form_submitted=!1,WCML_Multi_Currency.read_form_fields_status(),window.onbeforeunload=function(e){if(!WCML_Multi_Currency.wcml_mc_form_submitted&&WCML_Multi_Currency.form_fields_changed()||WCML_Multi_Currency.is_update_currency_lang_in_progress())return u("#wcml_warn_message").val()},u("#wcml_mc_options").on("submit",function(){WCML_Multi_Currency.wcml_mc_form_submitted=!0}))})},setup_multi_currency_toggle:function(){u("#multi_currency_independent").change(function(){"checked"==u(this).attr("checked")?u("#currency-switcher, #currency-switcher-widget, #currency-switcher-product, #multi-currency-per-language-details, #online-exchange-rates").fadeIn():u("#currency-switcher, #currency-switcher-widget, #currency-switcher-product, #multi-currency-per-language-details, #online-exchange-rates").fadeOut()})},select_currency:function(){var e=u(this).closest(".wcml_currency_options"),c=e.find(".wcml-dialog-close-button"),r=e.find(".this-currency").text(),n=e.find(".wcml-gateways-switcher"),t=e.find('.wcml-gateways select[name*="[currency]"] option[value="'+r+'"]'),a=n.find("label.otgs-on-off-switch").text().replace(r,u(this).val());c.attr("data-currency",u(this).val()),c.attr("data-symbol",u(this).find("option:selected").attr("data-symbol")),e.find(".this-currency").html(u(this).val()),n.find("label.otgs-on-off-switch").text(a),t.val(u(this).val()),t.html(u(this).val())},delete_currency:function(e){e.preventDefault();var c=!1,r=u(this).data("currency"),n=u(this).data("currency_name"),t=u(this).data("currency_symbol");if(u(".currency_lang_table .wcml-row-currency-lang:first .currency_languages").each(function(){if(!WCML_Multi_Currency.check_currency_language(u(this).find("li").data("lang"),r))return!(c=!0)}),!c){u("#currency_row_"+r+" .currency_action_update").hide();var a=u('<span class="spinner" style="visibility: visible;margin:0;">');return u(this).hide(),u(this).parent().append(a).show(),u.ajax({type:"post",url:ajaxurl,data:{action:"wcml_delete_currency",wcml_nonce:u("#del_currency_nonce").val(),code:r},success:function(e){u("#currency_row_"+r).remove(),u("#currency_row_langs_"+r).remove(),u("#wcml-row-currency-actions-"+r).remove(),u("#wcml_currencies_order .wcml_currencies_order_"+r).remove(),u("#wcml_currency_options_code_").prepend('<option data-symbol="'+t+'" value="'+r+'">'+n+"</option>"),u("#wcml_currency_options_code_").val(r).trigger("change"),u("#currency-lang-table").find("tr.default_currency select").each(function(){u(this).find("option[value='"+r+"']").remove()}),u(".wcml-ui-dialog").each(function(){WCML_Currency_Switcher_Settings.currency_switcher_preview(u(this))}),1==u(".wcml-row-currency").length&&(u("#online-exchange-rates-no-currencies").next().hide(),u("#online-exchange-rates-no-currencies").show())},done:function(){a.remove()}}),!1}},save_currency:function(){var l=u(this).closest(".wcml-dialog-container");if(WCML_Multi_Currency.check_on_numeric(l,".abstract_amount"))return!1;u(".wcml-currency-options-dialog :submit, .wcml-currency-options-dialog :button").prop("disabled",!0);var _=l.find('[name="currency_options[code]"]').val(),e=u('<span class="spinner" style="visibility:visible;position:absolute;margin-left:10px;"></span>');return e.show(),u(this).parent().prepend(e),u.ajax({url:ajaxurl,type:"POST",dataType:"json",data:l.find('[name^="currency_options"]').serialize()+"&action=wcml_save_currency&wcml_nonce="+jQuery("#wcml_save_currency_nonce").val(),success:function(e){if(l.find(".wcml-dialog-close-button").trigger("click"),u(".wcml-ui-dialog").each(function(){WCML_Currency_Switcher_Settings.currency_switcher_preview(u(this))}),0==u("#currency_row_"+_).length){var c;(c=u("#currency-table tr.wcml-row-currency:last").clone()).attr("id","currency_row_"+_),u("#currency-table").find("tr.default_currency").before(c),(c=u(".empty-currency-language-row").clone()).attr("id","currency_row_langs_"+_),u("#currency-lang-table").find("tr.default_currency").before(c),c.removeClass("hidden empty-currency-language-row"),c.find(".on a").each(function(){u(this).attr("data-currency",_),u(this).attr("title",u(this).attr("title").replace("%code%",e.currency_name)),u(this).attr("data-title-alt",u(this).attr("data-title-alt").replace("%code%",e.currency_name))}),u("#currency-lang-table").find("tr.default_currency select").each(function(){u(this).append('<option value="'+_+'">'+_+"</option>")}),u("#wcml_currencies_order").append('<li class="wcml_currencies_order_'+_+' ui-sortable-handle" cur="'+_+'">'+e.currency_name_formatted+"</li>");var r=u("#currency-settings-table tr.wcml-row-currencies-actions:last").clone();r.attr("id","wcml-row-currency-actions-"+_);var n=r.find(".wcml-col-edit a");n.attr("data-content","wcml_currency_options_"+_),n.attr("data-currency",_),n.data("dialog","wcml_currency_options_"+_),n.removeClass("hidden");var t=r.find(".delete_currency");t.removeClass("hidden"),t.attr("data-currency",_),t.attr("data-currency_name",e.currency_name),t.attr("data-currency_symbol",e.currency_symbol),u("#currency-settings-table").find("tr.default_currency").before(r)}u("#currency_row_"+_+" .wcml-col-currency").html(e.currency_name_formatted),u("#currency_row_"+_+" .wcml-col-rate").html(e.currency_meta_info);var a=u("#wcml_currency_options_"+_).find(".wcml-gateways-switcher");0==a.length&&(a=u("#wcml_currency_options_").find(".wcml-gateways-switcher").clone()),u("#wcml_currency_options_"+_).remove(),u("#wcml_mc_options").before(e.currency_options),u('#wcml_currency_options_code_ option[value="'+_+'"]').remove(),u("#online-exchange-rates-no-currencies").is(":visible")&&(u("#online-exchange-rates-no-currencies").hide(),u("#online-exchange-rates-no-currencies").next().show());var i=u("#wcml_currency_options_"+_),s=0<i.find('.wcml-gateways-switcher input[type="checkbox"]:checked').length;i.find(".wcml-gateways-switcher").remove(),i.find(".wcml-gateways").before(a),s?i.find('.wcml-gateways-switcher input[type="checkbox"]').attr("checked","checked"):i.find('.wcml-gateways-switcher input[type="checkbox"]').removeAttr("checked")}}),!1},check_on_numeric:function(e,c){var r=u('<span class="wcml-error">');return WCML_Multi_Currency.is_number(e.find(c).val())?(0<e.find(c).parent().find(".wcml-error").size()&&e.find(c).parent().find(".wcml-error").remove(),!1):(0==e.find(c).parent().find(".wcml-error").size()&&(e.find(c).parent().append(r),r.text(e.find(c).data("message"))),!0)},tooltip:function(){var e=u(this);u(".wp-pointer").fadeOut(100),u(this).pointer({content:"<h3>"+e.data("header")+"</h3><p>"+e.data("content")+"</p>",position:{edge:"left",align:"center",offset:"15 0"}}).pointer("open")},enable_currency_for_language:function(e){if(WCML_Multi_Currency.is_update_currency_lang_in_progress())return!1;e.preventDefault(),u(this).addClass("spinner").removeClass("otgs-ico-no").css("visibility","visible");u(this).closest("tr")[0].rowIndex;u('.default_currency select[rel="'+u(this).data("language")+'"]').append('<option value="'+u(this).data("currency")+'">'+u(this).data("currency")+"</option>"),WCML_Multi_Currency.update_currency_lang(u(this),1,0);var c=u(this).data("title-alt");u(this).data("title-alt",u(this).attr("title")),u(this).attr("title",c)},disable_currency_for_language:function(e){if(WCML_Multi_Currency.is_update_currency_lang_in_progress())return!1;e.preventDefault(),u(this).addClass("spinner").removeClass("otgs-ico-yes").css("visibility","visible");var c=u(this).data("language");if(WCML_Multi_Currency.check_currency_language(c)){u(this).closest("tr")[0].rowIndex;u('.currency_languages select[rel="'+u(this).data("language")+'"]').val()==u(this).data("currency")?WCML_Multi_Currency.update_currency_lang(u(this),0,1):WCML_Multi_Currency.update_currency_lang(u(this),0,0),u('.default_currency select[rel="'+u(this).data("language")+'"] option[value="'+u(this).data("currency")+'"]').remove();var r=u(this).data("title-alt");u(this).data("title-alt",u(this).attr("title")),u(this).attr("title",r)}else u(this).removeClass("spinner").addClass("otgs-ico-yes")},check_currency_language:function(e,c){var r=u('#currency-lang-table a.otgs-ico-yes[data-language="'+e+'"]');return c&&(r=u('#currency-lang-table a.otgs-ico-yes[data-language="'+e+'"]').not(u('[data-currency="'+c+'"]'))),0!=r.length||(alert(u("#wcml_warn_disable_language_massage").val()),!1)},is_update_currency_lang_in_progress:function(){return void 0!==WCML_Multi_Currency._update_currency_lang_sync_flag&&1==WCML_Multi_Currency._update_currency_lang_sync_flag},set_update_currency_lang_in_progress:function(e){WCML_Multi_Currency._update_currency_lang_sync_flag=e},update_currency_lang:function(e,c,r){WCML_Multi_Currency._currency_languages_saving++,u("#wcml_mc_options :submit").attr("disabled","disabled"),u('input[name="wcml_mc_options"]').attr("disabled","disabled");var n=e.data("language"),t=e.data("currency");discard=!0,WCML_Multi_Currency.set_update_currency_lang_in_progress(1),u.ajax({type:"post",url:ajaxurl,data:{action:"wcml_update_currency_lang",value:c,lang:n,code:t,wcml_nonce:u("#update_currency_lang_nonce").val()},success:function(){r&&WCML_Multi_Currency.update_default_currency(n,0)},complete:function(){u('input[name="wcml_mc_options"]').removeAttr("disabled"),discard=!1,e.removeClass("spinner").css("visibility","visible"),c?e.addClass("otgs-ico-yes"):e.addClass("otgs-ico-no"),WCML_Multi_Currency._currency_languages_saving--,0==WCML_Multi_Currency._currency_languages_saving&&u("#wcml_mc_options :submit").removeAttr("disabled"),WCML_Multi_Currency.set_update_currency_lang_in_progress(0)}})},change_default_currency:function(){WCML_Multi_Currency.update_default_currency(u(this).attr("rel"),u(this).val(),u(this))},update_default_currency:function(e,c,r){if(u("#wcml_mc_options_submit").attr("disabled","disabled"),r){var n=u('<span class="spinner" style="visibility: visible;float:none;position: absolute">');r.parent().append(n)}discard=!0,u.ajax({type:"post",url:ajaxurl,data:{action:"wcml_update_default_currency",lang:e,code:c,wcml_nonce:u("#wcml_update_default_currency_nonce").val()},complete:function(){discard=!1,u("#wcml_mc_options_submit").removeAttr("disabled"),r&&r.parent().find(".spinner").remove()}})},is_number:function(e){return!isNaN(parseFloat(e))&&isFinite(e)},setup_currencies_sorting:function(){u("#wcml_currencies_order").sortable({update:function(){var e=[];u("#wcml_currencies_order").find("li").each(function(){e.push(u(this).attr("cur"))}),u.ajax({type:"POST",url:ajaxurl,dataType:"json",data:{action:"wcml_currencies_order",wcml_nonce:u("#wcml_currencies_order_order_nonce").val(),order:e.join(";")},success:function(e){e.success&&(fadeInAjxResp(".wcml_currencies_order_ajx_resp",e.data.message),u(".wcml-ui-dialog").each(function(){WCML_Currency_Switcher_Settings.currency_switcher_preview(u(this))}))}})}})},price_preview:function(){var e=u(this).closest(".wcml_currency_options"),c=e.find(".currency_option_position").val(),r=e.find(".currency_option_thousand_sep").val(),n=(r=e.find(".currency_option_thousand_sep").val(),e.find(".currency_option_decimal_sep").val()),t=u(this).closest(".wcml_currency_options").find(".wcml-dialog-close-button").attr("data-symbol"),a="56789".substr(0,e.find(".currency_option_decimals").val());""==a&&(n="");var i="";switch(c){case"left":i="{symbol}1{thousand_sep}234{decimal_sep}{decimals}";break;case"right":i="1{thousand_sep}234{decimal_sep}{decimals}{symbol}";break;case"left_space":i="{symbol}&nbsp;1{thousand_sep}234{decimal_sep}{decimals}";break;case"right_space":i="1{thousand_sep}234{decimal_sep}{decimals}&nbsp;{symbol}"}var s=i.replace(/\{symbol\}/,t).replace(/\{thousand_sep\}/,r).replace(/\{decimal_sep\}/,n).replace(/\{decimals\}/,a);return e.find(".wcml-co-preview-value").html(s),!1},display_gateways:function(){"checked"==u(this).attr("checked")?(u(".wcml-gateways").slideDown(),WCML_Tooltip.init()):u(".wcml-gateways").slideUp()},preset_paypal_email:function(){var e=u('input[name="currency_options[gateways_settings][paypal][value]"]'),c=u(".paypal-gateway-warning");e.val(u(this).find(":selected").data("email")),u(this).find(":selected").data("is-valid")?(c.hide(),e.removeAttr("readonly")):(c.show(),e.val(""),e.attr("readonly","readonly"))},preset_stripe_settings:function(){u('input[name="currency_options[gateways_settings][stripe][publishable_key]"]').val(u(this).find(":selected").data("publishable-key")),u('input[name="currency_options[gateways_settings][stripe][secret_key]"]').val(u(this).find(":selected").data("secret-key"))},read_form_fields_status:function(){this.mc_form_status=u("#wcml_mc_options").serialize()},form_fields_changed:function(){return this.mc_form_status!=u("#wcml_mc_options").serialize()},exchange_rate_check:function(e){if(void 0===c)var c={DOM_SUBTRACT:109,DOM_DASH:189,DOM_E:69};u(this).val()<=0||!WCML_Multi_Currency.is_number(u(this).val())||e.keyCode==c.DOM_SUBTRACT||e.keyCode==c.DOM_DASH||e.keyCode==c.DOM_E?(u(".wcml-co-set-rate .wcml-error").fadeIn(),u(".currency_options_save").attr("disabled","disabled")):(u(".wcml-co-set-rate .wcml-error").fadeOut(),u(".currency_options_save").removeAttr("disabled"))}},WCML_Multi_Currency.init()});
res/js/tooltip_init.min.js CHANGED
@@ -1 +1 @@
1
- var WCML_Tooltip={default_args:{attribute:"data-tip",fadeIn:50,fadeOut:50,delay:200},setup:function(){jQuery(document).ready(function(){WCML_Tooltip.init()})},init:function(){jQuery(".wcml-tip:visible").tipTip(WCML_Tooltip.default_args)},create_tip:function(a,b,c){void 0===c&&(c={});var d=jQuery('<i class="otgs-ico-help wcml-tip" data-tip="'+a+'" style="'+b+'"></i>');for(var e in WCML_Tooltip.default_args)void 0===c[e]&&(c[e]=WCML_Tooltip.default_args[e]);return d.tipTip(c),d},add_before:function(a,b,c,d){return tip=WCML_Tooltip.create_tip(b,c,d),tip.insertBefore(a),tip},add_after:function(a,b,c,d){return tip=WCML_Tooltip.create_tip(b,c,d),tip.insertAfter(a),tip}};WCML_Tooltip.setup();
1
+ var WCML_Tooltip={default_args:{attribute:"data-tip",fadeIn:50,fadeOut:50,delay:200},setup:function(){jQuery(document).ready(function(){WCML_Tooltip.init()})},init:function(){jQuery(".wcml-tip:visible").tipTip(WCML_Tooltip.default_args)},create_tip:function(text,style,args){if(typeof args=="undefined"){args={}}var tip=jQuery('<i class="otgs-ico-help wcml-tip" data-tip="'+text+'" style="'+style+'"></i>');for(var i in WCML_Tooltip.default_args){if(typeof args[i]=="undefined"){args[i]=WCML_Tooltip.default_args[i]}}tip.tipTip(args);return tip},add_before:function(elem_class,text,style,args){tip=WCML_Tooltip.create_tip(text,style,args);tip.insertBefore(elem_class);return tip},add_after:function(elem_class,text,style,args){tip=WCML_Tooltip.create_tip(text,style,args);tip.insertAfter(elem_class);return tip}};WCML_Tooltip.setup();
res/js/trnsl_interface_dialog_warning.js CHANGED
@@ -23,10 +23,11 @@ jQuery(document).ready(function ($) {
23
  closeOnEscape: false,
24
  dialogClass: "otgs-ui-dialog",
25
  create: function () {
26
- jQuery('#jquery-ui-style-css').attr('disabled', 'disabled');
27
  },
28
  open: function (event, ui) {
29
  jQuery(".ui-dialog-titlebar-close", ui.dialog | ui).hide();
 
30
  },
31
  close: function (event, ui) {
32
  jQuery('#jquery-ui-style-css').removeAttr('disabled');
23
  closeOnEscape: false,
24
  dialogClass: "otgs-ui-dialog",
25
  create: function () {
26
+
27
  },
28
  open: function (event, ui) {
29
  jQuery(".ui-dialog-titlebar-close", ui.dialog | ui).hide();
30
+ jQuery('#jquery-ui-style-css').attr('disabled', 'disabled');
31
  },
32
  close: function (event, ui) {
33
  jQuery('#jquery-ui-style-css').removeAttr('disabled');
res/js/trnsl_interface_dialog_warning.min.js CHANGED
@@ -1 +1 @@
1
- jQuery(document).ready(function($){$(document).on("click",'input[name="trnsl_interface"]',function(){if($(this).val()==0){jQuery(document).ready(function(){var dialogBox=jQuery("#wcml-translation-interface-dialog-confirm");var buttonsOpts={};buttonsOpts[dialogBox.find(".cancel-button").val()]=function(){jQuery(this).dialog("close");jQuery('input[name="trnsl_interface"][value="1"]').attr("checked","checked")};buttonsOpts[dialogBox.find(".ok-button").val()]=function(){jQuery(this).dialog("close")};dialogBox.dialog({resizable:false,draggable:false,height:"auto",width:600,modal:true,closeOnEscape:false,dialogClass:"otgs-ui-dialog",create:function(){jQuery("#jquery-ui-style-css").attr("disabled","disabled")},open:function(event,ui){jQuery(".ui-dialog-titlebar-close",ui.dialog|ui).hide()},close:function(event,ui){jQuery("#jquery-ui-style-css").removeAttr("disabled")},buttons:buttonsOpts})})}})});
1
+ jQuery(document).ready(function(e){e(document).on("click",'input[name="trnsl_interface"]',function(){0==e(this).val()&&jQuery(document).ready(function(){var e=jQuery("#wcml-translation-interface-dialog-confirm"),t={};t[e.find(".cancel-button").val()]=function(){jQuery(this).dialog("close"),jQuery('input[name="trnsl_interface"][value="1"]').attr("checked","checked")},t[e.find(".ok-button").val()]=function(){jQuery(this).dialog("close")},e.dialog({resizable:!1,draggable:!1,height:"auto",width:600,modal:!0,closeOnEscape:!1,dialogClass:"otgs-ui-dialog",create:function(){},open:function(e,t){jQuery(".ui-dialog-titlebar-close",t.dialog|t).hide(),jQuery("#jquery-ui-style-css").attr("disabled","disabled")},close:function(e,t){jQuery("#jquery-ui-style-css").removeAttr("disabled")},buttons:t})})})});
templates/compatibility/product-addons-prices-dialog.twig ADDED
@@ -0,0 +1,29 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <div class="wcml-option-prices js-wcml-option-prices {% if not custom_prices_on %}hidden{% endif %}">
2
+ <button type="button" class="button-secondary js-wcml-dialog-trigger" data-dialog="{{ dialog_id }}" data-content="{{ dialog_id }}" data-width="350" data-class="wcml-dialog-product-addons">
3
+ <i class="otgs-ico-edit"></i>
4
+ </button>
5
+
6
+ <div class="wcml-dialog hidden" id="{{ dialog_id }}" title="{{ strings.dialog_title }}">
7
+
8
+ <p>{{ strings.description | raw }}</p>
9
+
10
+ <div class="wpml-form-row default-price">
11
+ <label>{{ default_currency }}</label>
12
+ <span><strong>{{ option_details.price }}</strong></span>
13
+ </div>
14
+
15
+ {% for code, currency in active_currencies %}
16
+ {% set price_key = [ 'price_', code|upper]|join %}
17
+ <div class="wpml-form-row">
18
+ <label>{{ code }}</label>
19
+ <input type="text" name="_product_addon_prices[{{ addon_id }}][{{ price_key }}][{{ option_id }}]" value="{{ option_details[price_key] }}" placeholder="0" class="wc_input_price" />
20
+ </div>
21
+ {% endfor %}
22
+
23
+ <footer class="wpml-dialog-footer">
24
+ <input type="button" class="cancel wcml-dialog-close-button wpml-dialog-close-button alignleft" value="{{ strings.cancel }}" />&nbsp;
25
+ <input type="button" class="button-primary wcml_product_addons_apply_prices alignright" data-dialog="{{ dialog_id }}" value="{{ strings.apply }}"/>
26
+ </footer>
27
+
28
+ </div>
29
+ </div>
templates/compatibility/product-addons-prices-settings.twig ADDED
@@ -0,0 +1,22 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <table>
2
+ <tr class="wcml_custom_prices hidden">
3
+ <th><label>{{ strings.label }}</label></th>
4
+ <td>
5
+ <fieldset>
6
+ <label for="wcml_custom_prices_auto">
7
+ <input type="radio" name="_wcml_custom_prices" id="wcml_custom_prices_auto" value="0" class="wcml_custom_prices_input" {% if not custom_prices_on %}checked="checked"{% endif %} />
8
+ {{ strings.auto }}
9
+ </label>
10
+
11
+ <br>
12
+
13
+ <label for="wcml_custom_prices_manually">
14
+ <input type="radio" name="_wcml_custom_prices" value="1" id="wcml_custom_prices_manually" class="wcml_custom_prices_input" {% if custom_prices_on %}checked="checked"{% endif %} />
15
+ {{ strings.manually }}
16
+ </label>
17
+
18
+ <input type="hidden" name="_wcml_custom_prices_nonce" value="{{ nonce }}"/>
19
+ </fieldset>
20
+ </td>
21
+ </tr>
22
+ </table>
templates/multi-currency/currencies-dropdown.twig ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
1
+ <select class="wcml-currencies">
2
+ {% for currency in active_currencies %}
3
+ <option value="{{ currency }}" {% if currency == selected_currency %}selected="selected"{% endif %}>{{ currency }}</option>
4
+ {% endfor %}
5
+ </select>
templates/multi-currency/custom-currency-options.twig CHANGED
@@ -108,6 +108,21 @@
108
  id="wcml_currency_options_subtract_{{ args.currency_code }}"/>
109
  </div>
110
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
111
 
112
  <footer class="wpml-dialog-footer">
113
  <input type="button" class="cancel wcml-dialog-close-button wpml-dialog-close-button alignleft"
@@ -115,7 +130,6 @@
115
  <input type="submit" class="wcml-dialog-close-button wpml-dialog-close-button button-primary currency_options_save alignright"
116
  value="{{ form.save }}" data-currency="{{ current_currency }}" data-symbol="{{ get_currency_symbol(current_currency) }}" data-stay="1" />
117
  </footer>
118
-
119
  </form>
120
 
121
  </div>
108
  id="wcml_currency_options_subtract_{{ args.currency_code }}"/>
109
  </div>
110
 
111
+ <hr>
112
+
113
+ <label class="label-header"><strong>{{ form.payment_gateways.label }}</strong></label>
114
+
115
+ <label class="wcml-gateways-switcher">
116
+ <input name="currency_options[gateways_enabled]" type="checkbox" class="wcml-gateways-enabled otgs-switcher-input" {% if payment_gateways_enabled %}checked="checked"{% endif %} />
117
+ <span class="otgs-switcher wpml-theme" data-on="ON" data-off="OFF">{{ form.payment_gateways.settings_label }}</span>
118
+ <a class="wpml-external-link" href="{{ form.payment_gateways.learn_url }}" target="_blank">{{ form.payment_gateways.learn_txt }}</a>
119
+ </label>
120
+
121
+ <div class="wcml-gateways" {% if not payment_gateways_enabled %}style="display: none;"{% endif %}>
122
+ {% for gateway in payment_gateways %}
123
+ {{ gateway.get_settings_output( current_currency, active_currencies )|raw }}
124
+ {% endfor %}
125
+ </div>
126
 
127
  <footer class="wpml-dialog-footer">
128
  <input type="button" class="cancel wcml-dialog-close-button wpml-dialog-close-button alignleft"
130
  <input type="submit" class="wcml-dialog-close-button wpml-dialog-close-button button-primary currency_options_save alignright"
131
  value="{{ form.save }}" data-currency="{{ current_currency }}" data-symbol="{{ get_currency_symbol(current_currency) }}" data-stay="1" />
132
  </footer>
 
133
  </form>
134
 
135
  </div>
templates/multi-currency/multi-currency.twig CHANGED
@@ -54,117 +54,106 @@
54
  </div>
55
  <input type="hidden" id="update_currency_lang_nonce" value="{{ form.update_currency_lang_nonce }}"/>
56
 
57
- <table class="widefat currency_table" id="currency-table">
58
- <thead>
59
  <tr>
60
  <th class="wcml-col-currency">{{ strings.currencies_table.head_currency }}</th>
61
  <th class="wcml-col-rate">{{ strings.currencies_table.head_rate }}</th>
62
- <th class="wcml-col-edit"></th>
63
  </tr>
64
- </thead>
65
- <tbody>
66
  <tr class="wcml-row-currency">
67
  <td class="wcml-col-currency">
68
  <span class="truncate">{{ attribute(wc_currencies, wc_currency)|raw }}</span>
69
  <small>{{ positioned_price|raw }}</small>
70
  </td>
71
- <td class="wcml-col-rate"><span class="truncate">{{ strings.currencies_table.default }}</span></td>
72
- <td class="wcml-col-edit">
73
- <a href="#" title="{{ strings.currencies_table.edit }}" class="edit_currency js-wcml-dialog-trigger hidden" data-height="530" data-width="480">
74
- <i class="otgs-ico-edit" title="{{ strings.currencies_table.edit }}"></i>
75
- </a>
76
-
77
- </td>
78
  </tr>
79
 
80
  {% for code, currency in currencies %}
81
- <tr id="currency_row_{{ code }}" class="wcml-row-currency">
82
- <td class="wcml-col-currency">
83
- <span class="truncate">{{ attribute(wc_currencies, code)|raw }}</span>
84
- <small>{{ attribute( currencies_positions, code )|raw }}</small>
85
- </td>
86
- <td class="wcml-col-rate">
87
- 1 {{ wc_currency }} = <span class="rate">{{ currency.rate }}</span> {{ code }}
88
- </td>
89
-
90
- <td class="wcml-col-edit">
91
- <a href="#" title="{{ strings.currencies_table.edit }}" class="edit_currency js-wcml-dialog-trigger"
92
- data-currency="{{ code }}" data-content="wcml_currency_options_{{ code }}" data-dialog="wcml_currency_options_{{ code }}"
93
- data-height="530" data-width="480">
94
- <i class="otgs-ico-edit" title="{{ strings.currencies_table.edit }}"></i>
95
- </a>
96
- </td>
97
- </tr>
98
  {% endfor %}
99
 
100
  <tr class="default_currency">
101
  <td colspan="3">{{ strings.currencies_table.default_currency }}
102
- <i class="wcml-tip otgs-ico-help" data-tip="{{ strings.currencies_table.default_cur_tip }}"></i>
 
103
 
104
  </td>
105
  </tr>
106
 
107
- </tbody>
108
- </table>
109
 
110
- <div class="currency_wrap">
111
- <div class="currency_inner">
112
- <table class="widefat currency_lang_table" id="currency-lang-table">
113
- <thead>
114
  <tr>
115
  <td colspan="{{ active_languages|length }}">{{ strings.currencies_table.help_title }}</td>
116
  </tr>
117
- <tr>
118
  {% for language in active_languages %}
119
- <th>
120
- <img src="{{ get_flag_url(language.code) }}" width="18" height="12"/>
121
- </th>
122
  {% endfor %}
123
  </tr>
124
- </thead>
125
- <tbody>
126
  <tr class="wcml-row-currency-lang">
127
  {% for language in active_languages %}
128
- <td class="currency_languages">
129
- <ul>
130
- {% set title_yes = strings.currencies_table.disable_for|format( get_currency_name(wc_currency), language.display_name ) %}
131
- {% set title_no = strings.currencies_table.enable_for|format( get_currency_name(wc_currency), language.display_name ) %}
132
- <li class="on" data-lang="{{ language.code }}">
133
- <a class="{% if is_currency_on(wc_currency, language.code) %}otgs-ico-yes{% else %} otgs-ico-no{% endif %}"
134
- data-language="{{ language.code }}" data-currency="{{ wc_currency }}" href="#"
135
- {% if is_currency_on(wc_currency, language.code) %}
136
- title="{{ title_yes }}" data-title-alt="{{ title_no }}"
137
- {% else %}
138
- title="{{ title_no }}" data-title-alt="{{ title_yes }}"
139
- {% endif %}
140
- ></a>
141
- </li>
142
- </ul>
143
- </td>
 
144
  {% endfor %}
145
  </tr>
146
 
147
  {% for code, currency in currencies %}
148
- <tr id="currency_row_langs_{{ code }}" class="wcml-row-currency-lang">
149
- {% for language in active_languages %}
150
- <td class="currency_languages">
151
- <ul>
152
- {% set title_yes = strings.currencies_table.disable_for|format( get_currency_name(code), language.display_name ) %}
153
- {% set title_no = strings.currencies_table.enable_for|format( get_currency_name(code), language.display_name ) %}
154
- <li class="on" data-lang="{{ language.code }}">
155
- <a class="{% if is_currency_on(code, language.code) %}otgs-ico-yes{% else %} otgs-ico-no{% endif %}"
156
- data-language="{{ language.code }}" data-currency="{{ code }}" href="#"
157
- {% if is_currency_on(wc_currency, language.code) %}
158
- title="{{ title_yes }}" data-title-alt="{{ title_no }}"
159
- {% else %}
160
- title="{{ title_no }}" data-title-alt="{{ title_yes }}"
161
- {% endif %}
162
- ></a>
163
- </li>
164
- </ul>
165
- </td>
166
- {% endfor %}
167
- </tr>
 
168
  {% endfor %}
169
 
170
  <tr class="wcml-row-currency-lang empty-currency-language-row hidden">
@@ -184,64 +173,85 @@
184
 
185
  <tr class="default_currency">
186
  {% for language in active_languages %}
187
- <td align="center">
188
- <select rel="{{ language.code }}">
189
- <option value="0" {% if get_language_currency(language.code) == 0 %}selected="selected"{% endif %}>{{ strings.currencies_table.keep_currency }}</option>
190
- {% if is_currency_on(wc_currency, language.code) %}
191
- <option value="{{ wc_currency }}" {% if get_language_currency(language.code) == wc_currency %}selected="selected"{% endif %}>{{ wc_currency }}</option>
192
- {% endif %}
193
-
194
- {% for code, currency in currencies %}
195
- {% if is_currency_on(code, language.code) %}
196
- <option value="{{ code }}" {% if get_language_currency(language.code) == code %}selected="selected"{% endif %}>{{ code }}</option>
197
- {% endif %}
198
- {% endfor %}
199
- </select>
200
- </td>
 
 
 
201
  {% endfor %}
202
  </tr>
203
 
204
- </tbody>
205
- </table>
206
- <input type="hidden" id="wcml_update_default_currency_nonce" value="{{ form.wpdate_default_cur_nonce }}" />
 
207
 
 
208
  </div>
209
- </div>
210
 
211
- <table class="widefat currency_delete_table" id="currency-delete-table">
212
- <thead>
213
  <tr>
214
- <th></th>
215
  </tr>
216
- </thead>
217
- <tbody>
218
- <tr class="currency_default wcml-row-currency-del">
219
- <td class="wcml-col-delete">
220
- <a title="{{ strings.currencies_table.delete }}" class="delete_currency hidden">
221
- <i class="otgs-ico-delete" title="{{ strings.currencies_table.delete }}"></i>
 
 
222
  </a>
223
- </td>
224
- </tr>
225
 
226
- {% for code, currency in currencies %}
227
- <tr id="currency_row_del_{{ code }}" class="wcml-row-currency-del">
228
  <td class="wcml-col-delete">
229
- <a title="{{ strings.currencies_table.delete }}" class="delete_currency"
230
- data-currency_name="{{ attribute(wc_currencies, code) }}"
231
- data-currency_symbol="{{ get_currency_symbol(code) }}"
232
- data-currency="{{ code }}" href="#">
233
  <i class="otgs-ico-delete" title="{{ strings.currencies_table.delete }}"></i>
234
  </a>
235
  </td>
236
  </tr>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
237
  {% endfor %}
238
 
239
  <tr class="default_currency">
240
- <td></td>
241
  </tr>
242
- </tbody>
243
- </table>
244
-
245
  </div>
246
 
247
  <ul id="display_custom_prices_select">
54
  </div>
55
  <input type="hidden" id="update_currency_lang_nonce" value="{{ form.update_currency_lang_nonce }}"/>
56
 
57
+ <table class="widefat currency_table" id="currency-table">
58
+ <thead>
59
  <tr>
60
  <th class="wcml-col-currency">{{ strings.currencies_table.head_currency }}</th>
61
  <th class="wcml-col-rate">{{ strings.currencies_table.head_rate }}</th>
 
62
  </tr>
63
+ </thead>
64
+ <tbody>
65
  <tr class="wcml-row-currency">
66
  <td class="wcml-col-currency">
67
  <span class="truncate">{{ attribute(wc_currencies, wc_currency)|raw }}</span>
68
  <small>{{ positioned_price|raw }}</small>
69
  </td>
70
+ <td class="wcml-col-rate"><span
71
+ class="truncate">{{ strings.currencies_table.default }}</span></td>
 
 
 
 
 
72
  </tr>
73
 
74
  {% for code, currency in currencies %}
75
+ <tr id="currency_row_{{ code }}" class="wcml-row-currency">
76
+ <td class="wcml-col-currency">
77
+ <span class="truncate">{{ attribute(wc_currencies, code)|raw }}</span>
78
+ <small>{{ attribute( currencies_positions, code )|raw }}</small>
79
+ </td>
80
+ <td class="wcml-col-rate">
81
+ 1 {{ wc_currency }} = <span class="rate">{{ currency.rate }}</span> {{ code }}
82
+ </td>
83
+ </tr>
 
 
 
 
 
 
 
 
84
  {% endfor %}
85
 
86
  <tr class="default_currency">
87
  <td colspan="3">{{ strings.currencies_table.default_currency }}
88
+ <i class="wcml-tip otgs-ico-help"
89
+ data-tip="{{ strings.currencies_table.default_cur_tip }}"></i>
90
 
91
  </td>
92
  </tr>
93
 
94
+ </tbody>
95
+ </table>
96
 
97
+ <div class="currency_wrap">
98
+ <div class="currency_inner">
99
+ <table class="widefat currency_lang_table" id="currency-lang-table">
100
+ <thead>
101
  <tr>
102
  <td colspan="{{ active_languages|length }}">{{ strings.currencies_table.help_title }}</td>
103
  </tr>
104
+ <tr class="currency-lang-flags">
105
  {% for language in active_languages %}
106
+ <th>
107
+ <img src="{{ get_flag_url(language.code) }}" width="18" height="12"/>
108
+ </th>
109
  {% endfor %}
110
  </tr>
111
+ </thead>
112
+ <tbody>
113
  <tr class="wcml-row-currency-lang">
114
  {% for language in active_languages %}
115
+ <td class="currency_languages">
116
+ <ul>
117
+ {% set title_yes = strings.currencies_table.disable_for|format( get_currency_name(wc_currency), language.display_name ) %}
118
+ {% set title_no = strings.currencies_table.enable_for|format( get_currency_name(wc_currency), language.display_name ) %}
119
+ <li class="on" data-lang="{{ language.code }}">
120
+ <a class="{% if is_currency_on(wc_currency, language.code) %}otgs-ico-yes{% else %} otgs-ico-no{% endif %}"
121
+ data-language="{{ language.code }}"
122
+ data-currency="{{ wc_currency }}" href="#"
123
+ {% if is_currency_on(wc_currency, language.code) %}
124
+ title="{{ title_yes }}" data-title-alt="{{ title_no }}"
125
+ {% else %}
126
+ title="{{ title_no }}" data-title-alt="{{ title_yes }}"
127
+ {% endif %}
128
+ ></a>
129
+ </li>
130
+ </ul>
131
+ </td>
132
  {% endfor %}
133
  </tr>
134
 
135
  {% for code, currency in currencies %}
136
+ <tr id="currency_row_langs_{{ code }}" class="wcml-row-currency-lang">
137
+ {% for language in active_languages %}
138
+ <td class="currency_languages">
139
+ <ul>
140
+ {% set title_yes = strings.currencies_table.disable_for|format( get_currency_name(code), language.display_name ) %}
141
+ {% set title_no = strings.currencies_table.enable_for|format( get_currency_name(code), language.display_name ) %}
142
+ <li class="on" data-lang="{{ language.code }}">
143
+ <a class="{% if is_currency_on(code, language.code) %}otgs-ico-yes{% else %} otgs-ico-no{% endif %}"
144
+ data-language="{{ language.code }}"
145
+ data-currency="{{ code }}" href="#"
146
+ {% if is_currency_on(wc_currency, language.code) %}
147
+ title="{{ title_yes }}" data-title-alt="{{ title_no }}"
148
+ {% else %}
149
+ title="{{ title_no }}" data-title-alt="{{ title_yes }}"
150
+ {% endif %}
151
+ ></a>
152
+ </li>
153
+ </ul>
154
+ </td>
155
+ {% endfor %}
156
+ </tr>
157
  {% endfor %}
158
 
159
  <tr class="wcml-row-currency-lang empty-currency-language-row hidden">
173
 
174
  <tr class="default_currency">
175
  {% for language in active_languages %}
176
+ <td align="center">
177
+ <select rel="{{ language.code }}">
178
+ <option value="0"
179
+ {% if get_language_currency(language.code) == 0 %}selected="selected"{% endif %}>{{ strings.currencies_table.keep_currency }}</option>
180
+ {% if is_currency_on(wc_currency, language.code) %}
181
+ <option value="{{ wc_currency }}"
182
+ {% if get_language_currency(language.code) == wc_currency %}selected="selected"{% endif %}>{{ wc_currency }}</option>
183
+ {% endif %}
184
+
185
+ {% for code, currency in currencies %}
186
+ {% if is_currency_on(code, language.code) %}
187
+ <option value="{{ code }}"
188
+ {% if get_language_currency(language.code) == code %}selected="selected"{% endif %}>{{ code }}</option>
189
+ {% endif %}
190
+ {% endfor %}
191
+ </select>
192
+ </td>
193
  {% endfor %}
194
  </tr>
195
 
196
+ </tbody>
197
+ </table>
198
+ <input type="hidden" id="wcml_update_default_currency_nonce"
199
+ value="{{ form.wpdate_default_cur_nonce }}"/>
200
 
201
+ </div>
202
  </div>
 
203
 
204
+ <table class="widefat currency_settings_table" id="currency-settings-table">
205
+ <thead>
206
  <tr>
207
+ <th colspan="2">{{ strings.settings }}</th>
208
  </tr>
209
+ </thead>
210
+ <tbody>
211
+ <tr class="currency_default wcml-row-currencies-actions">
212
+ <td class="wcml-col-edit">
213
+ <a href="#" title="{{ strings.currencies_table.edit }}"
214
+ class="edit_currency js-wcml-dialog-trigger hidden" data-height="530"
215
+ data-width="480">
216
+ <i class="otgs-ico-edit" title="{{ strings.currencies_table.edit }}"></i>
217
  </a>
 
 
218
 
219
+ </td>
 
220
  <td class="wcml-col-delete">
221
+ <a title="{{ strings.currencies_table.delete }}" class="delete_currency hidden">
 
 
 
222
  <i class="otgs-ico-delete" title="{{ strings.currencies_table.delete }}"></i>
223
  </a>
224
  </td>
225
  </tr>
226
+
227
+ {% for code, currency in currencies %}
228
+ <tr id="wcml-row-currency-actions-{{ code }}" class="wcml-row-currencies-actions">
229
+ <td class="wcml-col-edit">
230
+ <a href="#" title="{{ strings.currencies_table.edit }}"
231
+ class="edit_currency js-wcml-dialog-trigger"
232
+ data-currency="{{ code }}" data-content="wcml_currency_options_{{ code }}"
233
+ data-dialog="wcml_currency_options_{{ code }}"
234
+ data-height="530" data-width="480">
235
+ <i class="otgs-ico-edit" title="{{ strings.currencies_table.edit }}"></i>
236
+ </a>
237
+ </td>
238
+ <td class="wcml-col-delete">
239
+ <a title="{{ strings.currencies_table.delete }}" class="delete_currency"
240
+ data-currency_name="{{ attribute(wc_currencies, code) }}"
241
+ data-currency_symbol="{{ get_currency_symbol(code) }}"
242
+ data-currency="{{ code }}" href="#">
243
+ <i class="otgs-ico-delete"
244
+ title="{{ strings.currencies_table.delete }}"></i>
245
+ </a>
246
+ </td>
247
+ </tr>
248
  {% endfor %}
249
 
250
  <tr class="default_currency">
251
+ <td colspan="2"></td>
252
  </tr>
253
+ </tbody>
254
+ </table>
 
255
  </div>
256
 
257
  <ul id="display_custom_prices_select">
templates/multi-currency/payment-gateways/bacs.twig ADDED
@@ -0,0 +1,20 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <label class="label-header"><strong>{{ gateway_title }}</strong> <i class="wcml-tip otgs-ico-help" data-tip="{{ strings.tooltip }}"></i></label>
2
+ <div class="wpml-form-row">
3
+ <label>{{ strings.currency_label }}</label>
4
+ <select name="currency_options[gateways_settings][{{ gateway_id }}][currency]">
5
+ {% for code, currency in active_currencies %}
6
+ <option value="{{ code }}" {% if ( gateway_settings and code == gateway_settings.currency ) or ( gateway_settings is empty and code == current_currency ) %}selected="selected"{% endif %} >{{ code }}</option>
7
+ {% endfor %}
8
+ </select>
9
+ </div>
10
+ <div class="wpml-form-row">
11
+ <label>{{ strings.setting_label}}</label>
12
+
13
+ <select name="currency_options[gateways_settings][{{ gateway_id }}][value]">
14
+ <option value="all" {% if ( gateway_settings and "all" == gateway_settings.value ) %}selected="selected"{% endif %}>{{ strings.all_label }}</option>
15
+ <option value="all_in" {% if ( gateway_settings and "all_in" == gateway_settings.value ) %}selected="selected"{% endif %}>{{ strings.all_in_label }}</option>
16
+ {% for account_id, account in account_details %}
17
+ <option value="{{ account_id }}" {% if( gateway_settings and gateway_settings.value not in [ 'all', 'all_in' ] and account_id == gateway_settings.value ) %}selected="selected"{% endif %} >{{ account.account_name }}</option>
18
+ {% endfor %}
19
+ </select>
20
+ </div>
templates/multi-currency/payment-gateways/not-supported.twig ADDED
@@ -0,0 +1,4 @@
 
 
 
 
1
+ <label class="label-header"><strong>{{ gateway_title }}</strong></label>
2
+ <div class="wpml-form-row">
3
+ <span class="explanation-text">{{ strings.not_supported }}</span>
4
+ </div>
templates/multi-currency/payment-gateways/paypal.twig ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <label class="label-header"><strong>{{ gateway_title }}</strong></label>
2
+ <div class="wpml-form-row">
3
+ <label>{{ strings.currency_label }}</label>
4
+ <select name="currency_options[gateways_settings][{{ gateway_id }}][currency]" id="wcml_currency_options_gateway_code_{{ gateway_id }}">
5
+ {% for code, currency_details in currencies_details %}
6
+ <option value="{{ code }}" {% if ( gateway_settings and code == gateway_settings.currency ) or ( gateway_settings is empty and code == current_currency ) %}selected="selected"{% endif %} data-email="{{ currency_details.value }}" data-is-valid="{{ currency_details.is_valid }}" >{{ code }}</option>
7
+ {% endfor %}
8
+ </select>
9
+ <i class="wcml-tip otgs-ico-warning paypal-gateway-warning" data-tip="{{ strings.not_supported }}" {% if selected_currency_valid %}style="display: none;"{% endif %}></i>
10
+ </div>
11
+ <div class="wpml-form-row">
12
+ <label>{{ strings.setting_label}}</label>
13
+ <input type="text" name="currency_options[gateways_settings][{{ gateway_id }}][value]" value="{% if gateway_settings %}{{ gateway_settings.value }}{% endif %}" {% if not selected_currency_valid %}readonly="readonly"{% endif %}/>
14
+ </div>
templates/multi-currency/payment-gateways/stripe.twig ADDED
@@ -0,0 +1,17 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <label class="label-header"><strong>{{ gateway_title }}</strong></label>
2
+ <div class="wpml-form-row">
3
+ <label>{{ strings.currency_label }}</label>
4
+ <select name="currency_options[gateways_settings][{{ gateway_id }}][currency]" id="wcml_currency_options_gateway_code_{{ gateway_id }}">
5
+ {% for code, currency_details in currencies_details %}
6
+ <option value="{{ code }}" {% if ( gateway_settings and code == gateway_settings.currency ) or ( gateway_settings is empty and code == current_currency ) %}selected="selected"{% endif %} data-publishable-key="{{ currency_details.publishable_key }}" data-secret-key="{{ currency_details.secret_key }}" >{{ code }}</option>
7
+ {% endfor %}
8
+ </select>
9
+ </div>
10
+ <div class="wpml-form-row">
11
+ <label>{{ strings.publishable_label}}</label>
12
+ <input type="password" name="currency_options[gateways_settings][{{ gateway_id }}][publishable_key]" value="{{ gateway_settings.publishable_key }}"/>
13
+ </div>
14
+ <div class="wpml-form-row">
15
+ <label>{{ strings.secret_label}}</label>
16
+ <input type="password" name="currency_options[gateways_settings][{{ gateway_id }}][secret_key]" value="{{ gateway_settings.secret_key }}"/>
17
+ </div>
templates/plugins-wrap.twig CHANGED
@@ -47,19 +47,6 @@
47
  </li>
48
  {% endif %}
49
 
50
- {% if media_version %}
51
- <li>
52
- <i class="otgs-ico-ok wpml-media"></i>
53
- {{ strings.inst_active|format( strings.media )|raw }}
54
- </li>
55
- {% else %}
56
- <li>
57
- <i class="otgs-ico-warning wpml-media"></i>
58
- {{ strings.not_inst|format( strings.media )|raw }}
59
- <a href="{{ install_wpml_link|e }}" target="_blank">{{ strings.get_wpml_media }}</a>
60
- </li>
61
- {% endif %}
62
-
63
  {% if tm_version %}
64
  <li>
65
  <i class="otgs-ico-ok wpml-translation-management"></i>
47
  </li>
48
  {% endif %}
49
 
 
 
 
 
 
 
 
 
 
 
 
 
 
50
  {% if tm_version %}
51
  <li>
52
  <i class="otgs-ico-ok wpml-translation-management"></i>
templates/products-list/products.twig CHANGED
@@ -24,10 +24,12 @@
24
  </th>
25
  <th scope="col"
26
  class="column-categories">{{ strings.categories }}</th>
27
- <th scope="col" class="column-product_type">
28
- <span class="wc-type wcml-tip"
29
- data-tip="{{ strings.type|e }}">{{ strings.type }}</span>
30
- </th>
 
 
31
  <th scope="col" id="date" class="column-date {{ filter_urls.date_sorted }}">
32
  <a href="{{ filter_urls.date|e }}">
33
  <span>{{ strings.date }}</span>
@@ -108,11 +110,12 @@
108
  <a href="{{ category.href|e }}">{{ category.name }}</a>
109
  {% endfor %}
110
  </td>
111
-
112
- <td class="column-product_type">
113
- <span class="product-type wcml-tip {{ product.icon_class|e }}"
114
- data-tip="{{ product.icon_class|e }}"></span>
115
- </td>
 
116
 
117
  <td class="column-date">
118
  {{ product.formated_date }}
24
  </th>
25
  <th scope="col"
26
  class="column-categories">{{ strings.categories }}</th>
27
+ {% if ( strings.type ) %}
28
+ <th scope="col" class="column-product_type">
29
+ <span class="wc-type wcml-tip"
30
+ data-tip="{{ strings.type|e }}">{{ strings.type }}</span>
31
+ </th>
32
+ {% endif %}
33
  <th scope="col" id="date" class="column-date {{ filter_urls.date_sorted }}">
34
  <a href="{{ filter_urls.date|e }}">
35
  <span>{{ strings.date }}</span>
110
  <a href="{{ category.href|e }}">{{ category.name }}</a>
111
  {% endfor %}
112
  </td>
113
+ {% if ( strings.type ) %}
114
+ <td class="column-product_type">
115
+ <span class="product-type wcml-tip {{ product.icon_class|e }}"
116
+ data-tip="{{ product.icon_class|e }}"></span>
117
+ </td>
118
+ {% endif %}
119
 
120
  <td class="column-date">
121
  {{ product.formated_date }}
templates/troubleshooting.twig CHANGED
@@ -79,8 +79,8 @@
79
  <input id="count_prod" type="hidden" value="{{ prod_count }}"/>
80
  <input id="count_galleries" type="hidden" value="{{ prod_count }}"/>
81
  <input id="count_categories" type="hidden" value="{{ prod_categories_count }}"/>
82
- <input id="count_terms" type="hidden" value="<{{ terms_count }}"/>
83
- <input id="count_stock" type="hidden" value="<{{ sync_stock_count }}"/>
84
  <input id="sync_galerry_page" type="hidden" value="0"/>
85
  <input id="sync_category_page" type="hidden" value="0"/>
86
  <span class="spinner"></span>
79
  <input id="count_prod" type="hidden" value="{{ prod_count }}"/>
80
  <input id="count_galleries" type="hidden" value="{{ prod_count }}"/>
81
  <input id="count_categories" type="hidden" value="{{ prod_categories_count }}"/>
82
+ <input id="count_terms" type="hidden" value="{{ terms_count }}"/>
83
+ <input id="count_stock" type="hidden" value="{{ sync_stock_count }}"/>
84
  <input id="sync_galerry_page" type="hidden" value="0"/>
85
  <input id="sync_category_page" type="hidden" value="0"/>
86
  <span class="spinner"></span>
vendor/autoload.php CHANGED
@@ -4,4 +4,4 @@
4
 
5
  require_once __DIR__ . '/composer/autoload_real.php';
6
 
7
- return ComposerAutoloaderInit87c69e133ca17c099ad92fffa100f255::getLoader();
4
 
5
  require_once __DIR__ . '/composer/autoload_real.php';
6
 
7
+ return ComposerAutoloaderInit16830393fdb1b55f62e7d6c070d05751::getLoader();
vendor/autoload_52.php CHANGED
@@ -4,4 +4,4 @@
4
 
5
  require_once dirname(__FILE__) . '/composer'.'/autoload_real_52.php';
6
 
7
- return ComposerAutoloaderInitdf66a40527ea1c5196e12b44508f7caa::getLoader();
4
 
5
  require_once dirname(__FILE__) . '/composer'.'/autoload_real_52.php';
6
 
7
+ return ComposerAutoloaderInitee5ac953817836c77c6305986630a01e::getLoader();
vendor/composer/ClassLoader.php CHANGED
@@ -279,7 +279,7 @@ class ClassLoader
279
  */
280
  public function setApcuPrefix($apcuPrefix)
281
  {
282
- $this->apcuPrefix = function_exists('apcu_fetch') && ini_get('apc.enabled') ? $apcuPrefix : null;
283
  }
284
 
285
  /**
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
  /**
vendor/composer/autoload_classmap.php CHANGED
@@ -6,292 +6,6 @@ $vendorDir = dirname(dirname(__FILE__));
6
  $baseDir = dirname($vendorDir);
7
 
8
  return array(
9
- 'Composer\\Installers\\AglInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/AglInstaller.php',
10
- 'Composer\\Installers\\AimeosInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/AimeosInstaller.php',
11
- 'Composer\\Installers\\AnnotateCmsInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/AnnotateCmsInstaller.php',
12
- 'Composer\\Installers\\AsgardInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/AsgardInstaller.php',
13
- 'Composer\\Installers\\AttogramInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/AttogramInstaller.php',
14
- 'Composer\\Installers\\BaseInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/BaseInstaller.php',
15
- 'Composer\\Installers\\BitrixInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/BitrixInstaller.php',
16
- 'Composer\\Installers\\BonefishInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/BonefishInstaller.php',
17
- 'Composer\\Installers\\CakePHPInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/CakePHPInstaller.php',
18
- 'Composer\\Installers\\ChefInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/ChefInstaller.php',
19
- 'Composer\\Installers\\ClanCatsFrameworkInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/ClanCatsFrameworkInstaller.php',
20
- 'Composer\\Installers\\CockpitInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/CockpitInstaller.php',
21
- 'Composer\\Installers\\CodeIgniterInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/CodeIgniterInstaller.php',
22
- 'Composer\\Installers\\Concrete5Installer' => $vendorDir . '/composer/installers/src/Composer/Installers/Concrete5Installer.php',
23
- 'Composer\\Installers\\CraftInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/CraftInstaller.php',
24
- 'Composer\\Installers\\CroogoInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/CroogoInstaller.php',
25
- 'Composer\\Installers\\DecibelInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/DecibelInstaller.php',
26
- 'Composer\\Installers\\DokuWikiInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/DokuWikiInstaller.php',
27
- 'Composer\\Installers\\DolibarrInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/DolibarrInstaller.php',
28
- 'Composer\\Installers\\DrupalInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/DrupalInstaller.php',
29
- 'Composer\\Installers\\ElggInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/ElggInstaller.php',
30
- 'Composer\\Installers\\EliasisInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/EliasisInstaller.php',
31
- 'Composer\\Installers\\ExpressionEngineInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/ExpressionEngineInstaller.php',
32
- 'Composer\\Installers\\EzPlatformInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/EzPlatformInstaller.php',
33
- 'Composer\\Installers\\FuelInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/FuelInstaller.php',
34
- 'Composer\\Installers\\FuelphpInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/FuelphpInstaller.php',
35
- 'Composer\\Installers\\GravInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/GravInstaller.php',
36
- 'Composer\\Installers\\HuradInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/HuradInstaller.php',
37
- 'Composer\\Installers\\ImageCMSInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/ImageCMSInstaller.php',
38
- 'Composer\\Installers\\Installer' => $vendorDir . '/composer/installers/src/Composer/Installers/Installer.php',
39
- 'Composer\\Installers\\ItopInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/ItopInstaller.php',
40
- 'Composer\\Installers\\JoomlaInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/JoomlaInstaller.php',
41
- 'Composer\\Installers\\KanboardInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/KanboardInstaller.php',
42
- 'Composer\\Installers\\KirbyInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/KirbyInstaller.php',
43
- 'Composer\\Installers\\KodiCMSInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/KodiCMSInstaller.php',
44
- 'Composer\\Installers\\KohanaInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/KohanaInstaller.php',
45
- 'Composer\\Installers\\LanManagementSystemInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/LanManagementSystemInstaller.php',
46
- 'Composer\\Installers\\LaravelInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/LaravelInstaller.php',
47
- 'Composer\\Installers\\LavaLiteInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/LavaLiteInstaller.php',
48
- 'Composer\\Installers\\LithiumInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/LithiumInstaller.php',
49
- 'Composer\\Installers\\MODULEWorkInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/MODULEWorkInstaller.php',
50
- 'Composer\\Installers\\MODXEvoInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/MODXEvoInstaller.php',
51
- 'Composer\\Installers\\MagentoInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/MagentoInstaller.php',
52
- 'Composer\\Installers\\MajimaInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/MajimaInstaller.php',
53
- 'Composer\\Installers\\MakoInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/MakoInstaller.php',
54
- 'Composer\\Installers\\MauticInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/MauticInstaller.php',
55
- 'Composer\\Installers\\MayaInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/MayaInstaller.php',
56
- 'Composer\\Installers\\MediaWikiInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/MediaWikiInstaller.php',
57
- 'Composer\\Installers\\MicroweberInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/MicroweberInstaller.php',
58
- 'Composer\\Installers\\ModxInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/ModxInstaller.php',
59
- 'Composer\\Installers\\MoodleInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/MoodleInstaller.php',
60
- 'Composer\\Installers\\OctoberInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/OctoberInstaller.php',
61
- 'Composer\\Installers\\OntoWikiInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/OntoWikiInstaller.php',
62
- 'Composer\\Installers\\OsclassInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/OsclassInstaller.php',
63
- 'Composer\\Installers\\OxidInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/OxidInstaller.php',
64
- 'Composer\\Installers\\PPIInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/PPIInstaller.php',
65
- 'Composer\\Installers\\PhiftyInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/PhiftyInstaller.php',
66
- 'Composer\\Installers\\PhpBBInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/PhpBBInstaller.php',
67
- 'Composer\\Installers\\PimcoreInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/PimcoreInstaller.php',
68
- 'Composer\\Installers\\PiwikInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/PiwikInstaller.php',
69
- 'Composer\\Installers\\PlentymarketsInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/PlentymarketsInstaller.php',
70
- 'Composer\\Installers\\Plugin' => $vendorDir . '/composer/installers/src/Composer/Installers/Plugin.php',
71
- 'Composer\\Installers\\PortoInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/PortoInstaller.php',
72
- 'Composer\\Installers\\PrestashopInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/PrestashopInstaller.php',
73
- 'Composer\\Installers\\PuppetInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/PuppetInstaller.php',
74
- 'Composer\\Installers\\PxcmsInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/PxcmsInstaller.php',
75
- 'Composer\\Installers\\RadPHPInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/RadPHPInstaller.php',
76
- 'Composer\\Installers\\ReIndexInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/ReIndexInstaller.php',
77
- 'Composer\\Installers\\RedaxoInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/RedaxoInstaller.php',
78
- 'Composer\\Installers\\RoundcubeInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/RoundcubeInstaller.php',
79
- 'Composer\\Installers\\SMFInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/SMFInstaller.php',
80
- 'Composer\\Installers\\ShopwareInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/ShopwareInstaller.php',
81
- 'Composer\\Installers\\SilverStripeInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/SilverStripeInstaller.php',
82
- 'Composer\\Installers\\SiteDirectInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/SiteDirectInstaller.php',
83
- 'Composer\\Installers\\SyDESInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/SyDESInstaller.php',
84
- 'Composer\\Installers\\Symfony1Installer' => $vendorDir . '/composer/installers/src/Composer/Installers/Symfony1Installer.php',
85
- 'Composer\\Installers\\TYPO3CmsInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/TYPO3CmsInstaller.php',
86
- 'Composer\\Installers\\TYPO3FlowInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/TYPO3FlowInstaller.php',
87
- 'Composer\\Installers\\TheliaInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/TheliaInstaller.php',
88
- 'Composer\\Installers\\TuskInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/TuskInstaller.php',
89
- 'Composer\\Installers\\UserFrostingInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/UserFrostingInstaller.php',
90
- 'Composer\\Installers\\VanillaInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/VanillaInstaller.php',
91
- 'Composer\\Installers\\VgmcpInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/VgmcpInstaller.php',
92
- 'Composer\\Installers\\WHMCSInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/WHMCSInstaller.php',
93
- 'Composer\\Installers\\WolfCMSInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/WolfCMSInstaller.php',
94
- 'Composer\\Installers\\WordPressInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/WordPressInstaller.php',
95
- 'Composer\\Installers\\YawikInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/YawikInstaller.php',
96
- 'Composer\\Installers\\ZendInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/ZendInstaller.php',
97
- 'Composer\\Installers\\ZikulaInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/ZikulaInstaller.php',
98
- 'Twig_Autoloader' => $vendorDir . '/twig/twig/lib/Twig/Autoloader.php',
99
- 'Twig_BaseNodeVisitor' => $vendorDir . '/twig/twig/lib/Twig/BaseNodeVisitor.php',
100
- 'Twig_CacheInterface' => $vendorDir . '/twig/twig/lib/Twig/CacheInterface.php',
101
- 'Twig_Cache_Filesystem' => $vendorDir . '/twig/twig/lib/Twig/Cache/Filesystem.php',
102
- 'Twig_Cache_Null' => $vendorDir . '/twig/twig/lib/Twig/Cache/Null.php',
103
- 'Twig_Compiler' => $vendorDir . '/twig/twig/lib/Twig/Compiler.php',
104
- 'Twig_CompilerInterface' => $vendorDir . '/twig/twig/lib/Twig/CompilerInterface.php',
105
- 'Twig_ContainerRuntimeLoader' => $vendorDir . '/twig/twig/lib/Twig/ContainerRuntimeLoader.php',
106
- 'Twig_Environment' => $vendorDir . '/twig/twig/lib/Twig/Environment.php',
107
- 'Twig_Error' => $vendorDir . '/twig/twig/lib/Twig/Error.php',
108
- 'Twig_Error_Loader' => $vendorDir . '/twig/twig/lib/Twig/Error/Loader.php',
109
- 'Twig_Error_Runtime' => $vendorDir . '/twig/twig/lib/Twig/Error/Runtime.php',
110
- 'Twig_Error_Syntax' => $vendorDir . '/twig/twig/lib/Twig/Error/Syntax.php',
111
- 'Twig_ExistsLoaderInterface' => $vendorDir . '/twig/twig/lib/Twig/ExistsLoaderInterface.php',
112
- 'Twig_ExpressionParser' => $vendorDir . '/twig/twig/lib/Twig/ExpressionParser.php',
113
- 'Twig_Extension' => $vendorDir . '/twig/twig/lib/Twig/Extension.php',
114
- 'Twig_ExtensionInterface' => $vendorDir . '/twig/twig/lib/Twig/ExtensionInterface.php',
115
- 'Twig_Extension_Core' => $vendorDir . '/twig/twig/lib/Twig/Extension/Core.php',
116
- 'Twig_Extension_Debug' => $vendorDir . '/twig/twig/lib/Twig/Extension/Debug.php',
117
- 'Twig_Extension_Escaper' => $vendorDir . '/twig/twig/lib/Twig/Extension/Escaper.php',
118
- 'Twig_Extension_GlobalsInterface' => $vendorDir . '/twig/twig/lib/Twig/Extension/GlobalsInterface.php',
119
- 'Twig_Extension_InitRuntimeInterface' => $vendorDir . '/twig/twig/lib/Twig/Extension/InitRuntimeInterface.php',
120
- 'Twig_Extension_Optimizer' => $vendorDir . '/twig/twig/lib/Twig/Extension/Optimizer.php',
121
- 'Twig_Extension_Profiler' => $vendorDir . '/twig/twig/lib/Twig/Extension/Profiler.php',
122
- 'Twig_Extension_Sandbox' => $vendorDir . '/twig/twig/lib/Twig/Extension/Sandbox.php',
123
- 'Twig_Extension_Staging' => $vendorDir . '/twig/twig/lib/Twig/Extension/Staging.php',
124
- 'Twig_Extension_StringLoader' => $vendorDir . '/twig/twig/lib/Twig/Extension/StringLoader.php',
125
- 'Twig_FactoryRuntimeLoader' => $vendorDir . '/twig/twig/lib/Twig/FactoryRuntimeLoader.php',
126
- 'Twig_FileExtensionEscapingStrategy' => $vendorDir . '/twig/twig/lib/Twig/FileExtensionEscapingStrategy.php',
127
- 'Twig_Filter' => $vendorDir . '/twig/twig/lib/Twig/Filter.php',
128
- 'Twig_FilterCallableInterface' => $vendorDir . '/twig/twig/lib/Twig/FilterCallableInterface.php',
129
- 'Twig_FilterInterface' => $vendorDir . '/twig/twig/lib/Twig/FilterInterface.php',
130
- 'Twig_Filter_Function' => $vendorDir . '/twig/twig/lib/Twig/Filter/Function.php',
131
- 'Twig_Filter_Method' => $vendorDir . '/twig/twig/lib/Twig/Filter/Method.php',
132
- 'Twig_Filter_Node' => $vendorDir . '/twig/twig/lib/Twig/Filter/Node.php',
133
- 'Twig_Function' => $vendorDir . '/twig/twig/lib/Twig/Function.php',
134
- 'Twig_FunctionCallableInterface' => $vendorDir . '/twig/twig/lib/Twig/FunctionCallableInterface.php',
135
- 'Twig_FunctionInterface' => $vendorDir . '/twig/twig/lib/Twig/FunctionInterface.php',
136
- 'Twig_Function_Function' => $vendorDir . '/twig/twig/lib/Twig/Function/Function.php',
137
- 'Twig_Function_Method' => $vendorDir . '/twig/twig/lib/Twig/Function/Method.php',
138
- 'Twig_Function_Node' => $vendorDir . '/twig/twig/lib/Twig/Function/Node.php',
139
- 'Twig_Lexer' => $vendorDir . '/twig/twig/lib/Twig/Lexer.php',
140
- 'Twig_LexerInterface' => $vendorDir . '/twig/twig/lib/Twig/LexerInterface.php',
141
- 'Twig_LoaderInterface' => $vendorDir . '/twig/twig/lib/Twig/LoaderInterface.php',
142
- 'Twig_Loader_Array' => $vendorDir . '/twig/twig/lib/Twig/Loader/Array.php',
143
- 'Twig_Loader_Chain' => $vendorDir . '/twig/twig/lib/Twig/Loader/Chain.php',
144
- 'Twig_Loader_Filesystem' => $vendorDir . '/twig/twig/lib/Twig/Loader/Filesystem.php',
145
- 'Twig_Loader_String' => $vendorDir . '/twig/twig/lib/Twig/Loader/String.php',
146
- 'Twig_Markup' => $vendorDir . '/twig/twig/lib/Twig/Markup.php',
147
- 'Twig_Node' => $vendorDir . '/twig/twig/lib/Twig/Node.php',
148
- 'Twig_NodeCaptureInterface' => $vendorDir . '/twig/twig/lib/Twig/NodeCaptureInterface.php',
149
- 'Twig_NodeInterface' => $vendorDir . '/twig/twig/lib/Twig/NodeInterface.php',
150
- 'Twig_NodeOutputInterface' => $vendorDir . '/twig/twig/lib/Twig/NodeOutputInterface.php',
151
- 'Twig_NodeTraverser' => $vendorDir . '/twig/twig/lib/Twig/NodeTraverser.php',
152
- 'Twig_NodeVisitorInterface' => $vendorDir . '/twig/twig/lib/Twig/NodeVisitorInterface.php',
153
- 'Twig_NodeVisitor_Escaper' => $vendorDir . '/twig/twig/lib/Twig/NodeVisitor/Escaper.php',
154
- 'Twig_NodeVisitor_Optimizer' => $vendorDir . '/twig/twig/lib/Twig/NodeVisitor/Optimizer.php',
155
- 'Twig_NodeVisitor_SafeAnalysis' => $vendorDir . '/twig/twig/lib/Twig/NodeVisitor/SafeAnalysis.php',
156
- 'Twig_NodeVisitor_Sandbox' => $vendorDir . '/twig/twig/lib/Twig/NodeVisitor/Sandbox.php',
157
- 'Twig_Node_AutoEscape' => $vendorDir . '/twig/twig/lib/Twig/Node/AutoEscape.php',
158
- 'Twig_Node_Block' => $vendorDir . '/twig/twig/lib/Twig/Node/Block.php',
159
- 'Twig_Node_BlockReference' => $vendorDir . '/twig/twig/lib/Twig/Node/BlockReference.php',
160
- 'Twig_Node_Body' => $vendorDir . '/twig/twig/lib/Twig/Node/Body.php',
161
- 'Twig_Node_CheckSecurity' => $vendorDir . '/twig/twig/lib/Twig/Node/CheckSecurity.php',
162
- 'Twig_Node_Do' => $vendorDir . '/twig/twig/lib/Twig/Node/Do.php',
163
- 'Twig_Node_Embed' => $vendorDir . '/twig/twig/lib/Twig/Node/Embed.php',
164
- 'Twig_Node_Expression' => $vendorDir . '/twig/twig/lib/Twig/Node/Expression.php',
165
- 'Twig_Node_Expression_Array' => $vendorDir . '/twig/twig/lib/Twig/Node/Expression/Array.php',
166
- 'Twig_Node_Expression_AssignName' => $vendorDir . '/twig/twig/lib/Twig/Node/Expression/AssignName.php',
167
- 'Twig_Node_Expression_Binary' => $vendorDir . '/twig/twig/lib/Twig/Node/Expression/Binary.php',
168
- 'Twig_Node_Expression_Binary_Add' => $vendorDir . '/twig/twig/lib/Twig/Node/Expression/Binary/Add.php',
169
- 'Twig_Node_Expression_Binary_And' => $vendorDir . '/twig/twig/lib/Twig/Node/Expression/Binary/And.php',
170
- 'Twig_Node_Expression_Binary_BitwiseAnd' => $vendorDir . '/twig/twig/lib/Twig/Node/Expression/Binary/BitwiseAnd.php',
171
- 'Twig_Node_Expression_Binary_BitwiseOr' => $vendorDir . '/twig/twig/lib/Twig/Node/Expression/Binary/BitwiseOr.php',
172
- 'Twig_Node_Expression_Binary_BitwiseXor' => $vendorDir . '/twig/twig/lib/Twig/Node/Expression/Binary/BitwiseXor.php',
173
- 'Twig_Node_Expression_Binary_Concat' => $vendorDir . '/twig/twig/lib/Twig/Node/Expression/Binary/Concat.php',
174
- 'Twig_Node_Expression_Binary_Div' => $vendorDir . '/twig/twig/lib/Twig/Node/Expression/Binary/Div.php',
175
- 'Twig_Node_Expression_Binary_EndsWith' => $vendorDir . '/twig/twig/lib/Twig/Node/Expression/Binary/EndsWith.php',
176
- 'Twig_Node_Expression_Binary_Equal' => $vendorDir . '/twig/twig/lib/Twig/Node/Expression/Binary/Equal.php',
177
- 'Twig_Node_Expression_Binary_FloorDiv' => $vendorDir . '/twig/twig/lib/Twig/Node/Expression/Binary/FloorDiv.php',
178
- 'Twig_Node_Expression_Binary_Greater' => $vendorDir . '/twig/twig/lib/Twig/Node/Expression/Binary/Greater.php',
179
- 'Twig_Node_Expression_Binary_GreaterEqual' => $vendorDir . '/twig/twig/lib/Twig/Node/Expression/Binary/GreaterEqual.php',
180
- 'Twig_Node_Expression_Binary_In' => $vendorDir . '/twig/twig/lib/Twig/Node/Expression/Binary/In.php',
181
- 'Twig_Node_Expression_Binary_Less' => $vendorDir . '/twig/twig/lib/Twig/Node/Expression/Binary/Less.php',
182
- 'Twig_Node_Expression_Binary_LessEqual' => $vendorDir . '/twig/twig/lib/Twig/Node/Expression/Binary/LessEqual.php',
183
- 'Twig_Node_Expression_Binary_Matches' => $vendorDir . '/twig/twig/lib/Twig/Node/Expression/Binary/Matches.php',
184
- 'Twig_Node_Expression_Binary_Mod' => $vendorDir . '/twig/twig/lib/Twig/Node/Expression/Binary/Mod.php',
185
- 'Twig_Node_Expression_Binary_Mul' => $vendorDir . '/twig/twig/lib/Twig/Node/Expression/Binary/Mul.php',
186
- 'Twig_Node_Expression_Binary_NotEqual' => $vendorDir . '/twig/twig/lib/Twig/Node/Expression/Binary/NotEqual.php',
187
- 'Twig_Node_Expression_Binary_NotIn' => $vendorDir . '/twig/twig/lib/Twig/Node/Expression/Binary/NotIn.php',
188
- 'Twig_Node_Expression_Binary_Or' => $vendorDir . '/twig/twig/lib/Twig/Node/Expression/Binary/Or.php',
189
- 'Twig_Node_Expression_Binary_Power' => $vendorDir . '/twig/twig/lib/Twig/Node/Expression/Binary/Power.php',
190
- 'Twig_Node_Expression_Binary_Range' => $vendorDir . '/twig/twig/lib/Twig/Node/Expression/Binary/Range.php',
191
- 'Twig_Node_Expression_Binary_StartsWith' => $vendorDir . '/twig/twig/lib/Twig/Node/Expression/Binary/StartsWith.php',
192
- 'Twig_Node_Expression_Binary_Sub' => $vendorDir . '/twig/twig/lib/Twig/Node/Expression/Binary/Sub.php',
193
- 'Twig_Node_Expression_BlockReference' => $vendorDir . '/twig/twig/lib/Twig/Node/Expression/BlockReference.php',
194
- 'Twig_Node_Expression_Call' => $vendorDir . '/twig/twig/lib/Twig/Node/Expression/Call.php',
195
- 'Twig_Node_Expression_Conditional' => $vendorDir . '/twig/twig/lib/Twig/Node/Expression/Conditional.php',
196
- 'Twig_Node_Expression_Constant' => $vendorDir . '/twig/twig/lib/Twig/Node/Expression/Constant.php',
197
- 'Twig_Node_Expression_ExtensionReference' => $vendorDir . '/twig/twig/lib/Twig/Node/Expression/ExtensionReference.php',
198
- 'Twig_Node_Expression_Filter' => $vendorDir . '/twig/twig/lib/Twig/Node/Expression/Filter.php',
199
- 'Twig_Node_Expression_Filter_Default' => $vendorDir . '/twig/twig/lib/Twig/Node/Expression/Filter/Default.php',
200
- 'Twig_Node_Expression_Function' => $vendorDir . '/twig/twig/lib/Twig/Node/Expression/Function.php',
201
- 'Twig_Node_Expression_GetAttr' => $vendorDir . '/twig/twig/lib/Twig/Node/Expression/GetAttr.php',
202
- 'Twig_Node_Expression_MethodCall' => $vendorDir . '/twig/twig/lib/Twig/Node/Expression/MethodCall.php',
203
- 'Twig_Node_Expression_Name' => $vendorDir . '/twig/twig/lib/Twig/Node/Expression/Name.php',
204
- 'Twig_Node_Expression_NullCoalesce' => $vendorDir . '/twig/twig/lib/Twig/Node/Expression/NullCoalesce.php',
205
- 'Twig_Node_Expression_Parent' => $vendorDir . '/twig/twig/lib/Twig/Node/Expression/Parent.php',
206
- 'Twig_Node_Expression_TempName' => $vendorDir . '/twig/twig/lib/Twig/Node/Expression/TempName.php',
207
- 'Twig_Node_Expression_Test' => $vendorDir . '/twig/twig/lib/Twig/Node/Expression/Test.php',
208
- 'Twig_Node_Expression_Test_Constant' => $vendorDir . '/twig/twig/lib/Twig/Node/Expression/Test/Constant.php',
209
- 'Twig_Node_Expression_Test_Defined' => $vendorDir . '/twig/twig/lib/Twig/Node/Expression/Test/Defined.php',
210
- 'Twig_Node_Expression_Test_Divisibleby' => $vendorDir . '/twig/twig/lib/Twig/Node/Expression/Test/Divisibleby.php',
211
- 'Twig_Node_Expression_Test_Even' => $vendorDir . '/twig/twig/lib/Twig/Node/Expression/Test/Even.php',
212
- 'Twig_Node_Expression_Test_Null' => $vendorDir . '/twig/twig/lib/Twig/Node/Expression/Test/Null.php',
213
- 'Twig_Node_Expression_Test_Odd' => $vendorDir . '/twig/twig/lib/Twig/Node/Expression/Test/Odd.php',
214
- 'Twig_Node_Expression_Test_Sameas' => $vendorDir . '/twig/twig/lib/Twig/Node/Expression/Test/Sameas.php',
215
- 'Twig_Node_Expression_Unary' => $vendorDir . '/twig/twig/lib/Twig/Node/Expression/Unary.php',
216
- 'Twig_Node_Expression_Unary_Neg' => $vendorDir . '/twig/twig/lib/Twig/Node/Expression/Unary/Neg.php',
217
- 'Twig_Node_Expression_Unary_Not' => $vendorDir . '/twig/twig/lib/Twig/Node/Expression/Unary/Not.php',
218
- 'Twig_Node_Expression_Unary_Pos' => $vendorDir . '/twig/twig/lib/Twig/Node/Expression/Unary/Pos.php',
219
- 'Twig_Node_Flush' => $vendorDir . '/twig/twig/lib/Twig/Node/Flush.php',
220
- 'Twig_Node_For' => $vendorDir . '/twig/twig/lib/Twig/Node/For.php',
221
- 'Twig_Node_ForLoop' => $vendorDir . '/twig/twig/lib/Twig/Node/ForLoop.php',
222
- 'Twig_Node_If' => $vendorDir . '/twig/twig/lib/Twig/Node/If.php',
223
- 'Twig_Node_Import' => $vendorDir . '/twig/twig/lib/Twig/Node/Import.php',
224
- 'Twig_Node_Include' => $vendorDir . '/twig/twig/lib/Twig/Node/Include.php',
225
- 'Twig_Node_Macro' => $vendorDir . '/twig/twig/lib/Twig/Node/Macro.php',
226
- 'Twig_Node_Module' => $vendorDir . '/twig/twig/lib/Twig/Node/Module.php',
227
- 'Twig_Node_Print' => $vendorDir . '/twig/twig/lib/Twig/Node/Print.php',
228
- 'Twig_Node_Sandbox' => $vendorDir . '/twig/twig/lib/Twig/Node/Sandbox.php',
229
- 'Twig_Node_SandboxedPrint' => $vendorDir . '/twig/twig/lib/Twig/Node/SandboxedPrint.php',
230
- 'Twig_Node_Set' => $vendorDir . '/twig/twig/lib/Twig/Node/Set.php',
231
- 'Twig_Node_SetTemp' => $vendorDir . '/twig/twig/lib/Twig/Node/SetTemp.php',
232
- 'Twig_Node_Spaceless' => $vendorDir . '/twig/twig/lib/Twig/Node/Spaceless.php',
233
- 'Twig_Node_Text' => $vendorDir . '/twig/twig/lib/Twig/Node/Text.php',
234
- 'Twig_Node_With' => $vendorDir . '/twig/twig/lib/Twig/Node/With.php',
235
- 'Twig_Parser' => $vendorDir . '/twig/twig/lib/Twig/Parser.php',
236
- 'Twig_ParserInterface' => $vendorDir . '/twig/twig/lib/Twig/ParserInterface.php',
237
- 'Twig_Profiler_Dumper_Blackfire' => $vendorDir . '/twig/twig/lib/Twig/Profiler/Dumper/Blackfire.php',
238
- 'Twig_Profiler_Dumper_Html' => $vendorDir . '/twig/twig/lib/Twig/Profiler/Dumper/Html.php',
239
- 'Twig_Profiler_Dumper_Text' => $vendorDir . '/twig/twig/lib/Twig/Profiler/Dumper/Text.php',
240
- 'Twig_Profiler_NodeVisitor_Profiler' => $vendorDir . '/twig/twig/lib/Twig/Profiler/NodeVisitor/Profiler.php',
241
- 'Twig_Profiler_Node_EnterProfile' => $vendorDir . '/twig/twig/lib/Twig/Profiler/Node/EnterProfile.php',
242
- 'Twig_Profiler_Node_LeaveProfile' => $vendorDir . '/twig/twig/lib/Twig/Profiler/Node/LeaveProfile.php',
243
- 'Twig_Profiler_Profile' => $vendorDir . '/twig/twig/lib/Twig/Profiler/Profile.php',
244
- 'Twig_RuntimeLoaderInterface' => $vendorDir . '/twig/twig/lib/Twig/RuntimeLoaderInterface.php',
245
- 'Twig_Sandbox_SecurityError' => $vendorDir . '/twig/twig/lib/Twig/Sandbox/SecurityError.php',
246
- 'Twig_Sandbox_SecurityNotAllowedFilterError' => $vendorDir . '/twig/twig/lib/Twig/Sandbox/SecurityNotAllowedFilterError.php',
247
- 'Twig_Sandbox_SecurityNotAllowedFunctionError' => $vendorDir . '/twig/twig/lib/Twig/Sandbox/SecurityNotAllowedFunctionError.php',
248
- 'Twig_Sandbox_SecurityNotAllowedMethodError' => $vendorDir . '/twig/twig/lib/Twig/Sandbox/SecurityNotAllowedMethodError.php',
249
- 'Twig_Sandbox_SecurityNotAllowedPropertyError' => $vendorDir . '/twig/twig/lib/Twig/Sandbox/SecurityNotAllowedPropertyError.php',
250
- 'Twig_Sandbox_SecurityNotAllowedTagError' => $vendorDir . '/twig/twig/lib/Twig/Sandbox/SecurityNotAllowedTagError.php',
251
- 'Twig_Sandbox_SecurityPolicy' => $vendorDir . '/twig/twig/lib/Twig/Sandbox/SecurityPolicy.php',
252
- 'Twig_Sandbox_SecurityPolicyInterface' => $vendorDir . '/twig/twig/lib/Twig/Sandbox/SecurityPolicyInterface.php',
253
- 'Twig_SimpleFilter' => $vendorDir . '/twig/twig/lib/Twig/SimpleFilter.php',
254
- 'Twig_SimpleFunction' => $vendorDir . '/twig/twig/lib/Twig/SimpleFunction.php',
255
- 'Twig_SimpleTest' => $vendorDir . '/twig/twig/lib/Twig/SimpleTest.php',
256
- 'Twig_Source' => $vendorDir . '/twig/twig/lib/Twig/Source.php',
257
- 'Twig_SourceContextLoaderInterface' => $vendorDir . '/twig/twig/lib/Twig/SourceContextLoaderInterface.php',
258
- 'Twig_Template' => $vendorDir . '/twig/twig/lib/Twig/Template.php',
259
- 'Twig_TemplateInterface' => $vendorDir . '/twig/twig/lib/Twig/TemplateInterface.php',
260
- 'Twig_TemplateWrapper' => $vendorDir . '/twig/twig/lib/Twig/TemplateWrapper.php',
261
- 'Twig_Test' => $vendorDir . '/twig/twig/lib/Twig/Test.php',
262
- 'Twig_TestCallableInterface' => $vendorDir . '/twig/twig/lib/Twig/TestCallableInterface.php',
263
- 'Twig_TestInterface' => $vendorDir . '/twig/twig/lib/Twig/TestInterface.php',
264
- 'Twig_Test_Function' => $vendorDir . '/twig/twig/lib/Twig/Test/Function.php',
265
- 'Twig_Test_IntegrationTestCase' => $vendorDir . '/twig/twig/lib/Twig/Test/IntegrationTestCase.php',
266
- 'Twig_Test_Method' => $vendorDir . '/twig/twig/lib/Twig/Test/Method.php',
267
- 'Twig_Test_Node' => $vendorDir . '/twig/twig/lib/Twig/Test/Node.php',
268
- 'Twig_Test_NodeTestCase' => $vendorDir . '/twig/twig/lib/Twig/Test/NodeTestCase.php',
269
- 'Twig_Token' => $vendorDir . '/twig/twig/lib/Twig/Token.php',
270
- 'Twig_TokenParser' => $vendorDir . '/twig/twig/lib/Twig/TokenParser.php',
271
- 'Twig_TokenParserBroker' => $vendorDir . '/twig/twig/lib/Twig/TokenParserBroker.php',
272
- 'Twig_TokenParserBrokerInterface' => $vendorDir . '/twig/twig/lib/Twig/TokenParserBrokerInterface.php',
273
- 'Twig_TokenParserInterface' => $vendorDir . '/twig/twig/lib/Twig/TokenParserInterface.php',
274
- 'Twig_TokenParser_AutoEscape' => $vendorDir . '/twig/twig/lib/Twig/TokenParser/AutoEscape.php',
275
- 'Twig_TokenParser_Block' => $vendorDir . '/twig/twig/lib/Twig/TokenParser/Block.php',
276
- 'Twig_TokenParser_Do' => $vendorDir . '/twig/twig/lib/Twig/TokenParser/Do.php',
277
- 'Twig_TokenParser_Embed' => $vendorDir . '/twig/twig/lib/Twig/TokenParser/Embed.php',
278
- 'Twig_TokenParser_Extends' => $vendorDir . '/twig/twig/lib/Twig/TokenParser/Extends.php',
279
- 'Twig_TokenParser_Filter' => $vendorDir . '/twig/twig/lib/Twig/TokenParser/Filter.php',
280
- 'Twig_TokenParser_Flush' => $vendorDir . '/twig/twig/lib/Twig/TokenParser/Flush.php',
281
- 'Twig_TokenParser_For' => $vendorDir . '/twig/twig/lib/Twig/TokenParser/For.php',
282
- 'Twig_TokenParser_From' => $vendorDir . '/twig/twig/lib/Twig/TokenParser/From.php',
283
- 'Twig_TokenParser_If' => $vendorDir . '/twig/twig/lib/Twig/TokenParser/If.php',
284
- 'Twig_TokenParser_Import' => $vendorDir . '/twig/twig/lib/Twig/TokenParser/Import.php',
285
- 'Twig_TokenParser_Include' => $vendorDir . '/twig/twig/lib/Twig/TokenParser/Include.php',
286
- 'Twig_TokenParser_Macro' => $vendorDir . '/twig/twig/lib/Twig/TokenParser/Macro.php',
287
- 'Twig_TokenParser_Sandbox' => $vendorDir . '/twig/twig/lib/Twig/TokenParser/Sandbox.php',
288
- 'Twig_TokenParser_Set' => $vendorDir . '/twig/twig/lib/Twig/TokenParser/Set.php',
289
- 'Twig_TokenParser_Spaceless' => $vendorDir . '/twig/twig/lib/Twig/TokenParser/Spaceless.php',
290
- 'Twig_TokenParser_Use' => $vendorDir . '/twig/twig/lib/Twig/TokenParser/Use.php',
291
- 'Twig_TokenParser_With' => $vendorDir . '/twig/twig/lib/Twig/TokenParser/With.php',
292
- 'Twig_TokenStream' => $vendorDir . '/twig/twig/lib/Twig/TokenStream.php',
293
- 'Twig_Util_DeprecationCollector' => $vendorDir . '/twig/twig/lib/Twig/Util/DeprecationCollector.php',
294
- 'Twig_Util_TemplateDirIterator' => $vendorDir . '/twig/twig/lib/Twig/Util/TemplateDirIterator.php',
295
  'WCML_Accommodation_Bookings' => $baseDir . '/compatibility/class-wcml-accommodation-bookings.php',
296
  'WCML_Admin_Cookie' => $baseDir . '/classes/class-wcml-admin-cookie.php',
297
  'WCML_Admin_Currency_Selector' => $baseDir . '/classes/currencies/class-wcml-admin-currency-selector.php',
@@ -319,6 +33,8 @@ return array(
319
  'WCML_Composite_Products' => $baseDir . '/compatibility/class-wcml-composite-products.php',
320
  'WCML_Coupons' => $baseDir . '/inc/class-wcml-coupons.php',
321
  'WCML_Currencies' => $baseDir . '/classes/currencies/class-wcml-currencies.php',
 
 
322
  'WCML_Currency_Switcher' => $baseDir . '/inc/currencies/currency-switcher/class-wcml-currency-switcher.php',
323
  'WCML_Currency_Switcher_Ajax' => $baseDir . '/inc/currencies/currency-switcher/class-wcml-currency-switcher-ajax.php',
324
  'WCML_Currency_Switcher_Options_Dialog' => $baseDir . '/inc/template-classes/currency-switcher/class-wcml-currency-switcher-options-dialog.php',
@@ -339,6 +55,7 @@ return array(
339
  'WCML_Editor_UI_WYSIWYG_Field' => $baseDir . '/inc/translation-editor/class-wcml-editor-ui-wysiwyg-field.php',
340
  'WCML_Emails' => $baseDir . '/inc/class-wcml-emails.php',
341
  'WCML_Endpoints' => $baseDir . '/inc/class-wcml-endpoints.php',
 
342
  'WCML_Etheme_Blanco' => $baseDir . '/compatibility/class-wcml-etheme-blanco.php',
343
  'WCML_Exchange_Rate_Service' => $baseDir . '/classes/multi-currency/exchange-rate-services/class-wcml-exchange-rate-service.php',
344
  'WCML_Exchange_Rates' => $baseDir . '/classes/multi-currency/class-wcml-exchange-rates.php',
@@ -347,7 +64,6 @@ return array(
347
  'WCML_Exchange_Rates_UI' => $baseDir . '/inc/template-classes/multi-currency/class-wcml-exchange-rates-ui.php',
348
  'WCML_Extra_Product_Options' => $baseDir . '/compatibility/class-wcml-extra-product-options.php',
349
  'WCML_File' => $baseDir . '/inc/currencies/currency-switcher/class-wcml-file.php',
350
- 'WCML_Fix_Copied_Custom_Fields_WPML353' => $baseDir . '/inc/class-wcml-fix-copied-custom-fields-wpml353.php',
351
  'WCML_Flatsome' => $baseDir . '/compatibility/class-wcml-flatsome.php',
352
  'WCML_Install' => $baseDir . '/inc/class-wcml-install.php',
353
  'WCML_JCK_WSSV' => $baseDir . '/compatibility/class-wcml-jck-wssv.php',
@@ -369,12 +85,16 @@ return array(
369
  'WCML_Multi_Currency_Reports' => $baseDir . '/inc/currencies/class-wcml-multi-currency-reports.php',
370
  'WCML_Multi_Currency_Resources' => $baseDir . '/inc/currencies/class-wcml-multi-currency-resources.php',
371
  'WCML_Multi_Currency_Shipping' => $baseDir . '/inc/currencies/class-wcml-multi-currency-shipping.php',
372
- 'WCML_Multi_Currency_Shipping_Legacy' => $baseDir . '/inc/currencies/class-wcml-multi-currency-shipping-legacy.php',
373
  'WCML_Multi_Currency_Table_Rate_Shipping' => $baseDir . '/inc/currencies/class-wcml-multi-currency-table-rate-shipping.php',
374
  'WCML_Multi_Currency_UI' => $baseDir . '/inc/template-classes/multi-currency/class-wcml-multi-currency-ui.php',
 
375
  'WCML_Not_Translatable_Attributes' => $baseDir . '/inc/template-classes/class-wcml-not-translatable-attributes.php',
376
  'WCML_Orders' => $baseDir . '/inc/class-wcml-orders.php',
377
  'WCML_Page_Builders' => $baseDir . '/inc/translation-editor/class-wcml-page-builders.php',
 
 
 
 
378
  'WCML_Payment_Method_Filter' => $baseDir . '/classes/order-property-filter/class-wcml-payment-method-filter.php',
379
  'WCML_Per_Product_Shipping' => $baseDir . '/compatibility/class-wcml-per-product-shipping.php',
380
  'WCML_Pip' => $baseDir . '/compatibility/class-wcml-pip.php',
@@ -386,7 +106,6 @@ return array(
386
  'WCML_Privacy_Content_Factory' => $baseDir . '/classes/privacy/class-wcml-privacy-content-factory.php',
387
  'WCML_Product_Addons' => $baseDir . '/compatibility/class-wcml-product-addons.php',
388
  'WCML_Product_Bundles' => $baseDir . '/compatibility/class-wcml-product-bundles.php',
389
- 'WCML_Product_Bundles_Legacy' => $baseDir . '/compatibility/class-wcml-product-bundles-legacy.php',
390
  'WCML_Product_Gallery_Filter' => $baseDir . '/classes/media/class-wcml-product-gallery-filter.php',
391
  'WCML_Product_Gallery_Filter_Factory' => $baseDir . '/classes/media/class-wcml-product-gallery-filter-factory.php',
392
  'WCML_Product_Image_Filter' => $baseDir . '/classes/media/class-wcml-product-image-filter.php',
@@ -399,7 +118,6 @@ return array(
399
  'WCML_REST_API_Query_Filters_Products' => $baseDir . '/classes/rest-api-support/filters/class-wcml-rest-api-query-filters-products.php',
400
  'WCML_REST_API_Query_Filters_Terms' => $baseDir . '/classes/rest-api-support/filters/class-wcml-rest-api-query-filters-terms.php',
401
  'WCML_REST_API_Support' => $baseDir . '/classes/rest-api-support/class-wcml-rest-api-support.php',
402
- 'WCML_REST_API_Support_V1' => $baseDir . '/classes/rest-api-support/class-wcml-rest-api-support-v1.php',
403
  'WCML_REST_Generic_Exception' => $baseDir . '/classes/rest-api-support/exceptions/class-wcml-rest-generic-exception.php',
404
  'WCML_REST_Invalid_Currency_Exception' => $baseDir . '/classes/rest-api-support/exceptions/class-wcml-rest-invalid-currency-exception.php',
405
  'WCML_REST_Invalid_Language_Exception' => $baseDir . '/classes/rest-api-support/exceptions/class-wcml-rest-invalid-language-exception.php',
@@ -464,21 +182,19 @@ return array(
464
  'WCML_WC_Memberships' => $baseDir . '/compatibility/class-wcml-wc-memberships.php',
465
  'WCML_WC_Name_Your_Price' => $baseDir . '/compatibility/class-wcml-wc-name-your-price.php',
466
  'WCML_WC_Product_Bundles_Items' => $baseDir . '/compatibility/includes/class-wcml-wc-product-bundles-items.php',
 
467
  'WCML_WC_Shipping' => $baseDir . '/inc/class-wcml-wc-shipping.php',
468
  'WCML_WC_Shortcode_Product_Category' => $baseDir . '/classes/shortcodes/class-wcml-wc-shortcode-product-category.php',
469
  'WCML_WC_Strings' => $baseDir . '/inc/class-wcml-wc-strings.php',
470
  'WCML_WC_Subscriptions' => $baseDir . '/compatibility/class-wcml-wc-subscriptions.php',
471
  'WCML_WPSEO' => $baseDir . '/compatibility/class-wcml-wpseo.php',
472
  'WCML_Widgets' => $baseDir . '/inc/class-wcml-widgets.php',
473
- 'WCML_WooCommerce_Rest_API_Support' => $baseDir . '/inc/class-wcml-woocommerce-rest-api-support.php',
474
  'WCML_Woo_Var_Table' => $baseDir . '/compatibility/class-wcml-woo-var-table.php',
 
475
  'WCML_Wpb_Vc' => $baseDir . '/compatibility/class-wcml-wpb-vc.php',
476
  'WCML_YITH_WCQV' => $baseDir . '/compatibility/class-wcml-yith-wcqv.php',
477
  'WCML_gravityforms' => $baseDir . '/compatibility/class-wcml-gravityforms.php',
478
  'WCML_wcExporter' => $baseDir . '/compatibility/class-wcml-wcexporter.php',
479
  'WCML_xDomain_Data' => $baseDir . '/classes/urls/class-wcml-xdomain-data.php',
480
- 'WooCommerce_Functions_Wrapper' => $baseDir . '/inc/woocommerce-functions-wrapper.php',
481
  'woocommerce_wpml' => $baseDir . '/classes/class-woocommerce-wpml.php',
482
- 'xrstf\\Composer52\\AutoloadGenerator' => $vendorDir . '/xrstf/composer-php52/lib/xrstf/Composer52/AutoloadGenerator.php',
483
- 'xrstf\\Composer52\\Generator' => $vendorDir . '/xrstf/composer-php52/lib/xrstf/Composer52/Generator.php',
484
  );
6
  $baseDir = dirname($vendorDir);
7
 
8
  return array(
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
9
  'WCML_Accommodation_Bookings' => $baseDir . '/compatibility/class-wcml-accommodation-bookings.php',
10
  'WCML_Admin_Cookie' => $baseDir . '/classes/class-wcml-admin-cookie.php',
11
  'WCML_Admin_Currency_Selector' => $baseDir . '/classes/currencies/class-wcml-admin-currency-selector.php',
33
  'WCML_Composite_Products' => $baseDir . '/compatibility/class-wcml-composite-products.php',
34
  'WCML_Coupons' => $baseDir . '/inc/class-wcml-coupons.php',
35
  'WCML_Currencies' => $baseDir . '/classes/currencies/class-wcml-currencies.php',
36
+ 'WCML_Currencies_Dropdown_UI' => $baseDir . '/inc/template-classes/class-wcml-currencies-dropdown-ui.php',
37
+ 'WCML_Currencies_Payment_Gateways' => $baseDir . '/classes/multi-currency/payment-gateways/class-wcml-currencies-payment-gateways.php',
38
  'WCML_Currency_Switcher' => $baseDir . '/inc/currencies/currency-switcher/class-wcml-currency-switcher.php',
39
  'WCML_Currency_Switcher_Ajax' => $baseDir . '/inc/currencies/currency-switcher/class-wcml-currency-switcher-ajax.php',
40
  'WCML_Currency_Switcher_Options_Dialog' => $baseDir . '/inc/template-classes/currency-switcher/class-wcml-currency-switcher-options-dialog.php',
55
  'WCML_Editor_UI_WYSIWYG_Field' => $baseDir . '/inc/translation-editor/class-wcml-editor-ui-wysiwyg-field.php',
56
  'WCML_Emails' => $baseDir . '/inc/class-wcml-emails.php',
57
  'WCML_Endpoints' => $baseDir . '/inc/class-wcml-endpoints.php',
58
+ 'WCML_Endpoints_Legacy' => $baseDir . '/inc/class-wcml-endpoints-legacy.php',
59
  'WCML_Etheme_Blanco' => $baseDir . '/compatibility/class-wcml-etheme-blanco.php',
60
  'WCML_Exchange_Rate_Service' => $baseDir . '/classes/multi-currency/exchange-rate-services/class-wcml-exchange-rate-service.php',
61
  'WCML_Exchange_Rates' => $baseDir . '/classes/multi-currency/class-wcml-exchange-rates.php',
64
  'WCML_Exchange_Rates_UI' => $baseDir . '/inc/template-classes/multi-currency/class-wcml-exchange-rates-ui.php',
65
  'WCML_Extra_Product_Options' => $baseDir . '/compatibility/class-wcml-extra-product-options.php',
66
  'WCML_File' => $baseDir . '/inc/currencies/currency-switcher/class-wcml-file.php',
 
67
  'WCML_Flatsome' => $baseDir . '/compatibility/class-wcml-flatsome.php',
68
  'WCML_Install' => $baseDir . '/inc/class-wcml-install.php',
69
  'WCML_JCK_WSSV' => $baseDir . '/compatibility/class-wcml-jck-wssv.php',
85
  'WCML_Multi_Currency_Reports' => $baseDir . '/inc/currencies/class-wcml-multi-currency-reports.php',
86
  'WCML_Multi_Currency_Resources' => $baseDir . '/inc/currencies/class-wcml-multi-currency-resources.php',
87
  'WCML_Multi_Currency_Shipping' => $baseDir . '/inc/currencies/class-wcml-multi-currency-shipping.php',
 
88
  'WCML_Multi_Currency_Table_Rate_Shipping' => $baseDir . '/inc/currencies/class-wcml-multi-currency-table-rate-shipping.php',
89
  'WCML_Multi_Currency_UI' => $baseDir . '/inc/template-classes/multi-currency/class-wcml-multi-currency-ui.php',
90
+ 'WCML_Not_Supported_Payment_Gateway' => $baseDir . '/classes/multi-currency/payment-gateways/class-wcml-not-supported-payment-gateway.php',
91
  'WCML_Not_Translatable_Attributes' => $baseDir . '/inc/template-classes/class-wcml-not-translatable-attributes.php',
92
  'WCML_Orders' => $baseDir . '/inc/class-wcml-orders.php',
93
  'WCML_Page_Builders' => $baseDir . '/inc/translation-editor/class-wcml-page-builders.php',
94
+ 'WCML_Payment_Gateway' => $baseDir . '/classes/multi-currency/payment-gateways/class-wcml-payment-gateway.php',
95
+ 'WCML_Payment_Gateway_Bacs' => $baseDir . '/classes/multi-currency/payment-gateways/class-wcml-payment-gateway-bacs.php',
96
+ 'WCML_Payment_Gateway_PayPal' => $baseDir . '/classes/multi-currency/payment-gateways/class-wcml-payment-gateway-paypal.php',
97
+ 'WCML_Payment_Gateway_Stripe' => $baseDir . '/classes/multi-currency/payment-gateways/class-wcml-payment-gateway-stripe.php',
98
  'WCML_Payment_Method_Filter' => $baseDir . '/classes/order-property-filter/class-wcml-payment-method-filter.php',
99
  'WCML_Per_Product_Shipping' => $baseDir . '/compatibility/class-wcml-per-product-shipping.php',
100
  'WCML_Pip' => $baseDir . '/compatibility/class-wcml-pip.php',
106
  'WCML_Privacy_Content_Factory' => $baseDir . '/classes/privacy/class-wcml-privacy-content-factory.php',
107
  'WCML_Product_Addons' => $baseDir . '/compatibility/class-wcml-product-addons.php',
108
  'WCML_Product_Bundles' => $baseDir . '/compatibility/class-wcml-product-bundles.php',
 
109
  'WCML_Product_Gallery_Filter' => $baseDir . '/classes/media/class-wcml-product-gallery-filter.php',
110
  'WCML_Product_Gallery_Filter_Factory' => $baseDir . '/classes/media/class-wcml-product-gallery-filter-factory.php',
111
  'WCML_Product_Image_Filter' => $baseDir . '/classes/media/class-wcml-product-image-filter.php',
118
  'WCML_REST_API_Query_Filters_Products' => $baseDir . '/classes/rest-api-support/filters/class-wcml-rest-api-query-filters-products.php',
119
  'WCML_REST_API_Query_Filters_Terms' => $baseDir . '/classes/rest-api-support/filters/class-wcml-rest-api-query-filters-terms.php',
120
  'WCML_REST_API_Support' => $baseDir . '/classes/rest-api-support/class-wcml-rest-api-support.php',
 
121
  'WCML_REST_Generic_Exception' => $baseDir . '/classes/rest-api-support/exceptions/class-wcml-rest-generic-exception.php',
122
  'WCML_REST_Invalid_Currency_Exception' => $baseDir . '/classes/rest-api-support/exceptions/class-wcml-rest-invalid-currency-exception.php',
123
  'WCML_REST_Invalid_Language_Exception' => $baseDir . '/classes/rest-api-support/exceptions/class-wcml-rest-invalid-language-exception.php',
182
  'WCML_WC_Memberships' => $baseDir . '/compatibility/class-wcml-wc-memberships.php',
183
  'WCML_WC_Name_Your_Price' => $baseDir . '/compatibility/class-wcml-wc-name-your-price.php',
184
  'WCML_WC_Product_Bundles_Items' => $baseDir . '/compatibility/includes/class-wcml-wc-product-bundles-items.php',
185
+ 'WCML_WC_Product_Type_Column' => $baseDir . '/compatibility/class-wcml-wc-product-type-column.php',
186
  'WCML_WC_Shipping' => $baseDir . '/inc/class-wcml-wc-shipping.php',
187
  'WCML_WC_Shortcode_Product_Category' => $baseDir . '/classes/shortcodes/class-wcml-wc-shortcode-product-category.php',
188
  'WCML_WC_Strings' => $baseDir . '/inc/class-wcml-wc-strings.php',
189
  'WCML_WC_Subscriptions' => $baseDir . '/compatibility/class-wcml-wc-subscriptions.php',
190
  'WCML_WPSEO' => $baseDir . '/compatibility/class-wcml-wpseo.php',
191
  'WCML_Widgets' => $baseDir . '/inc/class-wcml-widgets.php',
 
192
  'WCML_Woo_Var_Table' => $baseDir . '/compatibility/class-wcml-woo-var-table.php',
193
+ 'WCML_WpFastest_Cache' => $baseDir . '/compatibility/class-wcml-wpfastest-cache.php',
194
  'WCML_Wpb_Vc' => $baseDir . '/compatibility/class-wcml-wpb-vc.php',
195
  'WCML_YITH_WCQV' => $baseDir . '/compatibility/class-wcml-yith-wcqv.php',
196
  'WCML_gravityforms' => $baseDir . '/compatibility/class-wcml-gravityforms.php',
197
  'WCML_wcExporter' => $baseDir . '/compatibility/class-wcml-wcexporter.php',
198
  'WCML_xDomain_Data' => $baseDir . '/classes/urls/class-wcml-xdomain-data.php',
 
199
  'woocommerce_wpml' => $baseDir . '/classes/class-woocommerce-wpml.php',
 
 
200
  );
vendor/composer/autoload_files.php ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
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
+ 'b45b351e6b6f7487d819961fef2fda77' => $vendorDir . '/jakeasmith/http_build_url/src/http_build_url.php',
10
+ );
vendor/composer/autoload_real.php CHANGED
@@ -2,7 +2,7 @@
2
 
3
  // autoload_real.php @generated by Composer
4
 
5
- class ComposerAutoloaderInit87c69e133ca17c099ad92fffa100f255
6
  {
7
  private static $loader;
8
 
@@ -19,15 +19,15 @@ class ComposerAutoloaderInit87c69e133ca17c099ad92fffa100f255
19
  return self::$loader;
20
  }
21
 
22
- spl_autoload_register(array('ComposerAutoloaderInit87c69e133ca17c099ad92fffa100f255', 'loadClassLoader'), true, true);
23
  self::$loader = $loader = new \Composer\Autoload\ClassLoader();
24
- spl_autoload_unregister(array('ComposerAutoloaderInit87c69e133ca17c099ad92fffa100f255', 'loadClassLoader'));
25
 
26
  $useStaticLoader = PHP_VERSION_ID >= 50600 && !defined('HHVM_VERSION') && (!function_exists('zend_loader_file_encoded') || !zend_loader_file_encoded());
27
  if ($useStaticLoader) {
28
  require_once __DIR__ . '/autoload_static.php';
29
 
30
- call_user_func(\Composer\Autoload\ComposerStaticInit87c69e133ca17c099ad92fffa100f255::getInitializer($loader));
31
  } else {
32
  $map = require __DIR__ . '/autoload_namespaces.php';
33
  foreach ($map as $namespace => $path) {
@@ -47,6 +47,24 @@ class ComposerAutoloaderInit87c69e133ca17c099ad92fffa100f255
47
 
48
  $loader->register(true);
49
 
 
 
 
 
 
 
 
 
 
50
  return $loader;
51
  }
52
  }
 
 
 
 
 
 
 
 
 
2
 
3
  // autoload_real.php @generated by Composer
4
 
5
+ class ComposerAutoloaderInit16830393fdb1b55f62e7d6c070d05751
6
  {
7
  private static $loader;
8
 
19
  return self::$loader;
20
  }
21
 
22
+ spl_autoload_register(array('ComposerAutoloaderInit16830393fdb1b55f62e7d6c070d05751', 'loadClassLoader'), true, true);
23
  self::$loader = $loader = new \Composer\Autoload\ClassLoader();
24
+ spl_autoload_unregister(array('ComposerAutoloaderInit16830393fdb1b55f62e7d6c070d05751', 'loadClassLoader'));
25
 
26
  $useStaticLoader = PHP_VERSION_ID >= 50600 && !defined('HHVM_VERSION') && (!function_exists('zend_loader_file_encoded') || !zend_loader_file_encoded());
27
  if ($useStaticLoader) {
28
  require_once __DIR__ . '/autoload_static.php';
29
 
30
+ call_user_func(\Composer\Autoload\ComposerStaticInit16830393fdb1b55f62e7d6c070d05751::getInitializer($loader));
31
  } else {
32
  $map = require __DIR__ . '/autoload_namespaces.php';
33
  foreach ($map as $namespace => $path) {
47
 
48
  $loader->register(true);
49
 
50
+ if ($useStaticLoader) {
51
+ $includeFiles = Composer\Autoload\ComposerStaticInit16830393fdb1b55f62e7d6c070d05751::$files;
52
+ } else {
53
+ $includeFiles = require __DIR__ . '/autoload_files.php';
54
+ }
55
+ foreach ($includeFiles as $fileIdentifier => $file) {
56
+ composerRequire16830393fdb1b55f62e7d6c070d05751($fileIdentifier, $file);
57
+ }
58
+
59
  return $loader;
60
  }
61
  }
62
+
63
+ function composerRequire16830393fdb1b55f62e7d6c070d05751($fileIdentifier, $file)
64
+ {
65
+ if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) {
66
+ require $file;
67
+
68
+ $GLOBALS['__composer_autoload_files'][$fileIdentifier] = true;
69
+ }
70
+ }
vendor/composer/autoload_real_52.php CHANGED
@@ -2,7 +2,7 @@
2
 
3
  // autoload_real_52.php generated by xrstf/composer-php52
4
 
5
- class ComposerAutoloaderInitdf66a40527ea1c5196e12b44508f7caa {
6
  private static $loader;
7
 
8
  public static function loadClassLoader($class) {
@@ -19,9 +19,9 @@ class ComposerAutoloaderInitdf66a40527ea1c5196e12b44508f7caa {
19
  return self::$loader;
20
  }
21
 
22
- spl_autoload_register(array('ComposerAutoloaderInitdf66a40527ea1c5196e12b44508f7caa', 'loadClassLoader'), true /*, true */);
23
  self::$loader = $loader = new xrstf_Composer52_ClassLoader();
24
- spl_autoload_unregister(array('ComposerAutoloaderInitdf66a40527ea1c5196e12b44508f7caa', 'loadClassLoader'));
25
 
26
  $vendorDir = dirname(dirname(__FILE__));
27
  $baseDir = dirname($vendorDir);
@@ -39,6 +39,8 @@ class ComposerAutoloaderInitdf66a40527ea1c5196e12b44508f7caa {
39
 
40
  $loader->register(true);
41
 
 
 
42
  return $loader;
43
  }
44
  }
2
 
3
  // autoload_real_52.php generated by xrstf/composer-php52
4
 
5
+ class ComposerAutoloaderInitee5ac953817836c77c6305986630a01e {
6
  private static $loader;
7
 
8
  public static function loadClassLoader($class) {
19
  return self::$loader;
20
  }
21
 
22
+ spl_autoload_register(array('ComposerAutoloaderInitee5ac953817836c77c6305986630a01e', 'loadClassLoader'), true /*, true */);
23
  self::$loader = $loader = new xrstf_Composer52_ClassLoader();
24
+ spl_autoload_unregister(array('ComposerAutoloaderInitee5ac953817836c77c6305986630a01e', 'loadClassLoader'));
25
 
26
  $vendorDir = dirname(dirname(__FILE__));
27
  $baseDir = dirname($vendorDir);
39
 
40
  $loader->register(true);
41
 
42
+ require $vendorDir . '/jakeasmith/http_build_url/src/http_build_url.php';
43
+
44
  return $loader;
45
  }
46
  }
vendor/composer/autoload_static.php CHANGED
@@ -4,8 +4,12 @@
4
 
5
  namespace Composer\Autoload;
6
 
7
- class ComposerStaticInit87c69e133ca17c099ad92fffa100f255
8
  {
 
 
 
 
9
  public static $prefixLengthsPsr4 = array (
10
  'C' =>
11
  array (
@@ -38,292 +42,6 @@ class ComposerStaticInit87c69e133ca17c099ad92fffa100f255
38
  );
39
 
40
  public static $classMap = array (
41
- 'Composer\\Installers\\AglInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/AglInstaller.php',
42
- 'Composer\\Installers\\AimeosInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/AimeosInstaller.php',
43
- 'Composer\\Installers\\AnnotateCmsInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/AnnotateCmsInstaller.php',
44
- 'Composer\\Installers\\AsgardInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/AsgardInstaller.php',
45
- 'Composer\\Installers\\AttogramInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/AttogramInstaller.php',
46
- 'Composer\\Installers\\BaseInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/BaseInstaller.php',
47
- 'Composer\\Installers\\BitrixInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/BitrixInstaller.php',
48
- 'Composer\\Installers\\BonefishInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/BonefishInstaller.php',
49
- 'Composer\\Installers\\CakePHPInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/CakePHPInstaller.php',
50
- 'Composer\\Installers\\ChefInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/ChefInstaller.php',
51
- 'Composer\\Installers\\ClanCatsFrameworkInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/ClanCatsFrameworkInstaller.php',
52
- 'Composer\\Installers\\CockpitInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/CockpitInstaller.php',
53
- 'Composer\\Installers\\CodeIgniterInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/CodeIgniterInstaller.php',
54
- 'Composer\\Installers\\Concrete5Installer' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/Concrete5Installer.php',
55
- 'Composer\\Installers\\CraftInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/CraftInstaller.php',
56
- 'Composer\\Installers\\CroogoInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/CroogoInstaller.php',
57
- 'Composer\\Installers\\DecibelInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/DecibelInstaller.php',
58
- 'Composer\\Installers\\DokuWikiInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/DokuWikiInstaller.php',
59
- 'Composer\\Installers\\DolibarrInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/DolibarrInstaller.php',
60
- 'Composer\\Installers\\DrupalInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/DrupalInstaller.php',
61
- 'Composer\\Installers\\ElggInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/ElggInstaller.php',
62
- 'Composer\\Installers\\EliasisInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/EliasisInstaller.php',
63
- 'Composer\\Installers\\ExpressionEngineInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/ExpressionEngineInstaller.php',
64
- 'Composer\\Installers\\EzPlatformInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/EzPlatformInstaller.php',
65
- 'Composer\\Installers\\FuelInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/FuelInstaller.php',
66
- 'Composer\\Installers\\FuelphpInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/FuelphpInstaller.php',
67
- 'Composer\\Installers\\GravInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/GravInstaller.php',
68
- 'Composer\\Installers\\HuradInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/HuradInstaller.php',
69
- 'Composer\\Installers\\ImageCMSInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/ImageCMSInstaller.php',
70
- 'Composer\\Installers\\Installer' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/Installer.php',
71
- 'Composer\\Installers\\ItopInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/ItopInstaller.php',
72
- 'Composer\\Installers\\JoomlaInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/JoomlaInstaller.php',
73
- 'Composer\\Installers\\KanboardInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/KanboardInstaller.php',
74
- 'Composer\\Installers\\KirbyInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/KirbyInstaller.php',
75
- 'Composer\\Installers\\KodiCMSInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/KodiCMSInstaller.php',
76
- 'Composer\\Installers\\KohanaInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/KohanaInstaller.php',
77
- 'Composer\\Installers\\LanManagementSystemInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/LanManagementSystemInstaller.php',
78
- 'Composer\\Installers\\LaravelInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/LaravelInstaller.php',
79
- 'Composer\\Installers\\LavaLiteInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/LavaLiteInstaller.php',
80
- 'Composer\\Installers\\LithiumInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/LithiumInstaller.php',
81
- 'Composer\\Installers\\MODULEWorkInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/MODULEWorkInstaller.php',
82
- 'Composer\\Installers\\MODXEvoInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/MODXEvoInstaller.php',
83
- 'Composer\\Installers\\MagentoInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/MagentoInstaller.php',
84
- 'Composer\\Installers\\MajimaInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/MajimaInstaller.php',
85
- 'Composer\\Installers\\MakoInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/MakoInstaller.php',
86
- 'Composer\\Installers\\MauticInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/MauticInstaller.php',
87
- 'Composer\\Installers\\MayaInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/MayaInstaller.php',
88
- 'Composer\\Installers\\MediaWikiInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/MediaWikiInstaller.php',
89
- 'Composer\\Installers\\MicroweberInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/MicroweberInstaller.php',
90
- 'Composer\\Installers\\ModxInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/ModxInstaller.php',
91
- 'Composer\\Installers\\MoodleInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/MoodleInstaller.php',
92
- 'Composer\\Installers\\OctoberInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/OctoberInstaller.php',
93
- 'Composer\\Installers\\OntoWikiInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/OntoWikiInstaller.php',
94
- 'Composer\\Installers\\OsclassInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/OsclassInstaller.php',
95
- 'Composer\\Installers\\OxidInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/OxidInstaller.php',
96
- 'Composer\\Installers\\PPIInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/PPIInstaller.php',
97
- 'Composer\\Installers\\PhiftyInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/PhiftyInstaller.php',
98
- 'Composer\\Installers\\PhpBBInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/PhpBBInstaller.php',
99
- 'Composer\\Installers\\PimcoreInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/PimcoreInstaller.php',
100
- 'Composer\\Installers\\PiwikInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/PiwikInstaller.php',
101
- 'Composer\\Installers\\PlentymarketsInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/PlentymarketsInstaller.php',
102
- 'Composer\\Installers\\Plugin' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/Plugin.php',
103
- 'Composer\\Installers\\PortoInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/PortoInstaller.php',
104
- 'Composer\\Installers\\PrestashopInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/PrestashopInstaller.php',
105
- 'Composer\\Installers\\PuppetInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/PuppetInstaller.php',
106
- 'Composer\\Installers\\PxcmsInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/PxcmsInstaller.php',
107
- 'Composer\\Installers\\RadPHPInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/RadPHPInstaller.php',
108
- 'Composer\\Installers\\ReIndexInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/ReIndexInstaller.php',
109
- 'Composer\\Installers\\RedaxoInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/RedaxoInstaller.php',
110
- 'Composer\\Installers\\RoundcubeInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/RoundcubeInstaller.php',
111
- 'Composer\\Installers\\SMFInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/SMFInstaller.php',
112
- 'Composer\\Installers\\ShopwareInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/ShopwareInstaller.php',
113
- 'Composer\\Installers\\SilverStripeInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/SilverStripeInstaller.php',
114
- 'Composer\\Installers\\SiteDirectInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/SiteDirectInstaller.php',
115
- 'Composer\\Installers\\SyDESInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/SyDESInstaller.php',
116
- 'Composer\\Installers\\Symfony1Installer' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/Symfony1Installer.php',
117
- 'Composer\\Installers\\TYPO3CmsInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/TYPO3CmsInstaller.php',
118
- 'Composer\\Installers\\TYPO3FlowInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/TYPO3FlowInstaller.php',
119
- 'Composer\\Installers\\TheliaInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/TheliaInstaller.php',
120
- 'Composer\\Installers\\TuskInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/TuskInstaller.php',
121
- 'Composer\\Installers\\UserFrostingInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/UserFrostingInstaller.php',
122
- 'Composer\\Installers\\VanillaInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/VanillaInstaller.php',
123
- 'Composer\\Installers\\VgmcpInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/VgmcpInstaller.php',
124
- 'Composer\\Installers\\WHMCSInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/WHMCSInstaller.php',
125
- 'Composer\\Installers\\WolfCMSInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/WolfCMSInstaller.php',
126
- 'Composer\\Installers\\WordPressInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/WordPressInstaller.php',
127
- 'Composer\\Installers\\YawikInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/YawikInstaller.php',
128
- 'Composer\\Installers\\ZendInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/ZendInstaller.php',
129
- 'Composer\\Installers\\ZikulaInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/ZikulaInstaller.php',
130
- 'Twig_Autoloader' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Autoloader.php',
131
- 'Twig_BaseNodeVisitor' => __DIR__ . '/..' . '/twig/twig/lib/Twig/BaseNodeVisitor.php',
132
- 'Twig_CacheInterface' => __DIR__ . '/..' . '/twig/twig/lib/Twig/CacheInterface.php',
133
- 'Twig_Cache_Filesystem' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Cache/Filesystem.php',
134
- 'Twig_Cache_Null' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Cache/Null.php',
135
- 'Twig_Compiler' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Compiler.php',
136
- 'Twig_CompilerInterface' => __DIR__ . '/..' . '/twig/twig/lib/Twig/CompilerInterface.php',
137
- 'Twig_ContainerRuntimeLoader' => __DIR__ . '/..' . '/twig/twig/lib/Twig/ContainerRuntimeLoader.php',
138
- 'Twig_Environment' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Environment.php',
139
- 'Twig_Error' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Error.php',
140
- 'Twig_Error_Loader' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Error/Loader.php',
141
- 'Twig_Error_Runtime' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Error/Runtime.php',
142
- 'Twig_Error_Syntax' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Error/Syntax.php',
143
- 'Twig_ExistsLoaderInterface' => __DIR__ . '/..' . '/twig/twig/lib/Twig/ExistsLoaderInterface.php',
144
- 'Twig_ExpressionParser' => __DIR__ . '/..' . '/twig/twig/lib/Twig/ExpressionParser.php',
145
- 'Twig_Extension' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Extension.php',
146
- 'Twig_ExtensionInterface' => __DIR__ . '/..' . '/twig/twig/lib/Twig/ExtensionInterface.php',
147
- 'Twig_Extension_Core' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Extension/Core.php',
148
- 'Twig_Extension_Debug' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Extension/Debug.php',
149
- 'Twig_Extension_Escaper' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Extension/Escaper.php',
150
- 'Twig_Extension_GlobalsInterface' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Extension/GlobalsInterface.php',
151
- 'Twig_Extension_InitRuntimeInterface' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Extension/InitRuntimeInterface.php',
152
- 'Twig_Extension_Optimizer' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Extension/Optimizer.php',
153
- 'Twig_Extension_Profiler' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Extension/Profiler.php',
154
- 'Twig_Extension_Sandbox' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Extension/Sandbox.php',
155
- 'Twig_Extension_Staging' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Extension/Staging.php',
156
- 'Twig_Extension_StringLoader' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Extension/StringLoader.php',
157
- 'Twig_FactoryRuntimeLoader' => __DIR__ . '/..' . '/twig/twig/lib/Twig/FactoryRuntimeLoader.php',
158
- 'Twig_FileExtensionEscapingStrategy' => __DIR__ . '/..' . '/twig/twig/lib/Twig/FileExtensionEscapingStrategy.php',
159
- 'Twig_Filter' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Filter.php',
160
- 'Twig_FilterCallableInterface' => __DIR__ . '/..' . '/twig/twig/lib/Twig/FilterCallableInterface.php',
161
- 'Twig_FilterInterface' => __DIR__ . '/..' . '/twig/twig/lib/Twig/FilterInterface.php',
162
- 'Twig_Filter_Function' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Filter/Function.php',
163
- 'Twig_Filter_Method' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Filter/Method.php',
164
- 'Twig_Filter_Node' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Filter/Node.php',
165
- 'Twig_Function' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Function.php',
166
- 'Twig_FunctionCallableInterface' => __DIR__ . '/..' . '/twig/twig/lib/Twig/FunctionCallableInterface.php',
167
- 'Twig_FunctionInterface' => __DIR__ . '/..' . '/twig/twig/lib/Twig/FunctionInterface.php',
168
- 'Twig_Function_Function' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Function/Function.php',
169
- 'Twig_Function_Method' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Function/Method.php',
170
- 'Twig_Function_Node' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Function/Node.php',
171
- 'Twig_Lexer' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Lexer.php',
172
- 'Twig_LexerInterface' => __DIR__ . '/..' . '/twig/twig/lib/Twig/LexerInterface.php',
173
- 'Twig_LoaderInterface' => __DIR__ . '/..' . '/twig/twig/lib/Twig/LoaderInterface.php',
174
- 'Twig_Loader_Array' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Loader/Array.php',
175
- 'Twig_Loader_Chain' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Loader/Chain.php',
176
- 'Twig_Loader_Filesystem' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Loader/Filesystem.php',
177
- 'Twig_Loader_String' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Loader/String.php',
178
- 'Twig_Markup' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Markup.php',
179
- 'Twig_Node' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Node.php',
180
- 'Twig_NodeCaptureInterface' => __DIR__ . '/..' . '/twig/twig/lib/Twig/NodeCaptureInterface.php',
181
- 'Twig_NodeInterface' => __DIR__ . '/..' . '/twig/twig/lib/Twig/NodeInterface.php',
182
- 'Twig_NodeOutputInterface' => __DIR__ . '/..' . '/twig/twig/lib/Twig/NodeOutputInterface.php',
183
- 'Twig_NodeTraverser' => __DIR__ . '/..' . '/twig/twig/lib/Twig/NodeTraverser.php',
184
- 'Twig_NodeVisitorInterface' => __DIR__ . '/..' . '/twig/twig/lib/Twig/NodeVisitorInterface.php',
185
- 'Twig_NodeVisitor_Escaper' => __DIR__ . '/..' . '/twig/twig/lib/Twig/NodeVisitor/Escaper.php',
186
- 'Twig_NodeVisitor_Optimizer' => __DIR__ . '/..' . '/twig/twig/lib/Twig/NodeVisitor/Optimizer.php',
187
- 'Twig_NodeVisitor_SafeAnalysis' => __DIR__ . '/..' . '/twig/twig/lib/Twig/NodeVisitor/SafeAnalysis.php',
188
- 'Twig_NodeVisitor_Sandbox' => __DIR__ . '/..' . '/twig/twig/lib/Twig/NodeVisitor/Sandbox.php',
189
- 'Twig_Node_AutoEscape' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Node/AutoEscape.php',
190
- 'Twig_Node_Block' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Node/Block.php',
191
- 'Twig_Node_BlockReference' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Node/BlockReference.php',
192
- 'Twig_Node_Body' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Node/Body.php',
193
- 'Twig_Node_CheckSecurity' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Node/CheckSecurity.php',
194
- 'Twig_Node_Do' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Node/Do.php',
195
- 'Twig_Node_Embed' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Node/Embed.php',
196
- 'Twig_Node_Expression' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Node/Expression.php',
197
- 'Twig_Node_Expression_Array' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Node/Expression/Array.php',
198
- 'Twig_Node_Expression_AssignName' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Node/Expression/AssignName.php',
199
- 'Twig_Node_Expression_Binary' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Node/Expression/Binary.php',
200
- 'Twig_Node_Expression_Binary_Add' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Node/Expression/Binary/Add.php',
201
- 'Twig_Node_Expression_Binary_And' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Node/Expression/Binary/And.php',
202
- 'Twig_Node_Expression_Binary_BitwiseAnd' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Node/Expression/Binary/BitwiseAnd.php',
203
- 'Twig_Node_Expression_Binary_BitwiseOr' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Node/Expression/Binary/BitwiseOr.php',
204
- 'Twig_Node_Expression_Binary_BitwiseXor' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Node/Expression/Binary/BitwiseXor.php',
205
- 'Twig_Node_Expression_Binary_Concat' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Node/Expression/Binary/Concat.php',
206
- 'Twig_Node_Expression_Binary_Div' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Node/Expression/Binary/Div.php',
207
- 'Twig_Node_Expression_Binary_EndsWith' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Node/Expression/Binary/EndsWith.php',
208
- 'Twig_Node_Expression_Binary_Equal' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Node/Expression/Binary/Equal.php',
209
- 'Twig_Node_Expression_Binary_FloorDiv' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Node/Expression/Binary/FloorDiv.php',
210
- 'Twig_Node_Expression_Binary_Greater' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Node/Expression/Binary/Greater.php',
211
- 'Twig_Node_Expression_Binary_GreaterEqual' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Node/Expression/Binary/GreaterEqual.php',
212
- 'Twig_Node_Expression_Binary_In' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Node/Expression/Binary/In.php',
213
- 'Twig_Node_Expression_Binary_Less' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Node/Expression/Binary/Less.php',
214
- 'Twig_Node_Expression_Binary_LessEqual' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Node/Expression/Binary/LessEqual.php',
215
- 'Twig_Node_Expression_Binary_Matches' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Node/Expression/Binary/Matches.php',
216
- 'Twig_Node_Expression_Binary_Mod' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Node/Expression/Binary/Mod.php',
217
- 'Twig_Node_Expression_Binary_Mul' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Node/Expression/Binary/Mul.php',
218
- 'Twig_Node_Expression_Binary_NotEqual' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Node/Expression/Binary/NotEqual.php',
219
- 'Twig_Node_Expression_Binary_NotIn' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Node/Expression/Binary/NotIn.php',
220
- 'Twig_Node_Expression_Binary_Or' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Node/Expression/Binary/Or.php',
221
- 'Twig_Node_Expression_Binary_Power' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Node/Expression/Binary/Power.php',
222
- 'Twig_Node_Expression_Binary_Range' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Node/Expression/Binary/Range.php',
223
- 'Twig_Node_Expression_Binary_StartsWith' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Node/Expression/Binary/StartsWith.php',
224
- 'Twig_Node_Expression_Binary_Sub' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Node/Expression/Binary/Sub.php',
225
- 'Twig_Node_Expression_BlockReference' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Node/Expression/BlockReference.php',
226
- 'Twig_Node_Expression_Call' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Node/Expression/Call.php',
227
- 'Twig_Node_Expression_Conditional' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Node/Expression/Conditional.php',
228
- 'Twig_Node_Expression_Constant' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Node/Expression/Constant.php',
229
- 'Twig_Node_Expression_ExtensionReference' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Node/Expression/ExtensionReference.php',
230
- 'Twig_Node_Expression_Filter' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Node/Expression/Filter.php',
231
- 'Twig_Node_Expression_Filter_Default' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Node/Expression/Filter/Default.php',
232
- 'Twig_Node_Expression_Function' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Node/Expression/Function.php',
233
- 'Twig_Node_Expression_GetAttr' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Node/Expression/GetAttr.php',
234
- 'Twig_Node_Expression_MethodCall' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Node/Expression/MethodCall.php',
235
- 'Twig_Node_Expression_Name' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Node/Expression/Name.php',
236
- 'Twig_Node_Expression_NullCoalesce' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Node/Expression/NullCoalesce.php',
237
- 'Twig_Node_Expression_Parent' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Node/Expression/Parent.php',
238
- 'Twig_Node_Expression_TempName' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Node/Expression/TempName.php',
239
- 'Twig_Node_Expression_Test' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Node/Expression/Test.php',
240
- 'Twig_Node_Expression_Test_Constant' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Node/Expression/Test/Constant.php',
241
- 'Twig_Node_Expression_Test_Defined' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Node/Expression/Test/Defined.php',
242
- 'Twig_Node_Expression_Test_Divisibleby' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Node/Expression/Test/Divisibleby.php',
243
- 'Twig_Node_Expression_Test_Even' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Node/Expression/Test/Even.php',
244
- 'Twig_Node_Expression_Test_Null' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Node/Expression/Test/Null.php',
245
- 'Twig_Node_Expression_Test_Odd' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Node/Expression/Test/Odd.php',
246
- 'Twig_Node_Expression_Test_Sameas' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Node/Expression/Test/Sameas.php',
247
- 'Twig_Node_Expression_Unary' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Node/Expression/Unary.php',
248
- 'Twig_Node_Expression_Unary_Neg' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Node/Expression/Unary/Neg.php',
249
- 'Twig_Node_Expression_Unary_Not' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Node/Expression/Unary/Not.php',
250
- 'Twig_Node_Expression_Unary_Pos' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Node/Expression/Unary/Pos.php',
251
- 'Twig_Node_Flush' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Node/Flush.php',
252
- 'Twig_Node_For' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Node/For.php',
253
- 'Twig_Node_ForLoop' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Node/ForLoop.php',
254
- 'Twig_Node_If' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Node/If.php',
255
- 'Twig_Node_Import' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Node/Import.php',
256
- 'Twig_Node_Include' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Node/Include.php',
257
- 'Twig_Node_Macro' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Node/Macro.php',
258
- 'Twig_Node_Module' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Node/Module.php',
259
- 'Twig_Node_Print' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Node/Print.php',
260
- 'Twig_Node_Sandbox' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Node/Sandbox.php',
261
- 'Twig_Node_SandboxedPrint' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Node/SandboxedPrint.php',
262
- 'Twig_Node_Set' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Node/Set.php',
263
- 'Twig_Node_SetTemp' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Node/SetTemp.php',
264
- 'Twig_Node_Spaceless' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Node/Spaceless.php',
265
- 'Twig_Node_Text' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Node/Text.php',
266
- 'Twig_Node_With' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Node/With.php',
267
- 'Twig_Parser' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Parser.php',
268
- 'Twig_ParserInterface' => __DIR__ . '/..' . '/twig/twig/lib/Twig/ParserInterface.php',
269
- 'Twig_Profiler_Dumper_Blackfire' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Profiler/Dumper/Blackfire.php',
270
- 'Twig_Profiler_Dumper_Html' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Profiler/Dumper/Html.php',
271
- 'Twig_Profiler_Dumper_Text' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Profiler/Dumper/Text.php',
272
- 'Twig_Profiler_NodeVisitor_Profiler' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Profiler/NodeVisitor/Profiler.php',
273
- 'Twig_Profiler_Node_EnterProfile' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Profiler/Node/EnterProfile.php',
274
- 'Twig_Profiler_Node_LeaveProfile' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Profiler/Node/LeaveProfile.php',
275
- 'Twig_Profiler_Profile' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Profiler/Profile.php',
276
- 'Twig_RuntimeLoaderInterface' => __DIR__ . '/..' . '/twig/twig/lib/Twig/RuntimeLoaderInterface.php',
277
- 'Twig_Sandbox_SecurityError' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Sandbox/SecurityError.php',
278
- 'Twig_Sandbox_SecurityNotAllowedFilterError' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Sandbox/SecurityNotAllowedFilterError.php',
279
- 'Twig_Sandbox_SecurityNotAllowedFunctionError' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Sandbox/SecurityNotAllowedFunctionError.php',
280
- 'Twig_Sandbox_SecurityNotAllowedMethodError' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Sandbox/SecurityNotAllowedMethodError.php',
281
- 'Twig_Sandbox_SecurityNotAllowedPropertyError' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Sandbox/SecurityNotAllowedPropertyError.php',
282
- 'Twig_Sandbox_SecurityNotAllowedTagError' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Sandbox/SecurityNotAllowedTagError.php',
283
- 'Twig_Sandbox_SecurityPolicy' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Sandbox/SecurityPolicy.php',
284
- 'Twig_Sandbox_SecurityPolicyInterface' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Sandbox/SecurityPolicyInterface.php',
285
- 'Twig_SimpleFilter' => __DIR__ . '/..' . '/twig/twig/lib/Twig/SimpleFilter.php',
286
- 'Twig_SimpleFunction' => __DIR__ . '/..' . '/twig/twig/lib/Twig/SimpleFunction.php',
287
- 'Twig_SimpleTest' => __DIR__ . '/..' . '/twig/twig/lib/Twig/SimpleTest.php',
288
- 'Twig_Source' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Source.php',
289
- 'Twig_SourceContextLoaderInterface' => __DIR__ . '/..' . '/twig/twig/lib/Twig/SourceContextLoaderInterface.php',
290
- 'Twig_Template' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Template.php',
291
- 'Twig_TemplateInterface' => __DIR__ . '/..' . '/twig/twig/lib/Twig/TemplateInterface.php',
292
- 'Twig_TemplateWrapper' => __DIR__ . '/..' . '/twig/twig/lib/Twig/TemplateWrapper.php',
293
- 'Twig_Test' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Test.php',
294
- 'Twig_TestCallableInterface' => __DIR__ . '/..' . '/twig/twig/lib/Twig/TestCallableInterface.php',
295
- 'Twig_TestInterface' => __DIR__ . '/..' . '/twig/twig/lib/Twig/TestInterface.php',
296
- 'Twig_Test_Function' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Test/Function.php',
297
- 'Twig_Test_IntegrationTestCase' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Test/IntegrationTestCase.php',
298
- 'Twig_Test_Method' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Test/Method.php',
299
- 'Twig_Test_Node' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Test/Node.php',
300
- 'Twig_Test_NodeTestCase' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Test/NodeTestCase.php',
301
- 'Twig_Token' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Token.php',
302
- 'Twig_TokenParser' => __DIR__ . '/..' . '/twig/twig/lib/Twig/TokenParser.php',
303
- 'Twig_TokenParserBroker' => __DIR__ . '/..' . '/twig/twig/lib/Twig/TokenParserBroker.php',
304
- 'Twig_TokenParserBrokerInterface' => __DIR__ . '/..' . '/twig/twig/lib/Twig/TokenParserBrokerInterface.php',
305
- 'Twig_TokenParserInterface' => __DIR__ . '/..' . '/twig/twig/lib/Twig/TokenParserInterface.php',
306
- 'Twig_TokenParser_AutoEscape' => __DIR__ . '/..' . '/twig/twig/lib/Twig/TokenParser/AutoEscape.php',
307
- 'Twig_TokenParser_Block' => __DIR__ . '/..' . '/twig/twig/lib/Twig/TokenParser/Block.php',
308
- 'Twig_TokenParser_Do' => __DIR__ . '/..' . '/twig/twig/lib/Twig/TokenParser/Do.php',
309
- 'Twig_TokenParser_Embed' => __DIR__ . '/..' . '/twig/twig/lib/Twig/TokenParser/Embed.php',
310
- 'Twig_TokenParser_Extends' => __DIR__ . '/..' . '/twig/twig/lib/Twig/TokenParser/Extends.php',
311
- 'Twig_TokenParser_Filter' => __DIR__ . '/..' . '/twig/twig/lib/Twig/TokenParser/Filter.php',
312
- 'Twig_TokenParser_Flush' => __DIR__ . '/..' . '/twig/twig/lib/Twig/TokenParser/Flush.php',
313
- 'Twig_TokenParser_For' => __DIR__ . '/..' . '/twig/twig/lib/Twig/TokenParser/For.php',
314
- 'Twig_TokenParser_From' => __DIR__ . '/..' . '/twig/twig/lib/Twig/TokenParser/From.php',
315
- 'Twig_TokenParser_If' => __DIR__ . '/..' . '/twig/twig/lib/Twig/TokenParser/If.php',
316
- 'Twig_TokenParser_Import' => __DIR__ . '/..' . '/twig/twig/lib/Twig/TokenParser/Import.php',
317
- 'Twig_TokenParser_Include' => __DIR__ . '/..' . '/twig/twig/lib/Twig/TokenParser/Include.php',
318
- 'Twig_TokenParser_Macro' => __DIR__ . '/..' . '/twig/twig/lib/Twig/TokenParser/Macro.php',
319
- 'Twig_TokenParser_Sandbox' => __DIR__ . '/..' . '/twig/twig/lib/Twig/TokenParser/Sandbox.php',
320
- 'Twig_TokenParser_Set' => __DIR__ . '/..' . '/twig/twig/lib/Twig/TokenParser/Set.php',
321
- 'Twig_TokenParser_Spaceless' => __DIR__ . '/..' . '/twig/twig/lib/Twig/TokenParser/Spaceless.php',
322
- 'Twig_TokenParser_Use' => __DIR__ . '/..' . '/twig/twig/lib/Twig/TokenParser/Use.php',
323
- 'Twig_TokenParser_With' => __DIR__ . '/..' . '/twig/twig/lib/Twig/TokenParser/With.php',
324
- 'Twig_TokenStream' => __DIR__ . '/..' . '/twig/twig/lib/Twig/TokenStream.php',
325
- 'Twig_Util_DeprecationCollector' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Util/DeprecationCollector.php',
326
- 'Twig_Util_TemplateDirIterator' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Util/TemplateDirIterator.php',
327
  'WCML_Accommodation_Bookings' => __DIR__ . '/../..' . '/compatibility/class-wcml-accommodation-bookings.php',
328
  'WCML_Admin_Cookie' => __DIR__ . '/../..' . '/classes/class-wcml-admin-cookie.php',
329
  'WCML_Admin_Currency_Selector' => __DIR__ . '/../..' . '/classes/currencies/class-wcml-admin-currency-selector.php',
@@ -351,6 +69,8 @@ class ComposerStaticInit87c69e133ca17c099ad92fffa100f255
351
  'WCML_Composite_Products' => __DIR__ . '/../..' . '/compatibility/class-wcml-composite-products.php',
352
  'WCML_Coupons' => __DIR__ . '/../..' . '/inc/class-wcml-coupons.php',
353
  'WCML_Currencies' => __DIR__ . '/../..' . '/classes/currencies/class-wcml-currencies.php',
 
 
354
  'WCML_Currency_Switcher' => __DIR__ . '/../..' . '/inc/currencies/currency-switcher/class-wcml-currency-switcher.php',
355
  'WCML_Currency_Switcher_Ajax' => __DIR__ . '/../..' . '/inc/currencies/currency-switcher/class-wcml-currency-switcher-ajax.php',
356
  'WCML_Currency_Switcher_Options_Dialog' => __DIR__ . '/../..' . '/inc/template-classes/currency-switcher/class-wcml-currency-switcher-options-dialog.php',
@@ -371,6 +91,7 @@ class ComposerStaticInit87c69e133ca17c099ad92fffa100f255
371
  'WCML_Editor_UI_WYSIWYG_Field' => __DIR__ . '/../..' . '/inc/translation-editor/class-wcml-editor-ui-wysiwyg-field.php',
372
  'WCML_Emails' => __DIR__ . '/../..' . '/inc/class-wcml-emails.php',
373
  'WCML_Endpoints' => __DIR__ . '/../..' . '/inc/class-wcml-endpoints.php',
 
374
  'WCML_Etheme_Blanco' => __DIR__ . '/../..' . '/compatibility/class-wcml-etheme-blanco.php',
375
  'WCML_Exchange_Rate_Service' => __DIR__ . '/../..' . '/classes/multi-currency/exchange-rate-services/class-wcml-exchange-rate-service.php',
376
  'WCML_Exchange_Rates' => __DIR__ . '/../..' . '/classes/multi-currency/class-wcml-exchange-rates.php',
@@ -379,7 +100,6 @@ class ComposerStaticInit87c69e133ca17c099ad92fffa100f255
379
  'WCML_Exchange_Rates_UI' => __DIR__ . '/../..' . '/inc/template-classes/multi-currency/class-wcml-exchange-rates-ui.php',
380
  'WCML_Extra_Product_Options' => __DIR__ . '/../..' . '/compatibility/class-wcml-extra-product-options.php',
381
  'WCML_File' => __DIR__ . '/../..' . '/inc/currencies/currency-switcher/class-wcml-file.php',
382
- 'WCML_Fix_Copied_Custom_Fields_WPML353' => __DIR__ . '/../..' . '/inc/class-wcml-fix-copied-custom-fields-wpml353.php',
383
  'WCML_Flatsome' => __DIR__ . '/../..' . '/compatibility/class-wcml-flatsome.php',
384
  'WCML_Install' => __DIR__ . '/../..' . '/inc/class-wcml-install.php',
385
  'WCML_JCK_WSSV' => __DIR__ . '/../..' . '/compatibility/class-wcml-jck-wssv.php',
@@ -401,12 +121,16 @@ class ComposerStaticInit87c69e133ca17c099ad92fffa100f255
401
  'WCML_Multi_Currency_Reports' => __DIR__ . '/../..' . '/inc/currencies/class-wcml-multi-currency-reports.php',
402
  'WCML_Multi_Currency_Resources' => __DIR__ . '/../..' . '/inc/currencies/class-wcml-multi-currency-resources.php',
403
  'WCML_Multi_Currency_Shipping' => __DIR__ . '/../..' . '/inc/currencies/class-wcml-multi-currency-shipping.php',
404
- 'WCML_Multi_Currency_Shipping_Legacy' => __DIR__ . '/../..' . '/inc/currencies/class-wcml-multi-currency-shipping-legacy.php',
405
  'WCML_Multi_Currency_Table_Rate_Shipping' => __DIR__ . '/../..' . '/inc/currencies/class-wcml-multi-currency-table-rate-shipping.php',
406
  'WCML_Multi_Currency_UI' => __DIR__ . '/../..' . '/inc/template-classes/multi-currency/class-wcml-multi-currency-ui.php',
 
407
  'WCML_Not_Translatable_Attributes' => __DIR__ . '/../..' . '/inc/template-classes/class-wcml-not-translatable-attributes.php',
408
  'WCML_Orders' => __DIR__ . '/../..' . '/inc/class-wcml-orders.php',
409
  'WCML_Page_Builders' => __DIR__ . '/../..' . '/inc/translation-editor/class-wcml-page-builders.php',
 
 
 
 
410
  'WCML_Payment_Method_Filter' => __DIR__ . '/../..' . '/classes/order-property-filter/class-wcml-payment-method-filter.php',
411
  'WCML_Per_Product_Shipping' => __DIR__ . '/../..' . '/compatibility/class-wcml-per-product-shipping.php',
412
  'WCML_Pip' => __DIR__ . '/../..' . '/compatibility/class-wcml-pip.php',
@@ -418,7 +142,6 @@ class ComposerStaticInit87c69e133ca17c099ad92fffa100f255
418
  'WCML_Privacy_Content_Factory' => __DIR__ . '/../..' . '/classes/privacy/class-wcml-privacy-content-factory.php',
419
  'WCML_Product_Addons' => __DIR__ . '/../..' . '/compatibility/class-wcml-product-addons.php',
420
  'WCML_Product_Bundles' => __DIR__ . '/../..' . '/compatibility/class-wcml-product-bundles.php',
421
- 'WCML_Product_Bundles_Legacy' => __DIR__ . '/../..' . '/compatibility/class-wcml-product-bundles-legacy.php',
422
  'WCML_Product_Gallery_Filter' => __DIR__ . '/../..' . '/classes/media/class-wcml-product-gallery-filter.php',
423
  'WCML_Product_Gallery_Filter_Factory' => __DIR__ . '/../..' . '/classes/media/class-wcml-product-gallery-filter-factory.php',
424
  'WCML_Product_Image_Filter' => __DIR__ . '/../..' . '/classes/media/class-wcml-product-image-filter.php',
@@ -431,7 +154,6 @@ class ComposerStaticInit87c69e133ca17c099ad92fffa100f255
431
  'WCML_REST_API_Query_Filters_Products' => __DIR__ . '/../..' . '/classes/rest-api-support/filters/class-wcml-rest-api-query-filters-products.php',
432
  'WCML_REST_API_Query_Filters_Terms' => __DIR__ . '/../..' . '/classes/rest-api-support/filters/class-wcml-rest-api-query-filters-terms.php',
433
  'WCML_REST_API_Support' => __DIR__ . '/../..' . '/classes/rest-api-support/class-wcml-rest-api-support.php',
434
- 'WCML_REST_API_Support_V1' => __DIR__ . '/../..' . '/classes/rest-api-support/class-wcml-rest-api-support-v1.php',
435
  'WCML_REST_Generic_Exception' => __DIR__ . '/../..' . '/classes/rest-api-support/exceptions/class-wcml-rest-generic-exception.php',
436
  'WCML_REST_Invalid_Currency_Exception' => __DIR__ . '/../..' . '/classes/rest-api-support/exceptions/class-wcml-rest-invalid-currency-exception.php',
437
  'WCML_REST_Invalid_Language_Exception' => __DIR__ . '/../..' . '/classes/rest-api-support/exceptions/class-wcml-rest-invalid-language-exception.php',
@@ -496,32 +218,30 @@ class ComposerStaticInit87c69e133ca17c099ad92fffa100f255
496
  'WCML_WC_Memberships' => __DIR__ . '/../..' . '/compatibility/class-wcml-wc-memberships.php',
497
  'WCML_WC_Name_Your_Price' => __DIR__ . '/../..' . '/compatibility/class-wcml-wc-name-your-price.php',
498
  'WCML_WC_Product_Bundles_Items' => __DIR__ . '/../..' . '/compatibility/includes/class-wcml-wc-product-bundles-items.php',
 
499
  'WCML_WC_Shipping' => __DIR__ . '/../..' . '/inc/class-wcml-wc-shipping.php',
500
  'WCML_WC_Shortcode_Product_Category' => __DIR__ . '/../..' . '/classes/shortcodes/class-wcml-wc-shortcode-product-category.php',
501
  'WCML_WC_Strings' => __DIR__ . '/../..' . '/inc/class-wcml-wc-strings.php',
502
  'WCML_WC_Subscriptions' => __DIR__ . '/../..' . '/compatibility/class-wcml-wc-subscriptions.php',
503
  'WCML_WPSEO' => __DIR__ . '/../..' . '/compatibility/class-wcml-wpseo.php',
504
  'WCML_Widgets' => __DIR__ . '/../..' . '/inc/class-wcml-widgets.php',
505
- 'WCML_WooCommerce_Rest_API_Support' => __DIR__ . '/../..' . '/inc/class-wcml-woocommerce-rest-api-support.php',
506
  'WCML_Woo_Var_Table' => __DIR__ . '/../..' . '/compatibility/class-wcml-woo-var-table.php',
 
507
  'WCML_Wpb_Vc' => __DIR__ . '/../..' . '/compatibility/class-wcml-wpb-vc.php',
508
  'WCML_YITH_WCQV' => __DIR__ . '/../..' . '/compatibility/class-wcml-yith-wcqv.php',
509
  'WCML_gravityforms' => __DIR__ . '/../..' . '/compatibility/class-wcml-gravityforms.php',
510
  'WCML_wcExporter' => __DIR__ . '/../..' . '/compatibility/class-wcml-wcexporter.php',
511
  'WCML_xDomain_Data' => __DIR__ . '/../..' . '/classes/urls/class-wcml-xdomain-data.php',
512
- 'WooCommerce_Functions_Wrapper' => __DIR__ . '/../..' . '/inc/woocommerce-functions-wrapper.php',
513
  'woocommerce_wpml' => __DIR__ . '/../..' . '/classes/class-woocommerce-wpml.php',
514
- 'xrstf\\Composer52\\AutoloadGenerator' => __DIR__ . '/..' . '/xrstf/composer-php52/lib/xrstf/Composer52/AutoloadGenerator.php',
515
- 'xrstf\\Composer52\\Generator' => __DIR__ . '/..' . '/xrstf/composer-php52/lib/xrstf/Composer52/Generator.php',
516
  );
517
 
518
  public static function getInitializer(ClassLoader $loader)
519
  {
520
  return \Closure::bind(function () use ($loader) {
521
- $loader->prefixLengthsPsr4 = ComposerStaticInit87c69e133ca17c099ad92fffa100f255::$prefixLengthsPsr4;
522
- $loader->prefixDirsPsr4 = ComposerStaticInit87c69e133ca17c099ad92fffa100f255::$prefixDirsPsr4;
523
- $loader->prefixesPsr0 = ComposerStaticInit87c69e133ca17c099ad92fffa100f255::$prefixesPsr0;
524
- $loader->classMap = ComposerStaticInit87c69e133ca17c099ad92fffa100f255::$classMap;
525
 
526
  }, null, ClassLoader::class);
527
  }
4
 
5
  namespace Composer\Autoload;
6
 
7
+ class ComposerStaticInit16830393fdb1b55f62e7d6c070d05751
8
  {
9
+ public static $files = array (
10
+ 'b45b351e6b6f7487d819961fef2fda77' => __DIR__ . '/..' . '/jakeasmith/http_build_url/src/http_build_url.php',
11
+ );
12
+
13
  public static $prefixLengthsPsr4 = array (
14
  'C' =>
15
  array (
42
  );
43
 
44
  public static $classMap = array (
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
45
  'WCML_Accommodation_Bookings' => __DIR__ . '/../..' . '/compatibility/class-wcml-accommodation-bookings.php',
46
  'WCML_Admin_Cookie' => __DIR__ . '/../..' . '/classes/class-wcml-admin-cookie.php',
47
  'WCML_Admin_Currency_Selector' => __DIR__ . '/../..' . '/classes/currencies/class-wcml-admin-currency-selector.php',
69
  'WCML_Composite_Products' => __DIR__ . '/../..' . '/compatibility/class-wcml-composite-products.php',
70
  'WCML_Coupons' => __DIR__ . '/../..' . '/inc/class-wcml-coupons.php',
71
  'WCML_Currencies' => __DIR__ . '/../..' . '/classes/currencies/class-wcml-currencies.php',
72
+ 'WCML_Currencies_Dropdown_UI' => __DIR__ . '/../..' . '/inc/template-classes/class-wcml-currencies-dropdown-ui.php',
73
+ 'WCML_Currencies_Payment_Gateways' => __DIR__ . '/../..' . '/classes/multi-currency/payment-gateways/class-wcml-currencies-payment-gateways.php',
74
  'WCML_Currency_Switcher' => __DIR__ . '/../..' . '/inc/currencies/currency-switcher/class-wcml-currency-switcher.php',
75
  'WCML_Currency_Switcher_Ajax' => __DIR__ . '/../..' . '/inc/currencies/currency-switcher/class-wcml-currency-switcher-ajax.php',
76
  'WCML_Currency_Switcher_Options_Dialog' => __DIR__ . '/../..' . '/inc/template-classes/currency-switcher/class-wcml-currency-switcher-options-dialog.php',
91
  'WCML_Editor_UI_WYSIWYG_Field' => __DIR__ . '/../..' . '/inc/translation-editor/class-wcml-editor-ui-wysiwyg-field.php',
92
  'WCML_Emails' => __DIR__ . '/../..' . '/inc/class-wcml-emails.php',
93
  'WCML_Endpoints' => __DIR__ . '/../..' . '/inc/class-wcml-endpoints.php',
94
+ 'WCML_Endpoints_Legacy' => __DIR__ . '/../..' . '/inc/class-wcml-endpoints-legacy.php',
95
  'WCML_Etheme_Blanco' => __DIR__ . '/../..' . '/compatibility/class-wcml-etheme-blanco.php',
96
  'WCML_Exchange_Rate_Service' => __DIR__ . '/../..' . '/classes/multi-currency/exchange-rate-services/class-wcml-exchange-rate-service.php',
97
  'WCML_Exchange_Rates' => __DIR__ . '/../..' . '/classes/multi-currency/class-wcml-exchange-rates.php',
100
  'WCML_Exchange_Rates_UI' => __DIR__ . '/../..' . '/inc/template-classes/multi-currency/class-wcml-exchange-rates-ui.php',
101
  'WCML_Extra_Product_Options' => __DIR__ . '/../..' . '/compatibility/class-wcml-extra-product-options.php',
102
  'WCML_File' => __DIR__ . '/../..' . '/inc/currencies/currency-switcher/class-wcml-file.php',
 
103
  'WCML_Flatsome' => __DIR__ . '/../..' . '/compatibility/class-wcml-flatsome.php',
104
  'WCML_Install' => __DIR__ . '/../..' . '/inc/class-wcml-install.php',
105
  'WCML_JCK_WSSV' => __DIR__ . '/../..' . '/compatibility/class-wcml-jck-wssv.php',
121
  'WCML_Multi_Currency_Reports' => __DIR__ . '/../..' . '/inc/currencies/class-wcml-multi-currency-reports.php',
122
  'WCML_Multi_Currency_Resources' => __DIR__ . '/../..' . '/inc/currencies/class-wcml-multi-currency-resources.php',
123
  'WCML_Multi_Currency_Shipping' => __DIR__ . '/../..' . '/inc/currencies/class-wcml-multi-currency-shipping.php',
 
124
  'WCML_Multi_Currency_Table_Rate_Shipping' => __DIR__ . '/../..' . '/inc/currencies/class-wcml-multi-currency-table-rate-shipping.php',
125
  'WCML_Multi_Currency_UI' => __DIR__ . '/../..' . '/inc/template-classes/multi-currency/class-wcml-multi-currency-ui.php',
126
+ 'WCML_Not_Supported_Payment_Gateway' => __DIR__ . '/../..' . '/classes/multi-currency/payment-gateways/class-wcml-not-supported-payment-gateway.php',
127
  'WCML_Not_Translatable_Attributes' => __DIR__ . '/../..' . '/inc/template-classes/class-wcml-not-translatable-attributes.php',
128
  'WCML_Orders' => __DIR__ . '/../..' . '/inc/class-wcml-orders.php',
129
  'WCML_Page_Builders' => __DIR__ . '/../..' . '/inc/translation-editor/class-wcml-page-builders.php',
130
+ 'WCML_Payment_Gateway' => __DIR__ . '/../..' . '/classes/multi-currency/payment-gateways/class-wcml-payment-gateway.php',
131
+ 'WCML_Payment_Gateway_Bacs' => __DIR__ . '/../..' . '/classes/multi-currency/payment-gateways/class-wcml-payment-gateway-bacs.php',
132
+ 'WCML_Payment_Gateway_PayPal' => __DIR__ . '/../..' . '/classes/multi-currency/payment-gateways/class-wcml-payment-gateway-paypal.php',
133
+ 'WCML_Payment_Gateway_Stripe' => __DIR__ . '/../..' . '/classes/multi-currency/payment-gateways/class-wcml-payment-gateway-stripe.php',
134
  'WCML_Payment_Method_Filter' => __DIR__ . '/../..' . '/classes/order-property-filter/class-wcml-payment-method-filter.php',
135
  'WCML_Per_Product_Shipping' => __DIR__ . '/../..' . '/compatibility/class-wcml-per-product-shipping.php',
136
  'WCML_Pip' => __DIR__ . '/../..' . '/compatibility/class-wcml-pip.php',
142
  'WCML_Privacy_Content_Factory' => __DIR__ . '/../..' . '/classes/privacy/class-wcml-privacy-content-factory.php',
143
  'WCML_Product_Addons' => __DIR__ . '/../..' . '/compatibility/class-wcml-product-addons.php',
144
  'WCML_Product_Bundles' => __DIR__ . '/../..' . '/compatibility/class-wcml-product-bundles.php',
 
145
  'WCML_Product_Gallery_Filter' => __DIR__ . '/../..' . '/classes/media/class-wcml-product-gallery-filter.php',
146
  'WCML_Product_Gallery_Filter_Factory' => __DIR__ . '/../..' . '/classes/media/class-wcml-product-gallery-filter-factory.php',
147
  'WCML_Product_Image_Filter' => __DIR__ . '/../..' . '/classes/media/class-wcml-product-image-filter.php',
154
  'WCML_REST_API_Query_Filters_Products' => __DIR__ . '/../..' . '/classes/rest-api-support/filters/class-wcml-rest-api-query-filters-products.php',
155
  'WCML_REST_API_Query_Filters_Terms' => __DIR__ . '/../..' . '/classes/rest-api-support/filters/class-wcml-rest-api-query-filters-terms.php',
156
  'WCML_REST_API_Support' => __DIR__ . '/../..' . '/classes/rest-api-support/class-wcml-rest-api-support.php',
 
157
  'WCML_REST_Generic_Exception' => __DIR__ . '/../..' . '/classes/rest-api-support/exceptions/class-wcml-rest-generic-exception.php',
158
  'WCML_REST_Invalid_Currency_Exception' => __DIR__ . '/../..' . '/classes/rest-api-support/exceptions/class-wcml-rest-invalid-currency-exception.php',
159
  'WCML_REST_Invalid_Language_Exception' => __DIR__ . '/../..' . '/classes/rest-api-support/exceptions/class-wcml-rest-invalid-language-exception.php',
218
  'WCML_WC_Memberships' => __DIR__ . '/../..' . '/compatibility/class-wcml-wc-memberships.php',
219
  'WCML_WC_Name_Your_Price' => __DIR__ . '/../..' . '/compatibility/class-wcml-wc-name-your-price.php',
220
  'WCML_WC_Product_Bundles_Items' => __DIR__ . '/../..' . '/compatibility/includes/class-wcml-wc-product-bundles-items.php',
221
+ 'WCML_WC_Product_Type_Column' => __DIR__ . '/../..' . '/compatibility/class-wcml-wc-product-type-column.php',
222
  'WCML_WC_Shipping' => __DIR__ . '/../..' . '/inc/class-wcml-wc-shipping.php',
223
  'WCML_WC_Shortcode_Product_Category' => __DIR__ . '/../..' . '/classes/shortcodes/class-wcml-wc-shortcode-product-category.php',
224
  'WCML_WC_Strings' => __DIR__ . '/../..' . '/inc/class-wcml-wc-strings.php',
225
  'WCML_WC_Subscriptions' => __DIR__ . '/../..' . '/compatibility/class-wcml-wc-subscriptions.php',
226
  'WCML_WPSEO' => __DIR__ . '/../..' . '/compatibility/class-wcml-wpseo.php',
227
  'WCML_Widgets' => __DIR__ . '/../..' . '/inc/class-wcml-widgets.php',
 
228
  'WCML_Woo_Var_Table' => __DIR__ . '/../..' . '/compatibility/class-wcml-woo-var-table.php',
229
+ 'WCML_WpFastest_Cache' => __DIR__ . '/../..' . '/compatibility/class-wcml-wpfastest-cache.php',
230
  'WCML_Wpb_Vc' => __DIR__ . '/../..' . '/compatibility/class-wcml-wpb-vc.php',
231
  'WCML_YITH_WCQV' => __DIR__ . '/../..' . '/compatibility/class-wcml-yith-wcqv.php',
232
  'WCML_gravityforms' => __DIR__ . '/../..' . '/compatibility/class-wcml-gravityforms.php',
233
  'WCML_wcExporter' => __DIR__ . '/../..' . '/compatibility/class-wcml-wcexporter.php',
234
  'WCML_xDomain_Data' => __DIR__ . '/../..' . '/classes/urls/class-wcml-xdomain-data.php',
 
235
  'woocommerce_wpml' => __DIR__ . '/../..' . '/classes/class-woocommerce-wpml.php',
 
 
236
  );
237
 
238
  public static function getInitializer(ClassLoader $loader)
239
  {
240
  return \Closure::bind(function () use ($loader) {
241
+ $loader->prefixLengthsPsr4 = ComposerStaticInit16830393fdb1b55f62e7d6c070d05751::$prefixLengthsPsr4;
242
+ $loader->prefixDirsPsr4 = ComposerStaticInit16830393fdb1b55f62e7d6c070d05751::$prefixDirsPsr4;
243
+ $loader->prefixesPsr0 = ComposerStaticInit16830393fdb1b55f62e7d6c070d05751::$prefixesPsr0;
244
+ $loader->classMap = ComposerStaticInit16830393fdb1b55f62e7d6c070d05751::$classMap;
245
 
246
  }, null, ClassLoader::class);
247
  }
vendor/composer/installers/README.md ADDED
@@ -0,0 +1,221 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # A Multi-Framework [Composer](http://getcomposer.org) Library Installer
2
+
3
+ [![Build Status](http://img.shields.io/travis/composer/installers.svg)](http://travis-ci.org/composer/installers)
4
+
5
+ This is for PHP package authors to require in their `composer.json`. It will
6
+ install their package to the correct location based on the specified package
7
+ type.
8
+
9
+ The goal of Installers is to be a simple package type to install path map.
10
+ Users can also customize the install path per package and package authors can
11
+ modify the package name upon installing.
12
+
13
+ Installers isn't intended on replacing all custom installers. If your
14
+ package requires special installation handling then by all means, create a
15
+ custom installer to handle it.
16
+
17
+ **Natively Supported Frameworks**:
18
+
19
+ The following frameworks natively work with Composer and will be
20
+ installed to the default `vendor` directory. `composer/installers`
21
+ is not needed to install packages with these frameworks:
22
+
23
+ * Aura
24
+ * Symfony2
25
+ * Yii
26
+ * Yii2
27
+
28
+ ## Current Supported Package Types
29
+
30
+ > Stable types are marked as **bold**, this means that installation paths
31
+ > for those type will not be changed. Any adjustment for those types would
32
+ > require creation of brand new type that will cover required changes.
33
+
34
+ | Framework | Types
35
+ | --------- | -----
36
+ | Aimeos | `aimeos-extension`
37
+ | Asgard | `asgard-module`<br>`asgard-theme`
38
+ | Attogram | `attogram-module`
39
+ | AGL | `agl-module`
40
+ | Bonefish | `bonefish-package`
41
+ | AnnotateCms | `annotatecms-module`<br>`annotatecms-component`<br>`annotatecms-service`
42
+ | Bitrix | `bitrix-module` (deprecated) <br>`bitrix-component` (deprecated) <br>`bitrix-theme` (deprecated) <br><br> `bitrix-d7-module` <br> `bitrix-d7-component` <br> `bitrix-d7-template`
43
+ | CakePHP 2+ | **`cakephp-plugin`**
44
+ | Chef | `chef-cookbook`<br>`chef-role`
45
+ | CCFramework | `ccframework-ship`<br>`ccframework-theme`
46
+ | Cockpit | `cockpit-module`
47
+ | CodeIgniter | `codeigniter-library`<br>`codeigniter-third-party`<br>`codeigniter-module`
48
+ | concrete5 | `concrete5-core`<br>`concrete5-package`<br>`concrete5-theme`<br>`concrete5-block`<br>`concrete5-update`
49
+ | Craft | `craft-plugin`
50
+ | Croogo | `croogo-plugin`<br>`croogo-theme`
51
+ | Decibel | `decibel-app`
52
+ | DokuWiki | `dokuwiki-plugin`<br>`dokuwiki-template`
53
+ | Dolibarr | `dolibarr-module`
54
+ | Drupal | <b>`drupal-core`<br>`drupal-module`<br>`drupal-theme`</b><br>`drupal-library`<br>`drupal-profile`<br>`drupal-drush`
55
+ | Elgg | `elgg-plugin`
56
+ | Eliasis | `eliasis-component`<br>`eliasis-module`<br>`eliasis-plugin`<br>`eliasis-template`
57
+ | ExpressionEngine 3 | `ee3-addon`<br>`ee3-theme`
58
+ | eZ Platform | `ezplatform-assets`<br>`ezplatform-meta-assets`
59
+ | FuelPHP v1.x | `fuel-module`<br>`fuel-package`<br/>`fuel-theme`
60
+ | FuelPHP v2.x | `fuelphp-component`
61
+ | Grav | `grav-plugin`<br>`grav-theme`
62
+ | Hurad | `hurad-plugin`<br>`hurad-theme`
63
+ | ImageCMS | `imagecms-template`<br>`imagecms-module`<br>`imagecms-library`
64
+ | iTop | `itop-extension`
65
+ | Joomla | `joomla-component`<br>`joomla-module`<br>`joomla-template`<br>`joomla-plugin`<br>`joomla-library`
66
+ | Kanboard | `kanboard-plugin`
67
+ | Kirby | **`kirby-plugin`**<br>`kirby-field`<br>`kirby-tag`
68
+ | KodiCMS | `kodicms-plugin`<br>`kodicms-media`
69
+ | Kohana | **`kohana-module`**
70
+ | Lan Management System | `lms-plugin`<br>`lms-template`<br>`lms-document-template`<br>`lms-userpanel-module`
71
+ | Laravel | `laravel-library`
72
+ | Lavalite | `lavalite-theme`<br>`lavalite-package`
73
+ | Lithium | **`lithium-library`<br>`lithium-source`**
74
+ | Magento | `magento-library`<br>`magento-skin`<br>`magento-theme`
75
+ | majima | `majima-plugin`
76
+ | Mako | `mako-package`
77
+ | Mautic | `mautic-plugin`<br>`mautic-theme`
78
+ | Maya | `maya-module`
79
+ | MODX | `modx-extra`
80
+ | MODX Evo | `modxevo-snippet`<br>`modxevo-plugin`<br>`modxevo-module`<br>`modxevo-template`<br>`modxevo-lib`
81
+ | MediaWiki | `mediawiki-extension`
82
+ | October | **`october-module`<br>`october-plugin`<br>`october-theme`**
83
+ | OntoWiki | `ontowiki-extension`<br>`ontowiki-theme`<br>`ontowiki-translation`
84
+ | OXID | `oxid-module`<br>`oxid-theme`<br>`oxid-out`
85
+ | Osclass | `osclass-plugin`<br>`osclass-theme`<br>`osclass-language`
86
+ | MODULEWork | `modulework-module`
87
+ | Moodle | `moodle-*` (Please [check source](https://raw.githubusercontent.com/composer/installers/master/src/Composer/Installers/MoodleInstaller.php) for all supported types)
88
+ | Piwik | `piwik-plugin`
89
+ | phpBB | `phpbb-extension`<br>`phpbb-style`<br>`phpbb-language`
90
+ | Pimcore | `pimcore-plugin`
91
+ | Plentymarkets | `plentymarkets-plugin`
92
+ | PPI | **`ppi-module`**
93
+ | Puppet | `puppet-module`
94
+ | Porto | `porto-container`
95
+ | RadPHP | `radphp-bundle`
96
+ | REDAXO | `redaxo-addon`
97
+ | ReIndex | **`reindex-plugin`** <br> **`reindex-theme`**
98
+ | Roundcube | `roundcube-plugin`
99
+ | shopware | `shopware-backend-plugin`<br/>`shopware-core-plugin`<br/>`shopware-frontend-plugin`<br/>`shopware-theme`<br/>`shopware-plugin`<br/>`shopware-frontend-theme`
100
+ | SilverStripe | `silverstripe-module`<br>`silverstripe-theme`
101
+ | SiteDirect | `sitedirect-module`<br>`sitedirect-plugin`
102
+ | SMF | `smf-module`<br>`smf-theme`
103
+ | SyDES | `sydes-module`<br>`sydes-theme`
104
+ | symfony1 | **`symfony1-plugin`**
105
+ | Tusk | `tusk-task`<br>`tusk-command`<br>`tusk-asset`
106
+ | TYPO3 Flow | `typo3-flow-package`<br>`typo3-flow-framework`<br>`typo3-flow-plugin`<br>`typo3-flow-site`<br>`typo3-flow-boilerplate`<br>`typo3-flow-build`
107
+ | TYPO3 CMS | `typo3-cms-extension` (Deprecated in this package, use the [TYPO3 CMS Installers](https://packagist.org/packages/typo3/cms-composer-installers) instead)
108
+ | UserFrosting | `userfrosting-sprinkle`
109
+ | Vanilla | `vanilla-plugin`<br>`vanilla-theme`
110
+ | Vgmcp | `vgmcp-bundle`<br>`vgmcp-theme`
111
+ | Wolf CMS | `wolfcms-plugin`
112
+ | WordPress | <b>`wordpress-plugin`<br>`wordpress-theme`</b><br>`wordpress-muplugin`<br>`wordpress-dropin`
113
+ | YAWIK | `yawik-module`
114
+ | Zend | `zend-library`<br>`zend-extra`<br>`zend-module`
115
+ | Zikula | `zikula-module`<br>`zikula-theme`
116
+ | Prestashop | `prestashop-module`<br>`prestashop-theme`
117
+ | Phifty | `phifty-bundle`<br>`phifty-framework`<br>`phifty-library`
118
+
119
+ ## Example `composer.json` File
120
+
121
+ This is an example for a CakePHP plugin. The only important parts to set in your
122
+ composer.json file are `"type": "cakephp-plugin"` which describes what your
123
+ package is and `"require": { "composer/installers": "~1.0" }` which tells composer
124
+ to load the custom installers.
125
+
126
+ ```json
127
+ {
128
+ "name": "you/ftp",
129
+ "type": "cakephp-plugin",
130
+ "require": {
131
+ "composer/installers": "~1.0"
132
+ }
133
+ }
134
+ ```
135
+
136
+ This would install your package to the `Plugin/Ftp/` folder of a CakePHP app
137
+ when a user runs `php composer.phar install`.
138
+
139
+ So submit your packages to [packagist.org](http://packagist.org)!
140
+
141
+ ## Custom Install Paths
142
+
143
+ If you are consuming a package that uses the `composer/installers` you can
144
+ override the install path with the following extra in your `composer.json`:
145
+
146
+ ```json
147
+ {
148
+ "extra": {
149
+ "installer-paths": {
150
+ "your/custom/path/{$name}/": ["shama/ftp", "vendor/package"]
151
+ }
152
+ }
153
+ }
154
+ ```
155
+
156
+ A package type can have a custom installation path with a `type:` prefix.
157
+
158
+ ``` json
159
+ {
160
+ "extra": {
161
+ "installer-paths": {
162
+ "your/custom/path/{$name}/": ["type:wordpress-plugin"]
163
+ }
164
+ }
165
+ }
166
+ ```
167
+
168
+ You can also have the same vendor packages with a custom installation path by
169
+ using the `vendor:` prefix.
170
+
171
+ ``` json
172
+ {
173
+ "extra": {
174
+ "installer-paths": {
175
+ "your/custom/path/{$name}/": ["vendor:my_organization"]
176
+ }
177
+ }
178
+ }
179
+ ```
180
+
181
+ These would use your custom path for each of the listed packages. The available
182
+ variables to use in your paths are: `{$name}`, `{$vendor}`, `{$type}`.
183
+
184
+ ## Custom Install Names
185
+
186
+ If you're a package author and need your package to be named differently when
187
+ installed consider using the `installer-name` extra.
188
+
189
+ For example you have a package named `shama/cakephp-ftp` with the type
190
+ `cakephp-plugin`. Installing with `composer/installers` would install to the
191
+ path `Plugin/CakephpFtp`. Due to the strict naming conventions, you as a
192
+ package author actually need the package to be named and installed to
193
+ `Plugin/Ftp`. Using the following config within your **package** `composer.json`
194
+ will allow this:
195
+
196
+ ```json
197
+ {
198
+ "name": "shama/cakephp-ftp",
199
+ "type": "cakephp-plugin",
200
+ "extra": {
201
+ "installer-name": "Ftp"
202
+ }
203
+ }
204
+ ```
205
+
206
+ Please note the name entered into `installer-name` will be the final and will
207
+ not be inflected.
208
+
209
+ ## Should we allow dynamic package types or paths? No.
210
+
211
+ What are they? The ability for a package author to determine where a package
212
+ will be installed either through setting the path directly in their
213
+ `composer.json` or through a dynamic package type: `"type":
214
+ "framework-install-here"`.
215
+
216
+ It has been proposed many times. Even implemented once early on and then
217
+ removed. Installers won't do this because it would allow a single package
218
+ author to wipe out entire folders without the user's consent. That user would
219
+ then come here to yell at us.
220
+
221
+ Anyone still wanting this capability should consider requiring https://github.com/oomphinc/composer-installers-extender.
vendor/jakeasmith/http_build_url/LICENSE ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2015 Jake A. Smith
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ 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 FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
vendor/jakeasmith/http_build_url/src/http_build_url.php ADDED
@@ -0,0 +1,174 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * URL constants as defined in the PHP Manual under "Constants usable with
5
+ * http_build_url()".
6
+ *
7
+ * @see http://us2.php.net/manual/en/http.constants.php#http.constants.url
8
+ */
9
+ if (!defined('HTTP_URL_REPLACE')) {
10
+ define('HTTP_URL_REPLACE', 1);
11
+ }
12
+ if (!defined('HTTP_URL_JOIN_PATH')) {
13
+ define('HTTP_URL_JOIN_PATH', 2);
14
+ }
15
+ if (!defined('HTTP_URL_JOIN_QUERY')) {
16
+ define('HTTP_URL_JOIN_QUERY', 4);
17
+ }
18
+ if (!defined('HTTP_URL_STRIP_USER')) {
19
+ define('HTTP_URL_STRIP_USER', 8);
20
+ }
21
+ if (!defined('HTTP_URL_STRIP_PASS')) {
22
+ define('HTTP_URL_STRIP_PASS', 16);
23
+ }
24
+ if (!defined('HTTP_URL_STRIP_AUTH')) {
25
+ define('HTTP_URL_STRIP_AUTH', 32);
26
+ }
27
+ if (!defined('HTTP_URL_STRIP_PORT')) {
28
+ define('HTTP_URL_STRIP_PORT', 64);
29
+ }
30
+ if (!defined('HTTP_URL_STRIP_PATH')) {
31
+ define('HTTP_URL_STRIP_PATH', 128);
32
+ }
33
+ if (!defined('HTTP_URL_STRIP_QUERY')) {
34
+ define('HTTP_URL_STRIP_QUERY', 256);
35
+ }
36
+ if (!defined('HTTP_URL_STRIP_FRAGMENT')) {
37
+ define('HTTP_URL_STRIP_FRAGMENT', 512);
38
+ }
39
+ if (!defined('HTTP_URL_STRIP_ALL')) {
40
+ define('HTTP_URL_STRIP_ALL', 1024);
41
+ }
42
+
43
+ if (!function_exists('http_build_url')) {
44
+
45
+ /**
46
+ * Build a URL.
47
+ *
48
+ * The parts of the second URL will be merged into the first according to
49
+ * the flags argument.
50
+ *
51
+ * @param mixed $url (part(s) of) an URL in form of a string or
52
+ * associative array like parse_url() returns
53
+ * @param mixed $parts same as the first argument
54
+ * @param int $flags a bitmask of binary or'ed HTTP_URL constants;
55
+ * HTTP_URL_REPLACE is the default
56
+ * @param array $new_url if set, it will be filled with the parts of the
57
+ * composed url like parse_url() would return
58
+ * @return string
59
+ */
60
+ function http_build_url($url, $parts = array(), $flags = HTTP_URL_REPLACE, &$new_url = array())
61
+ {
62
+ is_array($url) || $url = parse_url($url);
63
+ is_array($parts) || $parts = parse_url($parts);
64
+
65
+ isset($url['query']) && is_string($url['query']) || $url['query'] = null;
66
+ isset($parts['query']) && is_string($parts['query']) || $parts['query'] = null;
67
+
68
+ $keys = array('user', 'pass', 'port', 'path', 'query', 'fragment');
69
+
70
+ // HTTP_URL_STRIP_ALL and HTTP_URL_STRIP_AUTH cover several other flags.
71
+ if ($flags & HTTP_URL_STRIP_ALL) {
72
+ $flags |= HTTP_URL_STRIP_USER | HTTP_URL_STRIP_PASS
73
+ | HTTP_URL_STRIP_PORT | HTTP_URL_STRIP_PATH
74
+ | HTTP_URL_STRIP_QUERY | HTTP_URL_STRIP_FRAGMENT;
75
+ } elseif ($flags & HTTP_URL_STRIP_AUTH) {
76
+ $flags |= HTTP_URL_STRIP_USER | HTTP_URL_STRIP_PASS;
77
+ }
78
+
79
+ // Schema and host are alwasy replaced
80
+ foreach (array('scheme', 'host') as $part) {
81
+ if (isset($parts[$part])) {
82
+ $url[$part] = $parts[$part];
83
+ }
84
+ }
85
+
86
+ if ($flags & HTTP_URL_REPLACE) {
87
+ foreach ($keys as $key) {
88
+ if (isset($parts[$key])) {
89
+ $url[$key] = $parts[$key];
90
+ }
91
+ }
92
+ } else {
93
+ if (isset($parts['path']) && ($flags & HTTP_URL_JOIN_PATH)) {
94
+ if (isset($url['path']) && substr($parts['path'], 0, 1) !== '/') {
95
+ // Workaround for trailing slashes
96
+ $url['path'] .= 'a';
97
+ $url['path'] = rtrim(
98
+ str_replace(basename($url['path']), '', $url['path']),
99
+ '/'
100
+ ) . '/' . ltrim($parts['path'], '/');
101
+ } else {
102
+ $url['path'] = $parts['path'];
103
+ }
104
+ }
105
+
106
+ if (isset($parts['query']) && ($flags & HTTP_URL_JOIN_QUERY)) {
107
+ if (isset($url['query'])) {
108
+ parse_str($url['query'], $url_query);
109
+ parse_str($parts['query'], $parts_query);
110
+
111
+ $url['query'] = http_build_query(
112
+ array_replace_recursive(
113
+ $url_query,
114
+ $parts_query
115
+ )
116
+ );
117
+ } else {
118
+ $url['query'] = $parts['query'];
119
+ }
120
+ }
121
+ }
122
+
123
+ if (isset($url['path']) && $url['path'] !== '' && substr($url['path'], 0, 1) !== '/') {
124
+ $url['path'] = '/' . $url['path'];
125
+ }
126
+
127
+ foreach ($keys as $key) {
128
+ $strip = 'HTTP_URL_STRIP_' . strtoupper($key);
129
+ if ($flags & constant($strip)) {
130
+ unset($url[$key]);
131
+ }
132
+ }
133
+
134
+ $parsed_string = '';
135
+
136
+ if (!empty($url['scheme'])) {
137
+ $parsed_string .= $url['scheme'] . '://';
138
+ }
139
+
140
+ if (!empty($url['user'])) {
141
+ $parsed_string .= $url['user'];
142
+
143
+ if (isset($url['pass'])) {
144
+ $parsed_string .= ':' . $url['pass'];
145
+ }
146
+
147
+ $parsed_string .= '@';
148
+ }
149
+
150
+ if (!empty($url['host'])) {
151
+ $parsed_string .= $url['host'];
152
+ }
153
+
154
+ if (!empty($url['port'])) {
155
+ $parsed_string .= ':' . $url['port'];
156
+ }
157
+
158
+ if (!empty($url['path'])) {
159
+ $parsed_string .= $url['path'];
160
+ }
161
+
162
+ if (!empty($url['query'])) {
163
+ $parsed_string .= '?' . $url['query'];
164
+ }
165
+
166
+ if (!empty($url['fragment'])) {
167
+ $parsed_string .= '#' . $url['fragment'];
168
+ }
169
+
170
+ $new_url = $url;
171
+
172
+ return $parsed_string;
173
+ }
174
+ }
vendor/otgs/installer/Makefile ADDED
@@ -0,0 +1,83 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Tutorial: http://www.cs.colby.edu/maxwell/courses/tutorials/maketutor/
2
+ # Docs: https://www.gnu.org/software/make/
3
+
4
+ .PHONY: precommit
5
+ .PHONY: dupes comp jest phpunit test dev prod
6
+ .PHONY: setup test
7
+
8
+ setup:: vendor/autoload.php
9
+ setup:: yarn.lock
10
+ setup:: githooks
11
+
12
+ #test:: jest
13
+ test:: phpunit
14
+
15
+ precommit:: validate-composer
16
+ precommit:: validate-yarn
17
+ precommit:: dupes
18
+ precommit:: compatibility
19
+
20
+
21
+ # precommit
22
+
23
+ dupes: vendor/autoload.php
24
+ ./.make/check-duplicates.sh
25
+
26
+ compatibility: vendor/autoload.php
27
+ ./.make/check-compatibility.sh
28
+
29
+ validate-composer: composer.lock
30
+ ./.make/check-composer.sh
31
+
32
+ validate-yarn: yarn.lock
33
+ ./.make/check-yarn.sh
34
+
35
+
36
+ # Dependency managers
37
+
38
+ ## Composer
39
+
40
+ composer.lock: composer.json
41
+ composer install
42
+ touch $@
43
+
44
+ composer.json:
45
+ composer init -q
46
+
47
+ vendor/autoload.php: composer.lock
48
+ composer install
49
+ touch $@
50
+
51
+ ## Yarn
52
+
53
+ yarn.lock: package.json
54
+ yarn install
55
+ touch $@
56
+
57
+ # Setup
58
+
59
+ githooks:
60
+ ifndef CI
61
+ find .git/hooks -type l -exec rm {} \;
62
+ find .githooks -type f -exec ln -sf ../../{} .git/hooks/ \;
63
+ else
64
+ echo 'Skipping in CI'
65
+ endif
66
+
67
+ # Tests
68
+
69
+ jest: yarn.lock
70
+ yarn run test
71
+
72
+ phpunit: vendor/autoload.php
73
+ vendor/bin/phpunit --fail-on-warning
74
+
75
+ # Install
76
+ install:
77
+ composer install
78
+ yarn install
79
+
80
+ # Build
81
+
82
+ dev prod: yarn.lock
83
+ yarn run build:$@
vendor/otgs/installer/README.md ADDED
@@ -0,0 +1,61 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # OTGS WP Installer
2
+
3
+ OTGS WP Installer is a library that allows you to install and upgrade plugins and themes developed by OnTheGoSystems.
4
+
5
+ ## Installation
6
+
7
+ First, add OTGS WP Installer as a dependency with [Composer](http://getcomposer.org):
8
+
9
+ ```bash
10
+ composer require otgs/installer
11
+ ```
12
+
13
+ Make sure that your bootstrap file is loading the composer autoloader:
14
+
15
+ ```php
16
+ require_once 'vendor/autoload.php';
17
+ ```
18
+
19
+ Then, load the OTGS WP Installer bootstrap. Before the `plugins_loaded` action add:
20
+
21
+ ```php
22
+ include 'vendor/otgs/installer/loader.php';
23
+ ```
24
+
25
+ Optionally, you can specify parameters to configure showing a dedicated UI under `Plugins -> Install New` or to load specific repositories.
26
+ By default, all repositories configrede in `repositories.xml` will be loaded:
27
+ * wpml - [WPML.org](http://wpml.org)
28
+ * toolset - [WP-Types.com](http://wp-types.com)
29
+
30
+ ```php
31
+ WP_Installer_Setup( $wp_installer_instance,
32
+ array(
33
+ 'plugins_install_tab' => '1', // optional, default value: 0
34
+ 'repositories_include' => array( 'wpml' ) // optional, default to empty (show all)
35
+ )
36
+ );
37
+ ```
38
+
39
+ After `init`, configure display the OTGS WP Installer UI like in the example below:
40
+
41
+ ```php
42
+ WP_Installer_Show_Products(
43
+ array(
44
+ 'template' => 'compact', //required
45
+ 'product_name' => 'WPML',
46
+ 'box_title' => 'Multilingual Avada',
47
+ 'name' => 'Avada', //name of theme/plugin
48
+ 'box_description' => 'Avada theme is fully compatible with WPML - the WordPress Multilingual plugin. WPML lets
49
+ you add languages to your existing sites and includes advanced translation management.',
50
+ 'repository' => 'wpml', // required
51
+ 'package' => 'multilingual-cms', // required
52
+ 'product' => 'multilingual-cms' // required
53
+ )
54
+ );
55
+ ```
56
+
57
+ * `template` two options available: default and compact. Default will be the same GUI as on the Plugins -> Install new page while compact is a smaller version that can be fit in a different already existing screen
58
+ * `repository` only one product of a specific product package from a specific repository can be shown
59
+ * `package` only one product of a specific product package from a specific repository can be shown
60
+ * `product` only one product of a specific product package from a specific repository can be shown
61
+
vendor/otgs/installer/dist/css/component-settings-reports/styles.css ADDED
@@ -0,0 +1 @@
 
1
+ .otgs-installer-component-setting{margin:1em 0}.otgs-installer-component-setting h4{margin:0}.otgs-settings-container .otgs-installer-component-setting .spinner{position:absolute;margin:5px 0 0}
vendor/otgs/installer/dist/css/otgs-installer-support/styles.css ADDED
@@ -0,0 +1 @@
 
1
+ .otgs-installer-support-test-connection span.dashicons.dashicons-yes{color:darkgreen}.otgs-installer-support-test-connection span.dashicons.dashicons-no-alt{color:darkred}.otgs-installer-support-test-connection ul li{float:left;margin-right:20px}.otgs-installer-support-test-connection .spinner{float:left;position:relative;top:-5px}.otgs-installer-support-test-connection .check-again{position:relative;top:-6px;margin-left:10px}.installer-instances .active td{color:darkgreen;font-weight:bold}
vendor/otgs/installer/dist/css/ui/styles.css DELETED
@@ -1 +0,0 @@
1
- .otgs-installer-component-setting{margin:1em 0}.otgs-installer-component-setting h4{margin:0}.otgs-settings-container .otgs-installer-component-setting .spinner{position:absolute;margin:5px 0 0}.otgs-on-off-switch+.otgs-switch__onoff,.otgs-switch__onoff+.otgs-on-off-switch{-webkit-margin-start:7px;margin-inline-start:7px}.otgs-switch__onoff{position:relative;width:55px;display:inline-block;vertical-align:middle;-webkit-box-flex:0;-ms-flex:0 0 55px;flex:0 0 55px}.otgs-switch__onoff.otgs-pull-right{right:0}.otgs-switch__onoff .otgs-switch__onoff-label{display:block;overflow:hidden;cursor:pointer;border:1px solid #e6e6e6;border-radius:16px;margin:0}.otgs-switch__onoff .otgs-switch__onoff-inner{width:200%;margin-left:-100%;-webkit-transition:margin .15s ease-in-out;transition:margin .15s ease-in-out}.otgs-switch__onoff .otgs-switch__onoff-inner:after,.otgs-switch__onoff .otgs-switch__onoff-inner:before{float:left;width:50%;height:22px;padding:0;line-height:22px;font-size:11px;-webkit-box-sizing:border-box;box-sizing:border-box}.otgs-switch__onoff .otgs-switch__onoff-inner:before{content:"ON";padding-left:10px;background-color:#21759b;color:#fff}.otgs-switch__onoff .otgs-switch__onoff-inner:after{content:"OFF";padding-right:8px;background-color:#fafafa;color:#3d3d3d;text-align:right}.otgs-switch__onoff .otgs-switch__onoff-switch{width:18px;height:18px;margin:0;background:#fff;-webkit-box-shadow:0 0 3px rgba(0,0,0,.3);box-shadow:0 0 3px rgba(0,0,0,.3);border-radius:50%;position:absolute;top:3px;bottom:0;right:34px;-webkit-transition:right .15s ease-in-out;transition:right .15s ease-in-out}.otgs-toggle-group{position:relative;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center}.otgs-toggle-group .otgs-switch__onoff-inner{display:block}.otgs-toggle-group input[type=checkbox]{display:none}.otgs-toggle-group input[type=checkbox]:checked~.otgs-switch__onoff .otgs-switch__onoff-label .otgs-switch__onoff-inner{margin-left:0}.otgs-toggle-group input[type=checkbox]:checked~.otgs-switch__onoff .otgs-switch__onoff-label .otgs-switch__onoff-switch{right:3px;-webkit-box-shadow:0 0 3px rgba(0,0,0,.5);box-shadow:0 0 3px rgba(0,0,0,.5)}.otgs-toggle-group input[type=checkbox]:focus~.otgs-switch__onoff{outline:thin dotted #333}.otgs-toggle-group .otgs-on-off-switch{cursor:pointer;display:inline-block}.otgs-external-link:after{font-family:dashicons!important;content:"\A0\F504";vertical-align:baseline;line-height:1;display:inline-block}
 
vendor/otgs/installer/dist/js/component-settings-reports/app.js ADDED
@@ -0,0 +1 @@
 
1
+ !function(t){var e={};function r(o){if(e[o])return e[o].exports;var n=e[o]={i:o,l:!1,exports:{}};return t[o].call(n.exports,n,n.exports,r),n.l=!0,n.exports}r.m=t,r.c=e,r.d=function(t,e,o){r.o(t,e)||Object.defineProperty(t,e,{configurable:!1,enumerable:!0,get:o})},r.r=function(t){Object.defineProperty(t,"__esModule",{value:!0})},r.n=function(t){var e=t&&t.__esModule?function(){return t.default}:function(){return t};return r.d(e,"a",e),e},r.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},r.p="",r(r.s=2)}([function(t,e,r){"use strict";r(7)},function(t,e){!function(t){"use strict";if(!t.fetch){var e={searchParams:"URLSearchParams"in t,iterable:"Symbol"in t&&"iterator"in Symbol,blob:"FileReader"in t&&"Blob"in t&&function(){try{return new Blob,!0}catch(t){return!1}}(),formData:"FormData"in t,arrayBuffer:"ArrayBuffer"in t};if(e.arrayBuffer)var r=["[object Int8Array]","[object Uint8Array]","[object Uint8ClampedArray]","[object Int16Array]","[object Uint16Array]","[object Int32Array]","[object Uint32Array]","[object Float32Array]","[object Float64Array]"],o=function(t){return t&&DataView.prototype.isPrototypeOf(t)},n=ArrayBuffer.isView||function(t){return t&&r.indexOf(Object.prototype.toString.call(t))>-1};h.prototype.append=function(t,e){t=a(t),e=u(e);var r=this.map[t];this.map[t]=r?r+","+e:e},h.prototype.delete=function(t){delete this.map[a(t)]},h.prototype.get=function(t){return t=a(t),this.has(t)?this.map[t]:null},h.prototype.has=function(t){return this.map.hasOwnProperty(a(t))},h.prototype.set=function(t,e){this.map[a(t)]=u(e)},h.prototype.forEach=function(t,e){for(var r in this.map)this.map.hasOwnProperty(r)&&t.call(e,this.map[r],r,this)},h.prototype.keys=function(){var t=[];return this.forEach(function(e,r){t.push(r)}),f(t)},h.prototype.values=function(){var t=[];return this.forEach(function(e){t.push(e)}),f(t)},h.prototype.entries=function(){var t=[];return this.forEach(function(e,r){t.push([r,e])}),f(t)},e.iterable&&(h.prototype[Symbol.iterator]=h.prototype.entries);var i=["DELETE","GET","HEAD","OPTIONS","POST","PUT"];b.prototype.clone=function(){return new b(this,{body:this._bodyInit})},p.call(b.prototype),p.call(w.prototype),w.prototype.clone=function(){return new w(this._bodyInit,{status:this.status,statusText:this.statusText,headers:new h(this.headers),url:this.url})},w.error=function(){var t=new w(null,{status:0,statusText:""});return t.type="error",t};var s=[301,302,303,307,308];w.redirect=function(t,e){if(-1===s.indexOf(e))throw new RangeError("Invalid status code");return new w(null,{status:e,headers:{location:t}})},t.Headers=h,t.Request=b,t.Response=w,t.fetch=function(t,r){return new Promise(function(o,n){var i=new b(t,r),s=new XMLHttpRequest;s.onload=function(){var t={status:s.status,statusText:s.statusText,headers:function(t){var e=new h;return t.split(/\r?\n/).forEach(function(t){var r=t.split(":"),o=r.shift().trim();if(o){var n=r.join(":").trim();e.append(o,n)}}),e}(s.getAllResponseHeaders()||"")};t.url="responseURL"in s?s.responseURL:t.headers.get("X-Request-URL");var e="response"in s?s.response:s.responseText;o(new w(e,t))},s.onerror=function(){n(new TypeError("Network request failed"))},s.ontimeout=function(){n(new TypeError("Network request failed"))},s.open(i.method,i.url,!0),"include"===i.credentials&&(s.withCredentials=!0),"responseType"in s&&e.blob&&(s.responseType="blob"),i.headers.forEach(function(t,e){s.setRequestHeader(e,t)}),s.send(void 0===i._bodyInit?null:i._bodyInit)})},t.fetch.polyfill=!0}function a(t){if("string"!=typeof t&&(t=String(t)),/[^a-z0-9\-#$%&'*+.\^_`|~]/i.test(t))throw new TypeError("Invalid character in header field name");return t.toLowerCase()}function u(t){return"string"!=typeof t&&(t=String(t)),t}function f(t){var r={next:function(){var e=t.shift();return{done:void 0===e,value:e}}};return e.iterable&&(r[Symbol.iterator]=function(){return r}),r}function h(t){this.map={},t instanceof h?t.forEach(function(t,e){this.append(e,t)},this):Array.isArray(t)?t.forEach(function(t){this.append(t[0],t[1])},this):t&&Object.getOwnPropertyNames(t).forEach(function(e){this.append(e,t[e])},this)}function d(t){if(t.bodyUsed)return Promise.reject(new TypeError("Already read"));t.bodyUsed=!0}function c(t){return new Promise(function(e,r){t.onload=function(){e(t.result)},t.onerror=function(){r(t.error)}})}function y(t){var e=new FileReader,r=c(e);return e.readAsArrayBuffer(t),r}function l(t){if(t.slice)return t.slice(0);var e=new Uint8Array(t.byteLength);return e.set(new Uint8Array(t)),e.buffer}function p(){return this.bodyUsed=!1,this._initBody=function(t){if(this._bodyInit=t,t)if("string"==typeof t)this._bodyText=t;else if(e.blob&&Blob.prototype.isPrototypeOf(t))this._bodyBlob=t;else if(e.formData&&FormData.prototype.isPrototypeOf(t))this._bodyFormData=t;else if(e.searchParams&&URLSearchParams.prototype.isPrototypeOf(t))this._bodyText=t.toString();else if(e.arrayBuffer&&e.blob&&o(t))this._bodyArrayBuffer=l(t.buffer),this._bodyInit=new Blob([this._bodyArrayBuffer]);else{if(!e.arrayBuffer||!ArrayBuffer.prototype.isPrototypeOf(t)&&!n(t))throw new Error("unsupported BodyInit type");this._bodyArrayBuffer=l(t)}else this._bodyText="";this.headers.get("content-type")||("string"==typeof t?this.headers.set("content-type","text/plain;charset=UTF-8"):this._bodyBlob&&this._bodyBlob.type?this.headers.set("content-type",this._bodyBlob.type):e.searchParams&&URLSearchParams.prototype.isPrototypeOf(t)&&this.headers.set("content-type","application/x-www-form-urlencoded;charset=UTF-8"))},e.blob&&(this.blob=function(){var t=d(this);if(t)return t;if(this._bodyBlob)return Promise.resolve(this._bodyBlob);if(this._bodyArrayBuffer)return Promise.resolve(new Blob([this._bodyArrayBuffer]));if(this._bodyFormData)throw new Error("could not read FormData body as blob");return Promise.resolve(new Blob([this._bodyText]))},this.arrayBuffer=function(){return this._bodyArrayBuffer?d(this)||Promise.resolve(this._bodyArrayBuffer):this.blob().then(y)}),this.text=function(){var t=d(this);if(t)return t;if(this._bodyBlob)return function(t){var e=new FileReader,r=c(e);return e.readAsText(t),r}(this._bodyBlob);if(this._bodyArrayBuffer)return Promise.resolve(function(t){for(var e=new Uint8Array(t),r=new Array(e.length),o=0;o<e.length;o++)r[o]=String.fromCharCode(e[o]);return r.join("")}(this._bodyArrayBuffer));if(this._bodyFormData)throw new Error("could not read FormData body as text");return Promise.resolve(this._bodyText)},e.formData&&(this.formData=function(){return this.text().then(m)}),this.json=function(){return this.text().then(JSON.parse)},this}function b(t,e){var r=(e=e||{}).body;if(t instanceof b){if(t.bodyUsed)throw new TypeError("Already read");this.url=t.url,this.credentials=t.credentials,e.headers||(this.headers=new h(t.headers)),this.method=t.method,this.mode=t.mode,r||null==t._bodyInit||(r=t._bodyInit,t.bodyUsed=!0)}else this.url=String(t);if(this.credentials=e.credentials||this.credentials||"omit",!e.headers&&this.headers||(this.headers=new h(e.headers)),this.method=function(t){var e=t.toUpperCase();return i.indexOf(e)>-1?e:t}(e.method||this.method||"GET"),this.mode=e.mode||this.mode||null,this.referrer=null,("GET"===this.method||"HEAD"===this.method)&&r)throw new TypeError("Body not allowed for GET or HEAD requests");this._initBody(r)}function m(t){var e=new FormData;return t.trim().split("&").forEach(function(t){if(t){var r=t.split("="),o=r.shift().replace(/\+/g," "),n=r.join("=").replace(/\+/g," ");e.append(decodeURIComponent(o),decodeURIComponent(n))}}),e}function w(t,e){e||(e={}),this.type="default",this.status="status"in e?e.status:200,this.ok=this.status>=200&&this.status<300,this.statusText="statusText"in e?e.statusText:"OK",this.headers=new h(e.headers),this.url=e.url||"",this._initBody(t)}}("undefined"!=typeof self?self:this)},function(t,e,r){r(1),t.exports=r(0)},,,,,function(t,e){}]);
vendor/otgs/installer/dist/js/otgs-installer-support/app.js ADDED
@@ -0,0 +1 @@
 
1
+ !function(t){var e={};function r(n){if(e[n])return e[n].exports;var o=e[n]={i:n,l:!1,exports:{}};return t[n].call(o.exports,o,o.exports,r),o.l=!0,o.exports}r.m=t,r.c=e,r.d=function(t,e,n){r.o(t,e)||Object.defineProperty(t,e,{configurable:!1,enumerable:!0,get:n})},r.r=function(t){Object.defineProperty(t,"__esModule",{value:!0})},r.n=function(t){var e=t&&t.__esModule?function(){return t.default}:function(){return t};return r.d(e,"a",e),e},r.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},r.p="",r(r.s=3)}([function(t,e,r){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var n=function(){function t(t,e){for(var r=0;r<e.length;r++){var n=e[r];n.enumerable=n.enumerable||!1,n.configurable=!0,"value"in n&&(n.writable=!0),Object.defineProperty(t,n.key,n)}}return function(e,r,n){return r&&t(e.prototype,r),n&&t(e,n),e}}();var o=function(){function t(e){!function(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}(this,t),this.container=e.querySelector(".otgs-installer-support-test-connection")}return n(t,[{key:"addEvents",value:function(){var t=this;this.container.querySelector(".check-again").addEventListener("click",function(){return t.checkConnection()})}},{key:"checkConnection",value:function(){var t=this,e={successClass:"dashicons-yes",failClass:"dashicons-no-alt",iconClass:"dashicons",spinnerClass:"spinner",activeSpinnerClass:"is-active"};this.container.querySelectorAll(".endpoint").forEach(function(r){var n=r.querySelector(".status"),o=t.container.querySelector("#otgs_installer_test_connection").value;t.resetStatus(n,e),fetch(ajaxurl,{headers:{"Content-Type":"application/x-www-form-urlencoded; charset=utf-8"},credentials:"same-origin",method:"POST",body:"nonce="+o+"&action=otgs_installer_test_connection&repository="+r.getAttribute("data-repository")+"&type="+r.getAttribute("data-type")}).then(function(r){r.json().then(function(r){r.success?t.setSuccessStatus(n,e):t.setFailStatus(n,e)})})})}},{key:"resetStatus",value:function(t,e){t.classList.remove(e.successClass,e.failClass,e.iconClass),t.classList.add(e.spinnerClass,e.activeSpinnerClass)}},{key:"setSuccessStatus",value:function(t,e){t.classList.add(e.successClass,e.iconClass),t.classList.remove(e.failClass,e.spinnerClass,e.activeSpinnerClass)}},{key:"setFailStatus",value:function(t,e){t.classList.remove(e.successClass,e.spinnerClass,e.activeSpinnerClass),t.classList.add(e.failClass,e.iconClass)}}]),t}();e.default=o},function(t,e,r){"use strict";r(8);var n=function(t){return t&&t.__esModule?t:{default:t}}(r(0));document.addEventListener("DOMContentLoaded",function(){new n.default(document).addEvents()})},function(t,e){!function(t){"use strict";if(!t.fetch){var e={searchParams:"URLSearchParams"in t,iterable:"Symbol"in t&&"iterator"in Symbol,blob:"FileReader"in t&&"Blob"in t&&function(){try{return new Blob,!0}catch(t){return!1}}(),formData:"FormData"in t,arrayBuffer:"ArrayBuffer"in t};if(e.arrayBuffer)var r=["[object Int8Array]","[object Uint8Array]","[object Uint8ClampedArray]","[object Int16Array]","[object Uint16Array]","[object Int32Array]","[object Uint32Array]","[object Float32Array]","[object Float64Array]"],n=function(t){return t&&DataView.prototype.isPrototypeOf(t)},o=ArrayBuffer.isView||function(t){return t&&r.indexOf(Object.prototype.toString.call(t))>-1};f.prototype.append=function(t,e){t=a(t),e=u(e);var r=this.map[t];this.map[t]=r?r+","+e:e},f.prototype.delete=function(t){delete this.map[a(t)]},f.prototype.get=function(t){return t=a(t),this.has(t)?this.map[t]:null},f.prototype.has=function(t){return this.map.hasOwnProperty(a(t))},f.prototype.set=function(t,e){this.map[a(t)]=u(e)},f.prototype.forEach=function(t,e){for(var r in this.map)this.map.hasOwnProperty(r)&&t.call(e,this.map[r],r,this)},f.prototype.keys=function(){var t=[];return this.forEach(function(e,r){t.push(r)}),c(t)},f.prototype.values=function(){var t=[];return this.forEach(function(e){t.push(e)}),c(t)},f.prototype.entries=function(){var t=[];return this.forEach(function(e,r){t.push([r,e])}),c(t)},e.iterable&&(f.prototype[Symbol.iterator]=f.prototype.entries);var s=["DELETE","GET","HEAD","OPTIONS","POST","PUT"];b.prototype.clone=function(){return new b(this,{body:this._bodyInit})},p.call(b.prototype),p.call(v.prototype),v.prototype.clone=function(){return new v(this._bodyInit,{status:this.status,statusText:this.statusText,headers:new f(this.headers),url:this.url})},v.error=function(){var t=new v(null,{status:0,statusText:""});return t.type="error",t};var i=[301,302,303,307,308];v.redirect=function(t,e){if(-1===i.indexOf(e))throw new RangeError("Invalid status code");return new v(null,{status:e,headers:{location:t}})},t.Headers=f,t.Request=b,t.Response=v,t.fetch=function(t,r){return new Promise(function(n,o){var s=new b(t,r),i=new XMLHttpRequest;i.onload=function(){var t={status:i.status,statusText:i.statusText,headers:function(t){var e=new f;return t.split(/\r?\n/).forEach(function(t){var r=t.split(":"),n=r.shift().trim();if(n){var o=r.join(":").trim();e.append(n,o)}}),e}(i.getAllResponseHeaders()||"")};t.url="responseURL"in i?i.responseURL:t.headers.get("X-Request-URL");var e="response"in i?i.response:i.responseText;n(new v(e,t))},i.onerror=function(){o(new TypeError("Network request failed"))},i.ontimeout=function(){o(new TypeError("Network request failed"))},i.open(s.method,s.url,!0),"include"===s.credentials&&(i.withCredentials=!0),"responseType"in i&&e.blob&&(i.responseType="blob"),s.headers.forEach(function(t,e){i.setRequestHeader(e,t)}),i.send(void 0===s._bodyInit?null:s._bodyInit)})},t.fetch.polyfill=!0}function a(t){if("string"!=typeof t&&(t=String(t)),/[^a-z0-9\-#$%&'*+.\^_`|~]/i.test(t))throw new TypeError("Invalid character in header field name");return t.toLowerCase()}function u(t){return"string"!=typeof t&&(t=String(t)),t}function c(t){var r={next:function(){var e=t.shift();return{done:void 0===e,value:e}}};return e.iterable&&(r[Symbol.iterator]=function(){return r}),r}function f(t){this.map={},t instanceof f?t.forEach(function(t,e){this.append(e,t)},this):Array.isArray(t)?t.forEach(function(t){this.append(t[0],t[1])},this):t&&Object.getOwnPropertyNames(t).forEach(function(e){this.append(e,t[e])},this)}function l(t){if(t.bodyUsed)return Promise.reject(new TypeError("Already read"));t.bodyUsed=!0}function h(t){return new Promise(function(e,r){t.onload=function(){e(t.result)},t.onerror=function(){r(t.error)}})}function d(t){var e=new FileReader,r=h(e);return e.readAsArrayBuffer(t),r}function y(t){if(t.slice)return t.slice(0);var e=new Uint8Array(t.byteLength);return e.set(new Uint8Array(t)),e.buffer}function p(){return this.bodyUsed=!1,this._initBody=function(t){if(this._bodyInit=t,t)if("string"==typeof t)this._bodyText=t;else if(e.blob&&Blob.prototype.isPrototypeOf(t))this._bodyBlob=t;else if(e.formData&&FormData.prototype.isPrototypeOf(t))this._bodyFormData=t;else if(e.searchParams&&URLSearchParams.prototype.isPrototypeOf(t))this._bodyText=t.toString();else if(e.arrayBuffer&&e.blob&&n(t))this._bodyArrayBuffer=y(t.buffer),this._bodyInit=new Blob([this._bodyArrayBuffer]);else{if(!e.arrayBuffer||!ArrayBuffer.prototype.isPrototypeOf(t)&&!o(t))throw new Error("unsupported BodyInit type");this._bodyArrayBuffer=y(t)}else this._bodyText="";this.headers.get("content-type")||("string"==typeof t?this.headers.set("content-type","text/plain;charset=UTF-8"):this._bodyBlob&&this._bodyBlob.type?this.headers.set("content-type",this._bodyBlob.type):e.searchParams&&URLSearchParams.prototype.isPrototypeOf(t)&&this.headers.set("content-type","application/x-www-form-urlencoded;charset=UTF-8"))},e.blob&&(this.blob=function(){var t=l(this);if(t)return t;if(this._bodyBlob)return Promise.resolve(this._bodyBlob);if(this._bodyArrayBuffer)return Promise.resolve(new Blob([this._bodyArrayBuffer]));if(this._bodyFormData)throw new Error("could not read FormData body as blob");return Promise.resolve(new Blob([this._bodyText]))},this.arrayBuffer=function(){return this._bodyArrayBuffer?l(this)||Promise.resolve(this._bodyArrayBuffer):this.blob().then(d)}),this.text=function(){var t=l(this);if(t)return t;if(this._bodyBlob)return function(t){var e=new FileReader,r=h(e);return e.readAsText(t),r}(this._bodyBlob);if(this._bodyArrayBuffer)return Promise.resolve(function(t){for(var e=new Uint8Array(t),r=new Array(e.length),n=0;n<e.length;n++)r[n]=String.fromCharCode(e[n]);return r.join("")}(this._bodyArrayBuffer));if(this._bodyFormData)throw new Error("could not read FormData body as text");return Promise.resolve(this._bodyText)},e.formData&&(this.formData=function(){return this.text().then(m)}),this.json=function(){return this.text().then(JSON.parse)},this}function b(t,e){var r=(e=e||{}).body;if(t instanceof b){if(t.bodyUsed)throw new TypeError("Already read");this.url=t.url,this.credentials=t.credentials,e.headers||(this.headers=new f(t.headers)),this.method=t.method,this.mode=t.mode,r||null==t._bodyInit||(r=t._bodyInit,t.bodyUsed=!0)}else this.url=String(t);if(this.credentials=e.credentials||this.credentials||"omit",!e.headers&&this.headers||(this.headers=new f(e.headers)),this.method=function(t){var e=t.toUpperCase();return s.indexOf(e)>-1?e:t}(e.method||this.method||"GET"),this.mode=e.mode||this.mode||null,this.referrer=null,("GET"===this.method||"HEAD"===this.method)&&r)throw new TypeError("Body not allowed for GET or HEAD requests");this._initBody(r)}function m(t){var e=new FormData;return t.trim().split("&").forEach(function(t){if(t){var r=t.split("="),n=r.shift().replace(/\+/g," "),o=r.join("=").replace(/\+/g," ");e.append(decodeURIComponent(n),decodeURIComponent(o))}}),e}function v(t,e){e||(e={}),this.type="default",this.status="status"in e?e.status:200,this.ok=this.status>=200&&this.status<300,this.statusText="statusText"in e?e.statusText:"OK",this.headers=new f(e.headers),this.url=e.url||"",this._initBody(t)}}("undefined"!=typeof self?self:this)},function(t,e,r){r(2),t.exports=r(1)},,,,,function(t,e){}]);
vendor/otgs/installer/dist/js/ui/app.js DELETED
@@ -1 +0,0 @@
1
- !function(t){var e={};function r(n){if(e[n])return e[n].exports;var o=e[n]={i:n,l:!1,exports:{}};return t[n].call(o.exports,o,o.exports,r),o.l=!0,o.exports}r.m=t,r.c=e,r.d=function(t,e,n){r.o(t,e)||Object.defineProperty(t,e,{configurable:!1,enumerable:!0,get:n})},r.r=function(t){Object.defineProperty(t,"__esModule",{value:!0})},r.n=function(t){var e=t&&t.__esModule?function(){return t.default}:function(){return t};return r.d(e,"a",e),e},r.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},r.p="",r(r.s=4)}([function(t,e,r){"use strict";Object.defineProperty(e,"__esModule",{value:!0});e.default=function t(e){!function(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}(this,t);var r=e.parentElement,n=r.getElementsByClassName("heading"),o=r.getElementsByTagName("label").item(0);o&&o.classList.add("otgs-on-off-switch");var i=document.createElement("label");i.classList.add("otgs-toggle-group"),i.appendChild(e),i.appendChild(o);var s=document.createElement("span");s.classList.add("otgs-switch__onoff");var a=document.createElement("span");a.classList.add("otgs-switch__onoff-label");var u=document.createElement("span");u.classList.add("otgs-switch__onoff-inner");var f=document.createElement("span");f.classList.add("otgs-switch__onoff-switch"),a.appendChild(u),a.appendChild(f),s.appendChild(a),i.appendChild(s),r.appendChild(i),n.length?n.item(n.length-1).parentNode.insertBefore(i,n.item(n.length-1).nextSibling):r.insertBefore(i,r.firstChild)}},function(t,e,r){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),r(9);var n,o=r(0),i=(n=o)&&n.__esModule?n:{default:n};e.default=function t(e){!function(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}(this,t);var r=e.querySelectorAll('input[type="checkbox"]');r&&Array.from(r).map(function(t){return new i.default(t)})}},function(t,e,r){"use strict";var n,o=r(1),i=(n=o)&&n.__esModule?n:{default:n};window.addEventListener("DOMContentLoaded",function(){var t=document.querySelectorAll(".otgs-ui");t&&Array.from(t).map(function(t){return new i.default(t)})})},function(t,e){!function(t){"use strict";if(!t.fetch){var e={searchParams:"URLSearchParams"in t,iterable:"Symbol"in t&&"iterator"in Symbol,blob:"FileReader"in t&&"Blob"in t&&function(){try{return new Blob,!0}catch(t){return!1}}(),formData:"FormData"in t,arrayBuffer:"ArrayBuffer"in t};if(e.arrayBuffer)var r=["[object Int8Array]","[object Uint8Array]","[object Uint8ClampedArray]","[object Int16Array]","[object Uint16Array]","[object Int32Array]","[object Uint32Array]","[object Float32Array]","[object Float64Array]"],n=function(t){return t&&DataView.prototype.isPrototypeOf(t)},o=ArrayBuffer.isView||function(t){return t&&r.indexOf(Object.prototype.toString.call(t))>-1};d.prototype.append=function(t,e){t=a(t),e=u(e);var r=this.map[t];this.map[t]=r?r+","+e:e},d.prototype.delete=function(t){delete this.map[a(t)]},d.prototype.get=function(t){return t=a(t),this.has(t)?this.map[t]:null},d.prototype.has=function(t){return this.map.hasOwnProperty(a(t))},d.prototype.set=function(t,e){this.map[a(t)]=u(e)},d.prototype.forEach=function(t,e){for(var r in this.map)this.map.hasOwnProperty(r)&&t.call(e,this.map[r],r,this)},d.prototype.keys=function(){var t=[];return this.forEach(function(e,r){t.push(r)}),f(t)},d.prototype.values=function(){var t=[];return this.forEach(function(e){t.push(e)}),f(t)},d.prototype.entries=function(){var t=[];return this.forEach(function(e,r){t.push([r,e])}),f(t)},e.iterable&&(d.prototype[Symbol.iterator]=d.prototype.entries);var i=["DELETE","GET","HEAD","OPTIONS","POST","PUT"];b.prototype.clone=function(){return new b(this,{body:this._bodyInit})},y.call(b.prototype),y.call(w.prototype),w.prototype.clone=function(){return new w(this._bodyInit,{status:this.status,statusText:this.statusText,headers:new d(this.headers),url:this.url})},w.error=function(){var t=new w(null,{status:0,statusText:""});return t.type="error",t};var s=[301,302,303,307,308];w.redirect=function(t,e){if(-1===s.indexOf(e))throw new RangeError("Invalid status code");return new w(null,{status:e,headers:{location:t}})},t.Headers=d,t.Request=b,t.Response=w,t.fetch=function(t,r){return new Promise(function(n,o){var i=new b(t,r),s=new XMLHttpRequest;s.onload=function(){var t,e,r={status:s.status,statusText:s.statusText,headers:(t=s.getAllResponseHeaders()||"",e=new d,t.split(/\r?\n/).forEach(function(t){var r=t.split(":"),n=r.shift().trim();if(n){var o=r.join(":").trim();e.append(n,o)}}),e)};r.url="responseURL"in s?s.responseURL:r.headers.get("X-Request-URL");var o="response"in s?s.response:s.responseText;n(new w(o,r))},s.onerror=function(){o(new TypeError("Network request failed"))},s.ontimeout=function(){o(new TypeError("Network request failed"))},s.open(i.method,i.url,!0),"include"===i.credentials&&(s.withCredentials=!0),"responseType"in s&&e.blob&&(s.responseType="blob"),i.headers.forEach(function(t,e){s.setRequestHeader(e,t)}),s.send(void 0===i._bodyInit?null:i._bodyInit)})},t.fetch.polyfill=!0}function a(t){if("string"!=typeof t&&(t=String(t)),/[^a-z0-9\-#$%&'*+.\^_`|~]/i.test(t))throw new TypeError("Invalid character in header field name");return t.toLowerCase()}function u(t){return"string"!=typeof t&&(t=String(t)),t}function f(t){var r={next:function(){var e=t.shift();return{done:void 0===e,value:e}}};return e.iterable&&(r[Symbol.iterator]=function(){return r}),r}function d(t){this.map={},t instanceof d?t.forEach(function(t,e){this.append(e,t)},this):Array.isArray(t)?t.forEach(function(t){this.append(t[0],t[1])},this):t&&Object.getOwnPropertyNames(t).forEach(function(e){this.append(e,t[e])},this)}function h(t){if(t.bodyUsed)return Promise.reject(new TypeError("Already read"));t.bodyUsed=!0}function l(t){return new Promise(function(e,r){t.onload=function(){e(t.result)},t.onerror=function(){r(t.error)}})}function c(t){var e=new FileReader,r=l(e);return e.readAsArrayBuffer(t),r}function p(t){if(t.slice)return t.slice(0);var e=new Uint8Array(t.byteLength);return e.set(new Uint8Array(t)),e.buffer}function y(){return this.bodyUsed=!1,this._initBody=function(t){if(this._bodyInit=t,t)if("string"==typeof t)this._bodyText=t;else if(e.blob&&Blob.prototype.isPrototypeOf(t))this._bodyBlob=t;else if(e.formData&&FormData.prototype.isPrototypeOf(t))this._bodyFormData=t;else if(e.searchParams&&URLSearchParams.prototype.isPrototypeOf(t))this._bodyText=t.toString();else if(e.arrayBuffer&&e.blob&&n(t))this._bodyArrayBuffer=p(t.buffer),this._bodyInit=new Blob([this._bodyArrayBuffer]);else{if(!e.arrayBuffer||!ArrayBuffer.prototype.isPrototypeOf(t)&&!o(t))throw new Error("unsupported BodyInit type");this._bodyArrayBuffer=p(t)}else this._bodyText="";this.headers.get("content-type")||("string"==typeof t?this.headers.set("content-type","text/plain;charset=UTF-8"):this._bodyBlob&&this._bodyBlob.type?this.headers.set("content-type",this._bodyBlob.type):e.searchParams&&URLSearchParams.prototype.isPrototypeOf(t)&&this.headers.set("content-type","application/x-www-form-urlencoded;charset=UTF-8"))},e.blob&&(this.blob=function(){var t=h(this);if(t)return t;if(this._bodyBlob)return Promise.resolve(this._bodyBlob);if(this._bodyArrayBuffer)return Promise.resolve(new Blob([this._bodyArrayBuffer]));if(this._bodyFormData)throw new Error("could not read FormData body as blob");return Promise.resolve(new Blob([this._bodyText]))},this.arrayBuffer=function(){return this._bodyArrayBuffer?h(this)||Promise.resolve(this._bodyArrayBuffer):this.blob().then(c)}),this.text=function(){var t,e,r,n=h(this);if(n)return n;if(this._bodyBlob)return t=this._bodyBlob,e=new FileReader,r=l(e),e.readAsText(t),r;if(this._bodyArrayBuffer)return Promise.resolve(function(t){for(var e=new Uint8Array(t),r=new Array(e.length),n=0;n<e.length;n++)r[n]=String.fromCharCode(e[n]);return r.join("")}(this._bodyArrayBuffer));if(this._bodyFormData)throw new Error("could not read FormData body as text");return Promise.resolve(this._bodyText)},e.formData&&(this.formData=function(){return this.text().then(m)}),this.json=function(){return this.text().then(JSON.parse)},this}function b(t,e){var r,n,o=(e=e||{}).body;if(t instanceof b){if(t.bodyUsed)throw new TypeError("Already read");this.url=t.url,this.credentials=t.credentials,e.headers||(this.headers=new d(t.headers)),this.method=t.method,this.mode=t.mode,o||null==t._bodyInit||(o=t._bodyInit,t.bodyUsed=!0)}else this.url=String(t);if(this.credentials=e.credentials||this.credentials||"omit",!e.headers&&this.headers||(this.headers=new d(e.headers)),this.method=(r=e.method||this.method||"GET",n=r.toUpperCase(),i.indexOf(n)>-1?n:r),this.mode=e.mode||this.mode||null,this.referrer=null,("GET"===this.method||"HEAD"===this.method)&&o)throw new TypeError("Body not allowed for GET or HEAD requests");this._initBody(o)}function m(t){var e=new FormData;return t.trim().split("&").forEach(function(t){if(t){var r=t.split("="),n=r.shift().replace(/\+/g," "),o=r.join("=").replace(/\+/g," ");e.append(decodeURIComponent(n),decodeURIComponent(o))}}),e}function w(t,e){e||(e={}),this.type="default",this.status="status"in e?e.status:200,this.ok=this.status>=200&&this.status<300,this.statusText="statusText"in e?e.statusText:"OK",this.headers=new d(e.headers),this.url=e.url||"",this._initBody(t)}}("undefined"!=typeof self?self:this)},function(t,e,r){r(3),t.exports=r(2)},,,,,function(t,e){}]);
 
vendor/otgs/installer/includes/buy-url/class-otgs-installer-buy-url-hooks.php ADDED
@@ -0,0 +1,25 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class OTGS_Installer_Buy_URL_Hooks {
4
+
5
+ private $embedded_at;
6
+
7
+ public function __construct( $embedded_at ) {
8
+ $this->embedded_at = $embedded_at;
9
+ }
10
+
11
+ public function add_hooks() {
12
+ add_filter( 'wp_installer_buy_url', array( $this, 'append_installer_source' ) );
13
+ }
14
+
15
+ /**
16
+ * @param string $url
17
+ *
18
+ * @return string
19
+ */
20
+ public function append_installer_source( $url ) {
21
+ $url = add_query_arg( 'embedded_at', $this->embedded_at, $url );
22
+
23
+ return $url;
24
+ }
25
+ }
vendor/otgs/installer/includes/class-installer-dependencies.php CHANGED
@@ -5,6 +5,7 @@ class Installer_Dependencies {
5
  private $uploading_allowed = null;
6
  private $is_win_paths_exception = array();
7
 
 
8
 
9
  function __construct() {
10
 
@@ -284,6 +285,37 @@ class Installer_Dependencies {
284
 
285
  }
286
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
287
 
288
  }
289
 
5
  private $uploading_allowed = null;
6
  private $is_win_paths_exception = array();
7
 
8
+ private $missing_php_libraries = array();
9
 
10
  function __construct() {
11
 
285
 
286
  }
287
 
288
+ public function php_libraries_missing() {
289
+ $requirements = new OTGS_Installer_Requirements();
290
+
291
+ foreach ( $requirements->get() as $requirement ) {
292
+ if ( ! $requirement['active'] ) {
293
+ $this->missing_php_libraries[] = $requirement['name'];
294
+ }
295
+ }
296
+ if ( $this->missing_php_libraries ) {
297
+ add_action( 'admin_notices', array( $this, 'missing_php_functions_notice' ) );
298
+ }
299
+ }
300
+
301
+ public function missing_php_functions_notice() {
302
+ $installer_doc_url = 'https://wpml.org/?p=72674#automated-updates';
303
+ $installer_doc_link = '<a href="' . $installer_doc_url . '">' . __( 'OTGS Installer', 'installer' ) . '</a>';
304
+
305
+ echo '<div class="updated error">';
306
+ echo '<p>';
307
+ echo sprintf(
308
+ __( '%s, responsible for receiving automated updates for WPML and Toolset, requires the following PHP component(s) in order to function:', 'installer' ),
309
+ $installer_doc_link
310
+ );
311
+ echo '<code>' . join( ', ', $this->missing_php_libraries ) . '</code>';
312
+ echo '</p>';
313
+
314
+ $minimum_requirements_link = '<a href="https://wpml.org/?page_id=716">' . __( 'Minimum WPML requirements' ) . '</a>';
315
+ echo '<p>' . sprintf( __( 'Learn more: %s', 'installer' ), $minimum_requirements_link ) . '</p>';
316
+
317
+ echo '</div>';
318
+ }
319
 
320
  }
321
 
vendor/otgs/installer/includes/class-otgs-installer-autoloader.php ADDED
@@ -0,0 +1,20 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class OTGS_Installer_Autoloader {
4
+
5
+ public function initialize() {
6
+ include_once dirname( __FILE__ ) . '/functions-core.php';
7
+ include_once dirname( __FILE__ ) . '/functions-templates.php';
8
+
9
+ spl_autoload_register( array( $this, 'autoload' ) );
10
+ }
11
+
12
+ public function autoload( $class_name ) {
13
+ $classMap = require dirname( __FILE__ ) . '/otgs-installer-autoload-classmap.php';
14
+
15
+ if ( array_key_exists( $class_name, $classMap ) ) {
16
+ $file = $classMap[ $class_name ];
17
+ include $file;
18
+ }
19
+ }
20
+ }
vendor/otgs/installer/includes/class-otgs-installer-debug-info.php ADDED
@@ -0,0 +1,43 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class OTGS_Installer_Debug_Info {
4
+ private $installer;
5
+
6
+ public function __construct( WP_Installer $installer ) {
7
+ $this->installer = $installer;
8
+ }
9
+
10
+ public function add_hooks() {
11
+ add_filter( 'icl_get_extra_debug_info', array( $this, 'add_installer_config_in_debug_information' ) );
12
+ }
13
+
14
+ /**
15
+ * @param array $data
16
+ *
17
+ * @return array
18
+ */
19
+ public function add_installer_config_in_debug_information( $data ) {
20
+ global $wp_installer_instances;
21
+
22
+ $repositories_data = array();
23
+ $repositories = $this->installer->get_repositories();
24
+ $repository_settings = $this->installer->get_settings();
25
+ $repository_settings = $repository_settings['repositories'];
26
+
27
+ foreach ( $repositories as $repo_id => $repository ) {
28
+ $repositories_data[ $repo_id ] = array(
29
+ 'api-url' => $repository['api-url'],
30
+ 'products' => $repository['products'],
31
+ 'subscription' => isset( $repository_settings[ $repo_id ]['subscription'] ) ? $repository_settings[ $repo_id ]['subscription'] : '',
32
+ );
33
+ }
34
+
35
+ $data['installer'] = array(
36
+ 'version' => $this->installer->version(),
37
+ 'repositories' => $repositories_data,
38
+ 'instances' => $wp_installer_instances,
39
+ );
40
+
41
+ return $data;
42
+ }
43
+ }
vendor/otgs/installer/includes/class-otgs-installer-factory.php CHANGED
@@ -1,8 +1,5 @@
1
  <?php
2
 
3
- /**
4
- * @author OnTheGo Systems
5
- */
6
  class OTGS_Installer_Factory {
7
 
8
  private $installer;
@@ -15,6 +12,10 @@ class OTGS_Installer_Factory {
15
  private $wp_components_hooks;
16
  private $wp_components_sender;
17
  private $wp_components_storage;
 
 
 
 
18
 
19
  public function __construct( WP_Installer $installer ) {
20
  $this->installer = $installer;
@@ -31,6 +32,13 @@ class OTGS_Installer_Factory {
31
  return $this->filename_hooks;
32
  }
33
 
 
 
 
 
 
 
 
34
  /**
35
  * @return OTGS_Installer_Icons
36
  */
@@ -42,26 +50,60 @@ class OTGS_Installer_Factory {
42
  return $this->icons;
43
  }
44
 
 
 
 
 
 
 
 
45
  /**
46
  * @return OTGS_Installer_WP_Components_Setting_Ajax
47
  */
48
  public function create_local_components_ajax_setting() {
49
  if ( ! $this->local_components_ajax_setting ) {
50
  $this->local_components_ajax_setting = new OTGS_Installer_WP_Components_Setting_Ajax( $this->create_settings(),
51
- $this->get_installer() );
52
  }
53
 
54
  return $this->local_components_ajax_setting;
55
  }
56
 
 
 
 
 
 
 
 
 
 
 
57
  public function create_resources() {
58
  return new OTGS_Installer_WP_Components_Setting_Resources( $this->get_installer() );
59
  }
60
 
 
 
 
 
 
 
 
 
 
 
61
  public function create_settings_hooks() {
62
  return new OTGS_Installer_WP_Share_Local_Components_Setting_Hooks( $this->create_template_service_loader()
63
  ->get_service(),
64
- $this->create_settings() );
 
 
 
 
 
 
 
65
  }
66
 
67
  /**
@@ -70,10 +112,10 @@ class OTGS_Installer_Factory {
70
  private function create_template_service_loader() {
71
  if ( ! $this->template_service_loader ) {
72
  $this->template_service_loader = new OTGS_Installer_Twig_Template_Service_Loader( array(
73
- $this->get_installer()
74
- ->plugin_path()
75
- . '/templates/components-setting/'
76
- ) );
77
  }
78
 
79
  return $this->template_service_loader;
@@ -82,7 +124,7 @@ class OTGS_Installer_Factory {
82
  /**
83
  * @return OTGS_Installer_WP_Share_Local_Components_Setting
84
  */
85
- public function create_settings() {
86
  if ( ! $this->settings ) {
87
  $this->settings = new OTGS_Installer_WP_Share_Local_Components_Setting();
88
  }
@@ -96,14 +138,21 @@ class OTGS_Installer_Factory {
96
  public function create_wp_components_hooks() {
97
  if ( ! $this->wp_components_hooks ) {
98
  $this->wp_components_hooks = new OTGS_Installer_WP_Components_Hooks( $this->create_wp_components_storage(),
99
- $this->create_wp_components_sender(),
100
- $this->create_settings(),
101
- $this->create_installer_php_functions() );
102
  }
103
 
104
  return $this->wp_components_hooks;
105
  }
106
 
 
 
 
 
 
 
 
107
  /**
108
  * @return OTGS_Installer_WP_Components_Storage
109
  */
@@ -121,7 +170,7 @@ class OTGS_Installer_Factory {
121
  public function create_wp_components_sender() {
122
  if ( ! $this->wp_components_sender ) {
123
  $this->wp_components_sender = new OTGS_Installer_WP_Components_Sender( $this->get_installer(),
124
- $this->create_settings() );
125
  }
126
 
127
  return $this->wp_components_sender;
@@ -138,6 +187,154 @@ class OTGS_Installer_Factory {
138
  return $this->installer_php_functions;
139
  }
140
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
141
  /**
142
  * @return WP_Installer
143
  */
1
  <?php
2
 
 
 
 
3
  class OTGS_Installer_Factory {
4
 
5
  private $installer;
12
  private $wp_components_hooks;
13
  private $wp_components_sender;
14
  private $wp_components_storage;
15
+ private $upgrade_response;
16
+ private $plugin_finder;
17
+ private $plugin_factory;
18
+ private $repositories;
19
 
20
  public function __construct( WP_Installer $installer ) {
21
  $this->installer = $installer;
32
  return $this->filename_hooks;
33
  }
34
 
35
+ public function load_filename_hooks() {
36
+ $filename_hooks = $this->create_filename_hooks();
37
+ $filename_hooks->add_hooks();
38
+
39
+ return $this;
40
+ }
41
+
42
  /**
43
  * @return OTGS_Installer_Icons
44
  */
50
  return $this->icons;
51
  }
52
 
53
+ public function load_icons() {
54
+ $icons = $this->create_icons();
55
+ $icons->add_hooks();
56
+
57
+ return $this;
58
+ }
59
+
60
  /**
61
  * @return OTGS_Installer_WP_Components_Setting_Ajax
62
  */
63
  public function create_local_components_ajax_setting() {
64
  if ( ! $this->local_components_ajax_setting ) {
65
  $this->local_components_ajax_setting = new OTGS_Installer_WP_Components_Setting_Ajax( $this->create_settings(),
66
+ $this->get_installer() );
67
  }
68
 
69
  return $this->local_components_ajax_setting;
70
  }
71
 
72
+ public function load_local_components_ajax_settings() {
73
+ $settings = $this->create_local_components_ajax_setting();
74
+ $settings->add_hooks();
75
+
76
+ return $this;
77
+ }
78
+
79
+ /**
80
+ * @return OTGS_Installer_WP_Components_Setting_Resources
81
+ */
82
  public function create_resources() {
83
  return new OTGS_Installer_WP_Components_Setting_Resources( $this->get_installer() );
84
  }
85
 
86
+ public function load_resources() {
87
+ $resources = $this->create_resources();
88
+ $resources->add_hooks();
89
+
90
+ return $this;
91
+ }
92
+
93
+ /**
94
+ * @return OTGS_Installer_WP_Share_Local_Components_Setting_Hooks
95
+ */
96
  public function create_settings_hooks() {
97
  return new OTGS_Installer_WP_Share_Local_Components_Setting_Hooks( $this->create_template_service_loader()
98
  ->get_service(),
99
+ $this->create_settings() );
100
+ }
101
+
102
+ public function load_settings_hooks() {
103
+ $settings_hooks = $this->create_settings_hooks();
104
+ $settings_hooks->add_hooks();
105
+
106
+ return $this;
107
  }
108
 
109
  /**
112
  private function create_template_service_loader() {
113
  if ( ! $this->template_service_loader ) {
114
  $this->template_service_loader = new OTGS_Installer_Twig_Template_Service_Loader( array(
115
+ $this->get_installer()
116
+ ->plugin_path()
117
+ . '/templates/components-setting/'
118
+ ) );
119
  }
120
 
121
  return $this->template_service_loader;
124
  /**
125
  * @return OTGS_Installer_WP_Share_Local_Components_Setting
126
  */
127
+ private function create_settings() {
128
  if ( ! $this->settings ) {
129
  $this->settings = new OTGS_Installer_WP_Share_Local_Components_Setting();
130
  }
138
  public function create_wp_components_hooks() {
139
  if ( ! $this->wp_components_hooks ) {
140
  $this->wp_components_hooks = new OTGS_Installer_WP_Components_Hooks( $this->create_wp_components_storage(),
141
+ $this->create_wp_components_sender(),
142
+ $this->create_settings(),
143
+ $this->create_installer_php_functions() );
144
  }
145
 
146
  return $this->wp_components_hooks;
147
  }
148
 
149
+ public function load_wp_components_hooks() {
150
+ $wp_components_hooks = $this->create_wp_components_hooks();
151
+ $wp_components_hooks->add_hooks();
152
+
153
+ return $this;
154
+ }
155
+
156
  /**
157
  * @return OTGS_Installer_WP_Components_Storage
158
  */
170
  public function create_wp_components_sender() {
171
  if ( ! $this->wp_components_sender ) {
172
  $this->wp_components_sender = new OTGS_Installer_WP_Components_Sender( $this->get_installer(),
173
+ $this->create_settings() );
174
  }
175
 
176
  return $this->wp_components_sender;
187
  return $this->installer_php_functions;
188
  }
189
 
190
+ /**
191
+ * @return OTGS_Installer_Debug_Info
192
+ */
193
+ public function create_debug_info_hook() {
194
+ return new OTGS_Installer_Debug_Info( $this->get_installer() );
195
+ }
196
+
197
+ public function load_debug_info_hooks() {
198
+ $debug_info = $this->create_debug_info_hook();
199
+ $debug_info->add_hooks();
200
+
201
+ return $this;
202
+ }
203
+
204
+ /**
205
+ * @return OTGS_Installer_Plugin_Factory
206
+ */
207
+ public function get_plugin_factory() {
208
+ if ( ! $this->plugin_factory ) {
209
+ $this->plugin_factory = new OTGS_Installer_Plugin_Factory();
210
+ }
211
+
212
+ return $this->plugin_factory;
213
+ }
214
+
215
+ /**
216
+ * @return OTGS_Installer_Plugin_Finder
217
+ */
218
+ public function get_plugin_finder() {
219
+ if ( ! $this->plugin_finder ) {
220
+ $settings = $this->get_installer()->get_settings();
221
+ $this->plugin_finder = new OTGS_Installer_Plugin_Finder( $this->get_plugin_factory(), $settings['repositories'] );
222
+ }
223
+
224
+ return $this->plugin_finder;
225
+ }
226
+
227
+ /**
228
+ * @return OTGS_Installer_Upgrade_Response
229
+ */
230
+ public function create_upgrade_response() {
231
+ if ( ! $this->upgrade_response ) {
232
+ $this->upgrade_response = new OTGS_Installer_Upgrade_Response(
233
+ $this->get_plugin_finder()->get_all(),
234
+ $this->get_repositories(),
235
+ new OTGS_Installer_Source_Factory(),
236
+ new OTGS_Installer_Package_Product_Finder()
237
+ );
238
+ }
239
+
240
+ return $this->upgrade_response;
241
+ }
242
+
243
+ public function load_upgrade_response() {
244
+ $upgrade_response = $this->create_upgrade_response();
245
+ $upgrade_response->add_hooks();
246
+
247
+ return $this;
248
+ }
249
+
250
+ /**
251
+ * @return OTGS_Installer_Site_Key_Ajax
252
+ */
253
+ public function create_site_key_ajax_handler() {
254
+ $logger = new OTGS_Installer_Logger(
255
+ $this->installer,
256
+ new OTGS_Installer_Logger_Storage( new OTGS_Installer_Log_Factory() )
257
+ );
258
+
259
+ $fetch_subscription = new OTGS_Installer_Fetch_Subscription(
260
+ new OTGS_Installer_Source_Factory(),
261
+ $this->get_plugin_finder(),
262
+ $this->get_repositories(),
263
+ $logger,
264
+ new OTGS_Installer_Log_Factory()
265
+ );
266
+
267
+ return new OTGS_Installer_Site_Key_Ajax(
268
+ $fetch_subscription,
269
+ $logger,
270
+ $this->get_repositories(),
271
+ new OTGS_Installer_Subscription_Factory()
272
+ );
273
+ }
274
+
275
+ public function load_site_key_ajax_handler() {
276
+ $site_key_ajax_handler = $this->create_site_key_ajax_handler();
277
+ $site_key_ajax_handler->add_hooks();
278
+
279
+ return $this;
280
+ }
281
+
282
+ public function load_installer_support_hooks() {
283
+ $support_hooks = new OTGS_Installer_Support_Hooks( new OTGS_Installer_Support_Template_Factory( $this->get_installer()->plugin_path() ) );
284
+ $support_hooks->add_hooks();
285
+
286
+ if ( defined( 'DOING_AJAX' ) && DOING_AJAX ) {
287
+ $support_ajax = new OTGS_Installer_Connection_Test_Ajax(
288
+ new OTGS_Installer_Connection_Test(
289
+ $this->get_repositories(),
290
+ $this->create_upgrade_response(),
291
+ new OTGS_Installer_Logger_Storage( new OTGS_Installer_Log_Factory() ),
292
+ new OTGS_Installer_Log_Factory()
293
+ )
294
+ );
295
+
296
+ $support_ajax->add_hooks();
297
+ }
298
+
299
+ return $this;
300
+ }
301
+
302
+ public function load_translation_service_info_hooks() {
303
+ $translation_services = new Translation_Service_Info();
304
+ $translation_services->add_hooks();
305
+
306
+ return $this;
307
+ }
308
+ /**
309
+ * @return OTGS_Installer_Repositories
310
+ */
311
+ private function get_repositories() {
312
+ if ( ! $this->repositories ) {
313
+ $repositories_factory = new OTGS_Installer_Repositories_Factory( $this->get_installer() );
314
+ $this->repositories = $repositories_factory->create( $this->installer );
315
+ }
316
+
317
+ return $this->repositories;
318
+ }
319
+
320
+
321
+ /**
322
+ * @return $this
323
+ */
324
+ public function load_plugins_update_cache_cleaner() {
325
+ $plugins_update_cache_cleaner = new OTGS_Installer_Plugins_Update_Cache_Cleaner();
326
+ $plugins_update_cache_cleaner->add_hooks();
327
+
328
+ return $this;
329
+ }
330
+
331
+ public function load_buy_url_hooks() {
332
+ $buy_url = new OTGS_Installer_Buy_URL_Hooks( $this->installer->get_embedded_at() );
333
+ $buy_url->add_hooks();
334
+
335
+ return $this;
336
+ }
337
+
338
  /**
339
  * @return WP_Installer
340
  */
vendor/otgs/installer/includes/class-otgs-installer-icons.php CHANGED
@@ -12,7 +12,7 @@ class OTGS_Installer_Icons {
12
  }
13
 
14
  public function add_hooks() {
15
- add_filter( 'otgs_installer_upgrade_check_response', array( $this, 'add_icons_on_response' ), 10, 3 );
16
  }
17
 
18
  /**
@@ -21,12 +21,24 @@ class OTGS_Installer_Icons {
21
  *
22
  * @return stdClass
23
  */
24
- public function add_icons_on_response( $response, $name, $repository ) {
25
- $product = isset( $this->installer->settings['repositories'][ $repository ]['data']['products-map'][ $name ] )
26
- ? $this->installer->settings['repositories'][ $repository ]['data']['products-map'][ $name ]
27
- : '';
28
 
29
- if ( $product ) {
 
 
 
 
 
 
 
 
 
 
 
 
30
  $base = $this->installer->plugin_url() . '/../icons/plugin-icons/' . $repository . '/' . $product . '/icon';
31
  $response->icons = array(
32
  'svg' => $base . '.svg',
12
  }
13
 
14
  public function add_hooks() {
15
+ add_filter( 'otgs_installer_upgrade_check_response', array( $this, 'add_icons_on_response' ), 10, 2 );
16
  }
17
 
18
  /**
21
  *
22
  * @return stdClass
23
  */
24
+ public function add_icons_on_response( $response, $name ) {
25
+ $repositories = array_keys( $this->installer->get_repositories() );
26
+ $product = '';
27
+ $repository = '';
28
 
29
+ foreach( $repositories as $repository_id ) {
30
+ if ( isset( $this->installer->settings['repositories'][ $repository_id ]['data']['products-map'][ $response->plugin ] ) ) {
31
+ $product = $this->installer->settings['repositories'][ $repository_id ]['data']['products-map'][ $response->plugin ];
32
+ $repository = $repository_id;
33
+ break;
34
+ } elseif ( isset( $this->installer->settings['repositories'][ $repository_id ]['data']['products-map'][ $name ] ) ) {
35
+ $product = $this->installer->settings['repositories'][ $repository_id ]['data']['products-map'][ $name ];
36
+ $repository = $repository_id;
37
+ break;
38
+ }
39
+ }
40
+
41
+ if ( $product && $repository ) {
42
  $base = $this->installer->plugin_url() . '/../icons/plugin-icons/' . $repository . '/' . $product . '/icon';
43
  $response->icons = array(
44
  'svg' => $base . '.svg',
vendor/otgs/installer/includes/class-otgs-installer-loader.php ADDED
@@ -0,0 +1,32 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class OTGS_Installer_Loader {
4
+
5
+ private $installer_factory;
6
+
7
+ public function __construct( OTGS_Installer_Factory $installer_factory ) {
8
+ $this->installer_factory = $installer_factory;
9
+ }
10
+
11
+ public function init() {
12
+ $this->installer_factory->load_wp_components_hooks();
13
+
14
+ add_action( 'otgs_installer_initialized', array( $this, 'load_actions_after_installer_init' ) );
15
+ }
16
+
17
+ public function load_actions_after_installer_init() {
18
+ $this->installer_factory
19
+ ->load_resources()
20
+ ->load_settings_hooks()
21
+ ->load_local_components_ajax_settings()
22
+ ->load_filename_hooks()
23
+ ->load_icons()
24
+ ->load_debug_info_hooks()
25
+ ->load_upgrade_response()
26
+ ->load_site_key_ajax_handler()
27
+ ->load_installer_support_hooks()
28
+ ->load_translation_service_info_hooks()
29
+ ->load_plugins_update_cache_cleaner()
30
+ ->load_buy_url_hooks();
31
+ }
32
+ }
vendor/otgs/installer/includes/class-otgs-installer-package-product-finder.php ADDED
@@ -0,0 +1,32 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class OTGS_Installer_Package_Product_Finder {
4
+
5
+ /**
6
+ * @param OTGS_Installer_Repository $repository
7
+ * @param OTGS_Installer_Subscription $subscription
8
+ *
9
+ * @return null|OTGS_Installer_Package_Product
10
+ */
11
+ public function get_product_in_repository_by_subscription( OTGS_Installer_Repository $repository, OTGS_Installer_Subscription $subscription = null ) {
12
+ $product = null;
13
+
14
+ if ( ! $subscription ) {
15
+ $subscription = $repository->get_subscription();
16
+ }
17
+ if ( $subscription ) {
18
+ $type = $subscription->get_type();
19
+ $product = $repository->get_product_by_subscription_type( $type );
20
+
21
+ if ( ! $product ) {
22
+ $product = $repository->get_product_by_subscription_type_equivalent( $type );
23
+
24
+ if ( ! $product ) {
25
+ $product = $repository->get_product_by_subscription_type_on_upgrades( $type );
26
+ }
27
+ }
28
+ }
29
+
30
+ return $product;
31
+ }
32
+ }
vendor/otgs/installer/includes/class-otgs-installer-package-product.php ADDED
@@ -0,0 +1,93 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class OTGS_Installer_Package_Product {
4
+
5
+ private $id;
6
+ private $name;
7
+ private $description;
8
+ private $price;
9
+ private $subscription_type;
10
+ private $subscription_type_text;
11
+ private $subscription_info;
12
+ private $subscription_type_equivalent;
13
+ private $url;
14
+ private $renewals;
15
+ private $upgrades;
16
+ private $plugins;
17
+ private $downloads;
18
+
19
+ public function __construct( array $params = array() ) {
20
+ foreach ( get_object_vars( $this ) as $property => $value ) {
21
+ if ( array_key_exists( $property, $params ) ) {
22
+ $this->$property = $params[ $property ];
23
+ }
24
+ }
25
+ }
26
+
27
+ public function get_id() {
28
+ return $this->id;
29
+ }
30
+
31
+ public function get_name() {
32
+ return $this->name;
33
+ }
34
+
35
+ public function get_description() {
36
+ return $this->description;
37
+ }
38
+
39
+ public function get_price() {
40
+ return $this->price;
41
+ }
42
+
43
+ public function get_subscription_type() {
44
+ return $this->subscription_type;
45
+ }
46
+
47
+ public function get_subscription_type_text() {
48
+ return $this->subscription_type_text;
49
+ }
50
+
51
+ public function get_subscription_info() {
52
+ return $this->subscription_info;
53
+ }
54
+
55
+ public function get_subscription_type_equivalent() {
56
+ return (int) $this->subscription_type_equivalent;
57
+ }
58
+
59
+ public function get_url() {
60
+ return $this->url;
61
+ }
62
+
63
+ public function get_renewals() {
64
+ return $this->renewals;
65
+ }
66
+
67
+ public function get_upgrades() {
68
+ return $this->upgrades;
69
+ }
70
+
71
+ public function get_plugins() {
72
+ return $this->plugins;
73
+ }
74
+
75
+ /**
76
+ * @param string $slug
77
+ *
78
+ * @return bool
79
+ */
80
+ public function is_plugin_registered( $slug ) {
81
+ foreach ( $this->plugins as $plugin ) {
82
+ if ( $slug === $plugin ) {
83
+ return true;
84
+ }
85
+ }
86
+
87
+ return false;
88
+ }
89
+
90
+ public function get_downloads() {
91
+ return $this->downloads;
92
+ }
93
+ }
vendor/otgs/installer/includes/class-otgs-installer-package.php ADDED
@@ -0,0 +1,81 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class OTGS_Installer_Package {
4
+
5
+ private $key;
6
+ private $id;
7
+ private $name;
8
+ private $description;
9
+ private $image_url;
10
+ private $order;
11
+ private $parent;
12
+ private $products = array();
13
+
14
+ public function __construct( array $params = array() ) {
15
+ foreach ( get_object_vars( $this ) as $property => $value ) {
16
+ if ( array_key_exists( $property, $params ) ) {
17
+ $this->$property = $params[ $property ];
18
+ }
19
+ }
20
+ }
21
+
22
+ public function get_key() {
23
+ return $this->key;
24
+ }
25
+
26
+ public function get_products() {
27
+ return $this->products;
28
+ }
29
+
30
+ public function get_product_by_subscription_type( $type ) {
31
+ return $this->get_product_by( 'get_subscription_type', $type );
32
+ }
33
+
34
+ public function get_product_by_subscription_type_equivalent( $type ) {
35
+ return $this->get_product_by( 'get_subscription_type_equivalent', $type );
36
+ }
37
+
38
+ public function get_product_by( $function, $type ) {
39
+ foreach ( $this->products as $product ) {
40
+ if ( $type === $product->$function() ) {
41
+ return $product;
42
+ }
43
+ }
44
+ return null;
45
+ }
46
+
47
+ public function get_product_by_subscription_type_on_upgrades( $type ) {
48
+ foreach ( $this->products as $product ) {
49
+ foreach ( $product->get_upgrades() as $upgrade ) {
50
+ if ( $type === $upgrade['subscription_type'] ) {
51
+ return $product;
52
+ }
53
+ }
54
+ }
55
+ return null;
56
+ }
57
+
58
+ public function get_id() {
59
+ return $this->id;
60
+ }
61
+
62
+ public function get_name() {
63
+ return $this->name;
64
+ }
65
+
66
+ public function get_description() {
67
+ return $this->description;
68
+ }
69
+
70
+ public function get_image_url() {
71
+ return $this->image_url;
72
+ }
73
+
74
+ public function get_order() {
75
+ return $this->order;
76
+ }
77
+
78
+ public function get_parent() {
79
+ return $this->parent;
80
+ }
81
+ }
vendor/otgs/installer/includes/class-otgs-installer-plugin-factory.php ADDED
@@ -0,0 +1,13 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class OTGS_Installer_Plugin_Factory {
4
+
5
+ /**
6
+ * @param array $params
7
+ *
8
+ * @return OTGS_Installer_Plugin
9
+ */
10
+ public function create( array $params = array() ) {
11
+ return new OTGS_Installer_Plugin( $params );
12
+ }
13
+ }
vendor/otgs/installer/includes/class-otgs-installer-plugin-finder.php ADDED
@@ -0,0 +1,144 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class OTGS_Installer_Plugin_Finder {
4
+
5
+ /**
6
+ * @var array
7
+ */
8
+ private $plugins = array();
9
+ private $plugin_factory;
10
+ private $repositories;
11
+
12
+ /**
13
+ * @var array
14
+ */
15
+ private $installed_plugins;
16
+
17
+ public function __construct( OTGS_Installer_Plugin_Factory $plugin_factory, array $repositories ) {
18
+ $this->plugin_factory = $plugin_factory;
19
+ $this->repositories = $repositories;
20
+ $this->load();
21
+ }
22
+
23
+ private function load() {
24
+ if ( ! $this->plugins ) {
25
+ foreach ( $this->repositories as $repo_key => $repository ) {
26
+ foreach ( $repository['data']['downloads']['plugins'] as $slug => $plugin ) {
27
+ $plugin_id = $this->get_installed_plugin_id_by_slug( $plugin['slug'] );
28
+
29
+ if ( ! $plugin_id ) {
30
+ $plugin_id = $this->get_installed_plugin_id_by_name( $plugin['name'] );
31
+ }
32
+
33
+ $this->plugins[] = $this->plugin_factory->create( array(
34
+ 'name' => $plugin['name'],
35
+ 'slug' => $plugin['slug'],
36
+ 'description' => $plugin['description'],
37
+ 'changelog' => $plugin['changelog'],
38
+ 'version' => $plugin['version'],
39
+ 'installed_version' => isset( $this->installed_plugins[ $plugin_id ]['Version'] ) ? $this->installed_plugins[ $plugin_id ]['Version'] : null ,
40
+ 'date' => $plugin['date'],
41
+ 'url' => $plugin['url'],
42
+ 'free_on_wporg' => isset( $plugin['free-on-wporg'] ) ? $plugin['free-on-wporg'] : '',
43
+ 'fallback_on_wporg' => isset( $plugin['fallback-free-on-wporg'] ) ? $plugin['fallback-free-on-wporg'] : '',
44
+ 'basename' => $plugin['basename'],
45
+ 'external_repo' => isset( $plugin['external-repo'] ) ? $plugin['external-repo'] : '',
46
+ 'is_lite' => isset( $plugin['is-lite'] ) ? $plugin['is-lite'] : '',
47
+ 'repo' => $repo_key,
48
+ 'id' => $plugin_id,
49
+ 'channel' => $plugin['channel'],
50
+ ) );
51
+ }
52
+ }
53
+ }
54
+ }
55
+
56
+ /**
57
+ * @return OTGS_Installer_Plugin[]
58
+ */
59
+ public function get_all() {
60
+ return $this->plugins;
61
+ }
62
+
63
+ public function get_otgs_installed_plugins() {
64
+ $installed_plugins = array();
65
+
66
+ foreach ( $this->plugins as $plugin ) {
67
+ if ( $plugin->get_installed_version() ) {
68
+ $installed_plugins[] = $plugin;
69
+ }
70
+ }
71
+
72
+ return $installed_plugins;
73
+ }
74
+
75
+ /**
76
+ * @param string $slug
77
+ * @param string $repo
78
+ *
79
+ * @return null|OTGS_Installer_Plugin
80
+ */
81
+ public function get_plugin( $slug, $repo = '' ) {
82
+ foreach ( $this->plugins as $plugin ) {
83
+ if ( $slug === $plugin->get_slug() ) {
84
+
85
+ if ( ! $repo || $plugin->get_repo() === $repo ) {
86
+ return $plugin;
87
+ }
88
+ }
89
+ }
90
+
91
+ return null;
92
+ }
93
+
94
+ /**
95
+ * @param string $name
96
+ *
97
+ * @return null|OTGS_Installer_Plugin
98
+ */
99
+ public function get_plugin_by_name( $name ) {
100
+ foreach ( $this->plugins as $plugin ) {
101
+ if ( $name === strip_tags( $plugin->get_name() ) ) {
102
+ return $plugin;
103
+ }
104
+ }
105
+
106
+ return null;
107
+ }
108
+
109
+ /**
110
+ * @param $slug
111
+ *
112
+ * @return null|string
113
+ */
114
+ private function get_installed_plugin_id_by_slug( $slug ) {
115
+ foreach ( $this->get_installed_plugins() as $plugin_id => $plugin ) {
116
+ $plugin_slug = explode( '/', $plugin_id );
117
+
118
+ if ( $slug === $plugin_slug[0] ) {
119
+ return $plugin_id;
120
+ }
121
+ }
122
+
123
+ return null;
124
+ }
125
+
126
+ private function get_installed_plugins() {
127
+ if ( ! $this->installed_plugins ) {
128
+ $this->installed_plugins = get_plugins();
129
+ }
130
+
131
+ return $this->installed_plugins;
132
+ }
133
+
134
+ /**
135
+ * @param string $name
136
+ *
137
+ * @return string|null
138
+ */
139
+ private function get_installed_plugin_id_by_name( $name ) {
140
+ $plugin_id = array_keys( wp_list_filter( $this->get_installed_plugins(), array( 'Name' => $name ) ) );
141
+
142
+ return current( $plugin_id );
143
+ }
144
+ }
vendor/otgs/installer/includes/class-otgs-installer-plugin.php ADDED
@@ -0,0 +1,141 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class OTGS_Installer_Plugin {
4
+
5
+ private $name;
6
+ private $slug;
7
+ private $description;
8
+ private $changelog;
9
+ private $version;
10
+ private $date;
11
+ private $url;
12
+ private $free_on_wporg;
13
+ private $fallback_on_wporg;
14
+ private $basename;
15
+ private $external_repo;
16
+ private $is_lite;
17
+ private $repo;
18
+ private $id;
19
+ private $installed_version;
20
+ private $channel;
21
+
22
+ public function __construct( array $params = array() ) {
23
+ foreach ( get_object_vars( $this ) as $property => $value ) {
24
+ if ( array_key_exists( $property, $params ) ) {
25
+ $this->$property = $params[ $property ];
26
+ }
27
+ }
28
+ }
29
+
30
+ /**
31
+ * @return string
32
+ */
33
+ public function get_name() {
34
+ return $this->name;
35
+ }
36
+
37
+ /**
38
+ * @return string
39
+ */
40
+ public function get_slug() {
41
+ return $this->slug;
42
+ }
43
+
44
+ /**
45
+ * @return string
46
+ */
47
+ public function get_description() {
48
+ return $this->description;
49
+ }
50
+
51
+ /**
52
+ * @return string
53
+ */
54
+ public function get_changelog() {
55
+ return $this->changelog;
56
+ }
57
+
58
+ /**
59
+ * @return string
60
+ */
61
+ public function get_version() {
62
+ return $this->version;
63
+ }
64
+
65
+ /**
66
+ * @return string
67
+ */
68
+ public function get_date() {
69
+ return $this->date;
70
+ }
71
+
72
+ /**
73
+ * @return string
74
+ */
75
+ public function get_url() {
76
+ return $this->url;
77
+ }
78
+
79
+ /**
80
+ * @return string
81
+ */
82
+ public function get_repo() {
83
+ return $this->repo;
84
+ }
85
+
86
+ /**
87
+ * @return bool
88
+ */
89
+ public function is_free_on_wporg() {
90
+ return (bool) $this->free_on_wporg;
91
+ }
92
+
93
+ /**
94
+ * @return bool
95
+ */
96
+ public function has_fallback_on_wporg() {
97
+ return (bool) $this->fallback_on_wporg;
98
+ }
99
+
100
+ /**
101
+ * @return string
102
+ */
103
+ public function get_basename() {
104
+ return $this->basename;
105
+ }
106
+
107
+ /**
108
+ * @return string
109
+ */
110
+ public function get_external_repo() {
111
+ return $this->external_repo;
112
+ }
113
+
114
+ /**
115
+ * @return string
116
+ */
117
+ public function get_id() {
118
+ return $this->id;
119
+ }
120
+
121
+ /**
122
+ * @return string
123
+ */
124
+ public function get_installed_version() {
125
+ return $this->installed_version;
126
+ }
127
+
128
+ /**
129
+ * @return string
130
+ */
131
+ public function get_channel() {
132
+ return $this->channel;
133
+ }
134
+
135
+ /**
136
+ * @return string
137
+ */
138
+ public function is_lite() {
139
+ return $this->is_lite;
140
+ }
141
+ }
vendor/otgs/installer/includes/class-otgs-installer-plugins-page-notice.php CHANGED
@@ -13,8 +13,11 @@ class OTGS_Installer_Plugins_Page_Notice {
13
  */
14
  private $template_service;
15
 
16
- public function __construct( OTGS_Installer_Twig_Template_Service $template_service ) {
 
 
17
  $this->template_service = $template_service;
 
18
  }
19
 
20
  public function add_hooks() {
@@ -22,7 +25,7 @@ class OTGS_Installer_Plugins_Page_Notice {
22
  add_action( 'after_plugin_row_' . $plugin_id, array(
23
  $this,
24
  'show_purchase_notice_under_plugin'
25
- ), 10, 3 );
26
  }
27
  }
28
 
@@ -40,13 +43,19 @@ class OTGS_Installer_Plugins_Page_Notice {
40
  /**
41
  * @param string $plugin_file
42
  */
43
- public function show_purchase_notice_under_plugin( $plugin_file ) {
44
  $should_display_subscription_notice = isset( $this->plugins[ $plugin_file ][ self::DISPLAY_SUBSCRIPTION_NOTICE_KEY ] )
45
  ? $this->plugins[ $plugin_file ][ self::DISPLAY_SUBSCRIPTION_NOTICE_KEY ]
46
  : false;
47
 
 
 
48
  if ( $should_display_subscription_notice ) {
49
- echo $this->template_service->show( $this->get_model(), self::TEMPLATE );
 
 
 
 
50
  }
51
  }
52
 
@@ -56,13 +65,7 @@ class OTGS_Installer_Plugins_Page_Notice {
56
  private function get_model() {
57
  $wp_list_table = _get_list_table( 'WP_Plugins_List_Table' );
58
 
59
- $tr_classes = 'plugin-update-tr';
60
- $notice_classes = 'update-message installer-q-icon';
61
-
62
- if ( version_compare( get_bloginfo( 'version' ), '4.6', '>=' ) ) {
63
- $tr_classes = 'plugin-update-tr installer-plugin-update-tr';
64
- $notice_classes = 'notice inline notice-warning notice-alt';
65
- }
66
 
67
  if ( is_multisite() ) {
68
  if ( is_network_admin() ) {
@@ -86,4 +89,34 @@ class OTGS_Installer_Plugins_Page_Notice {
86
  'col_count' => $wp_list_table->get_column_count(),
87
  );
88
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
89
  }
13
  */
14
  private $template_service;
15
 
16
+ private $plugin_finder;
17
+
18
+ public function __construct( OTGS_Installer_Twig_Template_Service $template_service, OTGS_Installer_Plugin_Finder $plugin_finder ) {
19
  $this->template_service = $template_service;
20
+ $this->plugin_finder = $plugin_finder;
21
  }
22
 
23
  public function add_hooks() {
25
  add_action( 'after_plugin_row_' . $plugin_id, array(
26
  $this,
27
  'show_purchase_notice_under_plugin'
28
+ ), 10, 2 );
29
  }
30
  }
31
 
43
  /**
44
  * @param string $plugin_file
45
  */
46
+ public function show_purchase_notice_under_plugin( $plugin_file, $plugin_data ) {
47
  $should_display_subscription_notice = isset( $this->plugins[ $plugin_file ][ self::DISPLAY_SUBSCRIPTION_NOTICE_KEY ] )
48
  ? $this->plugins[ $plugin_file ][ self::DISPLAY_SUBSCRIPTION_NOTICE_KEY ]
49
  : false;
50
 
51
+ $plugin = $this->plugin_finder->get_plugin_by_name( $plugin_data['Name'] );
52
+
53
  if ( $should_display_subscription_notice ) {
54
+ if ( $plugin && 'toolset' === $plugin->get_external_repo() && $plugin->is_lite() ) {
55
+ echo $this->template_service->show( $this->get_toolset_lite_notice_model( $plugin->get_name() ), self::TEMPLATE );
56
+ } else {
57
+ echo $this->template_service->show( $this->get_model(), self::TEMPLATE );
58
+ }
59
  }
60
  }
61
 
65
  private function get_model() {
66
  $wp_list_table = _get_list_table( 'WP_Plugins_List_Table' );
67
 
68
+ list( $tr_classes, $notice_classes ) = $this->get_classes();
 
 
 
 
 
 
69
 
70
  if ( is_multisite() ) {
71
  if ( is_network_admin() ) {
89
  'col_count' => $wp_list_table->get_column_count(),
90
  );
91
  }
92
+
93
+ private function get_toolset_lite_notice_model( $plugin_name ) {
94
+ $wp_list_table = _get_list_table( 'WP_Plugins_List_Table' );
95
+
96
+ list( $tr_classes, $notice_classes ) = $this->get_classes();
97
+
98
+ return array(
99
+ 'strings' => array(
100
+ 'valid_subscription' => sprintf( __( 'You are using the complementary %1$s. For the %2$s, %3$s.', 'installer' ),
101
+ $plugin_name, '<a href="https://wpml.org/documentation/developing-custom-multilingual-sites/types-and-views-lite/?utm_source=viewsplugin&utm_campaign=wpml-toolset-lite&utm_medium=plugins-page&utm_term=features-link">' . __( 'complete set of features', 'installer' ) . '</a>', '<a href="https://toolset.com/?add-to-cart=631305&buy_now=1&apply_coupon=eyJjb3Vwb25fbmFtZSI6IndwbWwgY291cG9uIGJhc2ljIiwiY291cG9uX2lkIjoiODAyMDE2In0=">' . __( 'upgrade to Toolset', 'installer' ) . '</a>' ),
102
+ ),
103
+ 'css' => array(
104
+ 'tr_classes' => $tr_classes,
105
+ 'notice_classes' => $notice_classes,
106
+ ),
107
+ 'col_count' => $wp_list_table->get_column_count(),
108
+ );
109
+ }
110
+
111
+ private function get_classes() {
112
+ $tr_classes = 'plugin-update-tr';
113
+ $notice_classes = 'update-message installer-q-icon';
114
+
115
+ if ( version_compare( get_bloginfo( 'version' ), '4.6', '>=' ) ) {
116
+ $tr_classes = 'plugin-update-tr installer-plugin-update-tr';
117
+ $notice_classes = 'notice inline notice-warning notice-alt';
118
+ }
119
+
120
+ return array( $tr_classes, $notice_classes );
121
+ }
122
  }
vendor/otgs/installer/includes/class-otgs-installer-plugins-update-cache-cleaner.php ADDED
@@ -0,0 +1,12 @@
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class OTGS_Installer_Plugins_Update_Cache_Cleaner {
4
+
5
+ public function add_hooks() {
6
+ add_action( 'otgs_installer_clean_plugins_update_cache', array( $this, 'clean_plugins_update_cache' ) );
7
+ }
8
+
9
+ public function clean_plugins_update_cache() {
10
+ delete_site_transient( 'update_plugins' );
11
+ }
12
+ }
vendor/otgs/installer/includes/class-otgs-installer-source-factory.php ADDED
@@ -0,0 +1,12 @@
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class OTGS_Installer_Source_Factory {
4
+
5
+ public function create() {
6
+ WP_Filesystem();
7
+
8
+ global $wp_filesystem;
9
+
10
+ return new OTGS_Installer_Source( WP_Installer(), $wp_filesystem );
11
+ }
12
+ }
vendor/otgs/installer/includes/class-otgs-installer-source.php ADDED
@@ -0,0 +1,19 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class OTGS_Installer_Source {
4
+
5
+ private $installer;
6
+ private $file_system;
7
+
8
+ public function __construct( WP_Installer $installer, WP_Filesystem_Base $file_system ) {
9
+ $this->installer = $installer;
10
+ $this->file_system = $file_system;
11
+ }
12
+
13
+ /**
14
+ * @return array|null
15
+ */
16
+ public function get() {
17
+ return file_exists( $this->installer->plugin_path() ) ? json_decode( $this->file_system->get_contents( $this->installer->plugin_path() ) ) : null;
18
+ }
19
+ }
vendor/otgs/installer/includes/class-otgs-installer-subscription-factory.php ADDED
@@ -0,0 +1,8 @@
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class OTGS_Installer_Subscription_Factory {
4
+
5
+ public function create( $params = array() ) {
6
+ return new OTGS_Installer_Subscription( $params );
7
+ }
8
+ }
vendor/otgs/installer/includes/class-otgs-installer-subscription.php CHANGED
@@ -1,9 +1,7 @@
1
  <?php
2
 
3
- /**
4
- * @author OnTheGo Systems
5
- */
6
  class OTGS_Installer_Subscription {
 
7
  const SUBSCRIPTION_STATUS_INACTIVE = 0;
8
  const SUBSCRIPTION_STATUS_ACTIVE = 1;
9
  const SUBSCRIPTION_STATUS_EXPIRED = 2;
@@ -16,19 +14,46 @@ class OTGS_Installer_Subscription {
16
 
17
  private $status;
18
  private $expires;
 
 
 
 
 
19
 
20
  /**
21
  * WPML_Installer_Subscription constructor.
22
  *
23
- * @param stdClass|null $data
24
  */
25
- public function __construct( stdClass $data = null ) {
26
- if ( $data ) {
27
- if ( isset( $data->status ) ) {
28
- $this->status = (int) $data->status;
 
 
 
 
 
 
 
 
 
29
  }
30
- if ( isset( $data->expires ) ) {
31
- $this->expires = $data->expires;
 
 
 
 
 
 
 
 
 
 
 
 
 
32
  }
33
  }
34
  }
@@ -71,6 +96,26 @@ class OTGS_Installer_Subscription {
71
  return $this->expires;
72
  }
73
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
74
  /**
75
  * @return bool
76
  */
1
  <?php
2
 
 
 
 
3
  class OTGS_Installer_Subscription {
4
+
5
  const SUBSCRIPTION_STATUS_INACTIVE = 0;
6
  const SUBSCRIPTION_STATUS_ACTIVE = 1;
7
  const SUBSCRIPTION_STATUS_EXPIRED = 2;
14
 
15
  private $status;
16
  private $expires;
17
+ private $site_key;
18
+ private $site_url;
19
+ private $type;
20
+ private $registered_by;
21
+ private $data;
22
 
23
  /**
24
  * WPML_Installer_Subscription constructor.
25
  *
26
+ * @param array|null $subscription
27
  */
28
+ public function __construct( $subscription = array() ) {
29
+ if ( $subscription ) {
30
+
31
+ if ( isset( $subscription['data'] ) ) {
32
+ $this->data = $subscription['data'];
33
+ }
34
+
35
+ if ( isset( $subscription['data']->status ) ) {
36
+ $this->status = (int) $subscription['data']->status;
37
+ }
38
+
39
+ if ( isset( $subscription['data']->expires ) ) {
40
+ $this->expires = $subscription['data']->expires;
41
  }
42
+
43
+ if ( isset( $subscription['key'] ) ) {
44
+ $this->site_key = $subscription['key'];
45
+ }
46
+
47
+ if ( isset( $subscription['site_url'] ) ) {
48
+ $this->site_url = $subscription['site_url'];
49
+ }
50
+
51
+ if ( isset( $subscription['registered_by'] ) ) {
52
+ $this->registered_by = $subscription['registered_by'];
53
+ }
54
+
55
+ if ( isset( $subscription['data']->subscription_type ) ) {
56
+ $this->type = $subscription['data']->subscription_type;
57
  }
58
  }
59
  }
96
  return $this->expires;
97
  }
98
 
99
+ public function get_site_key() {
100
+ return $this->site_key;
101
+ }
102
+
103
+ public function get_site_url() {
104
+ return $this->site_url;
105
+ }
106
+
107
+ public function get_type() {
108
+ return $this->type;
109
+ }
110
+
111
+ public function get_registered_by() {
112
+ return $this->registered_by;
113
+ }
114
+
115
+ public function get_data() {
116
+ return $this->data;
117
+ }
118
+
119
  /**
120
  * @return bool
121
  */
vendor/otgs/installer/includes/class-otgs-installer-wp-components-setting-resources.php CHANGED
@@ -18,26 +18,20 @@ class OTGS_Installer_WP_Components_Setting_Resources {
18
  }
19
 
20
  public function enqueue_resources() {
21
- wp_register_style( self::HANDLES_OTGS_INSTALLER_UI,
22
- $this->installer->res_url() . '/dist/css/ui/styles.css',
23
- array(),
24
- WP_INSTALLER_VERSION );
25
- wp_register_script( self::HANDLES_OTGS_INSTALLER_UI,
26
- $this->installer->res_url() . '/dist/js/ui/app.js',
27
- array(),
28
- WP_INSTALLER_VERSION,
29
- true );
30
-
31
- wp_enqueue_style( 'otgs-installer-tooltip', $this->installer->res_url() . '/res/css/tooltip/tooltip.css', array( 'wp-pointer' ), WP_INSTALLER_VERSION );
32
- wp_enqueue_script( 'otgs-installer-tooltip', $this->installer->res_url() . '/res/js/tooltip/tooltip.js', array(
33
- 'wp-pointer',
34
- 'jquery'
35
- ), WP_INSTALLER_VERSION );
36
  wp_enqueue_script(
37
  'otgs-installer-components-save-setting',
38
- $this->installer->res_url() . '/res/js/save-components-setting.js',
39
  array(),
40
  WP_INSTALLER_VERSION
41
  );
42
  }
43
- }
18
  }
19
 
20
  public function enqueue_resources() {
21
+ $resources_url = $this->installer->res_url();
22
+
23
+ wp_register_style(
24
+ self::HANDLES_OTGS_INSTALLER_UI,
25
+ $resources_url . '/dist/css/component-settings-reports/styles.css',
26
+ array(),
27
+ WP_INSTALLER_VERSION
28
+ );
29
+
 
 
 
 
 
 
30
  wp_enqueue_script(
31
  'otgs-installer-components-save-setting',
32
+ $resources_url . '/res/js/save-components-setting.js',
33
  array(),
34
  WP_INSTALLER_VERSION
35
  );
36
  }
37
+ }
vendor/otgs/installer/includes/class-otgs-installer-wp-share-local-components-setting-hooks.php CHANGED
@@ -49,16 +49,19 @@ class OTGS_Installer_WP_Share_Local_Components_Setting_Hooks {
49
  public function render_local_components_setting( array $args ) {
50
  $params = $this->validate_arguments( $args );
51
 
52
- if ( (bool) $params['use_styles'] ) {
53
- wp_enqueue_style( OTGS_Installer_WP_Components_Setting_Resources::HANDLES_OTGS_INSTALLER_UI );
54
- wp_enqueue_script( OTGS_Installer_WP_Components_Setting_Resources::HANDLES_OTGS_INSTALLER_UI );
55
- }
56
-
57
  $template = self::TEMPLATE_CHECKBOX;
58
  if ( (bool) $params['use_radio'] ) {
59
  $template = self::TEMPLATE_RADIO;
60
  }
61
 
 
 
 
 
 
 
 
 
62
  echo $this->template_service->show( $this->get_model( $params ), $template );
63
  }
64
 
@@ -93,9 +96,9 @@ class OTGS_Installer_WP_Share_Local_Components_Setting_Hooks {
93
  'strings' => array(
94
  'heading' => __( 'Reporting to', 'installer' ),
95
  'report_to' => __( 'Report to', 'installer' ),
96
- 'radio_report_yes' => __( 'Send theme and plugins info, in order to get faster support and compatibility alerts',
97
  'installer' ),
98
- 'radio_report_no' => __( "Don't send this information and skip compatibility notes",
99
  'installer' ),
100
  'which_theme_and_plugins' => __( 'which theme and plugins you are using.', 'installer' ),
101
  ),
@@ -174,4 +177,4 @@ class OTGS_Installer_WP_Share_Local_Components_Setting_Hooks {
174
  private function has_required_argument( array $args, $required_argument ) {
175
  return array_key_exists( $required_argument, $args ) && $args[ $required_argument ];
176
  }
177
- }
49
  public function render_local_components_setting( array $args ) {
50
  $params = $this->validate_arguments( $args );
51
 
 
 
 
 
 
52
  $template = self::TEMPLATE_CHECKBOX;
53
  if ( (bool) $params['use_radio'] ) {
54
  $template = self::TEMPLATE_RADIO;
55
  }
56
 
57
+ if ( (bool) $params['use_styles'] ) {
58
+ wp_enqueue_style( OTGS_Installer_WP_Components_Setting_Resources::HANDLES_OTGS_INSTALLER_UI );
59
+
60
+ if(!(bool) $params['use_radio']) {
61
+ wp_enqueue_style('otgsSwitcher');
62
+ }
63
+ }
64
+
65
  echo $this->template_service->show( $this->get_model( $params ), $template );
66
  }
67
 
96
  'strings' => array(
97
  'heading' => __( 'Reporting to', 'installer' ),
98
  'report_to' => __( 'Report to', 'installer' ),
99
+ 'radio_report_yes' => __( 'Send theme and plugins information, in order to get faster support and compatibility alerts',
100
  'installer' ),
101
+ 'radio_report_no' => __( "Don't send this information and skip compatibility alerts",
102
  'installer' ),
103
  'which_theme_and_plugins' => __( 'which theme and plugins you are using.', 'installer' ),
104
  ),
177
  private function has_required_argument( array $args, $required_argument ) {
178
  return array_key_exists( $required_argument, $args ) && $args[ $required_argument ];
179
  }
180
+ }
vendor/otgs/installer/includes/class-translation-service-info.php CHANGED
@@ -2,13 +2,13 @@
2
 
3
  class Translation_Service_Info {
4
 
5
- function __construct() {
6
 
7
  add_action( 'installer_fetched_subscription_data', array( $this, 'save_info' ), 10, 2 );
8
 
9
  }
10
 
11
- function save_info( $data, $repository_id ) {
12
 
13
  $ts_info = isset( WP_Installer()->settings['repositories'][ $repository_id ]['ts_info'] ) ?
14
  WP_Installer()->settings['repositories'][ $repository_id ]['ts_info'] : false;
@@ -37,4 +37,3 @@ class Translation_Service_Info {
37
 
38
  }
39
 
40
- new Translation_Service_Info();
2
 
3
  class Translation_Service_Info {
4
 
5
+ public function add_hooks() {
6
 
7
  add_action( 'installer_fetched_subscription_data', array( $this, 'save_info' ), 10, 2 );
8
 
9
  }
10
 
11
+ public function save_info( $data, $repository_id ) {
12
 
13
  $ts_info = isset( WP_Installer()->settings['repositories'][ $repository_id ]['ts_info'] ) ?
14
  WP_Installer()->settings['repositories'][ $repository_id ]['ts_info'] : false;
37
 
38
  }
39
 
 
vendor/otgs/installer/includes/class-wp-installer.php CHANGED
@@ -1,6 +1,6 @@
1
  <?php
2
 
3
- final class WP_Installer {
4
 
5
  const TOOLSET_TYPES = 'Toolset Types';
6
 
@@ -23,6 +23,8 @@ final class WP_Installer {
23
 
24
  private $package_source = array();
25
 
 
 
26
  const SITE_KEY_VALIDATION_SOURCE_OTHER = 0;
27
  const SITE_KEY_VALIDATION_SOURCE_DOWNLOAD_SPECIFIC = 1;
28
  const SITE_KEY_VALIDATION_SOURCE_DOWNLOAD_REPORT = 2;
@@ -34,6 +36,11 @@ final class WP_Installer {
34
 
35
  private $components_setting;
36
 
 
 
 
 
 
37
  public static function instance() {
38
 
39
  if ( is_null( self::$_instance ) ) {
@@ -45,7 +52,7 @@ final class WP_Installer {
45
 
46
  public function __construct() {
47
 
48
- if ( ! is_admin() || ! is_user_logged_in() ) {
49
  return;
50
  } //Only for admin
51
 
@@ -59,12 +66,7 @@ final class WP_Installer {
59
 
60
  add_action( 'admin_menu', array( $this, 'menu_setup' ) );
61
  add_action( 'network_admin_menu', array( $this, 'menu_setup' ) );
62
-
63
- if ( defined( 'DOING_AJAX' ) && isset( $_POST['action'] ) && $_POST['action'] == 'installer_download_plugin' ) {
64
- add_filter( 'site_transient_update_plugins', array( $this, 'plugins_upgrade_check' ) );
65
- }
66
  add_filter( 'plugins_api', array( $this, 'custom_plugins_api_call' ), 10, 3 );
67
- add_filter( 'pre_set_site_transient_update_plugins', array( $this, 'plugins_upgrade_check' ) );
68
 
69
  // register repositories
70
  $this->load_repositories_list();
@@ -95,14 +97,17 @@ final class WP_Installer {
95
  public function init() {
96
  global $pagenow;
97
 
 
 
 
 
 
98
  if ( empty( $this->settings['last_repositories_update'] ) || time() - $this->settings['last_repositories_update'] > 86400
99
  || ( isset( $_GET['force-check'] ) && $_GET['force-check'] == 1 )
100
  ) {
101
  $this->refresh_repositories_data();
102
  }
103
 
104
- $this->dependencies = new Installer_Dependencies;
105
-
106
  if ( empty( $this->settings['_pre_1_0_clean_up'] ) ) {
107
  $this->_pre_1_0_clean_up();
108
  }
@@ -116,8 +121,12 @@ final class WP_Installer {
116
  $this->_using_icl = function_exists( 'wpml_site_uses_icl' ) && wpml_site_uses_icl();
117
  $this->_wpml_version = defined( 'ICL_SITEPRESS_VERSION' ) ? ICL_SITEPRESS_VERSION : '';
118
 
119
- wp_enqueue_script( 'installer-admin', $this->res_url() . '/res/js/admin.js', array( 'jquery' ), $this->version() );
120
- wp_enqueue_style( 'installer-admin', $this->res_url() . '/res/css/admin.css', array(), $this->version() );
 
 
 
 
121
 
122
  $translation_array = array(
123
  'installing' => __( 'Installing %s', 'installer' ),
@@ -141,10 +150,6 @@ final class WP_Installer {
141
  }
142
 
143
  if ( defined( 'DOING_AJAX' ) ) {
144
- add_action( 'wp_ajax_save_site_key', array( $this, 'save_site_key' ) );
145
- add_action( 'wp_ajax_remove_site_key', array( $this, 'remove_site_key_ajax' ) );
146
- add_action( 'wp_ajax_update_site_key', array( $this, 'update_site_key' ) );
147
-
148
  add_action( 'wp_ajax_installer_download_plugin', array( $this, 'download_plugin_ajax_handler' ) );
149
  add_action( 'wp_ajax_installer_activate_plugin', array( $this, 'activate_plugin' ) );
150
 
@@ -177,9 +182,23 @@ final class WP_Installer {
177
  global $wp_filesystem;
178
  $this->package_source = json_decode( $wp_filesystem->get_contents( $package_source_file ) );
179
  }
 
 
180
  }
181
 
182
- protected function log( $message ) {
 
 
 
 
 
 
 
 
 
 
 
 
183
  require_once ABSPATH . 'wp-admin/includes/file.php';
184
  WP_Filesystem();
185
  global $wp_filesystem;
@@ -307,18 +326,21 @@ final class WP_Installer {
307
 
308
  if ( array_key_exists( 'products', $package ) ) {
309
  foreach ( $package['products'] as $product ) {
 
 
310
 
311
- foreach ( $product['plugins'] as $plugin_slug ) {
312
 
313
- $download = $this->settings['repositories'][ $repository_id ]['data']['downloads']['plugins'][ $plugin_slug ];
 
 
 
 
 
314
 
315
- if ( ! isset( $repositories_plugins[ $repository_id ][ $download['slug'] ] ) ) {
316
- $repositories_plugins[ $repository_id ][ $download['slug'] ] = array(
317
- 'name' => $download['name'],
318
- 'registered' => $this->plugin_is_registered( $repository_id, $download['slug'] ) ? 1 : 0
319
- );
320
  }
321
-
 
322
  }
323
  }
324
  } else {
@@ -340,12 +362,35 @@ final class WP_Installer {
340
 
341
  if ( $wp_plugin_slug === $slug || $r_plugin['name'] === $plugin['Name'] || $r_plugin['name'] === $plugin['Title'] ) { //match order: slug, name, title
342
 
 
 
 
 
 
 
 
343
  if ( $r_plugin['registered'] ) {
 
 
 
 
 
 
344
  add_filter( 'plugin_action_links_' . $plugin_id, array(
345
  $this,
346
  'plugins_action_links_registered'
347
  ) );
348
  } else {
 
 
 
 
 
 
 
 
 
 
349
  add_filter( 'plugin_action_links_' . $plugin_id, array(
350
  $this,
351
  'plugins_action_links_not_registered'
@@ -355,7 +400,6 @@ final class WP_Installer {
355
  add_filter( 'plugin_action_links_' . $plugin_id, array( $this, 'types_upgrade_link' ) );
356
  }
357
  }
358
-
359
  }
360
 
361
  }
@@ -458,6 +502,23 @@ final class WP_Installer {
458
  return $url;
459
  }
460
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
461
  public function is_repositories_page() {
462
  global $pagenow;
463
 
@@ -680,7 +741,7 @@ final class WP_Installer {
680
 
681
  }
682
 
683
- return $site_url;
684
  }
685
 
686
  /**
@@ -779,7 +840,8 @@ final class WP_Installer {
779
  }
780
 
781
  $this->repositories[ $id ] = $data;
782
-
 
783
  }
784
  }
785
 
@@ -788,6 +850,16 @@ final class WP_Installer {
788
 
789
  }
790
 
 
 
 
 
 
 
 
 
 
 
791
  public function filter_repositories_list() {
792
 
793
  if ( ! empty( $this->settings['repositories'] ) ) {
@@ -853,6 +925,8 @@ final class WP_Installer {
853
 
854
  $this->register_admin_message( $error, 'error' );
855
 
 
 
856
  continue;
857
  }
858
 
@@ -923,7 +997,6 @@ final class WP_Installer {
923
  if ( $screen->base == 'settings_page_installer' ) { // settings page
924
  echo '<div class="wrap">';
925
  echo '<h2>' . __( 'Installer', 'installer' ) . '</h2>';
926
- echo '<br />';
927
  }
928
 
929
  if ( ! is_array( $args ) ) {
@@ -961,7 +1034,7 @@ final class WP_Installer {
961
 
962
  } else {
963
 
964
- echo '<center>' . __( 'No repositories defined.', 'installer' ) . '</center>';
965
 
966
  }
967
 
@@ -969,7 +1042,6 @@ final class WP_Installer {
969
  echo '</div>';
970
  }
971
 
972
-
973
  }
974
 
975
  public function get_product_price( $repository_id, $package_id, $product_id, $incl_discount = false ) {
@@ -1061,6 +1133,14 @@ final class WP_Installer {
1061
  if ( isset( $subscription_type ) && ! $expired && ( $product['subscription_type'] == $subscription_type || $product['subscription_type_equivalent'] == $subscription_type ) ) {
1062
 
1063
  foreach ( $product['plugins'] as $plugin_slug ) {
 
 
 
 
 
 
 
 
1064
  $row['downloads'][ $plugin_slug ] = $this->settings['repositories'][ $repository_id ]['data']['downloads']['plugins'][ $plugin_slug ];
1065
  }
1066
 
@@ -1221,6 +1301,7 @@ final class WP_Installer {
1221
  'site_url' => get_site_url(),
1222
  );
1223
  $this->save_settings();
 
1224
  } else {
1225
  $error = __( 'Invalid site key for the current site.', 'installer' )
1226
  . '<br /><div class="installer-footnote">' . __( 'Please note that the site key is case sensitive.', 'installer' ) . '</div>';
@@ -1269,19 +1350,13 @@ final class WP_Installer {
1269
  if ( isset( $this->settings['repositories'][ $repository_id ] ) ) {
1270
  unset( $this->settings['repositories'][ $repository_id ]['subscription'] );
1271
  $this->save_settings();
 
1272
  if( $refresh_repositories_data ){
1273
  $this->refresh_repositories_data();
1274
  }
1275
  }
1276
  }
1277
 
1278
- public function remove_site_key_ajax() {
1279
- if ( $_POST['nonce'] == wp_create_nonce( 'remove_site_key_' . $_POST['repository_id'] ) ) {
1280
- $this->remove_site_key( $_POST['repository_id'] );
1281
- }
1282
- exit;
1283
- }
1284
-
1285
  public function validate_repository_subscription() {
1286
  $repository_id = isset( $_GET['validate_repository'] ) ? sanitize_text_field( $_GET['validate_repository'] ) : false;
1287
  if ( $repository_id ) {
@@ -1308,56 +1383,6 @@ final class WP_Installer {
1308
 
1309
  }
1310
 
1311
- public function update_site_key() {
1312
-
1313
- $error = '';
1314
-
1315
- $repository_id = sanitize_text_field( $_POST['repository_id'] );
1316
- if ( $_POST['nonce'] == wp_create_nonce( 'update_site_key_' . $repository_id ) ) {
1317
-
1318
- $site_key = $this->get_site_key( $_POST['repository_id'] );
1319
-
1320
- if ( $site_key ) {
1321
- try {
1322
- $subscription_data = $this->fetch_subscription_data( $repository_id, $site_key, self::SITE_KEY_VALIDATION_SOURCE_UPDATES_CHECK );
1323
-
1324
- if ( $subscription_data ) {
1325
- $this->settings['repositories'][ $repository_id ]['subscription'] = array(
1326
- 'key' => $site_key,
1327
- 'data' => $subscription_data,
1328
- 'registered_by' => get_current_user_id()
1329
- );
1330
-
1331
- //also refresh products information
1332
- $this->refresh_repositories_data();
1333
-
1334
- $this->save_settings();
1335
-
1336
- } else {
1337
- unset( $this->settings['repositories'][ $repository_id ]['subscription'] );
1338
- $error = __( 'Invalid site key for the current site. If the error persists, try to unregister first and then register again with the same site key.', 'installer' );
1339
- }
1340
-
1341
-
1342
- } catch ( Exception $e ) {
1343
- $error = $e->getMessage();
1344
- if ( preg_match( '#Could not resolve host: (.*)#', $error, $matches ) || preg_match( '#Couldn\'t resolve host \'(.*)\'#', $error, $matches ) ) {
1345
- $error = sprintf( __( "%s cannot access %s to register. Try again to see if it's a temporary problem. If the problem continues, make sure that this site has access to the Internet. You can still use the plugin without registration, but you will not receive automated updates.", 'installer' ),
1346
- '<strong><i>' . $this->get_generic_product_name( $repository_id ) . '</i></strong>',
1347
- '<strong><i>' . $matches[1] . '</i></strong>'
1348
- );
1349
- }
1350
- }
1351
-
1352
- }
1353
-
1354
- }
1355
-
1356
- echo json_encode( array( 'error' => $error ) );
1357
-
1358
- exit;
1359
- }
1360
-
1361
  public function api_debug_log( $text ) {
1362
 
1363
  if ( defined( 'WPML_DEBUG_INSTALLER' ) && WPML_DEBUG_INSTALLER ) {
@@ -1491,7 +1516,7 @@ final class WP_Installer {
1491
  public function get_subscription( $repository_id ) {
1492
  $data = null;
1493
  if ( ! empty( $this->settings['repositories'][ $repository_id ]['subscription'] ) ) {
1494
- $data = $this->settings['repositories'][ $repository_id ]['subscription']['data'];
1495
  }
1496
 
1497
  return new OTGS_Installer_Subscription( $data );
@@ -1746,7 +1771,7 @@ final class WP_Installer {
1746
 
1747
  foreach ( $package['products'] as $product ) {
1748
 
1749
- if ( $subscription_type == $product['subscription_type'] ) {
1750
  $has_top_package = true;
1751
  if ( $product['name'] == $product_name ) {
1752
  return $available = true;
@@ -1758,7 +1783,7 @@ final class WP_Installer {
1758
  if ( ! empty( $package['sub-packages'] ) ) {
1759
  foreach ( $package['sub-packages'] as $sub_package ) {
1760
  foreach ( $sub_package['products'] as $product ) {
1761
- if ( $product['name'] == $product_name && ( $subscription_type == $product['subscription_type'] || $has_top_package ) ) {
1762
  return $available = true;
1763
  }
1764
  }
@@ -1952,6 +1977,11 @@ final class WP_Installer {
1952
 
1953
  $data = json_decode( base64_decode( sanitize_text_field( $_POST['data'] ) ), true );
1954
 
 
 
 
 
 
1955
  $ret = false;
1956
  $plugin_id = false;
1957
  $message = '';
@@ -1964,6 +1994,8 @@ final class WP_Installer {
1964
  } catch ( Exception $e ) {
1965
  $connection_error = $e->getMessage();
1966
  $subscription_data = false;
 
 
1967
  }
1968
 
1969
  if ( $subscription_data && ! is_wp_error( $subscription_data ) && $this->repository_has_valid_subscription( $data['repository_id'] ) ) {
@@ -2055,6 +2087,10 @@ final class WP_Installer {
2055
  $message = __( 'Your subscription appears to no longer be valid. Please try to register again using a valid site key.', 'installer' );
2056
  }
2057
 
 
 
 
 
2058
  $response['version'] = isset( $plugin_version ) ? $plugin_version : 0;
2059
  $response['non_stable']= isset( $non_stable ) ? $non_stable : '';
2060
  $response['plugin_id'] = $plugin_id;
@@ -2146,22 +2182,24 @@ final class WP_Installer {
2146
 
2147
  }
2148
 
2149
- public function custom_plugins_api_call( $false, $action, $args ) {
2150
 
2151
  if ( $action == 'plugin_information' ) {
2152
 
2153
  $plugins = get_plugins();
2154
- $plugin_names = array();
2155
  foreach ( $plugins as $plugin_id => $plugin ) {
2156
  // plugins by WP slug which (plugin folder) which can be different
2157
  // will use this to compare by title
2158
- $plugin_names[ dirname( $plugin_id ) ] = array(
2159
- 'name' => $plugin['Name'],
2160
- 'title' => $plugin['Title'],
 
2161
  );
2162
  }
2163
 
2164
- $slug = $args->slug;
 
2165
 
2166
  foreach ( $this->settings['repositories'] as $repository_id => $repository ) {
2167
 
@@ -2180,38 +2218,50 @@ final class WP_Installer {
2180
  $download = $this->settings['repositories'][ $repository_id ]['data']['downloads']['plugins'][ $plugin_slug ];
2181
 
2182
  if ( $download['slug'] == $slug ||
2183
- isset( $plugin_names[ $slug ] ) && (
2184
- $plugin_names[ $slug ]['name'] == $download['name'] ||
2185
- $plugin_names[ $slug ]['title'] == $download['name']
2186
  )
2187
  ) {
2188
 
2189
- if ( $this->should_fallback_under_wp_org_repo( $download, $site_key ) ) {
2190
- return false; // use data from wordpress.org
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2191
  }
 
2192
 
2193
- $res = new stdClass();
2194
- $res->external = true;
2195
-
2196
- $res->name = $download['name'];
2197
- $res->slug = $slug;
2198
- $res->version = $download['version'];
2199
- $res->author = '';
2200
- $res->author_profile = '';
2201
- $res->last_updated = $download['date'];
2202
 
2203
  if ( $site_key ) {
2204
- $res->download_link = $this->append_site_key_to_download_url( $download['url'], $site_key, $repository_id );
 
2205
  }
2206
 
2207
- $res->homepage = $repository['data']['url'];
2208
- $res->sections = array(
2209
  'Description' => $download['description'],
2210
  'Changelog' => $download['changelog']
2211
  );
2212
 
2213
- return $res;
2214
-
2215
  }
2216
 
2217
  }
@@ -2222,94 +2272,17 @@ final class WP_Installer {
2222
 
2223
  }
2224
 
2225
- }
2226
-
2227
- return $false;
2228
-
2229
- }
2230
-
2231
- public function plugins_upgrade_check( $update_plugins ) {
2232
-
2233
- if ( ! empty( $this->settings['repositories'] ) ) {
2234
-
2235
- $plugins = get_plugins();
2236
-
2237
- foreach ( $plugins as $plugin_id => $plugin ) {
2238
-
2239
- $slug = dirname( $plugin_id );
2240
- if ( empty( $slug ) ) {
2241
- continue;
2242
- }
2243
-
2244
- $version = $plugin['Version'];
2245
- $name = $plugin['Name'];
2246
-
2247
- foreach ( $this->settings['repositories'] as $repository_id => $repository ) {
2248
-
2249
-
2250
- if ( ! $this->repository_has_valid_subscription( $repository_id ) ) {
2251
- $site_key = false;
2252
- } else {
2253
- $site_key = $repository['subscription']['key'];
2254
- //$subscription_type = $this->get_subscription_type_for_repository($repository_id);
2255
- }
2256
-
2257
- foreach ( $repository['data']['packages'] as $package ) {
2258
-
2259
- foreach ( $package['products'] as $product ) {
2260
-
2261
- foreach ( $product['plugins'] as $plugin_slug ) {
2262
-
2263
- $download = $this->settings['repositories'][ $repository_id ]['data']['downloads']['plugins'][ $plugin_slug ];
2264
-
2265
- if ( ! $this->plugin_is_registered( $repository_id, $download['slug'] ) ) {
2266
- continue;
2267
- }
2268
-
2269
- $has_wporg_update = ! empty( $update_plugins->response[ $plugin_id ] );
2270
- if ( $this->should_fallback_under_wp_org_repo( $download, $site_key ) && $has_wporg_update ) {
2271
- continue;
2272
- }
2273
-
2274
- $needs_version_update = version_compare( $download['version'], $version, '>' ) ||
2275
- ! empty( $_POST['reset_to_channel'] );
2276
-
2277
- if (
2278
- ( empty( $update_plugins->response[ $plugin_id ] ) || ! $this->should_fallback_under_wp_org_repo( $download, $site_key ) ) &&
2279
- ( $download['slug'] == $slug || $download['name'] == $name ) &&
2280
- $needs_version_update
2281
- ) {
2282
- $response = new stdClass();
2283
- $response->id = 0;
2284
- $response->slug = $slug;
2285
- $response->plugin = $plugin_id;
2286
- $response->new_version = $download['version'];
2287
- $response->upgrade_notice = '';
2288
- $response->url = $download['url'];
2289
- if ( $site_key ) {
2290
- $response->package = $this->append_site_key_to_download_url( $download['url'], $site_key, $repository_id );
2291
- }
2292
-
2293
- $response = apply_filters( 'otgs_installer_upgrade_check_response', $response, $name, $repository_id );
2294
-
2295
- $update_plugins->checked[ $plugin_id ] = $version;
2296
- $update_plugins->response[ $plugin_id ] = $response;
2297
-
2298
- }
2299
-
2300
- }
2301
-
2302
- }
2303
-
2304
- }
2305
-
2306
  }
2307
-
2308
  }
2309
 
2310
  }
2311
 
2312
- return $update_plugins;
2313
 
2314
  }
2315
 
@@ -2330,7 +2303,7 @@ final class WP_Installer {
2330
  array( $this->plugin_path() . '/templates/components-setting/' )
2331
  );
2332
  $local_components_setting = new OTGS_Installer_WP_Share_Local_Components_Setting();
2333
- $plugin_page_notice = new OTGS_Installer_Plugins_Page_Notice( $template_service->get_service(), $local_components_setting );
2334
 
2335
  foreach ( $plugins as $plugin_id => $plugin ) {
2336
 
@@ -2355,6 +2328,14 @@ final class WP_Installer {
2355
 
2356
  foreach ( $product['plugins'] as $plugin_slug ) {
2357
 
 
 
 
 
 
 
 
 
2358
  $download = $this->settings['repositories'][ $repository_id ]['data']['downloads']['plugins'][ $plugin_slug ];
2359
  $display_subscription_notice = false;
2360
  $display_setting_notice = false;
@@ -2370,6 +2351,18 @@ final class WP_Installer {
2370
  if ( ! $this->should_fallback_under_wp_org_repo( $download, $site_key ) || $this->has_non_wporg_upgrade_available( $plugin_id ) ) {
2371
  $display_subscription_notice = true;
2372
  }
 
 
 
 
 
 
 
 
 
 
 
 
2373
  }
2374
  }
2375
 
@@ -2660,6 +2653,21 @@ final class WP_Installer {
2660
  return false;
2661
  }
2662
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2663
  public function plugin_upgrade_custom_errors() {
2664
 
2665
  if ( isset( $_REQUEST['action'] ) ) {
@@ -2712,6 +2720,11 @@ final class WP_Installer {
2712
  if ( empty( $sub_cache[ $plugin_repository ] ) ) {
2713
  $subscription_data = false;
2714
  $site_key = $this->get_repository_site_key( $plugin_repository );
 
 
 
 
 
2715
  if ( $site_key ) {
2716
  try {
2717
  $subscription_data = $this->fetch_subscription_data( $plugin_repository, $site_key, self::SITE_KEY_VALIDATION_SOURCE_REVALIDATION );
@@ -2726,7 +2739,7 @@ final class WP_Installer {
2726
  $subscription_data = $sub_cache[ $plugin_repository ]['subscription_data'];
2727
  }
2728
 
2729
- if ( ! $site_key && ! empty( $free_on_wporg ) ) { // allow the download from wp.org
2730
  continue;
2731
  }
2732
 
@@ -2791,6 +2804,11 @@ final class WP_Installer {
2791
 
2792
  //validate subscription
2793
  $site_key = $this->get_repository_site_key( $plugin_repository );
 
 
 
 
 
2794
  if ( $site_key ) {
2795
  try {
2796
  $subscription_data = $this->fetch_subscription_data( $plugin_repository, $site_key, self::SITE_KEY_VALIDATION_SOURCE_REVALIDATION );
@@ -2846,4 +2864,56 @@ final class WP_Installer {
2846
 
2847
  }
2848
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2849
  }
1
  <?php
2
 
3
+ class WP_Installer {
4
 
5
  const TOOLSET_TYPES = 'Toolset Types';
6
 
23
 
24
  private $package_source = array();
25
 
26
+ private $plugin_finder;
27
+
28
  const SITE_KEY_VALIDATION_SOURCE_OTHER = 0;
29
  const SITE_KEY_VALIDATION_SOURCE_DOWNLOAD_SPECIFIC = 1;
30
  const SITE_KEY_VALIDATION_SOURCE_DOWNLOAD_REPORT = 2;
36
 
37
  private $components_setting;
38
 
39
+ /**
40
+ * @var OTGS_Installer_Logger_Storage
41
+ */
42
+ private $logger_storage;
43
+
44
  public static function instance() {
45
 
46
  if ( is_null( self::$_instance ) ) {
52
 
53
  public function __construct() {
54
 
55
+ if ( ( ! is_admin() || ! is_user_logged_in() ) && ! ( defined( 'WP_CLI' ) && WP_CLI ) ) {
56
  return;
57
  } //Only for admin
58
 
66
 
67
  add_action( 'admin_menu', array( $this, 'menu_setup' ) );
68
  add_action( 'network_admin_menu', array( $this, 'menu_setup' ) );
 
 
 
 
69
  add_filter( 'plugins_api', array( $this, 'custom_plugins_api_call' ), 10, 3 );
 
70
 
71
  // register repositories
72
  $this->load_repositories_list();
97
  public function init() {
98
  global $pagenow;
99
 
100
+ $this->dependencies = new Installer_Dependencies;
101
+ if( $this->dependencies->php_libraries_missing() ){
102
+ return false;
103
+ }
104
+
105
  if ( empty( $this->settings['last_repositories_update'] ) || time() - $this->settings['last_repositories_update'] > 86400
106
  || ( isset( $_GET['force-check'] ) && $_GET['force-check'] == 1 )
107
  ) {
108
  $this->refresh_repositories_data();
109
  }
110
 
 
 
111
  if ( empty( $this->settings['_pre_1_0_clean_up'] ) ) {
112
  $this->_pre_1_0_clean_up();
113
  }
121
  $this->_using_icl = function_exists( 'wpml_site_uses_icl' ) && wpml_site_uses_icl();
122
  $this->_wpml_version = defined( 'ICL_SITEPRESS_VERSION' ) ? ICL_SITEPRESS_VERSION : '';
123
 
124
+ if ( ! $this->is_installer_running_on_otgs_plugin() || ( $this->is_commercial_page() && $this->is_installer_running_on_otgs_plugin() ) ) {
125
+ wp_enqueue_script( 'installer-admin', $this->res_url() . '/res/js/admin.js', array( 'jquery' ), $this->version() );
126
+ wp_enqueue_style( 'installer-admin', $this->res_url() . '/res/css/admin.css', array(), $this->version() );
127
+ }
128
+
129
+ wp_enqueue_script( 'installer-dismiss-nag', $this->res_url() . '/res/js/dismiss-nag.js', array( 'jquery' ), $this->version(), true );
130
 
131
  $translation_array = array(
132
  'installing' => __( 'Installing %s', 'installer' ),
150
  }
151
 
152
  if ( defined( 'DOING_AJAX' ) ) {
 
 
 
 
153
  add_action( 'wp_ajax_installer_download_plugin', array( $this, 'download_plugin_ajax_handler' ) );
154
  add_action( 'wp_ajax_installer_activate_plugin', array( $this, 'activate_plugin' ) );
155
 
182
  global $wp_filesystem;
183
  $this->package_source = json_decode( $wp_filesystem->get_contents( $package_source_file ) );
184
  }
185
+
186
+ do_action( 'otgs_installer_initialized' );
187
  }
188
 
189
+ private function is_installer_running_on_otgs_plugin() {
190
+ return ( defined( 'ICL_PLUGIN_PATH' ) && false !== strpos( $this->plugin_path(), realpath( ICL_PLUGIN_PATH ) ) )
191
+ || ( defined( 'TYPES_ABSPATH' ) && false !== strpos( $this->plugin_path(), realpath( TYPES_ABSPATH ) ) )
192
+ || ( defined( 'WCML_PLUGIN_PATH' ) && false !== strpos( $this->plugin_path(), realpath( WCML_PLUGIN_PATH ) ) );
193
+ }
194
+
195
+ private function is_commercial_page() {
196
+ global $pagenow;
197
+
198
+ return $pagenow === 'plugin-install.php' && isset( $_GET['tab'] ) && $_GET['tab'] === 'commercial';
199
+ }
200
+
201
+ public function log( $message ) {
202
  require_once ABSPATH . 'wp-admin/includes/file.php';
203
  WP_Filesystem();
204
  global $wp_filesystem;
326
 
327
  if ( array_key_exists( 'products', $package ) ) {
328
  foreach ( $package['products'] as $product ) {
329
+ if ( array_key_exists( 'plugins', $product ) ) {
330
+ foreach ( $product['plugins'] as $plugin_slug ) {
331
 
332
+ $download = $this->settings['repositories'][ $repository_id ]['data']['downloads']['plugins'][ $plugin_slug ];
333
 
334
+ if ( ! isset( $repositories_plugins[ $repository_id ][ $download['slug'] ] ) ) {
335
+ $repositories_plugins[ $repository_id ][ $download['slug'] ] = array(
336
+ 'name' => $download['name'],
337
+ 'registered' => $this->plugin_is_registered( $repository_id, $download['slug'] ) ? 1 : 0
338
+ );
339
+ }
340
 
 
 
 
 
 
341
  }
342
+ } else {
343
+ $this->refresh_repositories_data();
344
  }
345
  }
346
  } else {
362
 
363
  if ( $wp_plugin_slug === $slug || $r_plugin['name'] === $plugin['Name'] || $r_plugin['name'] === $plugin['Title'] ) { //match order: slug, name, title
364
 
365
+ $plugin_finder = $this->get_plugin_finder();
366
+ $plugin_obj = $plugin_finder->get_plugin( $slug, $repository_id );
367
+
368
+ if ( $plugin_obj && $plugin_obj->get_external_repo() && $plugin_obj->is_lite() ) {
369
+ continue;
370
+ }
371
+
372
  if ( $r_plugin['registered'] ) {
373
+
374
+ remove_filter( 'plugin_action_links_' . $plugin_id, array(
375
+ $this,
376
+ 'plugins_action_links_not_registered'
377
+ ) );
378
+
379
  add_filter( 'plugin_action_links_' . $plugin_id, array(
380
  $this,
381
  'plugins_action_links_registered'
382
  ) );
383
  } else {
384
+
385
+ if ( $this->plugin_is_registered( $plugin_obj->get_external_repo(), $slug ) || $this->plugin_is_registered( 'wpml', $slug ) ) {
386
+ continue;
387
+ }
388
+
389
+ remove_filter( 'plugin_action_links_' . $plugin_id, array(
390
+ $this,
391
+ 'plugins_action_links_registered'
392
+ ) );
393
+
394
  add_filter( 'plugin_action_links_' . $plugin_id, array(
395
  $this,
396
  'plugins_action_links_not_registered'
400
  add_filter( 'plugin_action_links_' . $plugin_id, array( $this, 'types_upgrade_link' ) );
401
  }
402
  }
 
403
  }
404
 
405
  }
502
  return $url;
503
  }
504
 
505
+ public function vendor_url() {
506
+ $url = null;
507
+
508
+ $site_url = get_site_url();
509
+ $site_path = ABSPATH;
510
+ $vendor_path = dirname( dirname( $this->plugin_path() ) );
511
+
512
+ return str_replace( '\\', '/', $site_url . '/' . substr( $vendor_path, strlen( $site_path ) ) );
513
+ }
514
+
515
+ public function get_embedded_at() {
516
+ $embedded_at = str_replace( array( get_template_directory_uri(), plugins_url() ), '', $this->plugin_url() );
517
+ preg_match( '/\/(.*?)\//', $embedded_at, $matches );
518
+
519
+ return isset( $matches[1] ) ? $matches[1] : '';
520
+ }
521
+
522
  public function is_repositories_page() {
523
  global $pagenow;
524
 
741
 
742
  }
743
 
744
+ return apply_filters( 'otgs_installer_site_url', $site_url );
745
  }
746
 
747
  /**
840
  }
841
 
842
  $this->repositories[ $id ] = $data;
843
+ $this->set_predefined_config( $id, 'api-url', 'API_URL' );
844
+ $this->set_predefined_config( $id, 'products', 'PRODUCTS' );
845
  }
846
  }
847
 
850
 
851
  }
852
 
853
+ /**
854
+ * @param string $id
855
+ */
856
+ private function set_predefined_config( $id, $setting_field, $constant_suffix ) {
857
+ $repo_upper = strtoupper( $id );
858
+ if ( defined( "OTGS_INSTALLER_{$repo_upper}_{$constant_suffix}" ) ) {
859
+ $this->repositories[ $id ][ $setting_field ] = constant( "OTGS_INSTALLER_{$repo_upper}_{$constant_suffix}" );
860
+ }
861
+ }
862
+
863
  public function filter_repositories_list() {
864
 
865
  if ( ! empty( $this->settings['repositories'] ) ) {
925
 
926
  $this->register_admin_message( $error, 'error' );
927
 
928
+ $this->store_log( $data['products'], null, OTGS_Installer_Logger_Storage::COMPONENT_REPOSITORIES, $error );
929
+
930
  continue;
931
  }
932
 
997
  if ( $screen->base == 'settings_page_installer' ) { // settings page
998
  echo '<div class="wrap">';
999
  echo '<h2>' . __( 'Installer', 'installer' ) . '</h2>';
 
1000
  }
1001
 
1002
  if ( ! is_array( $args ) ) {
1034
 
1035
  } else {
1036
 
1037
+ echo '<p>' . __( 'No repositories defined.', 'installer' ) . '</p>';
1038
 
1039
  }
1040
 
1042
  echo '</div>';
1043
  }
1044
 
 
1045
  }
1046
 
1047
  public function get_product_price( $repository_id, $package_id, $product_id, $incl_discount = false ) {
1133
  if ( isset( $subscription_type ) && ! $expired && ( $product['subscription_type'] == $subscription_type || $product['subscription_type_equivalent'] == $subscription_type ) ) {
1134
 
1135
  foreach ( $product['plugins'] as $plugin_slug ) {
1136
+ $plugin_finder = $this->get_plugin_finder();
1137
+ $plugin = $plugin_finder->get_plugin( $plugin_slug, $repository_id );
1138
+ $external_repo = $plugin->get_external_repo();
1139
+
1140
+ if ( $external_repo && $this->repository_has_valid_subscription( $external_repo ) ) {
1141
+ continue;
1142
+ }
1143
+
1144
  $row['downloads'][ $plugin_slug ] = $this->settings['repositories'][ $repository_id ]['data']['downloads']['plugins'][ $plugin_slug ];
1145
  }
1146
 
1301
  'site_url' => get_site_url(),
1302
  );
1303
  $this->save_settings();
1304
+ $this->clean_plugins_update_cache();
1305
  } else {
1306
  $error = __( 'Invalid site key for the current site.', 'installer' )
1307
  . '<br /><div class="installer-footnote">' . __( 'Please note that the site key is case sensitive.', 'installer' ) . '</div>';
1350
  if ( isset( $this->settings['repositories'][ $repository_id ] ) ) {
1351
  unset( $this->settings['repositories'][ $repository_id ]['subscription'] );
1352
  $this->save_settings();
1353
+ $this->clean_plugins_update_cache();
1354
  if( $refresh_repositories_data ){
1355
  $this->refresh_repositories_data();
1356
  }
1357
  }
1358
  }
1359
 
 
 
 
 
 
 
 
1360
  public function validate_repository_subscription() {
1361
  $repository_id = isset( $_GET['validate_repository'] ) ? sanitize_text_field( $_GET['validate_repository'] ) : false;
1362
  if ( $repository_id ) {
1383
 
1384
  }
1385
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1386
  public function api_debug_log( $text ) {
1387
 
1388
  if ( defined( 'WPML_DEBUG_INSTALLER' ) && WPML_DEBUG_INSTALLER ) {
1516
  public function get_subscription( $repository_id ) {
1517
  $data = null;
1518
  if ( ! empty( $this->settings['repositories'][ $repository_id ]['subscription'] ) ) {
1519
+ $data = $this->settings['repositories'][ $repository_id ]['subscription'];
1520
  }
1521
 
1522
  return new OTGS_Installer_Subscription( $data );
1771
 
1772
  foreach ( $package['products'] as $product ) {
1773
 
1774
+ if ( $subscription_type === (int) $product['subscription_type'] || $subscription_type === (int) $product['subscription_type_equivalent'] ) {
1775
  $has_top_package = true;
1776
  if ( $product['name'] == $product_name ) {
1777
  return $available = true;
1783
  if ( ! empty( $package['sub-packages'] ) ) {
1784
  foreach ( $package['sub-packages'] as $sub_package ) {
1785
  foreach ( $sub_package['products'] as $product ) {
1786
+ if ( $product['name'] == $product_name && ( $subscription_type === (int) $product['subscription_type'] || $subscription_type === (int) $product['subscription_type_equivalent'] || $has_top_package ) ) {
1787
  return $available = true;
1788
  }
1789
  }
1977
 
1978
  $data = json_decode( base64_decode( sanitize_text_field( $_POST['data'] ) ), true );
1979
 
1980
+ $data_url_parsed = wp_parse_url( $data['url'] );
1981
+ $data_url_args = $data_url_parsed['query'];
1982
+ unset( $data_url_parsed['query'] );
1983
+ $data_url = http_build_url( $data_url_parsed );
1984
+
1985
  $ret = false;
1986
  $plugin_id = false;
1987
  $message = '';
1994
  } catch ( Exception $e ) {
1995
  $connection_error = $e->getMessage();
1996
  $subscription_data = false;
1997
+
1998
+ $this->store_log( $data_url, $data_url_args, OTGS_Installer_Logger_Storage::COMPONENT_SUBSCRIPTION, $connection_error );
1999
  }
2000
 
2001
  if ( $subscription_data && ! is_wp_error( $subscription_data ) && $this->repository_has_valid_subscription( $data['repository_id'] ) ) {
2087
  $message = __( 'Your subscription appears to no longer be valid. Please try to register again using a valid site key.', 'installer' );
2088
  }
2089
 
2090
+ if ( $message ) {
2091
+ $this->store_log( $data_url, $data_url_args, OTGS_Installer_Logger_Storage::COMPONENT_DOWNLOAD, $message );
2092
+ }
2093
+
2094
  $response['version'] = isset( $plugin_version ) ? $plugin_version : 0;
2095
  $response['non_stable']= isset( $non_stable ) ? $non_stable : '';
2096
  $response['plugin_id'] = $plugin_id;
2182
 
2183
  }
2184
 
2185
+ public function custom_plugins_api_call( $result, $action, $args ) {
2186
 
2187
  if ( $action == 'plugin_information' ) {
2188
 
2189
  $plugins = get_plugins();
2190
+ $installed_plugins = array();
2191
  foreach ( $plugins as $plugin_id => $plugin ) {
2192
  // plugins by WP slug which (plugin folder) which can be different
2193
  // will use this to compare by title
2194
+ $installed_plugins[ dirname( $plugin_id ) ] = array(
2195
+ 'name' => $plugin['Name'],
2196
+ 'title' => $plugin['Title'],
2197
+ 'is_lite' => false !== stripos( $plugin['Version'], '-lite' ),
2198
  );
2199
  }
2200
 
2201
+ $slug = $args->slug;
2202
+ $custom_plugin = false;
2203
 
2204
  foreach ( $this->settings['repositories'] as $repository_id => $repository ) {
2205
 
2218
  $download = $this->settings['repositories'][ $repository_id ]['data']['downloads']['plugins'][ $plugin_slug ];
2219
 
2220
  if ( $download['slug'] == $slug ||
2221
+ isset( $installed_plugins[ $slug ] ) && (
2222
+ $installed_plugins[ $slug ]['name'] == $download['name'] ||
2223
+ $installed_plugins[ $slug ]['title'] == $download['name']
2224
  )
2225
  ) {
2226
 
2227
+ $this_plugin = new stdClass();
2228
+ $this_plugin->external = true;
2229
+
2230
+ $this_plugin->is_free = $this->should_fallback_under_wp_org_repo( $download,
2231
+ $site_key );
2232
+ $this_plugin->is_lite = ! empty( $download['is-lite'] );
2233
+ $this_plugin->is_download_available = $this->is_product_available_for_download( $product['name'],
2234
+ $repository_id );
2235
+
2236
+ if ( $custom_plugin ) {
2237
+ if ( ( ! $custom_plugin->is_free && $this_plugin->is_free )
2238
+ || ( ! $custom_plugin->is_lite && $custom_plugin->is_download_available )
2239
+ || ( $custom_plugin->is_lite && ! $this_plugin->is_download_available && $installed_plugins[ $slug ]['is_lite'] )
2240
+ ) {
2241
+ continue;
2242
+ }
2243
  }
2244
+ $custom_plugin = $this_plugin;
2245
 
2246
+ $custom_plugin->name = $download['name'];
2247
+ $custom_plugin->slug = $slug;
2248
+ $custom_plugin->version = $download['version'];
2249
+ $custom_plugin->author = '';
2250
+ $custom_plugin->author_profile = '';
2251
+ $custom_plugin->last_updated = $download['date'];
2252
+ $custom_plugin->tested = isset( $download['tested'] ) ? $download['tested'] : '';
 
 
2253
 
2254
  if ( $site_key ) {
2255
+ $custom_plugin->download_link = $this->append_site_key_to_download_url( $download['url'],
2256
+ $site_key, $repository_id );
2257
  }
2258
 
2259
+ $custom_plugin->homepage = $repository['data']['url'];
2260
+ $custom_plugin->sections = array(
2261
  'Description' => $download['description'],
2262
  'Changelog' => $download['changelog']
2263
  );
2264
 
 
 
2265
  }
2266
 
2267
  }
2272
 
2273
  }
2274
 
2275
+ if ( $custom_plugin ) {
2276
+ if ( $custom_plugin->is_free ) {
2277
+ $result = false;
2278
+ } else {
2279
+ $result = $custom_plugin;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2280
  }
 
2281
  }
2282
 
2283
  }
2284
 
2285
+ return $result;
2286
 
2287
  }
2288
 
2303
  array( $this->plugin_path() . '/templates/components-setting/' )
2304
  );
2305
  $local_components_setting = new OTGS_Installer_WP_Share_Local_Components_Setting();
2306
+ $plugin_page_notice = new OTGS_Installer_Plugins_Page_Notice( $template_service->get_service(), $this->get_plugin_finder() );
2307
 
2308
  foreach ( $plugins as $plugin_id => $plugin ) {
2309
 
2328
 
2329
  foreach ( $product['plugins'] as $plugin_slug ) {
2330
 
2331
+ $plugin_finder = $this->get_plugin_finder();
2332
+ $plugin_found = $plugin_finder->get_plugin( $plugin_slug, $repository_id );
2333
+ $external_repo = $plugin_found->get_external_repo();
2334
+
2335
+ if ( $external_repo && $this->plugin_is_registered( $external_repo, $plugin_slug ) ) {
2336
+ continue;
2337
+ }
2338
+
2339
  $download = $this->settings['repositories'][ $repository_id ]['data']['downloads']['plugins'][ $plugin_slug ];
2340
  $display_subscription_notice = false;
2341
  $display_setting_notice = false;
2351
  if ( ! $this->should_fallback_under_wp_org_repo( $download, $site_key ) || $this->has_non_wporg_upgrade_available( $plugin_id ) ) {
2352
  $display_subscription_notice = true;
2353
  }
2354
+
2355
+ if ( $external_repo && ! $this->plugin_is_registered( $external_repo, $plugin_slug ) && ! $this->plugin_is_registered( $plugin_found->get_repo(), $plugin_slug ) ) {
2356
+ $display_subscription_notice = true;
2357
+ }
2358
+
2359
+ if ( 'Toolset Types' === $name && version_compare( $plugin['Version'], '3.0', '<' ) ) {
2360
+ $display_subscription_notice = false;
2361
+ }
2362
+
2363
+ if ( 'Toolset Types' === $name && $this->plugin_is_registered( 'wpml', $slug ) ) {
2364
+ $display_subscription_notice = false;
2365
+ }
2366
  }
2367
  }
2368
 
2653
  return false;
2654
  }
2655
 
2656
+ /**
2657
+ * @return OTGS_Installer_Plugin_Finder
2658
+ */
2659
+ private function get_plugin_finder() {
2660
+ if ( ! $this->plugin_finder ) {
2661
+ $this->plugin_finder = new OTGS_Installer_Plugin_Finder( new OTGS_Installer_Plugin_Factory(), $this->settings['repositories'] );
2662
+ }
2663
+
2664
+ return $this->plugin_finder;
2665
+ }
2666
+
2667
+ private function clean_plugins_update_cache() {
2668
+ do_action( 'otgs_installer_clean_plugins_update_cache' );
2669
+ }
2670
+
2671
  public function plugin_upgrade_custom_errors() {
2672
 
2673
  if ( isset( $_REQUEST['action'] ) ) {
2720
  if ( empty( $sub_cache[ $plugin_repository ] ) ) {
2721
  $subscription_data = false;
2722
  $site_key = $this->get_repository_site_key( $plugin_repository );
2723
+
2724
+ if ( ! $site_key ) {
2725
+ list( $plugin_repository, $site_key ) = $this->match_product_in_external_repository( $plugin_repository, $wp_plugin_slug );
2726
+ }
2727
+
2728
  if ( $site_key ) {
2729
  try {
2730
  $subscription_data = $this->fetch_subscription_data( $plugin_repository, $site_key, self::SITE_KEY_VALIDATION_SOURCE_REVALIDATION );
2739
  $subscription_data = $sub_cache[ $plugin_repository ]['subscription_data'];
2740
  }
2741
 
2742
+ if ( ! $site_key && ( ! empty( $free_on_wporg ) || $this->should_fallback_under_wp_org_repo( $download, $site_key ) ) ) { // allow the download from wp.org
2743
  continue;
2744
  }
2745
 
2804
 
2805
  //validate subscription
2806
  $site_key = $this->get_repository_site_key( $plugin_repository );
2807
+
2808
+ if ( ! $site_key ) {
2809
+ list( $plugin_repository, $site_key ) = $this->match_product_in_external_repository( $plugin_repository, $wp_plugin_slug );
2810
+ }
2811
+
2812
  if ( $site_key ) {
2813
  try {
2814
  $subscription_data = $this->fetch_subscription_data( $plugin_repository, $site_key, self::SITE_KEY_VALIDATION_SOURCE_REVALIDATION );
2864
 
2865
  }
2866
 
2867
+ private function store_log( $url, $url_args, $component, $response ) {
2868
+ $logger_storage = $this->get_logger_storage();
2869
+
2870
+ $log = new OTGS_Installer_Log();
2871
+ $log->set_request_url( $url )
2872
+ ->set_component( $component )
2873
+ ->set_response( $response )
2874
+ ->set_request_args( $url_args );
2875
+
2876
+ $logger_storage->add( $log );
2877
+ }
2878
+
2879
+ /**
2880
+ * @return OTGS_Installer_Logger_Storage
2881
+ */
2882
+ private function get_logger_storage() {
2883
+ if ( ! $this->logger_storage ) {
2884
+ $this->logger_storage = new OTGS_Installer_Logger_Storage( new OTGS_Installer_Log_Factory() );
2885
+ }
2886
+
2887
+ return $this->logger_storage;
2888
+ }
2889
+
2890
+ public function get_api_debug() {
2891
+ return $this->api_debug;
2892
+ }
2893
+
2894
+ /**
2895
+ * @param string $current_repository
2896
+ * @param string $plugin_slug
2897
+ *
2898
+ * @return array
2899
+ */
2900
+ private function match_product_in_external_repository( $current_repository, $plugin_slug ) {
2901
+ foreach( $this->get_repositories() as $repo => $repo_data ) {
2902
+ if ( $repo !== $current_repository ) {
2903
+ $plugin_finder = $this->get_plugin_finder();
2904
+ $plugin_obj = $plugin_finder->get_plugin( $plugin_slug, $repo );
2905
+
2906
+ if ( $plugin_obj ) {
2907
+ $site_key = $this->get_repository_site_key( $repo );
2908
+
2909
+ if ( $site_key ) {
2910
+ return array( $repo, $site_key );
2911
+ }
2912
+ }
2913
+ }
2914
+ }
2915
+
2916
+ return array( '', '' );
2917
+ }
2918
+
2919
  }
vendor/otgs/installer/includes/debug/class-otgs-installer-log-factory.php ADDED
@@ -0,0 +1,11 @@
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class OTGS_Installer_Log_Factory {
4
+
5
+ /**
6
+ * @return OTGS_Installer_Log
7
+ */
8
+ public function create() {
9
+ return new OTGS_Installer_Log();
10
+ }
11
+ }
vendor/otgs/installer/includes/debug/class-otgs-installer-log.php ADDED
@@ -0,0 +1,95 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class OTGS_Installer_Log {
4
+
5
+ private $time;
6
+ private $request_url;
7
+ private $request_args;
8
+ private $response;
9
+ private $component;
10
+
11
+ /**
12
+ * @return string
13
+ */
14
+ public function get_time() {
15
+ return $this->time;
16
+ }
17
+
18
+ /**
19
+ * @param string $time
20
+ *
21
+ * @return $this
22
+ */
23
+ public function set_time( $time ) {
24
+ $this->time = $time;
25
+ return $this;
26
+ }
27
+
28
+ /**
29
+ * @return string
30
+ */
31
+ public function get_request_url() {
32
+ return $this->request_url;
33
+ }
34
+
35
+ /**
36
+ * @param string $request_url
37
+ *
38
+ * @return $this
39
+ */
40
+ public function set_request_url( $request_url ) {
41
+ $this->request_url = $request_url;
42
+ return $this;
43
+ }
44
+
45
+ /**
46
+ * @return array
47
+ */
48
+ public function get_request_args() {
49
+ return $this->request_args;
50
+ }
51
+
52
+ /**
53
+ * @param array $request_args
54
+ *
55
+ * @return $this
56
+ */
57
+ public function set_request_args( $request_args ) {
58
+ $this->request_args = $request_args;
59
+ return $this;
60
+ }
61
+
62
+ /**
63
+ * @return string
64
+ */
65
+ public function get_response() {
66
+ return $this->response;
67
+ }
68
+
69
+ /**
70
+ * @param string $response
71
+ *
72
+ * @return $this
73
+ */
74
+ public function set_response( $response ) {
75
+ $this->response = $response;
76
+ return $this;
77
+ }
78
+
79
+ /**
80
+ * @return string
81
+ */
82
+ public function get_component() {
83
+ return $this->component;
84
+ }
85
+
86
+ /**
87
+ * @param string $component
88
+ *
89
+ * @return $this
90
+ */
91
+ public function set_component( $component ) {
92
+ $this->component = $component;
93
+ return $this;
94
+ }
95
+ }
vendor/otgs/installer/includes/debug/class-otgs-installer-logger-storage.php ADDED
@@ -0,0 +1,85 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class OTGS_Installer_Logger_Storage {
4
+
5
+ const MAX_SIZE = 50;
6
+
7
+ const OPTION_KEY = 'otgs-installer-log';
8
+ const COMPONENT_SUBSCRIPTION = 'subscription-fetching';
9
+ const COMPONENT_DOWNLOAD = 'download';
10
+ const COMPONENT_REPOSITORIES = 'repositories-fetching';
11
+ const API_CONNECTION_TEST = 'api-connection-test';
12
+ const PRODUCTS_FILE_CONNECTION_TEST = 'products-connection-test';
13
+
14
+ private $log_entries;
15
+ private $log_factory;
16
+ private $max_size;
17
+
18
+ public function __construct( OTGS_Installer_Log_Factory $log_factory, $max_size = self::MAX_SIZE ) {
19
+ $this->max_size = $max_size;
20
+ $this->log_factory = $log_factory;
21
+ }
22
+
23
+ /**
24
+ * @return array|OTGS_Installer_Log[]
25
+ */
26
+ public function get() {
27
+ if ( ! $this->log_entries ) {
28
+ $this->log_entries = get_option( self::OPTION_KEY );
29
+ }
30
+
31
+ return $this->convert_to_object( $this->log_entries ? $this->log_entries : array() );
32
+ }
33
+
34
+ public function add( OTGS_Installer_Log $log ) {
35
+ $log->set_time( date( 'Y-d-m h:m:s' ) );
36
+ $log_entries = $this->get();
37
+ array_unshift( $log_entries, $log );
38
+ $log_entries = array_slice( $log_entries, 0, $this->max_size );
39
+ $log_entries_arr = $this->convert_to_array( $log_entries );
40
+ update_option( self::OPTION_KEY, $log_entries_arr );
41
+ $this->log_entries = $log_entries_arr;
42
+ }
43
+
44
+ /**
45
+ * @param array $log_entries
46
+ *
47
+ * @return array
48
+ */
49
+ private function convert_to_object( $log_entries ) {
50
+ $log_converted = array();
51
+
52
+ foreach ( $log_entries as $log_data ) {
53
+ $log = $this->log_factory->create();
54
+ $log->set_request_args( $log_data['request_args'] )
55
+ ->set_request_url( $log_data['request_url'] )
56
+ ->set_response( $log_data['response'] )
57
+ ->set_time( $log_data['time'] )
58
+ ->set_component( $log_data['component'] );
59
+ $log_converted[] = $log;
60
+ }
61
+
62
+ return $log_converted;
63
+ }
64
+
65
+ /**
66
+ * @param OTGS_Installer_Log[] $log_entries
67
+ *
68
+ * @return array
69
+ */
70
+ private function convert_to_array( $log_entries ) {
71
+ $log_converted = array();
72
+
73
+ foreach ( $log_entries as $log_data ) {
74
+ $log_converted[] = array(
75
+ 'request_args' => $log_data->get_request_args(),
76
+ 'request_url' => $log_data->get_request_url(),
77
+ 'response' => $log_data->get_response(),
78
+ 'component' => $log_data->get_component(),
79
+ 'time' => $log_data->get_time(),
80
+ );
81
+ }
82
+
83
+ return $log_converted;
84
+ }
85
+ }
vendor/otgs/installer/includes/debug/class-otgs-installer-logger.php ADDED
@@ -0,0 +1,29 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class OTGS_Installer_Logger {
4
+
5
+ private $installer;
6
+ private $storage;
7
+ private $logger_factory;
8
+
9
+ public function __construct( WP_Installer $installer, OTGS_Installer_Logger_Storage $storage ) {
10
+ $this->installer = $installer;
11
+ $this->storage = $storage;
12
+ }
13
+
14
+ public function get_api_log() {
15
+ return $this->installer->get_api_debug();
16
+ }
17
+
18
+ public function add_api_log( $log ) {
19
+ $this->installer->api_debug_log( $log );
20
+ }
21
+
22
+ public function save_log( OTGS_Installer_Log $log ) {
23
+ $this->storage->add( $log );
24
+ }
25
+
26
+ public function add_log( $log ) {
27
+ $this->installer->log( $log );
28
+ }
29
+ }
vendor/otgs/installer/includes/exceptions/class-otgs-installer-fetch-subscription-exception.php ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
1
+ <?php
2
+
3
+ class OTGS_Installer_Fetch_Subscription_Exception extends Exception {
4
+
5
+ }
vendor/otgs/installer/includes/exceptions/class-otgs-installer-site-key-exception.php ADDED
@@ -0,0 +1,4 @@
 
 
 
 
1
+ <?php
2
+
3
+ class OTGS_Installer_Site_Key_Exception extends Exception {
4
+ }
vendor/otgs/installer/includes/instances/class-otgs-installer-instance.php ADDED
@@ -0,0 +1,92 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class OTGS_Installer_Instance {
4
+
5
+ /**
6
+ * @var string
7
+ */
8
+ private $bootfile;
9
+
10
+ /**
11
+ * @var string
12
+ */
13
+ private $version;
14
+
15
+ /**
16
+ * @var string
17
+ */
18
+ private $high_priority;
19
+
20
+ /**
21
+ * @var bool
22
+ */
23
+ private $delegated;
24
+
25
+ /**
26
+ * @return string
27
+ */
28
+ public function get_bootfile() {
29
+ return $this->bootfile;
30
+ }
31
+
32
+ /**
33
+ * @return bool
34
+ */
35
+ public function is_delegated() {
36
+ return $this->delegated;
37
+ }
38
+
39
+ /**
40
+ * @return string
41
+ */
42
+ public function get_high_priority() {
43
+ return $this->high_priority;
44
+ }
45
+
46
+ /**
47
+ * @return string
48
+ */
49
+ public function get_version() {
50
+ return $this->version;
51
+ }
52
+
53
+ /**
54
+ * @param string $bootfile
55
+ *
56
+ * @return $this
57
+ */
58
+ public function set_bootfile( $bootfile ) {
59
+ $this->bootfile = $bootfile;
60
+ return $this;
61
+ }
62
+
63
+ /**
64
+ * @param string $high_priority
65
+ *
66
+ * @return $this
67
+ */
68
+ public function set_high_priority( $high_priority ) {
69
+ $this->high_priority = $high_priority;
70
+ return $this;
71
+ }
72
+
73
+ /**
74
+ * @param string $version
75
+ *
76
+ * @return $this
77
+ */
78
+ public function set_version( $version ) {
79
+ $this->version = $version;
80
+ return $this;
81
+ }
82
+
83
+ /**
84
+ * @param bool $delegated
85
+ *
86
+ * @return $this
87
+ */
88
+ public function set_delegated( $delegated ) {
89
+ $this->delegated = (bool) $delegated;
90
+ return $this;
91
+ }
92
+ }
vendor/otgs/installer/includes/instances/class-otgs-installer-instances-factory.php ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class OTGS_Installer_Instances_Factory {
4
+
5
+ public function create() {
6
+ global $wp_installer_instances;
7
+
8
+ return new OTGS_Installer_Instances( $wp_installer_instances );
9
+ }
10
+ }
vendor/otgs/installer/includes/instances/class-otgs-installer-instances.php ADDED
@@ -0,0 +1,32 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class OTGS_Installer_Instances {
4
+
5
+ private $instances;
6
+
7
+ /**
8
+ * @var OTGS_Installer_Instance[]
9
+ */
10
+ private $instances_obj = array();
11
+
12
+ public function __construct( $instances ) {
13
+ $this->instances = $instances;
14
+ }
15
+
16
+ public function get() {
17
+ if ( ! $this->instances_obj ) {
18
+ foreach( $this->instances as $instance ) {
19
+ $instance_obj = new OTGS_Installer_Instance();
20
+ $instance_obj->set_bootfile( $instance['bootfile'] )
21
+ ->set_high_priority( isset( $instance['high_priority'] ) && $instance['high_priority'] )
22
+ ->set_version( $instance['version'] )
23
+ ->set_delegated( isset( $instance['delegated'] ) && $instance['delegated'] );
24
+
25
+ $this->instances_obj[] = $instance_obj;
26
+
27
+ }
28
+ }
29
+
30
+ return $this->instances_obj;
31
+ }
32
+ }
vendor/otgs/installer/includes/otgs-installer-autoload-classmap.php ADDED
@@ -0,0 +1,66 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ $baseDir = dirname( dirname( __FILE__ ) );
3
+
4
+ return array(
5
+ 'IOTGS_Installer_Template_Service' => $baseDir . '/includes/template-service/interface-iotgs-installer-template-service.php',
6
+ 'Installer_Dependencies' => $baseDir . '/includes/class-installer-dependencies.php',
7
+ 'Installer_Theme_Class' => $baseDir . '/includes/class-installer-theme.php',
8
+ 'Installer_Upgrader_Skins' => $baseDir . '/includes/class-installer-upgrader-skins.php',
9
+ 'OTGS_Installer_Autoloader' => $baseDir . '/includes/class-otgs-installer-autoloader.php',
10
+ 'OTGS_Installer_Factory' => $baseDir . '/includes/class-otgs-installer-factory.php',
11
+ 'OTGS_Installer_Fetch_Subscription' => $baseDir . '/includes/site-key/class-otgs-installer-fetch-subscription.php',
12
+ 'OTGS_Installer_Fetch_Subscription_Exception' => $baseDir . '/includes/exceptions/class-otgs-installer-fetch-subscription-exception.php',
13
+ 'OTGS_Installer_Filename_Hooks' => $baseDir . '/includes/class-otgs-installer-filename-hooks.php',
14
+ 'OTGS_Installer_Icons' => $baseDir . '/includes/class-otgs-installer-icons.php',
15
+ 'OTGS_Installer_Logger' => $baseDir . '/includes/debug/class-otgs-installer-logger.php',
16
+ 'OTGS_Installer_PHP_Functions' => $baseDir . '/includes/class-otgs-installer-php-functions.php',
17
+ 'OTGS_Installer_Package' => $baseDir . '/includes/class-otgs-installer-package.php',
18
+ 'OTGS_Installer_Package_Product' => $baseDir . '/includes/class-otgs-installer-package-product.php',
19
+ 'OTGS_Installer_Package_Product_Finder' => $baseDir . '/includes/class-otgs-installer-package-product-finder.php',
20
+ 'OTGS_Installer_Plugin' => $baseDir . '/includes/class-otgs-installer-plugin.php',
21
+ 'OTGS_Installer_Plugin_Factory' => $baseDir . '/includes/class-otgs-installer-plugin-factory.php',
22
+ 'OTGS_Installer_Plugin_Finder' => $baseDir . '/includes/class-otgs-installer-plugin-finder.php',
23
+ 'OTGS_Installer_Plugins_Page_Notice' => $baseDir . '/includes/class-otgs-installer-plugins-page-notice.php',
24
+ 'OTGS_Installer_Repositories' => $baseDir . '/includes/repository/class-otgs-installer-repositories.php',
25
+ 'OTGS_Installer_Repositories_Factory' => $baseDir . '/includes/repository/class-otgs-installer-repositories-factory.php',
26
+ 'OTGS_Installer_Repository' => $baseDir . '/includes/repository/class-otgs-installer-repository.php',
27
+ 'OTGS_Installer_Repository_Factory' => $baseDir . '/includes/repository/class-otgs-installer-repository-factory.php',
28
+ 'OTGS_Installer_Site_Key_Ajax' => $baseDir . '/includes/site-key/class-otgs-installer-site-key-ajax.php',
29
+ 'OTGS_Installer_Site_Key_Exception' => $baseDir . '/includes/exceptions/class-otgs-installer-site-key-exception.php',
30
+ 'OTGS_Installer_Source' => $baseDir . '/includes/class-otgs-installer-source.php',
31
+ 'OTGS_Installer_Source_Factory' => $baseDir . '/includes/class-otgs-installer-source-factory.php',
32
+ 'OTGS_Installer_Subscription' => $baseDir . '/includes/class-otgs-installer-subscription.php',
33
+ 'OTGS_Installer_Twig_Template_Service' => $baseDir . '/includes/template-service/class-otgs-installer-twig-template-service.php',
34
+ 'OTGS_Installer_Twig_Template_Service_Loader' => $baseDir . '/includes/template-service/class-otgs-installer-twig-template-service-loader.php',
35
+ 'OTGS_Installer_Upgrade_Response' => $baseDir . '/includes/upgrade/class-otgs-installer-upgrade-response.php',
36
+ 'OTGS_Installer_WP_Components_Hooks' => $baseDir . '/includes/class-otgs-installer-wp-components-hooks.php',
37
+ 'OTGS_Installer_WP_Components_Sender' => $baseDir . '/includes/class-otgs-installer-wp-components-sender.php',
38
+ 'OTGS_Installer_WP_Components_Setting_Ajax' => $baseDir . '/includes/class-otgs-installer-wp-components-setting-ajax.php',
39
+ 'OTGS_Installer_WP_Components_Setting_Resources' => $baseDir . '/includes/class-otgs-installer-wp-components-setting-resources.php',
40
+ 'OTGS_Installer_WP_Components_Storage' => $baseDir . '/includes/class-otgs-installer-wp-components-storage.php',
41
+ 'OTGS_Installer_WP_Share_Local_Components_Setting' => $baseDir . '/includes/class-otgs-installer-wp-share-local-components-setting.php',
42
+ 'OTGS_Installer_WP_Share_Local_Components_Setting_Hooks' => $baseDir . '/includes/class-otgs-installer-wp-share-local-components-setting-hooks.php',
43
+ 'OTGS_Installer_Subscription_Factory' => $baseDir . '/includes/class-otgs-installer-subscription-factory.php',
44
+ 'OTGS_Twig_Autoloader' => $baseDir . '/includes/class-otgs-twig-autoloader.php',
45
+ 'Translation_Service_Info' => $baseDir . '/includes/class-translation-service-info.php',
46
+ 'WP_Installer' => $baseDir . '/includes/class-wp-installer.php',
47
+ 'WP_Installer_API' => $baseDir . '/includes/class-wp-installer-api.php',
48
+ 'WP_Installer_Channels' => $baseDir . '/includes/class-wp-installer-channels.php',
49
+ 'OTGS_Installer_Debug_Info' => $baseDir . '/includes/class-otgs-installer-debug-info.php',
50
+ 'OTGS_Installer_Loader' => $baseDir . '/includes/class-otgs-installer-loader.php',
51
+ 'OTGS_Installer_Logger_Storage' => $baseDir . '/includes/debug/class-otgs-installer-logger-storage.php',
52
+ 'OTGS_Installer_Log' => $baseDir . '/includes/debug/class-otgs-installer-log.php',
53
+ 'OTGS_Installer_Log_Factory' => $baseDir . '/includes/debug/class-otgs-installer-log-factory.php',
54
+ 'OTGS_Installer_Support_Hooks' => $baseDir . '/includes/support/class-otgs-installer-support-hooks.php',
55
+ 'OTGS_Installer_Support_Template' => $baseDir . '/includes/support/class-otgs-installer-support-template.php',
56
+ 'OTGS_Installer_Support_Template_Factory' => $baseDir . '/includes/support/class-otgs-installer-support-template-factory.php',
57
+ 'OTGS_Installer_Connection_Test' => $baseDir . '/includes/support/class-otgs-installer-connection-test.php',
58
+ 'OTGS_Installer_Connection_Test_Exception' => $baseDir . '/includes/support/class-otgs-installer-connection-test-exception.php',
59
+ 'OTGS_Installer_Connection_Test_Ajax' => $baseDir . '/includes/support/class-otgs-installer-connection-test-ajax.php',
60
+ 'OTGS_Installer_Requirements' => $baseDir . '/includes/support/class-otgs-installer-requirements.php',
61
+ 'OTGS_Installer_Instance' => $baseDir . '/includes/instances/class-otgs-installer-instance.php',
62
+ 'OTGS_Installer_Instances' => $baseDir . '/includes/instances/class-otgs-installer-instances.php',
63
+ 'OTGS_Installer_Instances_Factory' => $baseDir . '/includes/instances/class-otgs-installer-instances-factory.php',
64
+ 'OTGS_Installer_Plugins_Update_Cache_Cleaner' => $baseDir . '/includes/class-otgs-installer-plugins-update-cache-cleaner.php',
65
+ 'OTGS_Installer_Buy_URL_Hooks' => $baseDir . '/includes/buy-url/class-otgs-installer-buy-url-hooks.php',
66
+ );
vendor/otgs/installer/includes/repository/class-otgs-installer-repositories-factory.php ADDED
@@ -0,0 +1,8 @@
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class OTGS_Installer_Repositories_Factory {
4
+
5
+ public function create( WP_Installer $installer ) {
6
+ return new OTGS_Installer_Repositories( $installer, new OTGS_Installer_Repository_Factory(), new OTGS_Installer_Subscription_Factory() );
7
+ }
8
+ }
vendor/otgs/installer/includes/repository/class-otgs-installer-repositories.php ADDED
@@ -0,0 +1,130 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class OTGS_Installer_Repositories {
4
+
5
+ private $installer;
6
+ private $repositories;
7
+ private $repository_factory;
8
+ private $subscription_factory;
9
+
10
+ public function __construct(
11
+ WP_Installer $installer,
12
+ OTGS_Installer_Repository_Factory $repository_factory,
13
+ OTGS_Installer_Subscription_Factory $subscription_factory
14
+ ) {
15
+ $this->repository_factory = $repository_factory;
16
+ $this->subscription_factory = $subscription_factory;
17
+ $this->installer = $installer;
18
+ $settings = $this->installer->get_settings();
19
+ $this->repositories = $this->get_repositories( $settings['repositories'] );
20
+ }
21
+
22
+ public function get_all() {
23
+ return $this->repositories;
24
+ }
25
+
26
+ private function get_repositories( $setting_repositories ) {
27
+ $repositories = array();
28
+
29
+ foreach ( $setting_repositories as $id => $repository ) {
30
+ $subscription = isset( $repository['subscription']['data'] )
31
+ ? $this->subscription_factory->create( $repository['subscription'] )
32
+ : null;
33
+
34
+ $setting_repositories = $this->installer->get_repositories();
35
+
36
+ $packages = $this->get_packages( $repository );
37
+ $repositories[] = $this->repository_factory->create_repository( array(
38
+ 'id' => $id,
39
+ 'subscription' => $subscription,
40
+ 'packages' => $packages,
41
+ 'product_name' => $repository['data']['product-name'],
42
+ 'api_url' => $setting_repositories[ $id ]['api-url'],
43
+ 'products_url' => $setting_repositories[ $id ]['products'],
44
+ )
45
+ );
46
+ }
47
+
48
+ return $repositories;
49
+ }
50
+
51
+ private function get_packages( $repository ) {
52
+ $packages = array();
53
+
54
+ foreach ( $repository['data']['packages'] as $package_key => $package ) {
55
+ $products = $this->get_products( $package );
56
+
57
+ $packages[] = $this->repository_factory->create_package( array(
58
+ 'key' => $package_key,
59
+ 'id' => $package['id'],
60
+ 'name' => $package['name'],
61
+ 'description' => $package['description'],
62
+ 'image_url' => $package['image_url'],
63
+ 'order' => $package['order'],
64
+ 'parent' => $package['parent'],
65
+ 'products' => $products,
66
+ ) );
67
+ }
68
+
69
+ return $packages;
70
+ }
71
+
72
+ private function get_products( $package ) {
73
+ $products = array();
74
+
75
+ foreach ( $package['products'] as $product_key => $product ) {
76
+ $products[] = $this->repository_factory->create_product( array(
77
+ 'id' => $product_key,
78
+ 'name' => $product['name'],
79
+ 'description' => $product['description'],
80
+ 'price' => $product['price'],
81
+ 'subscription_type' => $product['subscription_type'],
82
+ 'subscription_type_text' => $product['subscription_type_text'],
83
+ 'subscription_info' => $product['subscription_info'],
84
+ 'subscription_type_equivalent' => $product['subscription_type_equivalent'],
85
+ 'url' => $product['url'],
86
+ 'renewals' => $product['renewals'],
87
+ 'upgrades' => $product['upgrades'],
88
+ 'plugins' => $product['plugins'],
89
+ 'downloads' => $product['downloads'],
90
+ ) );
91
+ }
92
+
93
+ return $products;
94
+ }
95
+
96
+ /**
97
+ * @param $id
98
+ *
99
+ * @return null|OTGS_Installer_Repository
100
+ */
101
+ public function get( $id ) {
102
+ foreach ( $this->repositories as $repository ) {
103
+ if ( $id === $repository->get_id() ) {
104
+ return $repository;
105
+ }
106
+ }
107
+
108
+ return null;
109
+ }
110
+
111
+ public function refresh() {
112
+ $this->installer->refresh_repositories_data();
113
+ }
114
+
115
+ public function save_subscription( OTGS_Installer_Repository $repository ) {
116
+ $subscription = $repository->get_subscription();
117
+ unset( $this->installer->settings['repositories'][ $repository->get_id() ]['subscription'] );
118
+
119
+ if ( $subscription ) {
120
+ $this->installer->settings['repositories'][ $repository->get_id() ]['subscription'] = array(
121
+ 'key' => $subscription->get_site_key(),
122
+ 'data' => $subscription->get_data(),
123
+ 'registered_by' => $subscription->get_registered_by(),
124
+ 'site_url' => $subscription->get_site_url(),
125
+ );
126
+ }
127
+
128
+ $this->installer->save_settings();
129
+ }
130
+ }
vendor/otgs/installer/includes/repository/class-otgs-installer-repository-factory.php ADDED
@@ -0,0 +1,16 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class OTGS_Installer_Repository_Factory {
4
+
5
+ public function create_repository( $params ) {
6
+ return new OTGS_Installer_Repository( $params );
7
+ }
8
+
9
+ public function create_package( $params ) {
10
+ return new OTGS_Installer_Package( $params );
11
+ }
12
+
13
+ public function create_product( $params ) {
14
+ return new OTGS_Installer_Package_Product( $params );
15
+ }
16
+ }
vendor/otgs/installer/includes/repository/class-otgs-installer-repository.php ADDED
@@ -0,0 +1,114 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class OTGS_Installer_Repository {
4
+
5
+ private $id;
6
+ private $subscription;
7
+ private $packages;
8
+ private $product_name;
9
+ private $api_url;
10
+ private $products_url;
11
+
12
+ public function __construct( array $params = array() ) {
13
+ foreach ( get_object_vars( $this ) as $property => $value ) {
14
+ if ( array_key_exists( $property, $params ) ) {
15
+ $this->$property = $params[ $property ];
16
+ }
17
+ }
18
+ }
19
+
20
+ /**
21
+ * @return string
22
+ */
23
+ public function get_id() {
24
+ return $this->id;
25
+ }
26
+
27
+ /**
28
+ * @return string
29
+ */
30
+ public function get_product_name() {
31
+ return $this->product_name;
32
+ }
33
+
34
+ /**
35
+ * @param bool $ssl
36
+ *
37
+ * @return string
38
+ */
39
+ public function get_api_url( $ssl = true ) {
40
+ $api_url = $this->api_url;
41
+
42
+ if ( ! $ssl ) {
43
+ $api_url = wp_parse_url( $api_url );
44
+ $api_url['scheme'] = 'http';
45
+ $api_url = http_build_url( $api_url );
46
+ }
47
+
48
+ return $api_url;
49
+ }
50
+
51
+ /**
52
+ * @return OTGS_Installer_Subscription
53
+ */
54
+ public function get_subscription() {
55
+ return $this->subscription;
56
+ }
57
+
58
+ /**
59
+ * @return string
60
+ */
61
+ public function get_products_url() {
62
+ return $this->products_url;
63
+ }
64
+
65
+ /**
66
+ * @return array
67
+ */
68
+ public function get_packages() {
69
+ return $this->packages;
70
+ }
71
+
72
+ /**
73
+ * @return null|OTGS_Installer_Package_Product
74
+ */
75
+ public function get_product_by_subscription_type() {
76
+ return $this->get_product_by( 'get_product_by_subscription_type' );
77
+ }
78
+
79
+ /**
80
+ * @return null|OTGS_Installer_Package_Product
81
+ */
82
+ public function get_product_by_subscription_type_equivalent() {
83
+ return $this->get_product_by( 'get_product_by_subscription_type_equivalent' );
84
+ }
85
+
86
+ /**
87
+ * @return null|OTGS_Installer_Package_Product
88
+ */
89
+ public function get_product_by_subscription_type_on_upgrades() {
90
+ return $this->get_product_by( 'get_product_by_subscription_type_on_upgrades' );
91
+ }
92
+
93
+ public function set_subscription( OTGS_Installer_Subscription $subscription = null ) {
94
+ $this->subscription = $subscription;
95
+ }
96
+
97
+ /**
98
+ * @param string $function_name
99
+ *
100
+ * @return null|OTGS_Installer_Package_Product
101
+ */
102
+ private function get_product_by( $function_name ) {
103
+ $subscription_type = $this->subscription->get_type();
104
+ foreach ( $this->packages as $package ) {
105
+ $product = $package->$function_name( $subscription_type );
106
+ if ( $product ) {
107
+ return $product;
108
+ }
109
+ }
110
+
111
+ return null;
112
+ }
113
+
114
+ }
vendor/otgs/installer/includes/site-key/class-otgs-installer-fetch-subscription.php ADDED
@@ -0,0 +1,197 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class OTGS_Installer_Fetch_Subscription {
4
+
5
+ private $package_source_factory;
6
+ private $plugin_finder;
7
+ private $repositories;
8
+ private $logger;
9
+ private $log_factory;
10
+
11
+ public function __construct(
12
+ OTGS_Installer_Source_Factory $package_source_factory,
13
+ OTGS_Installer_Plugin_Finder $plugin_finder,
14
+ OTGS_Installer_Repositories $repositories,
15
+ OTGS_Installer_Logger $logger,
16
+ OTGS_Installer_Log_Factory $log_factory
17
+ ) {
18
+ $this->package_source_factory = $package_source_factory;
19
+ $this->plugin_finder = $plugin_finder;
20
+ $this->repositories = $repositories;
21
+ $this->logger = $logger;
22
+ $this->log_factory = $log_factory;
23
+ }
24
+
25
+ /**
26
+ * @param string $repository_id
27
+ * @param string $site_key
28
+ * @param string $source
29
+ *
30
+ * @return bool|stdClass
31
+ * @throws OTGS_Installer_Fetch_Subscription_Exception
32
+ */
33
+ public function get( $repository_id, $site_key, $source ) {
34
+ if ( ! $repository_id || ! $site_key || ! $source ) {
35
+ throw new OTGS_Installer_Fetch_Subscription_Exception( 'Repository, site key and source are required fields.' );
36
+ }
37
+
38
+ $subscription_data = false;
39
+
40
+ $args['body'] = array(
41
+ 'action' => 'site_key_validation',
42
+ 'site_key' => $site_key,
43
+ 'site_url' => $this->get_installer_site_url( $repository_id ),
44
+ 'source' => $source
45
+ );
46
+
47
+ if ( $repository_id === 'wpml' ) {
48
+ $args['body']['using_icl'] = function_exists( 'wpml_site_uses_icl' ) && wpml_site_uses_icl();
49
+ $args['body']['wpml_version'] = defined( 'ICL_SITEPRESS_VERSION' ) ? ICL_SITEPRESS_VERSION : '';
50
+ }
51
+
52
+ $args['body']['installer_version'] = WP_INSTALLER_VERSION;
53
+ $args['body']['theme'] = wp_get_theme()->get( 'Name' );
54
+ $args['body']['site_name'] = get_bloginfo( 'name' );
55
+ $args['body']['repository_id'] = $repository_id;
56
+ $args['body']['versions'] = $this->get_local_product_versions();
57
+ $args['timeout'] = 45;
58
+
59
+ $package_source = $this->package_source_factory->create()->get();
60
+
61
+ // Add extra parameters for custom Installer packages
62
+ if ( $package_source ) {
63
+ $extra = $this->get_extra_url_parameters( $package_source );
64
+ if ( ! empty( $extra['repository'] ) && $extra['repository'] == $repository_id ) {
65
+ unset( $extra['repository'] );
66
+ foreach ( $extra as $key => $val ) {
67
+ $args['body'][ $key ] = $val;
68
+ }
69
+ }
70
+ }
71
+
72
+ $repository = $this->repositories->get( $repository_id );
73
+
74
+ $valid_response = null;
75
+ $valid_body = null;
76
+ $api_url = null;
77
+
78
+ foreach ( array( $repository->get_api_url(), $repository->get_api_url( false ) ) as $api_url ) {
79
+ $valid_response = false;
80
+ $valid_body = false;
81
+
82
+ $response = wp_remote_post(
83
+ $api_url,
84
+ apply_filters( 'installer_fetch_subscription_data_request', $args )
85
+ );
86
+
87
+ if ( is_wp_error( $response ) ) {
88
+ continue;
89
+ }
90
+
91
+ $valid_response = true;
92
+
93
+ $body = trim( wp_remote_retrieve_body( $response ) );
94
+
95
+ if ( ! $body || ! is_serialized( $body ) ) {
96
+ continue;
97
+ }
98
+
99
+ $valid_body = true;
100
+
101
+ break;
102
+ }
103
+
104
+ $this->logger->add_api_log( "POST {$api_url}" );
105
+ $this->logger->add_api_log( $args );
106
+
107
+ $this->logger->add_log( "POST {$api_url} - fetch subscription data" );
108
+
109
+ if ( $valid_response ) {
110
+ if ( $valid_body ) {
111
+ $data = unserialize( $body );
112
+ $this->logger->add_api_log( $data );
113
+
114
+ if ( isset( $data->subscription_data ) && $data->subscription_data ) {
115
+ $subscription_data = $data->subscription_data;
116
+ } else {
117
+ $this->store_log( $args, $api_url, isset( $data->error ) ? $data->error : '' );
118
+ }
119
+
120
+ do_action( 'installer_fetched_subscription_data', $data, $repository_id );
121
+ } else {
122
+ $this->store_log( $args, $api_url, $response->get_error_message() );
123
+ $this->logger->add_api_log( $body );
124
+ }
125
+
126
+ } else {
127
+ $this->store_log( $args, $api_url, $response->get_error_message() );
128
+ $this->logger->add_api_log( $response );
129
+ throw new OTGS_Installer_Fetch_Subscription_Exception( $response->get_error_message() );
130
+ }
131
+
132
+ return $subscription_data;
133
+ }
134
+
135
+ private function store_log( $args, $request_url, $response ) {
136
+ $log = $this->log_factory->create();
137
+ $log->set_request_args( $args )
138
+ ->set_request_url( $request_url )
139
+ ->set_response( $response )
140
+ ->set_component( OTGS_Installer_Logger_Storage::COMPONENT_SUBSCRIPTION );
141
+
142
+ $this->logger->save_log( $log );
143
+ }
144
+
145
+ /**
146
+ * @return array
147
+ */
148
+ private function get_local_product_versions() {
149
+ $installed_plugins = $this->plugin_finder->get_otgs_installed_plugins();
150
+ $versions = array();
151
+
152
+ foreach ( $installed_plugins as $plugin ) {
153
+ $versions[ $plugin->get_slug() ] = $plugin->get_installed_version();
154
+ }
155
+
156
+ return $versions;
157
+ }
158
+
159
+ /**
160
+ * @param string $source
161
+ *
162
+ * @return array
163
+ */
164
+ private function get_extra_url_parameters( $source ) {
165
+ if ( $source ) {
166
+ $parameters = $source;
167
+ }
168
+
169
+ $parameters['installer_version'] = WP_INSTALLER_VERSION;
170
+ $parameters['theme'] = wp_get_theme()->get( 'Name' );
171
+ $parameters['site_name'] = get_bloginfo( 'name' );
172
+
173
+ return $parameters;
174
+ }
175
+
176
+ /**
177
+ * @param bool $repository_id
178
+ *
179
+ * @return string
180
+ */
181
+ private function get_installer_site_url( $repository_id = false ) {
182
+ global $current_site;
183
+
184
+ $site_url = get_site_url();
185
+
186
+ if ( $repository_id && is_multisite() && $this->repositories->get_all() ) {
187
+ $network_settings = maybe_unserialize( get_site_option( 'wp_installer_network' ) );
188
+
189
+ if ( isset( $network_settings[ $repository_id ] ) ) {
190
+ $site_url = get_site_url( $current_site->blog_id );
191
+ }
192
+
193
+ }
194
+
195
+ return $site_url;
196
+ }
197
+ }
vendor/otgs/installer/includes/site-key/class-otgs-installer-site-key-ajax.php ADDED
@@ -0,0 +1,133 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class OTGS_Installer_Site_Key_Ajax {
4
+
5
+ private $subscription_fetch;
6
+ private $logger;
7
+ private $repositories;
8
+ private $subscription_factory;
9
+
10
+ public function __construct(
11
+ OTGS_Installer_Fetch_Subscription $subscription_fetch,
12
+ OTGS_Installer_Logger $logger,
13
+ OTGS_Installer_Repositories $repositories,
14
+ OTGS_Installer_Subscription_Factory $subscription_factory
15
+ ) {
16
+ $this->subscription_fetch = $subscription_fetch;
17
+ $this->logger = $logger;
18
+ $this->repositories = $repositories;
19
+ $this->subscription_factory = $subscription_factory;
20
+ }
21
+
22
+ public function add_hooks() {
23
+ add_action( 'wp_ajax_save_site_key', array( $this, 'save' ) );
24
+ add_action( 'wp_ajax_remove_site_key', array( $this, 'remove' ) );
25
+ add_action( 'wp_ajax_update_site_key', array( $this, 'update' ) );
26
+ }
27
+
28
+ public function save() {
29
+ $repository = isset( $_POST['repository_id'] ) && $_POST['repository_id'] ? sanitize_text_field( $_POST['repository_id'] ) : null;
30
+ $nonce = isset( $_POST['nonce'] ) && $_POST['nonce'] ? sanitize_text_field( $_POST['nonce'] ) : null;
31
+ $site_key = isset( $_POST[ 'site_key_' . $repository ] ) && $_POST[ 'site_key_' . $repository ] ? sanitize_text_field( $_POST[ 'site_key_' . $repository ] ) : null;
32
+ $site_key = preg_replace( '/[^A-Za-z0-9]/', '', $site_key );
33
+ $error = '';
34
+
35
+ if ( ! $repository || ! $nonce || ! $site_key || ! wp_verify_nonce( $nonce, 'save_site_key_' . $repository ) ) {
36
+ wp_send_json_error( esc_html__( 'Invalid request!', 'installer' ) );
37
+ }
38
+
39
+ try {
40
+ $subscription = $this->subscription_fetch->get( $repository, $site_key, WP_Installer::SITE_KEY_VALIDATION_SOURCE_REGISTRATION );
41
+ if ( $subscription ) {
42
+ $subscription_data = $this->subscription_factory->create( array(
43
+ 'data' => $subscription,
44
+ 'key' => $site_key,
45
+ 'site_url' => get_site_url(),
46
+ 'registered_by' => get_current_user_id()
47
+ ) );
48
+
49
+ $repository = $this->repositories->get( $repository );
50
+ $repository->set_subscription( $subscription_data );
51
+ $this->repositories->save_subscription( $repository );
52
+ } else {
53
+ $error = __( 'Invalid site key for the current site.', 'installer' ) . '<br /><div class="installer-footnote">' . __( 'Please note that the site key is case sensitive.', 'installer' ) . '</div>';
54
+ }
55
+ } catch ( OTGS_Installer_Site_Key_Exception $e ) {
56
+ $repository_data = $this->repositories->get( $repository );
57
+ $error = $this->get_error_message( $e, $repository_data );
58
+ }
59
+
60
+ $response = array( 'error' => $error );
61
+
62
+ if ( $this->logger->get_api_log() ) {
63
+ $response['debug'] = $this->logger->get_api_log();
64
+ }
65
+
66
+ wp_send_json_success( $response );
67
+ }
68
+
69
+ public function remove() {
70
+ $repository = isset( $_POST['repository_id'] ) ? sanitize_text_field( $_POST['repository_id'] ) : null;
71
+ $nonce = isset( $_POST['nonce'] ) ? sanitize_text_field( $_POST['nonce'] ) : null;
72
+ $nonce_action = 'remove_site_key_' . $repository;
73
+
74
+ if ( wp_verify_nonce( $nonce, $nonce_action ) ) {
75
+ $repository = $this->repositories->get( $repository );
76
+ $repository->set_subscription( null );
77
+ $this->repositories->save_subscription( $repository );
78
+ }
79
+
80
+ wp_send_json_success();
81
+ $this->repositories->refresh();
82
+ }
83
+
84
+ public function update() {
85
+ $error = '';
86
+ $nonce = isset( $_POST['nonce'] ) ? $_POST['nonce'] : null;
87
+ $repository = isset( $_POST['repository_id'] ) ? sanitize_text_field( $_POST['repository_id'] ) : null;
88
+
89
+ if ( $nonce && $repository && wp_verify_nonce( $nonce, 'update_site_key_' . $repository ) ) {
90
+ $repository_data = $this->repositories->get( $repository );
91
+ $site_key = $repository_data->get_subscription()->get_site_key();
92
+
93
+ if ( $site_key ) {
94
+ try {
95
+ $subscription = $this->subscription_fetch->get( $repository, $site_key, WP_Installer::SITE_KEY_VALIDATION_SOURCE_REGISTRATION );
96
+
97
+ if ( $subscription ) {
98
+ $subscription_data = $this->subscription_factory->create( array(
99
+ 'data' => $subscription,
100
+ 'key' => $site_key,
101
+ 'site_url' => get_site_url(),
102
+ 'registered_by' => get_current_user_id(),
103
+ ) );
104
+ $repository_data->set_subscription( $subscription_data );
105
+ } else {
106
+ $repository_data->set_subscription( null );
107
+ $error = __( 'Invalid site key for the current site. If the error persists, try to un-register first and then register again with the same site key.', 'installer' );
108
+ }
109
+
110
+ $this->repositories->save_subscription( $repository_data );
111
+ $this->repositories->refresh();
112
+ } catch ( OTGS_Installer_Site_Key_Exception $e ) {
113
+ $error = $this->get_error_message( $e, $repository_data );
114
+ }
115
+ }
116
+
117
+ }
118
+
119
+ wp_send_json_success( array( 'error' => $error ) );
120
+ }
121
+
122
+ private function get_error_message( Exception $e, OTGS_Installer_Repository $repository_data ) {
123
+ $error = $e->getMessage();
124
+ if ( preg_match( '#Could not resolve host: (.*)#', $error, $matches ) || preg_match( '#Couldn\'t resolve host \'(.*)\'#', $error, $matches ) ) {
125
+ $error = sprintf( __( "%s cannot access %s to register. Try again to see if it's a temporary problem. If the problem continues, make sure that this site has access to the Internet. You can still use the plugin without registration, but you will not receive automated updates.", 'installer' ),
126
+ '<strong><i>' . $repository_data->get_product_name() . '</i></strong>',
127
+ '<strong><i>' . $matches[1] . '</i></strong>'
128
+ );
129
+ }
130
+
131
+ return $error;
132
+ }
133
+ }
vendor/otgs/installer/includes/support/class-otgs-installer-connection-test-ajax.php ADDED
@@ -0,0 +1,37 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class OTGS_Installer_Connection_Test_Ajax {
4
+
5
+ const ACTION = 'otgs_installer_test_connection';
6
+
7
+ private $connection_test;
8
+
9
+ public function __construct( OTGS_Installer_Connection_Test $connection_test ) {
10
+ $this->connection_test = $connection_test;
11
+ }
12
+
13
+ public function add_hooks() {
14
+ add_action( 'wp_ajax_' . self::ACTION, array( $this, 'test_connection' ) );
15
+ }
16
+
17
+ public function test_connection() {
18
+ if ( $this->is_valid_request() ) {
19
+ $type = filter_var( $_POST['type'], FILTER_SANITIZE_FULL_SPECIAL_CHARS );
20
+ $repository = filter_var( $_POST['repository'], FILTER_SANITIZE_FULL_SPECIAL_CHARS );
21
+ $method = 'get_' . $type . '_status';
22
+
23
+ if ( $this->connection_test->{$method}( $repository ) ) {
24
+ wp_send_json_success();
25
+ }
26
+ }
27
+
28
+ wp_send_json_error();
29
+ }
30
+
31
+ /**
32
+ * @return bool
33
+ */
34
+ private function is_valid_request() {
35
+ return isset( $_POST['nonce'], $_POST['type'] ) && wp_verify_nonce( $_POST['nonce'], self::ACTION );
36
+ }
37
+ }
vendor/otgs/installer/includes/support/class-otgs-installer-connection-test-exception.php ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
1
+ <?php
2
+
3
+ class OTGS_Installer_Connection_Test_Exception extends Exception {
4
+
5
+ }
vendor/otgs/installer/includes/support/class-otgs-installer-connection-test.php ADDED
@@ -0,0 +1,131 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class OTGS_Installer_Connection_Test {
4
+
5
+ private $repositories;
6
+ private $upgrade_response;
7
+ private $logger_storage;
8
+ private $log_factory;
9
+
10
+ public function __construct(
11
+ OTGS_Installer_Repositories $repositories,
12
+ OTGS_Installer_Upgrade_Response $upgrade_response,
13
+ OTGS_Installer_Logger_Storage $logger_storage,
14
+ OTGS_Installer_Log_Factory $log_factory
15
+ ) {
16
+ $this->repositories = $repositories;
17
+ $this->upgrade_response = $upgrade_response;
18
+ $this->logger_storage = $logger_storage;
19
+ $this->log_factory = $log_factory;
20
+ }
21
+
22
+ /**
23
+ * @param string $repo_id
24
+ *
25
+ * @return null|string
26
+ */
27
+ public function get_api_status( $repo_id ) {
28
+ return $this->get_url_status( $this->repositories->get( $repo_id )->get_api_url() );
29
+ }
30
+
31
+ /**
32
+ * @param string $repo_id
33
+ *
34
+ * @return null|string
35
+ */
36
+ public function get_products_status( $repo_id ) {
37
+ return $this->get_url_status( $this->repositories->get( $repo_id )->get_products_url() );
38
+ }
39
+
40
+ /**
41
+ * @param string $plugin_id
42
+ *
43
+ * @return bool|string
44
+ */
45
+ public function get_download_status( $plugin_id ) {
46
+ $plugins_updates = get_site_transient( 'update_plugins' );
47
+ $update_response = $this->upgrade_response->modify_upgrade_response( $plugins_updates );
48
+ $response = false;
49
+ $error_message = '';
50
+
51
+ if ( isset( $update_response->response[ $plugin_id ] ) ) {
52
+ $request_response = wp_remote_head( $update_response->response[ $plugin_id ]->package );
53
+ $parsed_download_url = wp_parse_url( $update_response->response[ $plugin_id ]->package );
54
+ parse_str( $parsed_download_url['query'], $download_args );
55
+
56
+ if ( is_wp_error( $request_response ) ) {
57
+ $error_message = $request_response->get_error_message();
58
+ } elseif ( ! $this->is_response_successful( $request_response ) ) {
59
+ $error_message = 'Invalid response';
60
+ }
61
+
62
+ if ( $error_message ) {
63
+ $this->log(
64
+ sprintf(
65
+ '%s: an error occurred while trying to get information of this download URL. Error: %s, download: %s, version: %s.',
66
+ $plugin_id,
67
+ $error_message,
68
+ $download_args['download'],
69
+ $download_args['version']
70
+ ),
71
+ $update_response->response[ $plugin_id ]->package
72
+ );
73
+ } else {
74
+ $response = true;
75
+ }
76
+ }
77
+
78
+ return $response;
79
+ }
80
+
81
+ /**
82
+ * @param array $response
83
+ *
84
+ * @return bool
85
+ */
86
+ private function is_response_successful( $response ) {
87
+ return in_array( $response['response']['code'], $this->get_success_codes(), true );
88
+ }
89
+
90
+ /**
91
+ * @param string $url
92
+ *
93
+ * @return bool
94
+ */
95
+ private function get_url_status( $url ) {
96
+ $response = false;
97
+ $res = wp_remote_get( $url );
98
+ $error_message = '';
99
+
100
+ if ( is_wp_error( $res ) ) {
101
+ $error_message = sprintf( "Your site can't communicate with %s. Code %d: %s.", $url, $res->get_error_code(), $res->get_error_message() );
102
+ } elseif ( ! $this->is_response_successful( $res ) ) {
103
+ $error_message = sprintf( "Your site can't communicate with %s. Code %d.", $url, $res['response']['code'] );
104
+ }
105
+
106
+ if ( $error_message ) {
107
+ $this->log(
108
+ $error_message,
109
+ $url
110
+ );
111
+ } else {
112
+ $response = true;
113
+ }
114
+
115
+ return $response;
116
+ }
117
+
118
+ private function log( $msg, $url ) {
119
+ $this->logger_storage->add(
120
+ $this->log_factory
121
+ ->create()
122
+ ->set_request_url( $url )
123
+ ->set_component( OTGS_Installer_Logger_Storage::PRODUCTS_FILE_CONNECTION_TEST )
124
+ ->set_response( $msg )
125
+ );
126
+ }
127
+
128
+ private function get_success_codes() {
129
+ return array( 302, 200 );
130
+ }
131
+ }
vendor/otgs/installer/includes/support/class-otgs-installer-requirements.php ADDED
@@ -0,0 +1,27 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class OTGS_Installer_Requirements {
4
+
5
+ private $requirements;
6
+
7
+ public function get() {
8
+ if ( ! $this->requirements ) {
9
+ $this->requirements = $this->get_requirements();
10
+ }
11
+
12
+ return $this->requirements;
13
+ }
14
+
15
+ private function get_requirements() {
16
+ return array(
17
+ array(
18
+ 'name' => 'cURL',
19
+ 'active' => function_exists( 'curl_version' ),
20
+ ),
21
+ array(
22
+ 'name' => 'simpleXML',
23
+ 'active' => extension_loaded( 'simplexml' ),
24
+ ),
25
+ );
26
+ }
27
+ }
vendor/otgs/installer/includes/support/class-otgs-installer-support-hooks.php ADDED
@@ -0,0 +1,42 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class OTGS_Installer_Support_Hooks {
4
+
5
+ private $template_factory;
6
+
7
+ public function __construct( OTGS_Installer_Support_Template_Factory $template_factory ) {
8
+ $this->template_factory = $template_factory;
9
+ }
10
+
11
+ public function add_hooks() {
12
+ add_action( 'admin_menu', array( $this, 'add_support_page' ) );
13
+ add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_scripts' ) );
14
+ add_action( 'otgs_render_installer_support_link', array( $this, 'render_link' ) );
15
+ }
16
+
17
+ public function add_support_page() {
18
+ add_submenu_page(
19
+ 'commercial',
20
+ __( 'Installer Support', 'installer' ),
21
+ 'Installer Support',
22
+ 'manage_options',
23
+ 'otgs-installer-support',
24
+ array( $this, 'render_support_page' )
25
+ );
26
+ }
27
+
28
+ public function render_support_page() {
29
+ $this->template_factory->create()->show();
30
+ }
31
+
32
+ public function enqueue_scripts( $hook ) {
33
+ if ( 'admin_page_otgs-installer-support' === $hook ) {
34
+ wp_enqueue_style( 'otgs-installer-support-style', WP_Installer()->plugin_url() . '/dist/css/otgs-installer-support/styles.css', array(), WP_Installer()->version() );
35
+ wp_enqueue_script( 'otgs-installer-support-script', WP_Installer()->plugin_url() . '/dist/js/otgs-installer-support/app.js', array(), WP_Installer()->version() );
36
+ }
37
+ }
38
+
39
+ public function render_link( $args = array() ) {
40
+ $this->template_factory->create()->render_support_link( $args );
41
+ }
42
+ }
vendor/otgs/installer/includes/support/class-otgs-installer-support-template-factory.php ADDED
@@ -0,0 +1,28 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class OTGS_Installer_Support_Template_Factory {
4
+
5
+ private $installer_path;
6
+
7
+ public function __construct( $installer_path ) {
8
+ $this->installer_path = $installer_path;
9
+ }
10
+
11
+ /**
12
+ * @return OTGS_Installer_Support_Template
13
+ */
14
+ public function create() {
15
+ $template_service_loader = new OTGS_Installer_Twig_Template_Service_Loader( array(
16
+ $this->installer_path . '/templates/support/',
17
+ ) );
18
+
19
+ $instances_factory = new OTGS_Installer_Instances_Factory();
20
+
21
+ return new OTGS_Installer_Support_Template(
22
+ $template_service_loader->get_service(),
23
+ new OTGS_Installer_Logger_Storage( new OTGS_Installer_Log_Factory() ),
24
+ new OTGS_Installer_Requirements(),
25
+ $instances_factory->create()
26
+ );
27
+ }
28
+ }
vendor/otgs/installer/includes/support/class-otgs-installer-support-template.php ADDED
@@ -0,0 +1,131 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class OTGS_Installer_Support_Template {
4
+
5
+ const TEMPLATE_FILE = 'installer-support';
6
+ const SUPPORT_LINK = 'support-link';
7
+
8
+ private $template_service;
9
+ private $logger_storage;
10
+ private $requirements;
11
+
12
+ /**
13
+ * @var OTGS_Installer_Instance[]
14
+ */
15
+ private $instances;
16
+
17
+ public function __construct(
18
+ OTGS_Installer_Twig_Template_Service $template_service,
19
+ OTGS_Installer_Logger_Storage $logger_storage,
20
+ OTGS_Installer_Requirements $requirements,
21
+ OTGS_Installer_Instances $instances
22
+ ) {
23
+ $this->template_service = $template_service;
24
+ $this->logger_storage = $logger_storage;
25
+ $this->requirements = $requirements;
26
+ $this->instances = $instances;
27
+ }
28
+
29
+ public function show() {
30
+ echo $this->template_service->show( $this->get_model(), self::TEMPLATE_FILE );
31
+ }
32
+
33
+ public function render_support_link( $args = array() ) {
34
+ echo $this->template_service->show( $this->get_support_link_model( $args ), self::SUPPORT_LINK );
35
+ }
36
+
37
+ private function get_support_link_model( $args = array() ) {
38
+ return array(
39
+ 'title' => __( 'Installer Support', 'installer' ),
40
+ 'content' => __( 'For retrieving Installer debug information use the %s page.', 'installer' ),
41
+ 'link' => array(
42
+ 'url' => admin_url( 'admin.php?page=otgs-installer-support' ),
43
+ 'text' => __( 'Installer Support', 'installer' ),
44
+ ),
45
+ 'hide_title' => isset( $args['hide_title'] ) && $args['hide_title'],
46
+ );
47
+ }
48
+
49
+ /**
50
+ * @return array
51
+ */
52
+ private function get_model() {
53
+ $model = array(
54
+ 'log_entries' => $this->get_log_entries(),
55
+ 'strings' => array(
56
+ 'page_title' => __( 'Installer Support', 'installer' ),
57
+ 'log' => array(
58
+ 'title' => __( 'Installer Log', 'installer' ),
59
+ 'request_url' => __( 'Request URL', 'installer' ),
60
+ 'request_arguments' => __( 'Request Arguments', 'installer' ),
61
+ 'response' => __( 'Response', 'installer' ),
62
+ 'component' => __( 'Component', 'installer' ),
63
+ 'time' => __( 'Time', 'installer' ),
64
+ 'empty_log' => __( 'Log is empty', 'installer' ),
65
+ ),
66
+ 'tester' => array(
67
+ 'title' => __( 'Installer System Status', 'installer' ),
68
+ 'button_label' => __( 'Check Now', 'installer' ),
69
+ ),
70
+ 'requirements' => array(
71
+ 'title' => __( 'Required PHP Libraries', 'installer' ),
72
+ ),
73
+ 'instances' => array(
74
+ 'title' => __( 'All Installer Instances', 'installer' ),
75
+ 'path' => __( 'Path', 'installer' ),
76
+ 'version' => __( 'Version', 'installer' ),
77
+ 'high_priority' => __( 'High priority', 'installer' ),
78
+ 'delegated' => __( 'Delegated', 'installer' ),
79
+ ),
80
+ ),
81
+ 'tester' => array(
82
+ 'endpoints' => array(
83
+ array(
84
+ 'repository' => 'wpml',
85
+ 'type' => 'api',
86
+ 'description' => __( 'WPML API server', 'installer' )
87
+ ),
88
+ array(
89
+ 'repository' => 'toolset',
90
+ 'type' => 'api',
91
+ 'description' => __( 'Toolset API server', 'installer' )
92
+ ),
93
+ array(
94
+ 'repository' => 'wpml',
95
+ 'type' => 'products',
96
+ 'description' => __( 'WPML remote products file', 'installer' )
97
+ ),
98
+ array(
99
+ 'repository' => 'toolset',
100
+ 'type' => 'products',
101
+ 'description' => __( 'Toolset remote products file', 'installer' )
102
+ ),
103
+ ),
104
+ 'nonce' => wp_nonce_field( OTGS_Installer_Connection_Test_Ajax::ACTION, OTGS_Installer_Connection_Test_Ajax::ACTION, false ),
105
+ ),
106
+ 'requirements' => $this->requirements->get(),
107
+ 'instances' => $this->instances->get(),
108
+ );
109
+
110
+ return $model;
111
+ }
112
+
113
+ /**
114
+ * @return array
115
+ */
116
+ private function get_log_entries() {
117
+ $log_entries = array();
118
+
119
+ foreach ( $this->logger_storage->get() as $log ) {
120
+ $log_entries[] = array(
121
+ 'request_url' => $log->get_request_url(),
122
+ 'request_arguments' => $log->get_request_args(),
123
+ 'response' => $log->get_response(),
124
+ 'component' => $log->get_component(),
125
+ 'time' => $log->get_time(),
126
+ );
127
+ }
128
+
129
+ return $log_entries;
130
+ }
131
+ }
vendor/otgs/installer/{templates → includes}/template-service/class-otgs-installer-twig-template-service-loader.php RENAMED
File without changes
vendor/otgs/installer/{templates → includes}/template-service/class-otgs-installer-twig-template-service.php RENAMED
File without changes
vendor/otgs/installer/{templates → includes}/template-service/interface-iotgs-installer-template-service.php RENAMED
File without changes
vendor/otgs/installer/includes/upgrade/class-otgs-installer-upgrade-response.php ADDED
@@ -0,0 +1,166 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class OTGS_Installer_Upgrade_Response {
4
+
5
+ /**
6
+ * @var array
7
+ */
8
+ private $plugins;
9
+
10
+ /**
11
+ * @var array
12
+ */
13
+ private $repositories;
14
+
15
+ /**
16
+ * @var OTGS_Installer_Source_Factory
17
+ */
18
+ private $source_factory;
19
+
20
+ /**
21
+ * @var OTGS_Installer_Package_Product_Finder
22
+ */
23
+ private $product_finder;
24
+
25
+ public function __construct( array $plugins, OTGS_Installer_Repositories $repositories, OTGS_Installer_Source_Factory $source_factory, OTGS_Installer_Package_Product_Finder $product_finder ) {
26
+ $this->plugins = $plugins;
27
+ $this->repositories = $repositories;
28
+ $this->source_factory = $source_factory;
29
+ $this->product_finder = $product_finder;
30
+ }
31
+
32
+ public function add_hooks() {
33
+ if ( defined( 'DOING_AJAX' ) && isset( $_POST['action'] ) && 'installer_download_plugin' === $_POST['action'] ) {
34
+ add_filter( 'site_transient_update_plugins', array( $this, 'modify_upgrade_response' ) );
35
+ }
36
+
37
+ add_filter( 'pre_set_site_transient_update_plugins', array( $this, 'modify_upgrade_response' ) );
38
+ }
39
+
40
+ public function modify_upgrade_response( $update_plugins ) {
41
+
42
+ foreach ( $this->plugins as $plugin ) {
43
+ $repository = $this->repositories->get( $plugin->get_repo() );
44
+ $subscription = $repository->get_subscription();
45
+
46
+ if ( $this->should_skip_upgrade_process( $plugin, $update_plugins, $repository ) ) {
47
+ continue;
48
+ }
49
+
50
+ $response = new stdClass();
51
+ $response->id = 0;
52
+ $response->slug = $plugin->get_slug();
53
+ $response->plugin = $plugin->get_id();
54
+ $response->new_version = $plugin->get_version();
55
+ $response->upgrade_notice = '';
56
+ $response->url = $plugin->get_url();
57
+
58
+ if ( $subscription->get_site_key() ) {
59
+ $response->package = $this->append_site_key_to_download_url( $plugin->get_url(), $subscription->get_site_key(), $repository->get_id(), $subscription->get_site_url() );
60
+ }
61
+
62
+ $response = apply_filters( 'otgs_installer_upgrade_check_response', $response, $plugin->get_name(), $repository->get_id() );
63
+
64
+ $update_plugins->checked[ $plugin->get_id() ] = $plugin->get_installed_version();
65
+ $update_plugins->response[ $plugin->get_id() ] = $response;
66
+ }
67
+
68
+ return $update_plugins;
69
+ }
70
+
71
+ private function should_skip_upgrade_process( OTGS_Installer_Plugin $plugin, $update_plugins, OTGS_Installer_Repository $repository ) {
72
+ $has_wp_org_update = isset( $update_plugins->response[ $plugin->get_id() ] );
73
+ $subscription = $repository->get_subscription();
74
+ $needs_upgrade = $plugin->get_installed_version() && version_compare( $plugin->get_version(), $plugin->get_installed_version(), '>' ) || ! empty( $_POST['reset_to_channel'] );
75
+
76
+ if ( ! $needs_upgrade ) {
77
+ return true;
78
+ }
79
+
80
+ if ( ! $subscription || ! $subscription->is_valid() ) {
81
+ return true;
82
+ }
83
+
84
+ if ( isset( $update_plugins->response[ $plugin->get_id() ] ) ) {
85
+ return true;
86
+ }
87
+
88
+ if ( $this->is_plugin_registered_on_external_repo( $plugin ) ) {
89
+ return true;
90
+ }
91
+
92
+ $product = $this->product_finder->get_product_in_repository_by_subscription( $repository );
93
+
94
+ if ( ! $product || ! $product->is_plugin_registered( $plugin->get_slug() ) ) {
95
+ return true;
96
+ }
97
+
98
+ if ( $subscription && $this->should_fallback_under_wp_org_repo( $plugin, $subscription->get_site_key() ) && $has_wp_org_update ) {
99
+ return true;
100
+ }
101
+
102
+ return false;
103
+ }
104
+
105
+ private function is_plugin_registered_on_external_repo( OTGS_Installer_Plugin $plugin ) {
106
+ $repository = $this->repositories->get( $plugin->get_external_repo() );
107
+
108
+ if ( $repository ) {
109
+ $product = $this->product_finder->get_product_in_repository_by_subscription( $repository );
110
+
111
+ if ( $product && $plugin->get_external_repo() && $product->is_plugin_registered( $plugin->get_slug() ) ) {
112
+ return true;
113
+ }
114
+ }
115
+
116
+ return false;
117
+ }
118
+
119
+ private function append_site_key_to_download_url( $url, $key, $repository_id, $site_url ) {
120
+
121
+ $url_params['site_key'] = $key;
122
+ $url_params['site_url'] = $site_url;
123
+ $package_source = $this->source_factory->create()->get();
124
+
125
+ // Add extra parameters for custom Installer packages
126
+ if ( $package_source ) {
127
+ $extra = $this->get_extra_url_parameters( $package_source );
128
+ if ( ! empty( $extra['repository'] ) && $extra['repository'] == $repository_id ) {
129
+ unset( $extra['repository'] );
130
+ $url_params = array_merge( $url_params, $extra );
131
+ }
132
+ }
133
+
134
+ $url = add_query_arg( $url_params, $url );
135
+
136
+ if ( 'wpml' === $repository_id ) {
137
+ $url = add_query_arg( array(
138
+ 'using_icl' => function_exists( 'wpml_site_uses_icl' ) && wpml_site_uses_icl(),
139
+ 'wpml_version' => defined( 'ICL_SITEPRESS_VERSION' ) ? ICL_SITEPRESS_VERSION : ''
140
+ ), $url );
141
+ }
142
+
143
+ return $url;
144
+
145
+ }
146
+
147
+ private function get_extra_url_parameters( $source ) {
148
+ $parameters = array();
149
+
150
+ if ( $source ) {
151
+ foreach ( $source as $key => $val ) {
152
+ $parameters[ $key ] = $val;
153
+ }
154
+ }
155
+
156
+ $parameters['installer_version'] = WP_INSTALLER_VERSION;
157
+ $parameters['theme'] = wp_get_theme()->get( 'Name' );
158
+ $parameters['site_name'] = get_bloginfo( 'name' );
159
+
160
+ return $parameters;
161
+ }
162
+
163
+ private function should_fallback_under_wp_org_repo( OTGS_Installer_Plugin $plugin, $site_key ) {
164
+ return ( $plugin->is_free_on_wporg() || $plugin->has_fallback_on_wporg() && $plugin->has_fallback_on_wporg() && ! $site_key ) && $plugin->get_channel() === WP_Installer_Channels::CHANNEL_PRODUCTION;
165
+ }
166
+ }
vendor/otgs/installer/installer.php CHANGED
@@ -7,54 +7,13 @@ if ( version_compare( $delegate['version'], '1.8.12', '>=' ) ) {
7
  define( 'WP_INSTALLER_VERSION', $delegate['version'] );
8
  }
9
 
10
- $plugin_path = dirname( __FILE__ );
11
 
12
- include_once $plugin_path . '/includes/functions-core.php';
13
- include_once $plugin_path . '/includes/class-otgs-installer-subscription.php';
14
- include_once $plugin_path . '/includes/class-wp-installer.php';
15
 
16
- include_once WP_Installer()->plugin_path() . '/includes/class-wp-installer-api.php';
17
- include_once WP_Installer()->plugin_path() . '/includes/class-translation-service-info.php';
18
- include_once WP_Installer()->plugin_path() . '/includes/class-installer-dependencies.php';
19
- include_once WP_Installer()->plugin_path() . '/includes/class-wp-installer-channels.php';
20
-
21
- include_once WP_Installer()->plugin_path() . '/includes/class-otgs-installer-php-functions.php';
22
-
23
- include_once WP_Installer()->plugin_path() . '/includes/class-otgs-installer-wp-components-sender.php';
24
- include_once WP_Installer()->plugin_path() . '/includes/class-otgs-installer-wp-components-storage.php';
25
- include_once WP_Installer()->plugin_path() . '/includes/class-otgs-installer-wp-components-hooks.php';
26
-
27
- include_once WP_Installer()->plugin_path() . '/templates/template-service/interface-iotgs-installer-template-service.php';
28
- include_once WP_Installer()->plugin_path() . '/templates/template-service/class-otgs-installer-twig-template-service.php';
29
- include_once WP_Installer()->plugin_path() . '/templates/template-service/class-otgs-installer-twig-template-service-loader.php';
30
-
31
- include_once WP_Installer()->plugin_path() . '/includes/class-otgs-installer-wp-components-setting-resources.php';
32
- include_once WP_Installer()->plugin_path() . '/includes/class-otgs-installer-plugins-page-notice.php';
33
- include_once WP_Installer()->plugin_path() . '/includes/class-otgs-installer-wp-components-setting-ajax.php';
34
- include_once WP_Installer()->plugin_path() . '/includes/class-otgs-installer-filename-hooks.php';
35
- include_once WP_Installer()->plugin_path() . '/includes/class-otgs-installer-icons.php';
36
- include_once WP_Installer()->plugin_path() . '/includes/class-otgs-installer-wp-share-local-components-setting-hooks.php';
37
- include_once WP_Installer()->plugin_path() . '/includes/class-otgs-installer-factory.php';
38
-
39
- include_once WP_Installer()->plugin_path() . '/includes/functions-templates.php';
40
- include_once WP_Installer()->plugin_path() . '/includes/class-otgs-twig-autoloader.php';
41
-
42
- // Initialization
43
  WP_Installer();
44
  WP_Installer_Channels();
45
 
46
- $installer_factory = get_OTGS_Installer_Factory();
47
-
48
- $installer_factory->create_resources()
49
- ->add_hooks();
50
- $installer_factory->create_settings_hooks()
51
- ->add_hooks();
52
- $installer_factory->create_wp_components_hooks()
53
- ->add_hooks();
54
- $installer_factory->create_local_components_ajax_setting()
55
- ->add_hooks();
56
- $installer_factory->create_filename_hooks()
57
- ->add_hooks();
58
- $installer_factory->create_icons()
59
- ->add_hooks();
60
-
7
  define( 'WP_INSTALLER_VERSION', $delegate['version'] );
8
  }
9
 
10
+ include_once dirname( __FILE__ ) . '/includes/class-otgs-installer-autoloader.php';
11
 
12
+ $autoload = new OTGS_Installer_Autoloader();
13
+ $autoload->initialize();
 
14
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
15
  WP_Installer();
16
  WP_Installer_Channels();
17
 
18
+ $installer_loader = new OTGS_Installer_Loader( get_OTGS_Installer_Factory() );
19
+ $installer_loader->init();
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/otgs/installer/loader.php CHANGED
@@ -5,7 +5,7 @@ if ( ! defined( 'ABSPATH' ) ) {
5
  }
6
 
7
  //It should only be loaded on the admin side
8
- if ( ! ( defined( 'DOING_CRON' ) && DOING_CRON ) && ! is_admin() ) {
9
  if ( ! function_exists( 'WP_Installer_Setup' ) ) {
10
  function WP_Installer_Setup() {
11
  }
@@ -22,7 +22,7 @@ $wp_installer_instance = dirname( __FILE__ ) . '/installer.php';
22
  global $wp_installer_instances;
23
  $wp_installer_instances[ $wp_installer_instance ] = array(
24
  'bootfile' => $wp_installer_instance,
25
- 'version' => '1.8.21'
26
  );
27
 
28
 
@@ -85,15 +85,13 @@ if ( ! function_exists( 'wpml_installer_instance_delegator' ) ) {
85
  global $wp_installer_instances;
86
 
87
  // version based election
88
- foreach ( $wp_installer_instances as $instance ) {
 
89
 
90
- if ( ! isset( $delegate ) ) {
91
  $delegate = $instance;
92
- continue;
93
- }
94
 
95
- if ( version_compare( $instance['version'], $delegate['version'], '>' ) ) {
96
- $delegate = $instance;
97
  }
98
  }
99
 
@@ -123,7 +121,7 @@ if ( ! function_exists( 'wpml_installer_instance_delegator' ) ) {
123
  include_once $delegate['bootfile'];
124
 
125
  // set configuration
126
- if ( strpos( realpath( $delegate['bootfile'] ), realpath( TEMPLATEPATH ) ) === 0 ) {
127
  $delegate['args']['in_theme_folder'] = dirname( ltrim( str_replace( realpath( TEMPLATEPATH ), '', realpath( $delegate['bootfile'] ) ), '\\/' ) );
128
  }
129
  if ( isset( $delegate['args'] ) && is_array( $delegate['args'] ) ) {
@@ -152,4 +150,4 @@ if ( ! function_exists( 'WP_Installer_Setup' ) ) {
152
  }
153
  }
154
 
155
- }
5
  }
6
 
7
  //It should only be loaded on the admin side
8
+ if ( ! ( defined( 'DOING_CRON' ) && DOING_CRON ) && ! is_admin() && ! ( defined( 'WP_CLI' ) && WP_CLI ) ) {
9
  if ( ! function_exists( 'WP_Installer_Setup' ) ) {
10
  function WP_Installer_Setup() {
11
  }
22
  global $wp_installer_instances;
23
  $wp_installer_instances[ $wp_installer_instance ] = array(
24
  'bootfile' => $wp_installer_instance,
25
+ 'version' => '1.9.0'
26
  );
27
 
28
 
85
  global $wp_installer_instances;
86
 
87
  // version based election
88
+ foreach ( $wp_installer_instances as $instance_key => $instance ) {
89
+ $wp_installer_instances[ $instance_key ]['delegated'] = false;
90
 
91
+ if ( ! isset( $delegate ) || version_compare( $instance['version'], $delegate['version'], '>' ) ) {
92
  $delegate = $instance;
 
 
93
 
94
+ $wp_installer_instances[ $instance_key ]['delegated'] = true;
 
95
  }
96
  }
97
 
121
  include_once $delegate['bootfile'];
122
 
123
  // set configuration
124
+ if ( strpos( realpath( $delegate['bootfile'] ), (string) realpath( TEMPLATEPATH ) ) === 0 ) {
125
  $delegate['args']['in_theme_folder'] = dirname( ltrim( str_replace( realpath( TEMPLATEPATH ), '', realpath( $delegate['bootfile'] ) ), '\\/' ) );
126
  }
127
  if ( isset( $delegate['args'] ) && is_array( $delegate['args'] ) ) {
150
  }
151
  }
152
 
153
+ }
vendor/otgs/installer/locale/{installer-uk_UA.mo → installer-uk.mo} RENAMED
File without changes
vendor/otgs/installer/phpcs.compatibility.xml ADDED
@@ -0,0 +1,19 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <ruleset name="WPML">
3
+ <description>WPML Coding Standards</description>
4
+
5
+ <config name="testVersion" value="5.2-"/>
6
+
7
+ <rule ref="PHPCompatibility" />
8
+
9
+ <exclude-pattern>*/vendor/*</exclude-pattern>
10
+ <exclude-pattern>*/tests/*</exclude-pattern>
11
+ <exclude-pattern>*.js</exclude-pattern>
12
+ <exclude-pattern>*.mo</exclude-pattern>
13
+ <exclude-pattern>*.po</exclude-pattern>
14
+ <exclude-pattern>*.twig</exclude-pattern>
15
+ <exclude-pattern>*.css</exclude-pattern>
16
+ <exclude-pattern>*.scss</exclude-pattern>
17
+
18
+
19
+ </ruleset>
vendor/otgs/installer/phpcs.xml ADDED
@@ -0,0 +1,17 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <ruleset name="WPML">
3
+ <description>WPML Coding Standards</description>
4
+
5
+ <rule ref="WordPress-Core"/>
6
+ <rule ref="WordPress-Docs"/>
7
+ <rule ref="WordPress-Extra"/>
8
+
9
+ <exclude-pattern>*/vendor/*</exclude-pattern>
10
+ <exclude-pattern>*/tests/*</exclude-pattern>
11
+ <exclude-pattern>*.js</exclude-pattern>
12
+ <exclude-pattern>*.mo</exclude-pattern>
13
+ <exclude-pattern>*.po</exclude-pattern>
14
+ <exclude-pattern>*.twig</exclude-pattern>
15
+ <exclude-pattern>*.css</exclude-pattern>
16
+ <exclude-pattern>*.scss</exclude-pattern>
17
+ </ruleset>
vendor/otgs/installer/phpunit.xml ADDED
@@ -0,0 +1,24 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <phpunit
2
+ bootstrap="./tests/phpunit/bootstrap.php"
3
+ backupGlobals="false"
4
+ colors="true"
5
+ convertErrorsToExceptions="true"
6
+ convertNoticesToExceptions="true"
7
+ convertWarningsToExceptions="true"
8
+ >
9
+ <testsuites>
10
+ <testsuite name="installer-tests">
11
+ <directory suffix=".php">./tests/phpunit/tests/</directory>
12
+ </testsuite>
13
+ </testsuites>
14
+ <filter>
15
+ <whitelist>
16
+ <directory suffix=".php">./</directory>
17
+ <exclude>
18
+ <directory>./locale</directory>
19
+ <directory>./tests</directory>
20
+ <directory>./vendor</directory>
21
+ </exclude>
22
+ </whitelist>
23
+ </filter>
24
+ </phpunit>
vendor/otgs/installer/{src/postcss.config.js → postcss.config.js} RENAMED
File without changes
vendor/otgs/installer/repositories.xml ADDED
@@ -0,0 +1,13 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0" encoding="utf-8"?>
2
+ <repositories>
3
+ <repository>
4
+ <id>wpml</id>
5
+ <apiurl>https://api.wpml.org/</apiurl>
6
+ <products>http://d2salfytceyqoe.cloudfront.net/wpml33-products.json</products>
7
+ </repository>
8
+ <repository>
9
+ <id>toolset</id>
10
+ <apiurl>https://api.toolset.com/</apiurl>
11
+ <products>http://d7j863fr5jhrr.cloudfront.net/toolset33-products.json</products>
12
+ </repository>
13
+ </repositories>
vendor/otgs/installer/res/css/admin.css CHANGED
@@ -334,13 +334,24 @@
334
  .otgs-installer-keepuptodate small {
335
  -webkit-margin-start: 25px;
336
  -moz-margin-start: 25px;
337
- margin-start: 25px;
338
  }
339
  }
340
 
341
  .otgs-installer-component-setting .spinner.otgs-components-report-setting-spinner {
342
  float: right;
343
  }
 
 
 
344
  .otgs-installer-component-privacy-policy {
345
  margin-top: 30px;
 
 
 
 
 
 
 
 
346
  }
334
  .otgs-installer-keepuptodate small {
335
  -webkit-margin-start: 25px;
336
  -moz-margin-start: 25px;
337
+ margin-inline-start: 25px;
338
  }
339
  }
340
 
341
  .otgs-installer-component-setting .spinner.otgs-components-report-setting-spinner {
342
  float: right;
343
  }
344
+ .rtl .otgs-installer-component-setting .spinner.otgs-components-report-setting-spinner {
345
+ float: left;
346
+ }
347
  .otgs-installer-component-privacy-policy {
348
  margin-top: 30px;
349
+ }
350
+
351
+ .otgs-external-link:after {
352
+ font-family: dashicons!important;
353
+ content: "\A0\F504";
354
+ vertical-align: baseline;
355
+ line-height: 1;
356
+ display: inline-block;
357
  }
vendor/otgs/installer/res/css/tooltip/tooltip.css DELETED
@@ -1 +0,0 @@
1
- .otgs-installer-tooltip-open{text-decoration:none}.js-otgs-installer-tooltip{z-index:110000 !important}.js-otgs-installer-tooltip .wp-pointer-content{padding:10px 25px 10px 10px}.js-otgs-installer-tooltip .wp-pointer-buttons{padding:0;position:absolute;overflow:hidden;top:4px;right:5px}.js-otgs-installer-tooltip a.close{width:18px;height:18px;padding:0}.js-otgs-installer-tooltip a.close:before{left:1px;top:0}
 
vendor/otgs/installer/res/js/admin.js CHANGED
@@ -15,9 +15,7 @@
15
  jQuery('.otgs_wp_installer_table').on('submit', '.otgsi_site_key_form', otgs_wp_installer.save_site_key);
16
  jQuery('.otgs_wp_installer_table').on('submit', '.otgsi_downloads_form', otgs_wp_installer.download_downloads);
17
  jQuery('.otgs_wp_installer_table').on('change', '.otgsi_downloads_form :checkbox[name="downloads[]"]', otgs_wp_installer.update_downloads_form);
18
-
19
- jQuery('.installer-dismiss-nag').click(otgs_wp_installer.dismiss_nag);
20
-
21
  jQuery('.otgs_wp_installer_table').on('click', '.installer_expand_button', otgs_wp_installer.toggle_subpackages);
22
 
23
  otgs_wp_installer.scroll_to_repository();
@@ -104,15 +102,15 @@
104
 
105
  jQuery.ajax({url: ajaxurl, type: 'POST', dataType:'json', data: data, success:
106
  function(ret){
107
- if(!ret.error){
108
  otgs_wp_installer.saved_site_key();
109
  }else{
110
- otgs_wp_installer.show_error(thisf.find('[name=repository_id]').val(), ret.error);
111
  thisf.find('input').removeAttr('disabled');
112
  }
113
 
114
- if(typeof ret.debug != 'undefined'){
115
- thisf.append('<textarea style="width:100%" rows="20">' + ret.debug + '</textarea>');
116
  }
117
 
118
  spinner.remove();
@@ -379,21 +377,6 @@
379
 
380
  },
381
 
382
- dismiss_nag: function(){
383
-
384
- var thisa = jQuery(this);
385
-
386
- data = {action: 'installer_dismiss_nag', repository: jQuery(this).data('repository')}
387
-
388
- jQuery.ajax({url: ajaxurl, type: 'POST', dataType:'json', data: data, success:
389
- function(ret){
390
- thisa.closest('.otgs-is-dismissible').remove();
391
- }
392
- });
393
-
394
- return false;
395
- },
396
-
397
  toggle_subpackages: function(){
398
  var list = jQuery(this).closest('td').find('.otgs_wp_installer_subtable');
399
 
15
  jQuery('.otgs_wp_installer_table').on('submit', '.otgsi_site_key_form', otgs_wp_installer.save_site_key);
16
  jQuery('.otgs_wp_installer_table').on('submit', '.otgsi_downloads_form', otgs_wp_installer.download_downloads);
17
  jQuery('.otgs_wp_installer_table').on('change', '.otgsi_downloads_form :checkbox[name="downloads[]"]', otgs_wp_installer.update_downloads_form);
18
+
 
 
19
  jQuery('.otgs_wp_installer_table').on('click', '.installer_expand_button', otgs_wp_installer.toggle_subpackages);
20
 
21
  otgs_wp_installer.scroll_to_repository();
102
 
103
  jQuery.ajax({url: ajaxurl, type: 'POST', dataType:'json', data: data, success:
104
  function(ret){
105
+ if(!ret.data.error){
106
  otgs_wp_installer.saved_site_key();
107
  }else{
108
+ otgs_wp_installer.show_error(thisf.find('[name=repository_id]').val(), ret.data.error);
109
  thisf.find('input').removeAttr('disabled');
110
  }
111
 
112
+ if(typeof ret.data.debug != 'undefined'){
113
+ thisf.append('<textarea style="width:100%" rows="20">' + ret.data.debug + '</textarea>');
114
  }
115
 
116
  spinner.remove();
377
 
378
  },
379
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
380
  toggle_subpackages: function(){
381
  var list = jQuery(this).closest('td').find('.otgs_wp_installer_subtable');
382
 
vendor/otgs/installer/res/js/dismiss-nag.js ADDED
@@ -0,0 +1,23 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ var otgs_wp_installer_dismiss_nag = {
2
+
3
+ init: function() {
4
+ jQuery( '.installer-dismiss-nag' ).click( otgs_wp_installer_dismiss_nag.dismiss_nag );
5
+ },
6
+
7
+ dismiss_nag: function() {
8
+ var thisa = jQuery( this );
9
+
10
+ data = { action: 'installer_dismiss_nag', repository: jQuery( this ).data( 'repository' ) };
11
+
12
+ jQuery.ajax( {
13
+ url: ajaxurl, type: 'POST', dataType: 'json', data: data, success:
14
+ function( ret ) {
15
+ thisa.closest( '.otgs-is-dismissible' ).remove();
16
+ }
17
+ } );
18
+
19
+ return false;
20
+ }
21
+ };
22
+
23
+ jQuery( document ).ready( otgs_wp_installer_dismiss_nag.init );
vendor/otgs/installer/res/js/iframeResizer.min.js DELETED
@@ -1,10 +0,0 @@
1
- /*! iFrame Resizer (iframeSizer.min.js ) - v2.6.1 - 2014-09-03
2
- * Desc: Force cross domain iframes to size to content.
3
- * Requires: iframeResizer.contentWindow.min.js to be loaded into the target frame.
4
- * Copyright: (c) 2014 David J. Bradshaw - dave@bradshaw.net
5
- * License: MIT
6
- */
7
-
8
- !function(){"use strict";function a(a,b,c){"addEventListener"in window?a.addEventListener(b,c,!1):"attachEvent"in window&&a.attachEvent("on"+b,c)}function b(){var a,b=["moz","webkit","o","ms"];for(a=0;a<b.length&&!w;a+=1)w=window[b[a]+"RequestAnimationFrame"];w||c(" RequestAnimationFrame not supported")}function c(a){y.log&&"object"==typeof console&&console.log(s+"[Host page"+u+"]"+a)}function d(a){function b(){function a(){h(z),f(),y.resizedCallback(z)}i(a,z,"resetPage")}function d(a){var b=a.id;c(" Removing iFrame: "+b),a.parentNode.removeChild(a),y.closedCallback(b),c(" --")}function e(){var a=x.substr(t).split(":");return{iframe:document.getElementById(a[0]),id:a[0],height:a[1],width:a[2],type:a[3]}}function j(a){var b=Number(y["max"+a]),d=Number(y["min"+a]),e=a.toLowerCase(),f=Number(z[e]);if(d>b)throw new Error("Value for min"+a+" can not be greater than max"+a);c(" Checking "+e+" is in range "+d+"-"+b),d>f&&(f=d,c(" Set "+e+" to min value")),f>b&&(f=b,c(" Set "+e+" to max value")),z[e]=""+f}function k(){var b=a.origin,d=z.iframe.src.split("/").slice(0,3).join("/");if(y.checkOrigin&&(c(" Checking connection is from: "+d),""+b!="null"&&b!==d))throw new Error("Unexpected message received from: "+b+" for "+z.iframe.id+". Message was: "+a.data+". This error can be disabled by adding the checkOrigin: false option.");return!0}function l(){return s===(""+x).substr(0,t)}function m(){var a=z.type in{"true":1,"false":1};return a&&c(" Ignoring init message from meta parent page"),a}function n(){var a=x.substr(x.indexOf(":")+r+6);c(" MessageCallback passed: {iframe: "+z.iframe.id+", message: "+a+"}"),y.messageCallback({iframe:z.iframe,message:a}),c(" --")}function o(){if(null===z.iframe)throw new Error("iFrame ("+z.id+") does not exist on "+u);return!0}function q(){c(" Reposition requested from iFrame"),v={x:z.width,y:z.height},f()}function w(){switch(z.type){case"close":d(z.iframe),y.resizedCallback(z);break;case"message":n();break;case"scrollTo":q();break;case"reset":g(z);break;case"init":b(),y.initCallback(z.iframe);break;default:b()}}var x=a.data,z={};l()&&(c(" Received: "+x),z=e(),j("Height"),j("Width"),!m()&&o()&&k()&&(w(),p=!1))}function e(){null===v&&(v={x:void 0!==window.pageXOffset?window.pageXOffset:document.documentElement.scrollLeft,y:void 0!==window.pageYOffset?window.pageYOffset:document.documentElement.scrollTop},c(" Get position: "+v.x+","+v.y))}function f(){null!==v&&(window.scrollTo(v.x,v.y),c(" Set position: "+v.x+","+v.y),v=null)}function g(a){function b(){h(a),j("reset","reset",a.iframe)}c(" Size reset requested by "+("init"===a.type?"host page":"iFrame")),e(),i(b,a,"init")}function h(a){function b(b){a.iframe.style[b]=a[b]+"px",c(" IFrame ("+a.iframe.id+") "+b+" set to "+a[b]+"px")}y.sizeHeight&&b("height"),y.sizeWidth&&b("width")}function i(a,b,d){d!==b.type&&w?(c(" Requesting animation frame"),w(a)):a()}function j(a,b,d){c("["+a+"] Sending msg to iframe ("+b+")"),d.contentWindow.postMessage(s+b,"*")}function k(){function b(){function a(a){1/0!==y[a]&&0!==y[a]&&(k.style[a]=y[a]+"px",c(" Set "+a+" = "+y[a]+"px"))}a("maxHeight"),a("minHeight"),a("maxWidth"),a("minWidth")}function d(a){return""===a&&(k.id=a="iFrameResizer"+o++,c(" Added missing iframe ID: "+a+" ("+k.src+")")),a}function e(){c(" IFrame scrolling "+(y.scrolling?"enabled":"disabled")+" for "+l),k.style.overflow=!1===y.scrolling?"hidden":"auto",k.scrolling=!1===y.scrolling?"no":"yes"}function f(){("number"==typeof y.bodyMargin||"0"===y.bodyMargin)&&(y.bodyMarginV1=y.bodyMargin,y.bodyMargin=""+y.bodyMargin+"px")}function h(){return l+":"+y.bodyMarginV1+":"+y.sizeWidth+":"+y.log+":"+y.interval+":"+y.enablePublicMethods+":"+y.autoResize+":"+y.bodyMargin+":"+y.heightCalculationMethod+":"+y.bodyBackground+":"+y.bodyPadding+":"+y.tolerance}function i(b){a(k,"load",function(){var a=p;j("iFrame.onload",b,k),!a&&y.heightCalculationMethod in x&&g({iframe:k,height:0,width:0,type:"init"})}),j("init",b,k)}var k=this,l=d(k.id);e(),b(),f(),i(h())}function l(a){if("object"!=typeof a)throw new TypeError("Options is not an object.")}function m(){function a(a){if("IFRAME"!==a.tagName.toUpperCase())throw new TypeError("Expected <IFRAME> tag, found <"+a.tagName+">.");k.call(a)}function b(a){a=a||{},l(a);for(var b in z)z.hasOwnProperty(b)&&(y[b]=a.hasOwnProperty(b)?a[b]:z[b])}return function(c,d){b(c),Array.prototype.forEach.call(document.querySelectorAll(d||"iframe"),a)}}function n(a){a.fn.iFrameResize=function(b){return b=b||{},l(b),y=a.extend({},z,b),this.filter("iframe").each(k).end()}}var o=0,p=!0,q="message",r=q.length,s="[iFrameSizer]",t=s.length,u="",v=null,w=window.requestAnimationFrame,x={max:1,scroll:1,bodyScroll:1,documentElementScroll:1},y={},z={autoResize:!0,bodyBackground:null,bodyMargin:null,bodyMarginV1:8,bodyPadding:null,checkOrigin:!0,enablePublicMethods:!1,heightCalculationMethod:"offset",interval:32,log:!1,maxHeight:1/0,maxWidth:1/0,minHeight:0,minWidth:0,scrolling:!1,sizeHeight:!0,sizeWidth:!1,tolerance:0,closedCallback:function(){},initCallback:function(){},messageCallback:function(){},resizedCallback:function(){}};b(),a(window,"message",d),"jQuery"in window&&n(jQuery),"function"==typeof define&&define.amd?define(function(){return m()}):window.iFrameResize=m()}();
9
- //# sourceMappingURL=../src/iframeResizer.map
10
-
 
 
 
 
 
 
 
 
 
 
vendor/otgs/installer/res/js/tooltip/tooltip.js DELETED
@@ -1,82 +0,0 @@
1
- (function () {
2
- 'use strict';
3
-
4
- var OTGS_Installer_Tooltip = function( element ) {
5
- this.trigger = element;
6
- this.content = this.trigger.html(this.trigger.html()).text();
7
- this.edge = 'bottom';
8
- this.align = 'left';
9
- this.margin_left = '-54px';
10
-
11
- if ( !this.content ) {
12
- this.content = this.decodeEntities(this.trigger.data('content'));
13
- }
14
-
15
- if ( this.trigger.data( 'edge' ) ) {
16
- this.edge = this.trigger.data( 'edge' );
17
- }
18
-
19
- if ( this.trigger.data( 'align' ) ) {
20
- this.align = this.trigger.data( 'align' );
21
- }
22
-
23
- if ( this.trigger.data( 'margin_left' ) ) {
24
- this.margin_left = this.trigger.data( 'margin_left' );
25
- }
26
-
27
- this.trigger.empty();
28
- this.trigger.click( jQuery.proxy( this.onTriggerClick,this ) );
29
- };
30
-
31
- OTGS_Installer_Tooltip.prototype = {
32
- open: function () {
33
- if (this.trigger.length && this.content) {
34
- this.trigger.addClass('js-otgs-installer-active-tooltip');
35
- this.trigger.pointer({
36
- pointerClass: 'js-otgs-installer-tooltip',
37
- content: this.content,
38
- position: {
39
- edge: this.edge,
40
- align: this.align
41
- },
42
- show: jQuery.proxy( this.onShow, this ),
43
- close: this.onClose,
44
- buttons: this.buttons
45
-
46
- }).pointer('open');
47
- }
48
- },
49
- onShow: function(event, t) {
50
- t.pointer.css('marginLeft', this.margin_left);
51
- },
52
- onClose: function (event, t) {
53
- t.pointer.css('marginLeft', '0');
54
- },
55
- onTriggerClick: function(e) {
56
- e.preventDefault();
57
- this.open();
58
- },
59
- buttons: function (event, t) {
60
- var button = jQuery('<a class="close" href="#">&nbsp;</a>');
61
-
62
- return button.bind('click.pointer', function (e) {
63
- e.preventDefault();
64
- t.element.pointer('close');
65
- });
66
- },
67
- decodeEntities: function(encodedString) {
68
- var textArea = document.createElement('textarea');
69
- textArea.innerHTML = encodedString;
70
- return textArea.value;
71
- }
72
- };
73
-
74
- jQuery(document).ready(function () {
75
- var tooltips = jQuery('.js-otgs-installer-tooltip-open'),
76
- tooltip = {};
77
-
78
- tooltips.each(function (index, element) {
79
- tooltip = new OTGS_Installer_Tooltip(jQuery(element));
80
- });
81
- });
82
- }());
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/otgs/installer/src/js/component-settings-reports/app.js ADDED
@@ -0,0 +1,2 @@
 
 
1
+ import '../../scss/component-settings-reports/styles.scss';
2
+
vendor/otgs/installer/src/js/otgs-installer-support/app.js ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
1
+ import '../../scss/otgs-installer-support/styles.scss';
2
+ import testConnection from './testConnection.js';
3
+
4
+ document.addEventListener('DOMContentLoaded', function(){
5
+ const testConnectionObj = new testConnection( document );
6
+ testConnectionObj.addEvents();
7
+ });
vendor/otgs/installer/src/js/otgs-installer-support/testConnection.js ADDED
@@ -0,0 +1,66 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*globals ajaxurl*/
2
+
3
+ class testConnection {
4
+
5
+ constructor( element ) {
6
+ this.container = element.querySelector('.otgs-installer-support-test-connection');
7
+ }
8
+
9
+ addEvents() {
10
+ this.container.querySelector('.check-again').addEventListener('click', () => this.checkConnection());
11
+ }
12
+
13
+ checkConnection() {
14
+ const cssClasses = {
15
+ successClass: 'dashicons-yes',
16
+ failClass: 'dashicons-no-alt',
17
+ iconClass: 'dashicons',
18
+ spinnerClass: 'spinner',
19
+ activeSpinnerClass: 'is-active'
20
+ };
21
+
22
+ this.container.querySelectorAll( '.endpoint' ).forEach((el) => {
23
+
24
+ const status = el.querySelector('.status'),
25
+ nonce = this.container.querySelector('#otgs_installer_test_connection').value;
26
+
27
+ this.resetStatus(status, cssClasses);
28
+
29
+ fetch(ajaxurl, {
30
+ headers: {
31
+ 'Content-Type': 'application/x-www-form-urlencoded; charset=utf-8'
32
+ },
33
+ credentials: 'same-origin',
34
+ method: "POST",
35
+ body: `nonce=${nonce}&action=otgs_installer_test_connection&repository=${el.getAttribute('data-repository')}&type=${el.getAttribute('data-type')}`
36
+ })
37
+ .then(response => {
38
+ response.json()
39
+ .then(res => {
40
+ if (res.success) {
41
+ this.setSuccessStatus(status, cssClasses);
42
+ } else {
43
+ this.setFailStatus(status, cssClasses);
44
+ }
45
+ });
46
+ });
47
+ });
48
+ }
49
+
50
+ resetStatus(status, cssClasses) {
51
+ status.classList.remove(cssClasses.successClass, cssClasses.failClass, cssClasses.iconClass);
52
+ status.classList.add(cssClasses.spinnerClass, cssClasses.activeSpinnerClass);
53
+ }
54
+
55
+ setSuccessStatus(status, cssClasses) {
56
+ status.classList.add(cssClasses.successClass, cssClasses.iconClass);
57
+ status.classList.remove(cssClasses.failClass, cssClasses.spinnerClass, cssClasses.activeSpinnerClass);
58
+ }
59
+
60
+ setFailStatus(status, cssClasses) {
61
+ status.classList.remove(cssClasses.successClass, cssClasses.spinnerClass, cssClasses.activeSpinnerClass);
62
+ status.classList.add(cssClasses.failClass, cssClasses.iconClass);
63
+ }
64
+ }
65
+
66
+ export default testConnection;
vendor/otgs/installer/src/js/ui/Switcher.js DELETED
@@ -1,44 +0,0 @@
1
- class Switcher {
2
- constructor (element) {
3
- const checkBoxContainer = element.parentElement;
4
- const heading = checkBoxContainer.getElementsByClassName('heading');
5
- const label = checkBoxContainer.getElementsByTagName('label').item(0);
6
-
7
- if (label) {
8
- label.classList.add('otgs-on-off-switch');
9
- }
10
-
11
- const toggleGroup = document.createElement('label');
12
- toggleGroup.classList.add('otgs-toggle-group');
13
- toggleGroup.appendChild(element);
14
- toggleGroup.appendChild(label);
15
-
16
- const switcherContainer = document.createElement('span');
17
- switcherContainer.classList.add('otgs-switch__onoff');
18
- const switcherBorder = document.createElement('span');
19
- switcherBorder.classList.add('otgs-switch__onoff-label');
20
- const switcherInner = document.createElement('span');
21
- switcherInner.classList.add('otgs-switch__onoff-inner');
22
- const switcherSwitch = document.createElement('span');
23
- switcherSwitch.classList.add('otgs-switch__onoff-switch');
24
-
25
- switcherBorder.appendChild(switcherInner);
26
- switcherBorder.appendChild(switcherSwitch);
27
-
28
- switcherContainer.appendChild(switcherBorder);
29
-
30
- toggleGroup.appendChild(switcherContainer);
31
-
32
- checkBoxContainer.appendChild(toggleGroup);
33
-
34
- if (heading.length) {
35
- heading.item(heading.length - 1).parentNode
36
- .insertBefore(toggleGroup, heading.item(heading.length - 1).nextSibling);
37
- } else {
38
- checkBoxContainer.insertBefore(toggleGroup, checkBoxContainer.firstChild);
39
- }
40
- }
41
-
42
- }
43
-
44
- export default Switcher;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/otgs/installer/src/js/ui/UI.js DELETED
@@ -1,14 +0,0 @@
1
- import '../../scss/ui/styles.scss';
2
- import Switcher from './Switcher';
3
-
4
- class UI {
5
- constructor (element) {
6
- const checkBoxes = element.querySelectorAll('input[type="checkbox"]');
7
-
8
- if(checkBoxes) {
9
- Array.from(checkBoxes).map(checkBox => new Switcher(checkBox));
10
- }
11
- }
12
- }
13
-
14
- export default UI;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/otgs/installer/src/js/ui/app.js DELETED
@@ -1,10 +0,0 @@
1
- import UI from './UI';
2
-
3
- window.addEventListener('DOMContentLoaded', () => {
4
-
5
- const otgsUIElements = document.querySelectorAll('.otgs-ui');
6
-
7
- if (otgsUIElements) {
8
- Array.from(otgsUIElements).map(otgsUI => new UI(otgsUI));
9
- }
10
- });
 
 
 
 
 
 
 
 
 
 
vendor/otgs/installer/src/webpack.config.js DELETED
@@ -1,56 +0,0 @@
1
- const path = require('path');
2
- const ExtractTextPlugin = require('extract-text-webpack-plugin');
3
-
4
- const webPackModule = {
5
- rules: [
6
- {
7
- loader: 'babel-loader',
8
- test: /\.js$/,
9
- exclude: /node_modules/,
10
- query: {
11
- presets: ['es2015'],
12
- },
13
- }, {
14
- test: /\.s?css$/,
15
- use: ExtractTextPlugin.extract({
16
- fallback: 'style-loader',
17
- use: [
18
- {
19
- loader: 'css-loader',
20
- options: {
21
- sourceMap: true,
22
- },
23
- }, {
24
- loader: 'sass-loader',
25
- options: {
26
- sourceMap: true,
27
- },
28
- }, {
29
- loader: 'postcss-loader',
30
- },
31
- ],
32
- }),
33
- },
34
- ],
35
- };
36
-
37
- const ui = (env) => {
38
- const isProduction = env === 'production';
39
-
40
- return {
41
- entry: ['whatwg-fetch', './js/ui/app.js'],
42
- output: {
43
- path: path.join(__dirname, '..', 'dist'),
44
- filename: path.join('js', 'ui', 'app.js'),
45
- },
46
- module: webPackModule,
47
- plugins: [
48
- new ExtractTextPlugin(path.join('css', 'ui', 'styles.css')),
49
- ],
50
- devtool: isProduction ? '' : 'inline-source-map',
51
- };
52
- };
53
-
54
- module.exports = [
55
- ui,
56
- ];
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/otgs/installer/templates/channel-selector.php CHANGED
@@ -48,11 +48,11 @@
48
  <button class="button-primary js-proceed"><?php _e("Switch", 'installer') ?></button>
49
  </p>
50
  <p>
51
- <?php _e("Plugins will be updated to their most advanced version in the channel that you selected.", 'installer') ?>
52
  </p>
53
  <label>
54
  <input type="checkbox" value="1" class="js-remember"/>
55
- &nbsp;<?php _e("Remember my preference.", 'installer') ?><br />
56
  </label>
57
  </div>
58
  <?php endif; ?>
48
  <button class="button-primary js-proceed"><?php _e("Switch", 'installer') ?></button>
49
  </p>
50
  <p>
51
+ <?php _e( 'The plugins will update to the most recent version in the channel that you selected.', 'installer') ?>
52
  </p>
53
  <label>
54
  <input type="checkbox" value="1" class="js-remember"/>
55
+ &nbsp;<?php _e( 'Remember my preference.', 'installer') ?><br />
56
  </label>
57
  </div>
58
  <?php endif; ?>
vendor/otgs/installer/templates/components-setting/commercial-tab.twig DELETED
@@ -1,7 +0,0 @@
1
- <p class="otgs-installer-keepuptodate">
2
- <input checked name="repo_allowed_to_send_data" value="{{ repo_id }}" type="checkbox"> {{ strings.message }}
3
- <a class="js-otgs-installer-tooltip-open otgs-ico-help">
4
- {{ strings.tooltip }}
5
- </a>
6
- <small>{{ strings.stop_sending|raw }}</small>
7
- </p>
 
 
 
 
 
 
 
vendor/otgs/installer/templates/components-setting/share-local-data-setting-radio.twig CHANGED
@@ -1,4 +1,4 @@
1
- <div class="otgs-installer-component-setting otgs-ui" data-has-setting="{{ has_setting }}">
2
  <span class="spinner otgs-components-report-setting-spinner"></span>
3
  <ul>
4
  <li>
1
+ <div class="otgs-installer-component-setting" data-has-setting="{{ has_setting }}">
2
  <span class="spinner otgs-components-report-setting-spinner"></span>
3
  <ul>
4
  <li>
vendor/otgs/installer/templates/components-setting/share-local-data-setting.twig CHANGED
@@ -1,4 +1,4 @@
1
- <div class="otgs-installer-component-setting otgs-ui" data-has-setting="{{ has_setting }}">
2
  {% if custom_raw_heading is defined and custom_raw_heading is not null %}
3
  {{ custom_raw_heading|raw }}
4
  {% else %}
@@ -13,33 +13,23 @@
13
  </a>
14
  </h4>
15
  {% endif %}
16
- <p>
17
- <a
18
- href="{{ privacy_policy_url }}"
19
- target="_blank"
20
- rel="noopener"
21
- class="otgs-external-link"
22
- >
23
- {%- if custom_privacy_policy_text is defined and custom_privacy_policy_text is not null -%}
24
- {{- custom_privacy_policy_text|raw -}}
25
- {%- else -%}
26
- {{- privacy_policy_text -}}
27
- {%- endif -%}
28
- </a>
29
- </p>
30
  <input
31
  type="checkbox"
32
  {% if is_repo_allowed %}
33
  checked="checked"
34
  {% endif %}
35
  id="{{ nonce.action }}{{ nonce.value }}"
36
- class="js-otgs-components-report-user-choice"
37
  value="1"
38
  data-nonce-action="{{ nonce.action }}"
39
  data-nonce-value="{{ nonce.value }}"
40
  data-repo="{{ repo }}"
41
  />
42
- <label for="{{ nonce.action }}{{ nonce.value }}">
 
 
 
 
43
  {% if custom_raw_label is defined and custom_raw_label is not null %}
44
  {{ custom_raw_label|raw }}
45
  {% else %}
@@ -47,4 +37,19 @@
47
  {% endif %}
48
  </label>
49
  <div class="spinner otgs-components-report-setting-spinner"></div>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
50
  </div>
1
+ <div class="otgs-installer-component-setting" data-has-setting="{{ has_setting }}">
2
  {% if custom_raw_heading is defined and custom_raw_heading is not null %}
3
  {{ custom_raw_heading|raw }}
4
  {% else %}
13
  </a>
14
  </h4>
15
  {% endif %}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
16
  <input
17
  type="checkbox"
18
  {% if is_repo_allowed %}
19
  checked="checked"
20
  {% endif %}
21
  id="{{ nonce.action }}{{ nonce.value }}"
22
+ class="js-otgs-components-report-user-choice otgs-switcher-input"
23
  value="1"
24
  data-nonce-action="{{ nonce.action }}"
25
  data-nonce-value="{{ nonce.value }}"
26
  data-repo="{{ repo }}"
27
  />
28
+ <label for="{{ nonce.action }}{{ nonce.value }}"
29
+ class="otgs-switcher wpml-theme"
30
+ data-on="ON"
31
+ data-off="OFF"
32
+ >
33
  {% if custom_raw_label is defined and custom_raw_label is not null %}
34
  {{ custom_raw_label|raw }}
35
  {% else %}
37
  {% endif %}
38
  </label>
39
  <div class="spinner otgs-components-report-setting-spinner"></div>
40
+
41
+ <p>
42
+ <a
43
+ href="{{ privacy_policy_url }}"
44
+ target="_blank"
45
+ rel="noopener"
46
+ class="otgs-external-link"
47
+ >
48
+ {%- if custom_privacy_policy_text is defined and custom_privacy_policy_text is not null -%}
49
+ {{- custom_privacy_policy_text|raw -}}
50
+ {%- else -%}
51
+ {{- privacy_policy_text -}}
52
+ {%- endif -%}
53
+ </a>
54
+ </p>
55
  </div>
vendor/otgs/installer/templates/downloads-list.php CHANGED
@@ -32,7 +32,7 @@
32
  'repository_id' => $repository_id
33
  );
34
  ?>
35
- <input type="checkbox" name="downloads[]" value="<?php echo base64_encode(json_encode($download_data)); ?>" <?php
36
  if( $this->plugin_is_installed($download['name'], $download['slug'], $download['version'] )
37
  && ! $this->plugin_is_embedded_version( $download['name'], $download['slug'] )
38
  || WP_Installer()->dependencies->cant_download( $repository_id ) ): ?>disabled="disabled"<?php endif; ?> />&nbsp;
32
  'repository_id' => $repository_id
33
  );
34
  ?>
35
+ <input type="checkbox" name="downloads[]" value="<?php echo base64_encode(json_encode($download_data)); ?>" data-slug="<?php echo $download['slug'] ?>" <?php
36
  if( $this->plugin_is_installed($download['name'], $download['slug'], $download['version'] )
37
  && ! $this->plugin_is_embedded_version( $download['name'], $download['slug'] )
38
  || WP_Installer()->dependencies->cant_download( $repository_id ) ): ?>disabled="disabled"<?php endif; ?> />&nbsp;
vendor/otgs/installer/templates/support/header-instance.twig ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <tr>
2
+ <th>
3
+ <span>{{ strings.instances.path }}</span>
4
+ </th>
5
+ <th>
6
+ <span>{{ strings.instances.version }}</span>
7
+ </th>
8
+ <th>
9
+ <span>{{ strings.instances.high_priority }}</span>
10
+ </th>
11
+ <th>
12
+ <span>{{ strings.instances.delegated }}</span>
13
+ </th>
14
+ </tr>
vendor/otgs/installer/templates/support/header.twig ADDED
@@ -0,0 +1,17 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <tr>
2
+ <th>
3
+ <span>{{ strings.log.request_url }}</span>
4
+ </th>
5
+ <th>
6
+ <span>{{ strings.log.request_arguments }}</span>
7
+ </th>
8
+ <th>
9
+ <span>{{ strings.log.response }}</span>
10
+ </th>
11
+ <th>
12
+ <span>{{ strings.log.component }}</span>
13
+ </th>
14
+ <th>
15
+ <span>{{ strings.log.time }}</span>
16
+ </th>
17
+ </tr>
vendor/otgs/installer/templates/support/installer-support.twig ADDED
@@ -0,0 +1,130 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <div class="wrap">
2
+ <h1>{{ strings.page_title }}</h1>
3
+
4
+ <div class="otgs-installer-support-test-connection">
5
+ <h2>{{ strings.tester.title }} <a class="button check-again">{{ strings.tester.button_label }}</a></h2>
6
+
7
+ <ul>
8
+ {% for endpoint in tester.endpoints %}
9
+ <li class="endpoint" data-repository="{{ endpoint.repository }}" data-type="{{ endpoint.type }}"><span class="dashicons dashicons-yes status"></span> {{ endpoint.description }}</li>
10
+ {% endfor %}
11
+ </ul>
12
+
13
+ {{ tester.nonce|raw }}
14
+
15
+ <span class="clearfix"></span>
16
+ </div>
17
+
18
+ <hr>
19
+
20
+ <div class="otgs-installer-support-test-connection">
21
+ <h2>{{ strings.requirements.title }}</h2>
22
+
23
+ <ul>
24
+ {% for requirement in requirements %}
25
+ {% set icon_class = requirement.active ? 'dashicons-yes' : 'dashicons-no-alt' %}
26
+
27
+ <li><span class="dashicons {{ icon_class }} status"></span> {{ requirement.name }}</li>
28
+ {% endfor %}
29
+ </ul>
30
+
31
+ {{ tester.nonce|raw }}
32
+
33
+ <span class="clearfix"></span>
34
+ </div>
35
+
36
+ <hr>
37
+
38
+ <h2>{{ strings.instances.title }}</h2>
39
+
40
+ <table class="wp-list-table widefat striped installer-instances">
41
+ <thead>
42
+
43
+ {% include 'header-instance.twig' %}
44
+
45
+ </thead>
46
+
47
+ <tbody>
48
+
49
+ {% for instance in instances %}
50
+ <tr {% if instance.is_delegated %} class="active" {% endif %}>
51
+ <td>
52
+ {{ instance.get_bootfile }}
53
+ </td>
54
+ <td>
55
+ {{ instance.get_version }}
56
+ </td>
57
+ <td>
58
+ {{ instance.get_high_priority }}
59
+ </td>
60
+ <td>
61
+ {% if instance.is_delegated %} <span class="dashicons dashicons-yes"></span> {% endif %}
62
+ </td>
63
+ </tr>
64
+ {% endfor %}
65
+
66
+ </tbody>
67
+ <tfoot>
68
+
69
+ {% include 'header-instance.twig' %}
70
+
71
+ </tfoot>
72
+
73
+ </table>
74
+
75
+ <br>
76
+
77
+ <hr>
78
+
79
+ <h2>{{ strings.log.title }}</h2>
80
+
81
+ <table class="wp-list-table widefat fixed striped posts">
82
+ <thead>
83
+
84
+ {% include 'header.twig' %}
85
+
86
+ </thead>
87
+
88
+ <tbody id="the-list">
89
+
90
+ {% for log in log_entries %}
91
+
92
+ <tr>
93
+ <td class="title column-title has-row-actions column-primary">
94
+ {{ log.request_url }}
95
+ </td>
96
+ <td class="title column-title has-row-actions column-primary">
97
+ {{ log.request_arguments }}
98
+ </td>
99
+ <td class="title column-title has-row-actions column-primary">
100
+ {{ log.response }}
101
+ </td>
102
+ <td class="title column-title has-row-actions column-primary">
103
+ {{ log.component }}
104
+ </td>
105
+ <td class="title column-title has-row-actions column-primary">
106
+ {{ log.time }}
107
+ </td>
108
+ </tr>
109
+
110
+ {% endfor %}
111
+
112
+ {% if log_entries is empty %}
113
+ <tr>
114
+ <td colspan="5" class="title column-title has-row-actions column-primary">
115
+ {{ strings.log.empty_log }}
116
+ </td>
117
+ </tr>
118
+ {% endif %}
119
+
120
+
121
+ </tbody>
122
+ <tfoot>
123
+
124
+ {% include 'header.twig' %}
125
+
126
+ </tfoot>
127
+
128
+ </table>
129
+ </div>
130
+
vendor/otgs/installer/templates/support/support-link.twig ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
1
+ <div class="wrap otgs-installer-support-link">
2
+ {% if not hide_title %}
3
+ <h2>{{ title }}</h2>
4
+ {% endif %}
5
+
6
+ <p>{{ content|format( '<a href="'~link.url~'">'~link.text~'</a>' )|raw }}</p>
7
+ </div>
vendor/otgs/installer/webpack.config.js ADDED
@@ -0,0 +1,82 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ const path = require('path');
2
+ const ExtractTextPlugin = require('extract-text-webpack-plugin');
3
+
4
+
5
+ const webPackModule = (production = true) => {
6
+ return {
7
+ rules: [
8
+ {
9
+ loader: 'babel-loader',
10
+ test: /\.js$/,
11
+ exclude: /node_modules/,
12
+ query: {
13
+ presets: ['es2015'],
14
+ },
15
+ },
16
+ {
17
+ test: /\.s?css$/,
18
+ use: ExtractTextPlugin.extract({
19
+ fallback: 'style-loader',
20
+ use: [
21
+ {
22
+ loader: 'css-loader',
23
+ options: {
24
+ sourceMap: !production,
25
+ minimize: production,
26
+ },
27
+ },
28
+ {
29
+ loader: 'sass-loader',
30
+ options: {
31
+ sourceMap: !production,
32
+ },
33
+ },
34
+ {
35
+ loader: 'postcss-loader',
36
+ },
37
+ ],
38
+ }),
39
+ },
40
+ ],
41
+ }
42
+ };
43
+
44
+ const componentSettings = (env) => {
45
+ const isProduction = env === 'production';
46
+
47
+ return {
48
+ entry: ['whatwg-fetch', './src/js/component-settings-reports/app.js'],
49
+ output: {
50
+ path: path.join(__dirname, 'dist'),
51
+ filename: path.join('js', 'component-settings-reports', 'app.js'),
52
+ },
53
+ plugins: [
54
+ new ExtractTextPlugin(path.join('css', 'component-settings-reports', 'styles.css')),
55
+ ],
56
+ module: webPackModule(!isProduction),
57
+ devtool: isProduction ? '' : 'inline-source-map'
58
+ };
59
+ };
60
+
61
+ const installerSupport = (env) => {
62
+ const isProduction = env === 'production';
63
+ return {
64
+ entry: ['whatwg-fetch', './src/js/otgs-installer-support/app.js'],
65
+ output: {
66
+ path: path.join(__dirname, 'dist'),
67
+ filename: path.join('js', 'otgs-installer-support', 'app.js')
68
+ },
69
+ plugins: [
70
+ new ExtractTextPlugin(path.join('css', 'otgs-installer-support', 'styles.css'))
71
+ ],
72
+
73
+ module: webPackModule(!isProduction),
74
+ devtool: isProduction ? '' : 'inline-source-map',
75
+ };
76
+ };
77
+
78
+ module.exports = [
79
+ componentSettings,
80
+ installerSupport
81
+ ];
82
+
wpml-config.xml CHANGED
@@ -12,7 +12,7 @@
12
  <custom-field action="copy">_featured</custom-field>
13
  <custom-field action="copy">_manage_stock</custom-field>
14
  <custom-field action="copy">_sku</custom-field>
15
- <custom-field action="copy">_stock</custom-field>
16
  <custom-field action="copy">_stock_status</custom-field>
17
  <custom-field action="copy">_sold_individually</custom-field>
18
  <custom-field action="copy">_subscription_length</custom-field>
@@ -64,6 +64,7 @@
64
  <custom-field action="ignore">_product_attributes</custom-field>
65
  <custom-field action="translate">_children</custom-field>
66
  <custom-field action="copy">_subscription_limit</custom-field>
 
67
  </custom-fields>
68
  <custom-types>
69
  <custom-type translate="1">product</custom-type>
12
  <custom-field action="copy">_featured</custom-field>
13
  <custom-field action="copy">_manage_stock</custom-field>
14
  <custom-field action="copy">_sku</custom-field>
15
+ <custom-field action="ignore">_stock</custom-field>
16
  <custom-field action="copy">_stock_status</custom-field>
17
  <custom-field action="copy">_sold_individually</custom-field>
18
  <custom-field action="copy">_subscription_length</custom-field>
64
  <custom-field action="ignore">_product_attributes</custom-field>
65
  <custom-field action="translate">_children</custom-field>
66
  <custom-field action="copy">_subscription_limit</custom-field>
67
+ <custom-field action="copy">_low_stock_amount</custom-field>
68
  </custom-fields>
69
  <custom-types>
70
  <custom-type translate="1">product</custom-type>
wpml-woocommerce.php CHANGED
@@ -7,17 +7,17 @@
7
  Author URI: http://www.onthegosystems.com/
8
  Text Domain: woocommerce-multilingual
9
  Requires at least: 3.9
10
- Tested up to: 4.9.8
11
- Version: 4.3.7
12
- WC requires at least: 2.1.0
13
- WC tested up to: 3.5
14
  */
15
 
16
  if ( defined( 'WCML_VERSION' ) ) {
17
  return;
18
  }
19
 
20
- define( 'WCML_VERSION', '4.3.7' );
21
  define( 'WCML_PLUGIN_PATH', dirname( __FILE__ ) );
22
  define( 'WCML_PLUGIN_FOLDER', basename( WCML_PLUGIN_PATH ) );
23
  define( 'WCML_LOCALE_PATH', WCML_PLUGIN_PATH . '/locale' );
@@ -78,10 +78,8 @@ function wcml_loader(){
78
  $loaders[] = 'WCML_Append_Gallery_To_Post_Media_Ids_Factory';
79
  }
80
 
81
- if( version_compare( ICL_SITEPRESS_VERSION, '3.9.0', '>=' ) ){
82
- $action_filter_loader = new WPML_Action_Filter_Loader();
83
- $action_filter_loader->load( $loaders );
84
- }
85
  }
86
 
87
  $WCML_REST_API = new WCML_REST_API();
7
  Author URI: http://www.onthegosystems.com/
8
  Text Domain: woocommerce-multilingual
9
  Requires at least: 3.9
10
+ Tested up to: 5.0.3
11
+ Version: 4.4.0
12
+ WC requires at least: 3.3.0
13
+ WC tested up to: 3.5.4
14
  */
15
 
16
  if ( defined( 'WCML_VERSION' ) ) {
17
  return;
18
  }
19
 
20
+ define( 'WCML_VERSION', '4.4.0' );
21
  define( 'WCML_PLUGIN_PATH', dirname( __FILE__ ) );
22
  define( 'WCML_PLUGIN_FOLDER', basename( WCML_PLUGIN_PATH ) );
23
  define( 'WCML_LOCALE_PATH', WCML_PLUGIN_PATH . '/locale' );
78
  $loaders[] = 'WCML_Append_Gallery_To_Post_Media_Ids_Factory';
79
  }
80
 
81
+ $action_filter_loader = new WPML_Action_Filter_Loader();
82
+ $action_filter_loader->load( $loaders );
 
 
83
  }
84
 
85
  $WCML_REST_API = new WCML_REST_API();