WooCommerce Multilingual – run WooCommerce with WPML - Version 4.2.0

Version Description

  • Added the ability to translate Sensei question custom post types
  • Added the ability to translate serialized custom fields in the Translation Editor
  • Payment method title not displaying in emails Mollie Payment's payment processor compatibility
  • Show an admin notice for environments in which switching the language or currency on the front end, could corrupt the cart contents
  • When selecting the currencylayer provider for automatic exchange rate, the API KEY filter was not visible
  • The multi-currency component made the admin dashboard page loading unnecessarily slow
  • Variations with custom attributes could not be duplicated as translations
  • A fatal error occurred when using old WordPress versions (before 4.4.0) - rest_get_url_prefix didn't exist
  • The admin orders page was loading slower than necessary
  • A PHP fatal error was occurring when using the Adventure Tours extension
  • A product addon was added to the cart more then once in combination with Bookings
  • For translated products, the product variation names were displayed in the old format (before WooCommerce 3.0)
  • The prices in the secondary currencies for products in secondary languages for products read via the REST API were incorrect
  • CSS for the currency switcher was loaded when the multi-currency was not enabled
  • Fixed a javascript error on the shop page
  • It was not possible to use the clear cart feature with enabled WPML Ajax cookies only
  • WooCommerce Product Bundles: Bundled items filtering by variation was not synced with translations
  • Bookings max availability value was changing after adding bookable product to cart few times
  • In some cases the option to prompt for a confirmation about resetting the cart when switching the language was not working
  • The variation names were, sometimes, displayed in the wrong language in the orders, on the back-end
Download this release

Release Info

Developer mihaimihai
Plugin Icon 128x128 WooCommerce Multilingual – run WooCommerce with WPML
Version 4.2.0
Comparing to
See all releases

Code changes from version 4.1.4 to 4.2.0

Files changed (257) hide show
  1. changelog/4.1.4.md +0 -1
  2. changelog/4.2.0.md +23 -0
  3. classes/order-property-filter/class-wcml-payment-method-filter.php +54 -0
  4. compatibility/class-wcml-adventure-tours.php +59 -33
  5. compatibility/class-wcml-bookings.php +19 -19
  6. compatibility/class-wcml-composite-products.php +26 -8
  7. compatibility/class-wcml-product-addons.php +11 -18
  8. compatibility/class-wcml-product-bundles-legacy.php +19 -7
  9. compatibility/class-wcml-product-bundles.php +27 -0
  10. compatibility/class-wcml-sensei.php +211 -190
  11. compatibility/class-wcml-tab-manager.php +28 -16
  12. inc/abstracts/class-wcml-exchange-rate-service.php +2 -3
  13. inc/class-wcml-attributes.php +35 -4
  14. inc/class-wcml-cart-sync-warnings.php +117 -0
  15. inc/class-wcml-cart.php +40 -12
  16. inc/class-wcml-compatibility.php +218 -198
  17. inc/class-wcml-emails.php +0 -18
  18. inc/class-wcml-endpoints.php +46 -0
  19. inc/class-wcml-orders.php +18 -2
  20. inc/class-wcml-products.php +1 -9
  21. inc/class-wcml-requests.php +18 -9
  22. inc/class-wcml-tp-support.php +41 -39
  23. inc/class-wcml-upgrade.php +11 -1
  24. inc/class-wcml-wc-shipping.php +28 -15
  25. inc/class-wcml-wc-strings.php +65 -51
  26. inc/class-woocommerce-wpml.php +27 -3
  27. inc/currencies/class-wcml-admin-currency-selector.php +114 -113
  28. inc/currencies/class-wcml-multi-currency-orders.php +252 -235
  29. inc/currencies/class-wcml-multi-currency-reports.php +189 -132
  30. inc/currencies/class-wcml-multi-currency-resources.php +10 -4
  31. inc/currencies/class-wcml-multi-currency.php +36 -4
  32. inc/currencies/class-wcml-price-filter.php +3 -1
  33. inc/currencies/currency-switcher/class-wcml-currency-switcher-properties.php +22 -0
  34. inc/currencies/currency-switcher/class-wcml-currency-switcher-templates.php +26 -13
  35. inc/currencies/currency-switcher/class-wcml-currency-switcher.php +13 -11
  36. inc/currencies/exchange-rate-services/class-wcml-exchange-rates-currencylayer.php +8 -9
  37. inc/missing-php-functions.php +71 -58
  38. inc/template-classes/class-wcml-settings-ui.php +17 -4
  39. inc/template-classes/multi-currency/class-wcml-multi-currency-ui.php +2 -0
  40. inc/translation-editor/class-wcml-editor-ui-product-job.php +106 -30
  41. inc/translation-editor/class-wcml-synchronize-product-data.php +166 -15
  42. inc/wcml-switch-lang-request.php +13 -4
  43. readme.txt +33 -42
  44. res/css/wcml-cart-warning.css +15 -0
  45. res/js/wcml-multi-currency.js +1 -1
  46. templates/settings-ui.twig +26 -12
  47. templates/status/store-pages.twig +1 -1
  48. templates/status/taxonomies.twig +1 -1
  49. vendor/autoload.php +1 -1
  50. vendor/autoload_52.php +1 -1
  51. vendor/composer/autoload_classmap.php +184 -1
  52. vendor/composer/autoload_psr4.php +1 -0
  53. vendor/composer/autoload_real.php +4 -4
  54. vendor/composer/autoload_real_52.php +3 -3
  55. vendor/composer/autoload_static.php +197 -6
  56. vendor/composer/installers/src/Composer/Installers/CakePHPInstaller.php +0 -1
  57. vendor/composer/installers/src/Composer/Installers/Concrete5Installer.php +3 -2
  58. vendor/composer/installers/src/Composer/Installers/EliasisInstaller.php +9 -0
  59. vendor/composer/installers/src/Composer/Installers/Installer.php +8 -0
  60. vendor/composer/installers/src/Composer/Installers/ItopInstaller.php +9 -0
  61. vendor/composer/installers/src/Composer/Installers/KanboardInstaller.php +18 -0
  62. vendor/composer/installers/src/Composer/Installers/LavaLiteInstaller.php +10 -0
  63. vendor/composer/installers/src/Composer/Installers/MayaInstaller.php +33 -0
  64. vendor/composer/installers/src/Composer/Installers/MoodleInstaller.php +1 -0
  65. vendor/composer/installers/src/Composer/Installers/OntoWikiInstaller.php +24 -0
  66. vendor/composer/installers/src/Composer/Installers/PortoInstaller.php +9 -0
  67. vendor/composer/installers/src/Composer/Installers/SyDESInstaller.php +49 -0
  68. vendor/composer/installers/src/Composer/Installers/VgmcpInstaller.php +49 -0
  69. vendor/otgs/installer/includes/class-installer-dependencies.php +175 -167
  70. vendor/otgs/installer/includes/class-installer-upgrader-skins.php +38 -0
  71. vendor/otgs/installer/includes/class-translation-service-info.php +40 -0
  72. vendor/otgs/installer/includes/class-wp-installer-api.php +134 -0
  73. vendor/otgs/installer/includes/class-wp-installer-channels.php +291 -0
  74. vendor/otgs/installer/includes/class-wp-installer.php +2769 -0
  75. vendor/otgs/installer/includes/functions-core.php +9 -0
  76. vendor/otgs/installer/includes/functions-templates.php +6 -0
  77. vendor/otgs/installer/installer.php +12 -16
  78. vendor/otgs/installer/loader.php +1 -1
  79. vendor/otgs/installer/res/css/admin.css +89 -1
  80. vendor/otgs/installer/res/js/admin.js +51 -11
  81. vendor/otgs/installer/res/js/channels.js +261 -0
  82. vendor/otgs/installer/templates/channel-selector.php +68 -0
  83. vendor/otgs/installer/templates/downloads-list.php +40 -16
  84. vendor/otgs/installer/templates/repository-listing.php +6 -3
  85. vendor/twig/twig/CHANGELOG +32 -2
  86. vendor/twig/twig/ext/twig/php_twig.h +1 -1
  87. vendor/twig/twig/lib/Twig/BaseNodeVisitor.php +4 -0
  88. vendor/twig/twig/lib/Twig/Cache/Filesystem.php +2 -0
  89. vendor/twig/twig/lib/Twig/Cache/Null.php +2 -0
  90. vendor/twig/twig/lib/Twig/CacheInterface.php +2 -0
  91. vendor/twig/twig/lib/Twig/Compiler.php +3 -0
  92. vendor/twig/twig/lib/Twig/ContainerRuntimeLoader.php +2 -0
  93. vendor/twig/twig/lib/Twig/Environment.php +25 -6
  94. vendor/twig/twig/lib/Twig/Error.php +3 -5
  95. vendor/twig/twig/lib/Twig/Error/Loader.php +2 -0
  96. vendor/twig/twig/lib/Twig/Error/Runtime.php +2 -0
  97. vendor/twig/twig/lib/Twig/Error/Syntax.php +2 -0
  98. vendor/twig/twig/lib/Twig/ExistsLoaderInterface.php +2 -0
  99. vendor/twig/twig/lib/Twig/ExpressionParser.php +2 -0
  100. vendor/twig/twig/lib/Twig/Extension.php +4 -0
  101. vendor/twig/twig/lib/Twig/Extension/Core.php +37 -28
  102. vendor/twig/twig/lib/Twig/Extension/Debug.php +3 -1
  103. vendor/twig/twig/lib/Twig/Extension/Escaper.php +2 -0
  104. vendor/twig/twig/lib/Twig/Extension/GlobalsInterface.php +2 -0
  105. vendor/twig/twig/lib/Twig/Extension/InitRuntimeInterface.php +2 -0
  106. vendor/twig/twig/lib/Twig/Extension/Optimizer.php +2 -0
  107. vendor/twig/twig/lib/Twig/Extension/Profiler.php +3 -0
  108. vendor/twig/twig/lib/Twig/Extension/Sandbox.php +2 -0
  109. vendor/twig/twig/lib/Twig/Extension/Staging.php +2 -0
  110. vendor/twig/twig/lib/Twig/Extension/StringLoader.php +2 -0
  111. vendor/twig/twig/lib/Twig/ExtensionInterface.php +3 -0
  112. vendor/twig/twig/lib/Twig/FactoryRuntimeLoader.php +2 -0
  113. vendor/twig/twig/lib/Twig/FileExtensionEscapingStrategy.php +2 -0
  114. vendor/twig/twig/lib/Twig/Lexer.php +2 -0
  115. vendor/twig/twig/lib/Twig/Loader/Array.php +2 -0
  116. vendor/twig/twig/lib/Twig/Loader/Chain.php +2 -0
  117. vendor/twig/twig/lib/Twig/Loader/Filesystem.php +2 -0
  118. vendor/twig/twig/lib/Twig/LoaderInterface.php +2 -0
  119. vendor/twig/twig/lib/Twig/Markup.php +2 -0
  120. vendor/twig/twig/lib/Twig/Node.php +3 -0
  121. vendor/twig/twig/lib/Twig/Node/AutoEscape.php +2 -0
  122. vendor/twig/twig/lib/Twig/Node/Block.php +2 -0
  123. vendor/twig/twig/lib/Twig/Node/BlockReference.php +2 -0
  124. vendor/twig/twig/lib/Twig/Node/Body.php +2 -0
  125. vendor/twig/twig/lib/Twig/Node/CheckSecurity.php +2 -0
  126. vendor/twig/twig/lib/Twig/Node/Do.php +2 -0
  127. vendor/twig/twig/lib/Twig/Node/Embed.php +2 -0
  128. vendor/twig/twig/lib/Twig/Node/Expression.php +2 -0
  129. vendor/twig/twig/lib/Twig/Node/Expression/Array.php +2 -0
  130. vendor/twig/twig/lib/Twig/Node/Expression/AssignName.php +2 -0
  131. vendor/twig/twig/lib/Twig/Node/Expression/Binary.php +2 -0
  132. vendor/twig/twig/lib/Twig/Node/Expression/Binary/Add.php +2 -0
  133. vendor/twig/twig/lib/Twig/Node/Expression/Binary/And.php +2 -0
  134. vendor/twig/twig/lib/Twig/Node/Expression/Binary/BitwiseAnd.php +2 -0
  135. vendor/twig/twig/lib/Twig/Node/Expression/Binary/BitwiseOr.php +2 -0
  136. vendor/twig/twig/lib/Twig/Node/Expression/Binary/BitwiseXor.php +2 -0
  137. vendor/twig/twig/lib/Twig/Node/Expression/Binary/Concat.php +2 -0
  138. vendor/twig/twig/lib/Twig/Node/Expression/Binary/Div.php +2 -0
  139. vendor/twig/twig/lib/Twig/Node/Expression/Binary/EndsWith.php +2 -0
  140. vendor/twig/twig/lib/Twig/Node/Expression/Binary/Equal.php +2 -0
  141. vendor/twig/twig/lib/Twig/Node/Expression/Binary/FloorDiv.php +2 -0
  142. vendor/twig/twig/lib/Twig/Node/Expression/Binary/Greater.php +2 -0
  143. vendor/twig/twig/lib/Twig/Node/Expression/Binary/GreaterEqual.php +2 -0
  144. vendor/twig/twig/lib/Twig/Node/Expression/Binary/In.php +2 -0
  145. vendor/twig/twig/lib/Twig/Node/Expression/Binary/Less.php +2 -0
  146. vendor/twig/twig/lib/Twig/Node/Expression/Binary/LessEqual.php +2 -0
  147. vendor/twig/twig/lib/Twig/Node/Expression/Binary/Matches.php +2 -0
  148. vendor/twig/twig/lib/Twig/Node/Expression/Binary/Mod.php +2 -0
  149. vendor/twig/twig/lib/Twig/Node/Expression/Binary/Mul.php +2 -0
  150. vendor/twig/twig/lib/Twig/Node/Expression/Binary/NotEqual.php +2 -0
  151. vendor/twig/twig/lib/Twig/Node/Expression/Binary/NotIn.php +2 -0
  152. vendor/twig/twig/lib/Twig/Node/Expression/Binary/Or.php +2 -0
  153. vendor/twig/twig/lib/Twig/Node/Expression/Binary/Power.php +2 -0
  154. vendor/twig/twig/lib/Twig/Node/Expression/Binary/Range.php +2 -0
  155. vendor/twig/twig/lib/Twig/Node/Expression/Binary/StartsWith.php +2 -0
  156. vendor/twig/twig/lib/Twig/Node/Expression/Binary/Sub.php +2 -0
  157. vendor/twig/twig/lib/Twig/Node/Expression/BlockReference.php +2 -0
  158. vendor/twig/twig/lib/Twig/Node/Expression/Call.php +2 -0
  159. vendor/twig/twig/lib/Twig/Node/Expression/Conditional.php +2 -0
  160. vendor/twig/twig/lib/Twig/Node/Expression/Constant.php +2 -0
  161. vendor/twig/twig/lib/Twig/Node/Expression/Filter.php +2 -0
  162. vendor/twig/twig/lib/Twig/Node/Expression/Filter/Default.php +2 -0
  163. vendor/twig/twig/lib/Twig/Node/Expression/Function.php +2 -0
  164. vendor/twig/twig/lib/Twig/Node/Expression/GetAttr.php +2 -0
  165. vendor/twig/twig/lib/Twig/Node/Expression/MethodCall.php +2 -0
  166. vendor/twig/twig/lib/Twig/Node/Expression/Name.php +2 -0
  167. vendor/twig/twig/lib/Twig/Node/Expression/NullCoalesce.php +2 -0
  168. vendor/twig/twig/lib/Twig/Node/Expression/Parent.php +2 -0
  169. vendor/twig/twig/lib/Twig/Node/Expression/TempName.php +2 -0
  170. vendor/twig/twig/lib/Twig/Node/Expression/Test.php +2 -0
  171. vendor/twig/twig/lib/Twig/Node/Expression/Test/Constant.php +2 -0
  172. vendor/twig/twig/lib/Twig/Node/Expression/Test/Defined.php +2 -0
  173. vendor/twig/twig/lib/Twig/Node/Expression/Test/Divisibleby.php +2 -0
  174. vendor/twig/twig/lib/Twig/Node/Expression/Test/Even.php +2 -0
  175. vendor/twig/twig/lib/Twig/Node/Expression/Test/Null.php +2 -0
  176. vendor/twig/twig/lib/Twig/Node/Expression/Test/Odd.php +2 -0
  177. vendor/twig/twig/lib/Twig/Node/Expression/Test/Sameas.php +2 -0
  178. vendor/twig/twig/lib/Twig/Node/Expression/Unary.php +2 -0
  179. vendor/twig/twig/lib/Twig/Node/Expression/Unary/Neg.php +2 -0
  180. vendor/twig/twig/lib/Twig/Node/Expression/Unary/Not.php +2 -0
  181. vendor/twig/twig/lib/Twig/Node/Expression/Unary/Pos.php +2 -0
  182. vendor/twig/twig/lib/Twig/Node/Flush.php +2 -0
  183. vendor/twig/twig/lib/Twig/Node/For.php +2 -0
  184. vendor/twig/twig/lib/Twig/Node/ForLoop.php +2 -0
  185. vendor/twig/twig/lib/Twig/Node/If.php +2 -0
  186. vendor/twig/twig/lib/Twig/Node/Import.php +2 -0
  187. vendor/twig/twig/lib/Twig/Node/Include.php +2 -0
  188. vendor/twig/twig/lib/Twig/Node/Macro.php +2 -0
  189. vendor/twig/twig/lib/Twig/Node/Module.php +2 -0
  190. vendor/twig/twig/lib/Twig/Node/Print.php +2 -0
  191. vendor/twig/twig/lib/Twig/Node/Sandbox.php +2 -0
  192. vendor/twig/twig/lib/Twig/Node/SandboxedPrint.php +2 -0
  193. vendor/twig/twig/lib/Twig/Node/Set.php +2 -0
  194. vendor/twig/twig/lib/Twig/Node/SetTemp.php +5 -0
  195. vendor/twig/twig/lib/Twig/Node/Spaceless.php +2 -0
  196. vendor/twig/twig/lib/Twig/Node/Text.php +2 -0
  197. vendor/twig/twig/lib/Twig/Node/With.php +2 -0
  198. vendor/twig/twig/lib/Twig/NodeCaptureInterface.php +2 -0
  199. vendor/twig/twig/lib/Twig/NodeOutputInterface.php +2 -0
  200. vendor/twig/twig/lib/Twig/NodeTraverser.php +2 -0
  201. vendor/twig/twig/lib/Twig/NodeVisitor/Escaper.php +2 -0
  202. vendor/twig/twig/lib/Twig/NodeVisitor/Optimizer.php +2 -0
  203. vendor/twig/twig/lib/Twig/NodeVisitor/SafeAnalysis.php +2 -0
  204. vendor/twig/twig/lib/Twig/NodeVisitor/Sandbox.php +2 -0
  205. vendor/twig/twig/lib/Twig/NodeVisitorInterface.php +4 -0
  206. vendor/twig/twig/lib/Twig/Parser.php +4 -0
  207. vendor/twig/twig/lib/Twig/Profiler/Dumper/Base.php +62 -0
  208. vendor/twig/twig/lib/Twig/Profiler/Dumper/Blackfire.php +2 -0
  209. vendor/twig/twig/lib/Twig/Profiler/Dumper/Html.php +3 -1
  210. vendor/twig/twig/lib/Twig/Profiler/Dumper/Text.php +3 -38
  211. vendor/twig/twig/lib/Twig/Profiler/Node/EnterProfile.php +2 -0
  212. vendor/twig/twig/lib/Twig/Profiler/Node/LeaveProfile.php +2 -0
  213. vendor/twig/twig/lib/Twig/Profiler/NodeVisitor/Profiler.php +2 -0
  214. vendor/twig/twig/lib/Twig/Profiler/Profile.php +2 -0
  215. vendor/twig/twig/lib/Twig/RuntimeLoaderInterface.php +2 -0
  216. vendor/twig/twig/lib/Twig/Sandbox/SecurityError.php +2 -0
  217. vendor/twig/twig/lib/Twig/Sandbox/SecurityNotAllowedFilterError.php +2 -0
  218. vendor/twig/twig/lib/Twig/Sandbox/SecurityNotAllowedFunctionError.php +2 -0
  219. vendor/twig/twig/lib/Twig/Sandbox/SecurityNotAllowedMethodError.php +2 -0
  220. vendor/twig/twig/lib/Twig/Sandbox/SecurityNotAllowedPropertyError.php +2 -0
  221. vendor/twig/twig/lib/Twig/Sandbox/SecurityNotAllowedTagError.php +2 -0
  222. vendor/twig/twig/lib/Twig/Sandbox/SecurityPolicy.php +2 -0
  223. vendor/twig/twig/lib/Twig/Sandbox/SecurityPolicyInterface.php +2 -0
  224. vendor/twig/twig/lib/Twig/SimpleFilter.php +2 -0
  225. vendor/twig/twig/lib/Twig/SimpleFunction.php +2 -0
  226. vendor/twig/twig/lib/Twig/SimpleTest.php +2 -0
  227. vendor/twig/twig/lib/Twig/Source.php +2 -0
  228. vendor/twig/twig/lib/Twig/SourceContextLoaderInterface.php +2 -0
  229. vendor/twig/twig/lib/Twig/Template.php +10 -5
  230. vendor/twig/twig/lib/Twig/TemplateWrapper.php +2 -0
  231. vendor/twig/twig/lib/Twig/Test/IntegrationTestCase.php +19 -2
  232. vendor/twig/twig/lib/Twig/Test/NodeTestCase.php +8 -1
  233. vendor/twig/twig/lib/Twig/Token.php +2 -0
  234. vendor/twig/twig/lib/Twig/TokenParser.php +2 -0
  235. vendor/twig/twig/lib/Twig/TokenParser/AutoEscape.php +2 -0
  236. vendor/twig/twig/lib/Twig/TokenParser/Block.php +2 -0
  237. vendor/twig/twig/lib/Twig/TokenParser/Do.php +2 -0
  238. vendor/twig/twig/lib/Twig/TokenParser/Embed.php +2 -0
  239. vendor/twig/twig/lib/Twig/TokenParser/Extends.php +2 -0
  240. vendor/twig/twig/lib/Twig/TokenParser/Filter.php +2 -0
  241. vendor/twig/twig/lib/Twig/TokenParser/Flush.php +2 -0
  242. vendor/twig/twig/lib/Twig/TokenParser/For.php +2 -0
  243. vendor/twig/twig/lib/Twig/TokenParser/From.php +2 -0
  244. vendor/twig/twig/lib/Twig/TokenParser/If.php +2 -0
  245. vendor/twig/twig/lib/Twig/TokenParser/Import.php +2 -0
  246. vendor/twig/twig/lib/Twig/TokenParser/Include.php +2 -2
  247. vendor/twig/twig/lib/Twig/TokenParser/Macro.php +2 -0
  248. vendor/twig/twig/lib/Twig/TokenParser/Sandbox.php +2 -0
  249. vendor/twig/twig/lib/Twig/TokenParser/Set.php +2 -0
  250. vendor/twig/twig/lib/Twig/TokenParser/Spaceless.php +2 -0
  251. vendor/twig/twig/lib/Twig/TokenParser/Use.php +2 -0
  252. vendor/twig/twig/lib/Twig/TokenParser/With.php +2 -0
  253. vendor/twig/twig/lib/Twig/TokenParserInterface.php +4 -0
  254. vendor/twig/twig/lib/Twig/TokenStream.php +2 -0
  255. vendor/twig/twig/lib/Twig/Util/DeprecationCollector.php +2 -0
  256. vendor/twig/twig/lib/Twig/Util/TemplateDirIterator.php +2 -0
  257. wpml-woocommerce.php +7 -3
changelog/4.1.4.md CHANGED
@@ -1,5 +1,4 @@
1
  # Fixes
2
- * [wcml-1954] A PHP warning was shown on a product bundle page on the front end (when using WooCommerce Product Bundles)
3
  * [wcml-1949] Added possibility to filter available Currency Switcher templates paths via "wcml_cs_directories_to_scan" filter
4
  * [wcml-1948] The "Copy to a new draft" link was showing two times on the product edit page
5
  * [wcml-1947] For taxonomies having the term_id distinct from term_taxonomy_id, the translations could have been accidentally overwritten
1
  # Fixes
 
2
  * [wcml-1949] Added possibility to filter available Currency Switcher templates paths via "wcml_cs_directories_to_scan" filter
3
  * [wcml-1948] The "Copy to a new draft" link was showing two times on the product edit page
4
  * [wcml-1947] For taxonomies having the term_id distinct from term_taxonomy_id, the translations could have been accidentally overwritten
changelog/4.2.0.md ADDED
@@ -0,0 +1,23 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Features
2
+ * [wcml-496] Added the ability to translate Sensei question custom post types
3
+ * [wcml-1920] Added the ability to translate serialized custom fields in the Translation Editor
4
+ * [wcml-1681] Payment method title not displaying in emails Mollie Payment's payment processor compatibility
5
+ * [wcml-1672] Show an admin notice for environments in which switching the language or currency on the front end, could corrupt the cart contents
6
+
7
+ # Fixes
8
+ * [wcml-2037] When selecting the currencylayer provider for automatic exchange rate, the API KEY filter was not visible
9
+ * [wcml-2025] The multi-currency component made the admin dashboard page loading unnecessarily slow
10
+ * [wcml-2019] Variations with custom attributes could not be duplicated as translations
11
+ * [wcml-2010] A fatal error occurred when using old WordPress versions (before 4.4.0) - rest_get_url_prefix didn't exist
12
+ * [wcml-2009] The admin orders page was loading slower than necessary
13
+ * [wcml-1997] A PHP fatal error was occurring when using the Adventure Tours extension
14
+ * [wcml-1990] A product addon was added to the cart more then once in combination with Bookings
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
21
+ * [wcml-1923] Bookings max availability value was changing after adding bookable product to cart few times
22
+ * [wcml-1832] In some cases the option to prompt for a confirmation about resetting the cart when switching the language was not working
23
+ * [wcml-1765] The variation names were, sometimes, displayed in the wrong language in the orders, on the back-end
classes/order-property-filter/class-wcml-payment-method-filter.php ADDED
@@ -0,0 +1,54 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class WCML_Payment_Method_Filter {
4
+ /** @var array */
5
+ private $payment_gateway_cache = array();
6
+
7
+ /** @var array */
8
+ private $post_type_cache = array();
9
+
10
+ public function add_hooks() {
11
+ add_filter( 'get_post_metadata', array( $this, 'payment_method_string' ), 10, 3 );
12
+ }
13
+
14
+ public function payment_method_string( $title, $object_id, $meta_key ) {
15
+ if ( '_payment_method_title' === $meta_key && '' !== $title && $object_id && 'shop_order' === $this->get_post_type( $object_id ) ) {
16
+ $payment_gateway = $this->get_payment_gateway( $object_id );
17
+
18
+ if( $payment_gateway ){
19
+ $title = icl_translate( 'woocommerce', $payment_gateway->id . '_gateway_title', $payment_gateway->title );
20
+ }
21
+ }
22
+
23
+ return $title;
24
+ }
25
+
26
+ /**
27
+ * @param int $object_id
28
+ *
29
+ * @return string
30
+ */
31
+ private function get_post_type( $object_id ) {
32
+ if ( ! array_key_exists( $object_id, $this->post_type_cache ) ) {
33
+ $this->post_type_cache[ $object_id ] = get_post_type( $object_id );
34
+ }
35
+
36
+ return $this->post_type_cache[ $object_id ];
37
+ }
38
+
39
+ /**
40
+ * @param int $object_id
41
+ *
42
+ * @return bool|WC_Payment_Gateway
43
+ */
44
+ private function get_payment_gateway( $object_id ) {
45
+ if ( ! array_key_exists( $object_id, $this->payment_gateway_cache ) ) {
46
+ remove_filter( 'get_post_metadata', array( $this, 'payment_method_string' ), 10, 3 );
47
+ $payment_gateway = wc_get_payment_gateway_by_order( $object_id );
48
+ add_filter( 'get_post_metadata', array( $this, 'payment_method_string' ), 10, 3 );
49
+ $this->payment_gateway_cache[ $object_id ] = $payment_gateway;
50
+ }
51
+
52
+ return $this->payment_gateway_cache[ $object_id ];
53
+ }
54
+ }
compatibility/class-wcml-adventure-tours.php CHANGED
@@ -2,22 +2,44 @@
2
 
3
  class WCML_Adventure_tours{
4
 
 
 
 
 
 
 
 
 
 
 
 
 
5
  private $tp;
6
 
7
- function __construct(){
8
- add_action('updated_post_meta', array($this, 'sync_tour_data_across_translations'), 10, 4);
9
- add_filter( 'get_post_metadata', array( $this, 'product_price_filter'), 9, 4 );
 
 
 
 
 
 
 
 
10
 
11
- if (is_admin()) {
 
 
12
 
13
- add_action('wcml_gui_additional_box_html', array($this, 'custom_box_html'), 10, 3);
14
- add_filter('wcml_gui_additional_box_data', array($this, 'custom_box_html_data'), 10, 4);
15
- add_action('wcml_update_extra_fields', array($this, 'tour_data_update'), 10, 3);
16
 
17
- $this->tp = new WPML_Element_Translation_Package();
 
 
18
 
19
- add_filter('wpml_tm_translation_job_data', array($this, 'append_tour_data_translation_package'), 10, 2);
20
- add_action('wpml_translation_job_saved', array($this, 'save_tour_data_translation'), 10, 3);
21
 
22
  add_action( 'admin_footer', array( $this, 'load_assets' ) );
23
  add_action( 'wcml_after_custom_prices_block', array( $this, 'add_custom_prices_block' ) );
@@ -26,6 +48,12 @@ class WCML_Adventure_tours{
26
  add_filter( 'wcml_is_variable_product', array( $this, 'is_variable_tour' ), 10, 2 );
27
  add_filter( 'wcml_variation_term_taxonomy_ids', array( $this, 'add_tour_tax_id' ) );
28
  add_filter( 'wcml_is_attributes_page', array( $this, 'is_attributes_page' ) );
 
 
 
 
 
 
29
  }
30
  }
31
 
@@ -36,8 +64,6 @@ class WCML_Adventure_tours{
36
  return false;
37
 
38
 
39
- global $sitepress, $woocommerce_wpml;
40
-
41
  $post = get_post($post_id);
42
 
43
  // skip auto-drafts // skip autosave
@@ -49,18 +75,14 @@ class WCML_Adventure_tours{
49
 
50
  remove_action('updated_post_meta', array($this, 'sync_tour_data_across_translations'), 10, 4);
51
 
52
- if ( $woocommerce_wpml->products->is_original_product( $post_id ) ) {
53
-
54
- $original_product_id = $post_id;
55
-
56
- } else {
57
-
58
- $original_product_id = $this->woocommerce_wpml->products->get_original_product_id( $post_id );
59
-
60
  }
61
 
62
- $product_trid = $sitepress->get_element_trid( $original_product_id, 'post_product' );
63
- $product_translations = $sitepress->get_element_translations( $product_trid, 'post_product' );
64
 
65
  foreach ($product_translations as $product_translation) {
66
 
@@ -237,7 +259,7 @@ class WCML_Adventure_tours{
237
  }
238
 
239
  function load_assets(){
240
- global $pagenow, $woocommerce_wpml;
241
 
242
  if( $pagenow == 'post.php' || $pagenow == 'post-new.php' ){
243
  wp_register_script( 'wcml-adventure-tours', WCML_PLUGIN_URL . '/compatibility/res/js/wcml-adventure-tours.js', array( 'jquery' ), WCML_VERSION );
@@ -246,10 +268,9 @@ class WCML_Adventure_tours{
246
  }
247
 
248
  function add_custom_prices_block( $product_id ){
249
- global $woocommerce_wpml;
250
 
251
  if( $product_id != 'new' ){
252
- $currencies = $woocommerce_wpml->multi_currency->get_currencies();
253
  $tour_booking_periods = get_post_meta( $product_id, 'tour_booking_periods', true );
254
  $custom_periods_prices = get_post_meta( $product_id, 'custom_booking_periods_prices', true );
255
  if( $tour_booking_periods ){
@@ -274,10 +295,9 @@ class WCML_Adventure_tours{
274
  }
275
 
276
  function save_custom_costs( $post_id ){
277
- global $woocommerce_wpml;
278
 
279
  $tour_spec_price = array();
280
- $currencies = $woocommerce_wpml->multi_currency->get_currencies();
281
 
282
  if( isset( $_POST[ 'tour_spec_price' ] ) && is_array( $_POST[ 'tour_spec_price' ] ) ) {
283
 
@@ -295,19 +315,19 @@ class WCML_Adventure_tours{
295
  }
296
 
297
  function product_price_filter( $value, $object_id, $meta_key, $single ){
298
- global $woocommerce_wpml;
299
 
300
  if(
301
- get_post_type( $object_id ) == 'product' &&
302
- $meta_key == 'tour_booking_periods' &&
303
- $woocommerce_wpml->settings[ 'enable_multi_currency' ] == WCML_MULTI_CURRENCIES_INDEPENDENT &&
304
  !is_admin() &&
305
- ( $currency = $woocommerce_wpml->multi_currency->get_client_currency() ) != get_option( 'woocommerce_currency' )
306
  ) {
307
 
308
  remove_filter( 'get_post_metadata', array( $this, 'product_price_filter' ), 9, 4 );
309
 
310
- $original_product = $this->woocommerce_wpml->products->get_original_product_id( $object_id );
 
311
 
312
  if ( get_post_meta( $original_product, '_wcml_custom_prices_status' ) ) {
313
  $custom_periods_prices = get_post_meta( $object_id, 'custom_booking_periods_prices', true );
@@ -366,4 +386,10 @@ class WCML_Adventure_tours{
366
  return $is_attributes_page;
367
  }
368
 
 
 
 
 
 
 
369
  }
2
 
3
  class WCML_Adventure_tours{
4
 
5
+ /**
6
+ * @var woocommerce_wpml
7
+ */
8
+ private $woocommerce_wpml;
9
+ /**
10
+ * @var SitePress
11
+ */
12
+ private $sitepress;
13
+
14
+ /**
15
+ * @var WPML_Element_Translation_Package
16
+ */
17
  private $tp;
18
 
19
+ /**
20
+ * WCML_Adventure_tours constructor.
21
+ * @param woocommerce_wpml $woocommerce_wpml
22
+ * @param SitePress $sitepress
23
+ * @param WPML_Element_Translation_Package $tp
24
+ */
25
+ function __construct( woocommerce_wpml $woocommerce_wpml, SitePress $sitepress, WPML_Element_Translation_Package $tp ) {
26
+ $this->woocommerce_wpml = $woocommerce_wpml;
27
+ $this->sitepress = $sitepress;
28
+ $this->tp = $tp;
29
+ }
30
 
31
+ public function add_hooks(){
32
+ add_action( 'updated_post_meta', array( $this, 'sync_tour_data_across_translations' ), 10, 4 );
33
+ add_filter( 'get_post_metadata', array( $this, 'product_price_filter'), 9, 4 );
34
 
35
+ if ( is_admin() ) {
 
 
36
 
37
+ add_action( 'wcml_gui_additional_box_html', array( $this, 'custom_box_html' ), 10, 3 );
38
+ add_filter( 'wcml_gui_additional_box_data', array( $this, 'custom_box_html_data' ), 10, 4 );
39
+ add_action( 'wcml_update_extra_fields', array( $this, 'tour_data_update' ), 10, 3 );
40
 
41
+ add_filter( 'wpml_tm_translation_job_data', array( $this, 'append_tour_data_translation_package' ), 10, 2 );
42
+ add_action( 'wpml_translation_job_saved', array( $this, 'save_tour_data_translation' ), 10, 3 );
43
 
44
  add_action( 'admin_footer', array( $this, 'load_assets' ) );
45
  add_action( 'wcml_after_custom_prices_block', array( $this, 'add_custom_prices_block' ) );
48
  add_filter( 'wcml_is_variable_product', array( $this, 'is_variable_tour' ), 10, 2 );
49
  add_filter( 'wcml_variation_term_taxonomy_ids', array( $this, 'add_tour_tax_id' ) );
50
  add_filter( 'wcml_is_attributes_page', array( $this, 'is_attributes_page' ) );
51
+ add_filter( 'wcml_is_attributes_page', array( $this, 'is_attributes_page' ) );
52
+
53
+ add_filter( 'wcml_do_not_display_custom_fields_for_product', array(
54
+ $this,
55
+ 'replace_tm_editor_custom_fields_with_own_sections'
56
+ ) );
57
  }
58
  }
59
 
64
  return false;
65
 
66
 
 
 
67
  $post = get_post($post_id);
68
 
69
  // skip auto-drafts // skip autosave
75
 
76
  remove_action('updated_post_meta', array($this, 'sync_tour_data_across_translations'), 10, 4);
77
 
78
+ $original_product_id = $post_id;
79
+ if ( ! $this->woocommerce_wpml->products->is_original_product( $post_id ) ) {
80
+ $original_product_language = $this->woocommerce_wpml->products->get_original_product_language( $post_id );
81
+ $original_product_id = apply_filters( 'translate_object_id', $post_id, 'product', true, $original_product_language );
 
 
 
 
82
  }
83
 
84
+ $product_trid = $this->sitepress->get_element_trid( $original_product_id, 'post_product' );
85
+ $product_translations = $this->sitepress->get_element_translations( $product_trid, 'post_product' );
86
 
87
  foreach ($product_translations as $product_translation) {
88
 
259
  }
260
 
261
  function load_assets(){
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 );
268
  }
269
 
270
  function add_custom_prices_block( $product_id ){
 
271
 
272
  if( $product_id != 'new' ){
273
+ $currencies = $this->woocommerce_wpml->multi_currency->get_currencies();
274
  $tour_booking_periods = get_post_meta( $product_id, 'tour_booking_periods', true );
275
  $custom_periods_prices = get_post_meta( $product_id, 'custom_booking_periods_prices', true );
276
  if( $tour_booking_periods ){
295
  }
296
 
297
  function save_custom_costs( $post_id ){
 
298
 
299
  $tour_spec_price = array();
300
+ $currencies = $this->woocommerce_wpml->multi_currency->get_currencies();
301
 
302
  if( isset( $_POST[ 'tour_spec_price' ] ) && is_array( $_POST[ 'tour_spec_price' ] ) ) {
303
 
315
  }
316
 
317
  function product_price_filter( $value, $object_id, $meta_key, $single ){
 
318
 
319
  if(
320
+ get_post_type( $object_id ) === 'product' &&
321
+ $meta_key === 'tour_booking_periods' &&
322
+ $this->woocommerce_wpml->settings[ 'enable_multi_currency' ] === WCML_MULTI_CURRENCIES_INDEPENDENT &&
323
  !is_admin() &&
324
+ ( $currency = $this->woocommerce_wpml->multi_currency->get_client_currency() ) !== get_option( 'woocommerce_currency' )
325
  ) {
326
 
327
  remove_filter( 'get_post_metadata', array( $this, 'product_price_filter' ), 9, 4 );
328
 
329
+ $original_language = $this->woocommerce_wpml->products->get_original_product_language( $object_id );
330
+ $original_product = apply_filters( 'translate_object_id', $object_id, 'product', true, $original_language );
331
 
332
  if ( get_post_meta( $original_product, '_wcml_custom_prices_status' ) ) {
333
  $custom_periods_prices = get_post_meta( $object_id, 'custom_booking_periods_prices', true );
386
  return $is_attributes_page;
387
  }
388
 
389
+ function replace_tm_editor_custom_fields_with_own_sections( $fields ){
390
+ $fields[] = 'tour_tabs_meta';
391
+
392
+ return $fields;
393
+ }
394
+
395
  }
compatibility/class-wcml-bookings.php CHANGED
@@ -8,30 +8,38 @@ class WCML_Bookings {
8
  /**
9
  * @var WPML_Element_Translation_Package
10
  */
11
- public $tp;
12
 
13
  /**
14
  * @var SitePress
15
  */
16
- public $sitepress;
17
 
18
  /**
19
  * @var woocommerce_wpml
20
  */
21
- public $woocommerce_wpml;
22
 
23
  /**
24
  * @var wpdb
25
  */
26
- public $wpdb;
27
 
28
  /**
29
  * WCML_Bookings constructor.
 
 
 
 
30
  */
31
- function __construct( &$sitepress, &$woocommerce_wpml, &$wpdb ) {
32
  $this->sitepress = $sitepress;
33
  $this->woocommerce_wpml = $woocommerce_wpml;
34
  $this->wpdb = $wpdb;
 
 
 
 
35
  add_action( 'woocommerce_bookings_after_booking_base_cost', array(
36
  $this,
37
  'wcml_price_field_after_booking_base_cost'
@@ -107,7 +115,7 @@ class WCML_Bookings {
107
  add_action( 'wcml_gui_additional_box_html', array( $this, 'custom_box_html' ), 10, 3 );
108
  add_filter( 'wcml_gui_additional_box_data', array( $this, 'custom_box_html_data' ), 10, 4 );
109
  add_filter( 'wcml_check_is_single', array( $this, 'show_custom_blocks_for_resources_and_persons' ), 10, 3 );
110
- add_filter( 'wcml_product_content_exception', array( $this, 'remove_custom_fields_to_translate' ), 10, 3 );
111
  add_filter( 'wcml_not_display_single_fields_to_translate', array(
112
  $this,
113
  'remove_single_custom_fields_to_translate'
@@ -138,8 +146,6 @@ class WCML_Bookings {
138
 
139
  if ( is_admin() ) {
140
 
141
- $this->tp = new WPML_Element_Translation_Package;
142
-
143
  add_filter( 'wpml_tm_translation_job_data', array(
144
  $this,
145
  'append_persons_to_translation_package'
@@ -171,7 +177,7 @@ class WCML_Bookings {
171
  }
172
 
173
  //@TODO review after WPML 3.6
174
- if ( version_compare( ICL_SITEPRESS_VERSION, '3.6', '<' ) ) {
175
  add_action( 'added_post_meta', array(
176
  $this,
177
  'maybe_fix_double_serialized_wc_booking_availability'
@@ -1090,11 +1096,7 @@ class WCML_Bookings {
1090
 
1091
  $booking_form = new WC_Booking_Form( wc_get_product( $current_id ) );
1092
 
1093
- $prod_qty = get_post_meta( $current_id, '_wc_booking_qty', true );
1094
- update_post_meta( $current_id, '_wc_booking_qty', intval( $prod_qty + $cart_item['booking']['_qty'] ) );
1095
  $cost = $booking_form->calculate_booking_cost( $booking_info );
1096
- update_post_meta( $current_id, '_wc_booking_qty', $prod_qty );
1097
-
1098
  if ( ! is_wp_error( $cost ) ) {
1099
  $cart_item['data']->set_price( $cost );
1100
  }
@@ -1103,7 +1105,6 @@ class WCML_Bookings {
1103
  }
1104
 
1105
  return $cart_item;
1106
-
1107
  }
1108
 
1109
  function booking_currency_dropdown() {
@@ -1378,12 +1379,11 @@ class WCML_Bookings {
1378
  return $check;
1379
  }
1380
 
1381
- function remove_custom_fields_to_translate( $exception, $product_id, $meta_key ) {
1382
- if ( in_array( $meta_key, array( '_resource_base_costs', '_resource_block_costs' ) ) ) {
1383
- $exception = true;
1384
- }
1385
 
1386
- return $exception;
1387
  }
1388
 
1389
  function remove_single_custom_fields_to_translate( $fields ) {
8
  /**
9
  * @var WPML_Element_Translation_Package
10
  */
11
+ private $tp;
12
 
13
  /**
14
  * @var SitePress
15
  */
16
+ private $sitepress;
17
 
18
  /**
19
  * @var woocommerce_wpml
20
  */
21
+ private $woocommerce_wpml;
22
 
23
  /**
24
  * @var wpdb
25
  */
26
+ private $wpdb;
27
 
28
  /**
29
  * WCML_Bookings constructor.
30
+ * @param SitePress $sitepress
31
+ * @param woocommerce_wpml $woocommerce_wpml
32
+ * @param wpdb $wpdb
33
+ * @param WPML_Element_Translation_Package $tp
34
  */
35
+ function __construct( SitePress $sitepress, woocommerce_wpml $woocommerce_wpml, wpdb $wpdb, WPML_Element_Translation_Package $tp ) {
36
  $this->sitepress = $sitepress;
37
  $this->woocommerce_wpml = $woocommerce_wpml;
38
  $this->wpdb = $wpdb;
39
+ $this->tp = $tp;
40
+ }
41
+
42
+ public function add_hooks(){
43
  add_action( 'woocommerce_bookings_after_booking_base_cost', array(
44
  $this,
45
  'wcml_price_field_after_booking_base_cost'
115
  add_action( 'wcml_gui_additional_box_html', array( $this, 'custom_box_html' ), 10, 3 );
116
  add_filter( 'wcml_gui_additional_box_data', array( $this, 'custom_box_html_data' ), 10, 4 );
117
  add_filter( 'wcml_check_is_single', array( $this, 'show_custom_blocks_for_resources_and_persons' ), 10, 3 );
118
+ add_filter( 'wcml_do_not_display_custom_fields_for_product', array( $this, 'replace_tm_editor_custom_fields_with_own_sections' ) );
119
  add_filter( 'wcml_not_display_single_fields_to_translate', array(
120
  $this,
121
  'remove_single_custom_fields_to_translate'
146
 
147
  if ( is_admin() ) {
148
 
 
 
149
  add_filter( 'wpml_tm_translation_job_data', array(
150
  $this,
151
  'append_persons_to_translation_package'
177
  }
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'
1096
 
1097
  $booking_form = new WC_Booking_Form( wc_get_product( $current_id ) );
1098
 
 
 
1099
  $cost = $booking_form->calculate_booking_cost( $booking_info );
 
 
1100
  if ( ! is_wp_error( $cost ) ) {
1101
  $cart_item['data']->set_price( $cost );
1102
  }
1105
  }
1106
 
1107
  return $cart_item;
 
1108
  }
1109
 
1110
  function booking_currency_dropdown() {
1379
  return $check;
1380
  }
1381
 
1382
+ function replace_tm_editor_custom_fields_with_own_sections( $fields ) {
1383
+ $fields[] = '_resource_base_costs';
1384
+ $fields[] = '_resource_block_costs';
 
1385
 
1386
+ return $fields;
1387
  }
1388
 
1389
  function remove_single_custom_fields_to_translate( $fields ) {
compatibility/class-wcml-composite-products.php CHANGED
@@ -6,18 +6,29 @@ class WCML_Composite_Products extends WCML_Compatibility_Helper{
6
  /**
7
  * @var SitePress
8
  */
9
- public $sitepress;
10
-
11
  /**
12
  * @var woocommerce_wpml
13
  */
14
- public $woocommerce_wpml;
15
-
 
 
16
  private $tp;
17
 
18
- function __construct( &$sitepress, &$woocommerce_wpml ) {
19
- $this->sitepress = $sitepress;
 
 
 
 
 
 
20
  $this->woocommerce_wpml = $woocommerce_wpml;
 
 
 
 
21
 
22
  add_filter( 'woocommerce_composite_component_default_option', array($this, 'woocommerce_composite_component_default_option'), 10, 3 );
23
  add_filter( 'wcml_cart_contents', array($this, 'wpml_composites_compat'), 11, 4 );
@@ -31,8 +42,6 @@ class WCML_Composite_Products extends WCML_Compatibility_Helper{
31
  add_action( 'wcml_update_extra_fields', array( $this, 'components_update' ), 10, 4 );
32
  add_filter( 'woocommerce_json_search_found_products', array( $this, 'woocommerce_json_search_found_products' ) );
33
 
34
- $this->tp = new WPML_Element_Translation_Package();
35
-
36
  add_filter( 'wpml_tm_translation_job_data', array( $this, 'append_composite_data_translation_package' ), 10, 2 );
37
  add_action( 'wpml_translation_job_saved', array( $this, 'save_composite_data_translation' ), 10, 3 );
38
  //lock fields on translations pages
@@ -42,6 +51,8 @@ class WCML_Composite_Products extends WCML_Compatibility_Helper{
42
  add_action( 'init', array( $this, 'load_assets' ) );
43
 
44
  add_action( 'wcml_after_save_custom_prices', array( $this, 'update_composite_custom_prices' ), 10, 4 );
 
 
45
  }else{
46
  add_filter( 'get_post_metadata', array( $this, 'filter_composite_product_cost' ), 10, 4 );
47
  }
@@ -544,4 +555,11 @@ class WCML_Composite_Products extends WCML_Compatibility_Helper{
544
 
545
  }
546
 
 
 
 
 
 
 
 
547
  }
6
  /**
7
  * @var SitePress
8
  */
9
+ private $sitepress;
 
10
  /**
11
  * @var woocommerce_wpml
12
  */
13
+ private $woocommerce_wpml;
14
+ /**
15
+ * @var WPML_Element_Translation_Package
16
+ */
17
  private $tp;
18
 
19
+ /**
20
+ * WCML_Composite_Products constructor.
21
+ * @param SitePress $sitepress
22
+ * @param woocommerce_wpml $woocommerce_wpml
23
+ * @param WPML_Element_Translation_Package $tp
24
+ */
25
+ function __construct( SitePress $sitepress, woocommerce_wpml $woocommerce_wpml, WPML_Element_Translation_Package $tp ) {
26
+ $this->sitepress = $sitepress;
27
  $this->woocommerce_wpml = $woocommerce_wpml;
28
+ $this->tp = $tp;
29
+ }
30
+
31
+ public function add_hooks(){
32
 
33
  add_filter( 'woocommerce_composite_component_default_option', array($this, 'woocommerce_composite_component_default_option'), 10, 3 );
34
  add_filter( 'wcml_cart_contents', array($this, 'wpml_composites_compat'), 11, 4 );
42
  add_action( 'wcml_update_extra_fields', array( $this, 'components_update' ), 10, 4 );
43
  add_filter( 'woocommerce_json_search_found_products', array( $this, 'woocommerce_json_search_found_products' ) );
44
 
 
 
45
  add_filter( 'wpml_tm_translation_job_data', array( $this, 'append_composite_data_translation_package' ), 10, 2 );
46
  add_action( 'wpml_translation_job_saved', array( $this, 'save_composite_data_translation' ), 10, 3 );
47
  //lock fields on translations pages
51
  add_action( 'init', array( $this, 'load_assets' ) );
52
 
53
  add_action( 'wcml_after_save_custom_prices', array( $this, 'update_composite_custom_prices' ), 10, 4 );
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, 'filter_composite_product_cost' ), 10, 4 );
58
  }
555
 
556
  }
557
 
558
+ function replace_tm_editor_custom_fields_with_own_sections( $fields ){
559
+ $fields[] = '_bto_data';
560
+ $fields[] = '_bto_scenario_data';
561
+
562
+ return $fields;
563
+ }
564
+
565
  }
compatibility/class-wcml-product-addons.php CHANGED
@@ -12,9 +12,13 @@ class WCML_Product_Addons {
12
 
13
  /**
14
  * WCML_Product_Addons constructor.
 
15
  */
16
- function __construct( &$sitepress ) {
17
  $this->sitepress = $sitepress;
 
 
 
18
  add_filter( 'get_product_addons_product_terms', array( $this, 'addons_product_terms' ) );
19
  add_filter( 'get_product_addons_fields', array( $this, 'product_addons_filter' ), 10, 1 );
20
 
@@ -42,12 +46,10 @@ class WCML_Product_Addons {
42
  add_action( 'wcml_update_extra_fields', array( $this, 'addons_update' ), 10, 3 );
43
 
44
  add_action( 'woocommerce_product_data_panels', array( $this, 'show_pointer_info' ) );
 
 
45
  }
46
 
47
- add_filter( 'wcml_cart_contents_not_changed', array(
48
- $this,
49
- 'filter_booing_addon_product_in_cart_contents'
50
- ), 20 );
51
  }
52
 
53
  /**
@@ -266,19 +268,10 @@ class WCML_Product_Addons {
266
  $pointer_ui->show();
267
  }
268
 
269
- // special case for WC Bookings plugin - need add addon cost after re-calculating booking costs #wcml-1877
270
- public function filter_booing_addon_product_in_cart_contents( $cart_item ) {
271
 
272
- if ( $cart_item['data'] instanceof WC_Product_Booking && isset( $cart_item['addons'] ) ) {
273
- $cost = $cart_item['data']->get_price();
274
-
275
- foreach( $cart_item['addons'] as $addon ){
276
- $cost += $addon['price'];
277
- }
278
-
279
- $cart_item['data']->set_price( $cost );
280
- }
281
-
282
- return $cart_item;
283
  }
 
284
  }
12
 
13
  /**
14
  * WCML_Product_Addons constructor.
15
+ * @param SitePress $sitepress
16
  */
17
+ function __construct( $sitepress ){
18
  $this->sitepress = $sitepress;
19
+ }
20
+
21
+ public function add_hooks(){
22
  add_filter( 'get_product_addons_product_terms', array( $this, 'addons_product_terms' ) );
23
  add_filter( 'get_product_addons_fields', array( $this, 'product_addons_filter' ), 10, 1 );
24
 
46
  add_action( 'wcml_update_extra_fields', array( $this, 'addons_update' ), 10, 3 );
47
 
48
  add_action( 'woocommerce_product_data_panels', array( $this, 'show_pointer_info' ) );
49
+
50
+ add_filter( 'wcml_do_not_display_custom_fields_for_product', array( $this, 'replace_tm_editor_custom_fields_with_own_sections' ) );
51
  }
52
 
 
 
 
 
53
  }
54
 
55
  /**
268
  $pointer_ui->show();
269
  }
270
 
271
+ function replace_tm_editor_custom_fields_with_own_sections( $fields ){
272
+ $fields[] = '_product_addons';
273
 
274
+ return $fields;
 
 
 
 
 
 
 
 
 
 
275
  }
276
+
277
  }
compatibility/class-wcml-product-bundles-legacy.php CHANGED
@@ -4,13 +4,11 @@ class WCML_Product_Bundles_Legacy{
4
  /**
5
  * @var WPML_Element_Translation_Package
6
  */
7
- var $tp;
8
-
9
  /**
10
  * @var SitePress
11
  */
12
  private $sitepress;
13
-
14
  /**
15
  * @var woocommerce_wpml
16
  */
@@ -18,10 +16,17 @@ class WCML_Product_Bundles_Legacy{
18
 
19
  /**
20
  * WCML_Product_Bundles constructor.
 
 
 
21
  */
22
- function __construct( &$sitepress, &$woocommerce_wpml ){
23
- $this->sitepress = $sitepress;
24
  $this->woocommerce_wpml = $woocommerce_wpml;
 
 
 
 
25
 
26
  add_action( 'wcml_gui_additional_box_html', array( $this, 'custom_box_html' ), 10, 3 );
27
  add_filter( 'wcml_gui_additional_box_data', array( $this, 'custom_box_html_data' ), 10, 4 );
@@ -30,16 +35,16 @@ class WCML_Product_Bundles_Legacy{
30
  add_action( 'woocommerce_get_cart_item_from_session', array( $this, 'resync_bundle' ), 5, 3 );
31
  add_filter( 'woocommerce_cart_loaded_from_session', array( $this, 'resync_bundle_clean' ), 10 );
32
 
33
- if( version_compare( WCML_VERSION, '3.7.2', '>' ) ){
34
  add_filter( 'option_wpml_config_files_arr', array( $this, 'make__bundle_data_not_translatable_by_default' ), 0 );
35
  }
36
 
37
  if( is_admin() ){
38
- $this->tp = new WPML_Element_Translation_Package();
39
 
40
  add_filter( 'wpml_tm_translation_job_data', array( $this, 'append_bundle_data_translation_package' ), 10, 2 );
41
  add_action( 'wpml_translation_job_saved', array( $this, 'save_bundle_data_translation' ), 10, 3 );
42
 
 
43
  }
44
 
45
 
@@ -409,4 +414,11 @@ class WCML_Product_Bundles_Legacy{
409
  update_post_meta( $post_id, '_bundle_data', $bundle_data );
410
 
411
  }
 
 
 
 
 
 
 
412
  }
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
  */
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 );
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
 
414
  update_post_meta( $post_id, '_bundle_data', $bundle_data );
415
 
416
  }
417
+
418
+ function replace_tm_editor_custom_fields_with_own_sections( $fields ){
419
+ $fields[] = '_bundle_data';
420
+
421
+ return $fields;
422
+ }
423
+
424
  }
compatibility/class-wcml-product-bundles.php CHANGED
@@ -162,6 +162,22 @@ class WCML_Product_Bundles {
162
 
163
  }
164
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
165
  private function get_product_id_for_item_id( $item_id ) {
166
  global $wpdb;
167
 
@@ -372,6 +388,17 @@ class WCML_Product_Bundles {
372
  $translated_bundle_data[ $translated_item_id ]['override_description'] = $bundle_item_data['override_description'];
373
  }
374
 
 
 
 
 
 
 
 
 
 
 
 
375
  }
376
 
377
  }
162
 
163
  }
164
 
165
+ /**
166
+ * @param array $allowed_variations
167
+ * @param string $lang
168
+ *
169
+ * @return array
170
+ */
171
+ public function translate_allowed_variations( $allowed_variations, $lang ) {
172
+
173
+ foreach ( $allowed_variations as $k => $variation_id ) {
174
+ $allowed_variations[ $k ] =
175
+ apply_filters( 'translate_object_id', $variation_id, 'product_variation', true, $lang );
176
+ }
177
+
178
+ return $allowed_variations;
179
+ }
180
+
181
  private function get_product_id_for_item_id( $item_id ) {
182
  global $wpdb;
183
 
388
  $translated_bundle_data[ $translated_item_id ]['override_description'] = $bundle_item_data['override_description'];
389
  }
390
 
391
+ if( isset( $bundle_item_data['allowed_variations'] ) ){
392
+ if( is_array( $bundle_item_data['allowed_variations'] ) ){
393
+ $translated_bundle_data[ $translated_item_id ]['allowed_variations'] =
394
+ $this->translate_allowed_variations( $bundle_item_data['allowed_variations'], $lang );
395
+ }else{
396
+ $translated_bundle_data[ $translated_item_id ]['allowed_variations'] =
397
+ $bundle_item_data['allowed_variations'];
398
+ }
399
+
400
+ }
401
+
402
  }
403
 
404
  }
compatibility/class-wcml-sensei.php CHANGED
@@ -1,235 +1,256 @@
1
  <?php
2
 
3
- class WCML_sensei{
4
-
5
- function __construct(){
6
- global $sitepress, $wpdb;
7
-
8
- $custom_columns = new WPML_Custom_Columns( $wpdb, $sitepress );
9
-
10
- add_filter( 'manage_edit-lesson_columns', array( $custom_columns, 'add_posts_management_column' ) );
11
- add_filter( 'manage_edit-course_columns', array( $custom_columns, 'add_posts_management_column' ) );
12
-
13
- add_action( 'save_post', array( $this, 'save_post_actions' ), 100, 2 );
14
- add_action( 'sensei_log_activity_after', array( $this, 'log_activity_after' ), 10, 3 );
15
- add_filter( 'sensei_bought_product_id', array( $this, 'filter_bought_product_id' ), 10, 2 );
16
- add_action( 'delete_comment', array( $this, 'delete_user_activity' ) );
17
-
18
- add_action( 'pre_get_comments', array( $this, 'pre_get_comments') );
19
-
20
- if( is_admin() &&
21
- (
22
- ( isset($_GET['post_type']) && $_GET['post_type'] == 'sensei_message' ) ||
23
- ( isset($_GET['page']) && $_GET['page'] == 'sensei_grading' )
24
- ) ){
25
- remove_action( 'wp_before_admin_bar_render', array($sitepress, 'admin_language_switcher') );
26
- }
27
-
28
- }
29
-
30
- function save_post_actions( $post_id, $post ){
31
- global $sitepress;
32
-
33
- // skip not related post types
34
- if ( !in_array( $post->post_type , array( 'lesson', 'course', 'quiz' ) ) ) {
35
- return;
36
- }
37
- // skip auto-drafts
38
- if ( $post->post_status == 'auto-draft' ) {
39
- return;
40
- }
41
- // skip autosave
42
- if ( isset( $_POST[ 'autosave' ] ) ) {
43
- return;
44
- }
45
-
46
- if( $post->post_type == 'quiz' && isset( $_POST[ 'ID' ] ) ){
47
- $this->save_post_actions( $_POST[ 'ID' ], get_post( $_POST[ 'ID' ] ) );
48
- }
49
-
50
-
51
- // sync fields from original
52
- $trid = $sitepress->get_element_trid( $post_id, 'post_' . $post->post_type );
53
- $translations = $sitepress->get_element_translations( $trid, 'post_' . $post->post_type );
54
-
55
- if ( !empty( $translations ) ) {
56
- $original_post_id = false;
57
- foreach ( $translations as $t ) {
58
- if ( $t->original ) {
59
- $original_post_id = $t->element_id;
60
- break;
61
- }
62
- }
63
-
64
- if ( $post_id != $original_post_id ) {
65
- $this->sync_custom_fields( $original_post_id, $post_id, $post->post_type );
66
- } else {
67
- foreach ( $translations as $t ) {
68
- if ( $original_post_id != $t->element_id ) {
69
- $this->sync_custom_fields( $original_post_id, $t->element_id, $post->post_type );
70
- }
71
- }
72
- }
73
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
74
 
75
- }
 
 
76
 
 
 
77
 
78
- function sync_custom_fields ( $original_post_id, $post_id, $post_type ){
79
- global $sitepress;
80
-
81
- $language = $sitepress->get_language_for_element( $post_id, 'post_'.$post_type );
82
- if( $post_type == 'quiz' ){
83
-
84
- //sync quiz lesson
85
- $lesson_id = get_post_meta( $original_post_id, '_quiz_lesson', true );
86
-
87
- if( $lesson_id ){
88
- $tr_lesson_id = apply_filters( 'translate_object_id', $lesson_id, 'lesson', false, $language );
89
 
90
- if( !is_null( $tr_lesson_id ) ){
91
- update_post_meta( $post_id, '_quiz_lesson', $tr_lesson_id );
92
- }
93
- }else{
94
- delete_post_meta( $post_id, '_quiz_lesson' );
95
- }
96
 
97
- } elseif( $post_type == 'lesson' ){
98
- //sync lesson course
99
- $course_id = get_post_meta( $original_post_id, '_lesson_course', true );
100
 
101
- if( $course_id ){
102
- $tr_course_id = apply_filters( 'translate_object_id', $course_id, 'course', false, $language );
 
 
 
 
103
 
104
- if( !is_null( $tr_course_id ) ){
105
- update_post_meta( $post_id, '_lesson_course', $tr_course_id );
106
- }
107
- }else{
108
- delete_post_meta( $post_id, '_lesson_course' );
109
- }
110
 
111
- //sync lesson prerequisite
112
- $lesson_id = get_post_meta( $original_post_id, '_lesson_prerequisite', true );
113
 
114
- if( $lesson_id ){
115
- $tr_lesson_id = apply_filters( 'translate_object_id', $lesson_id, 'lesson', false, $language );
116
 
117
- if( !is_null( $tr_lesson_id ) ){
118
- update_post_meta( $post_id, '_lesson_prerequisite', $tr_lesson_id );
119
- }
120
- }else{
121
- delete_post_meta( $post_id, '_lesson_prerequisite' );
122
- }
123
 
124
- }else{
 
125
 
126
- //sync course woocommerce_product
127
- $product_id = get_post_meta( $original_post_id, '_course_woocommerce_product', true );
128
 
129
- if( $product_id ){
130
- $tr_product_id = apply_filters( 'translate_object_id', $product_id, get_post_type( $product_id ), false, $language );
 
 
 
 
131
 
132
- if( !is_null( $tr_product_id ) ){
133
- update_post_meta( $post_id, '_course_woocommerce_product', $tr_product_id );
134
- }
135
- }else{
136
- delete_post_meta( $post_id, '_course_woocommerce_product' );
137
- }
138
 
139
- //sync course prerequisite
140
- $course_id = get_post_meta( $original_post_id, '_course_prerequisite', true );
141
 
142
- if( $course_id ){
143
- $tr_course_id = apply_filters( 'translate_object_id', $course_id, 'course', false, $language );
144
 
145
- if( !is_null( $tr_course_id ) ){
146
- update_post_meta( $post_id, '_course_prerequisite', $tr_course_id );
147
- }
148
- }else{
149
- delete_post_meta( $post_id, '_course_prerequisite' );
150
- }
151
 
152
- }
 
 
153
 
154
- }
155
 
156
- function log_activity_after ( $args, $data, $comment_id = false ){
157
- global $sitepress;
158
 
159
- if( !$comment_id ){
160
- return false;
161
- }
162
 
163
- $comment_post_id = $data['comment_post_ID'];
164
- $trid = $sitepress->get_element_trid( $comment_post_id, 'post_'.get_post_type( $comment_post_id ) );
165
- $translations = $sitepress->get_element_translations( $trid, 'post_'.get_post_type( $comment_post_id ) );
 
 
 
 
 
 
166
 
167
- foreach($translations as $translation){
168
 
169
- if( $comment_post_id != $translation->element_id ){
170
- $data['comment_post_ID'] = $translation->element_id;
171
 
172
- $trid = $sitepress->get_element_trid( $comment_id, 'comment' );
173
 
174
- $tr_comment_id = apply_filters( 'translate_object_id', $comment_id, 'comment', false, $translation->language_code );
175
- if ( isset( $args['action'] ) && 'update' == $args['action'] && !is_null( $tr_comment_id ) && get_comment( $tr_comment_id ) ) {
176
- $data['comment_ID'] = $tr_comment_id;
177
- $tr_comment_id = wp_update_comment( $data );
178
- }else{
179
- $tr_comment_id = wp_insert_comment( $data );
180
- $sitepress->set_element_language_details( $tr_comment_id, 'comment', $trid, $translation->language_code );
181
- }
182
- }
183
 
184
- }
185
 
186
- }
 
 
 
 
 
187
 
188
- function filter_bought_product_id( $product_id, $order ){
 
189
 
190
- $order_id = method_exists( 'WC_Order', 'get_id' ) ? $order->get_id() : $order->id;
191
- $order_language = get_post_meta( $order_id, 'wpml_language', true );
192
 
193
- $tr_product_id = apply_filters( 'translate_object_id', $product_id, get_post_type( $product_id ), false, $order_language );
194
 
195
- if( !is_null( $tr_product_id ) ){
196
- return $tr_product_id;
197
- }else{
198
- return $product_id;
199
- }
200
- }
201
 
202
- function delete_user_activity ( $comment_id ){
203
- global $sitepress;
 
 
 
 
204
 
205
- $comment_type = get_comment_type( $comment_id );
206
 
207
- if( strstr( $comment_type, "sensei" ) ){
208
 
209
- $trid = $sitepress->get_element_trid( $comment_id, 'comment' );
210
- $translations = $sitepress->get_element_translations( $trid, 'comment' );
211
 
212
- remove_action( 'delete_comment', array ( $this, 'delete_user_activity' ) );
213
- foreach ( $translations as $translation ){
214
- if( $comment_id != $translation->element_id ){
215
- wp_delete_comment( $translation->element_id, true );
216
- }
217
- }
218
 
219
- }
220
 
 
221
 
222
- }
223
 
224
- function pre_get_comments($obj){
225
- global $sitepress;
226
-
227
- if( $obj->query_vars[ 'type' ] == 'sensei_course_start' ){
228
-
229
- remove_filter( 'comments_clauses', array( $sitepress, 'comments_clauses' ), 10, 2 );
230
-
231
- }
232
-
233
- }
234
 
235
  }
1
  <?php
2
 
3
+ class WCML_Sensei {
4
+
5
+ /** @var SitePress */
6
+ private $sitepress;
7
+ /** @var wpdb */
8
+ private $wpdb;
9
+ /** WPML_Custom_Columns $wpml_custom_columns */
10
+ private $custom_columns;
11
+
12
+ /**
13
+ * WCML_Sensei constructor.
14
+ *
15
+ * @param Sitepress $sitepress
16
+ * @param wpdb $wpdb
17
+ * @param WPML_Custom_Columns $custom_columns
18
+ */
19
+ public function __construct( SitePress $sitepress, wpdb $wpdb, WPML_Custom_Columns $custom_columns ) {
20
+ $this->sitepress = $sitepress;
21
+ $this->wpdb = $wpdb;
22
+ $this->custom_columns = $custom_columns;
23
+ }
24
+
25
+ public function add_hooks() {
26
+
27
+ add_filter( 'manage_edit-lesson_columns', array( $this->custom_columns, 'add_posts_management_column' ) );
28
+ add_filter( 'manage_edit-course_columns', array( $this->custom_columns, 'add_posts_management_column' ) );
29
+ add_filter( 'manage_edit-question_columns', array( $this->custom_columns, 'add_posts_management_column' ) );
30
+
31
+ add_action( 'save_post', array( $this, 'save_post_actions' ), 100, 2 );
32
+ add_action( 'sensei_log_activity_after', array( $this, 'log_activity_after' ), 10, 3 );
33
+ add_filter( 'sensei_bought_product_id', array( $this, 'filter_bought_product_id' ), 10, 2 );
34
+ add_action( 'delete_comment', array( $this, 'delete_user_activity' ) );
35
+
36
+ add_action( 'pre_get_comments', array( $this, 'pre_get_comments' ) );
37
+
38
+ if ( $this->is_sensei_admin_without_language_switcher() ) {
39
+ remove_action( 'wp_before_admin_bar_render', array( $this->sitepress, 'admin_language_switcher' ) );
40
+ }
41
+ }
42
+
43
+ private function is_sensei_admin_without_language_switcher() {
44
+
45
+ $is_message_post_type = isset( $_GET['post_type'] ) && $_GET['post_type'] == 'sensei_message';
46
+ $is_grading_page = isset( $_GET['page'] ) && $_GET['page'] == 'sensei_grading';
47
+
48
+ return is_admin() && ( $is_message_post_type || $is_grading_page );
49
+ }
50
+
51
+ public function save_post_actions( $post_id, $post ) {
52
+ global $sitepress;
53
+
54
+ // skip not related post types
55
+ if ( ! in_array( $post->post_type, array( 'lesson', 'course', 'quiz' ) ) ) {
56
+ return;
57
+ }
58
+ // skip auto-drafts
59
+ if ( $post->post_status == 'auto-draft' ) {
60
+ return;
61
+ }
62
+ // skip autosave
63
+ if ( isset( $_POST['autosave'] ) ) {
64
+ return;
65
+ }
66
+
67
+ if ( $post->post_type == 'quiz' && isset( $_POST['ID'] ) ) {
68
+ $this->save_post_actions( $_POST['ID'], get_post( $_POST['ID'] ) );
69
+ }
70
+
71
+
72
+ // sync fields from original
73
+ $trid = $sitepress->get_element_trid( $post_id, 'post_' . $post->post_type );
74
+ $translations = $sitepress->get_element_translations( $trid, 'post_' . $post->post_type );
75
+
76
+ if ( ! empty( $translations ) ) {
77
+ $original_post_id = false;
78
+ foreach ( $translations as $t ) {
79
+ if ( $t->original ) {
80
+ $original_post_id = $t->element_id;
81
+ break;
82
+ }
83
+ }
84
+
85
+ if ( $post_id != $original_post_id ) {
86
+ $this->sync_custom_fields( $original_post_id, $post_id, $post->post_type );
87
+ } else {
88
+ foreach ( $translations as $t ) {
89
+ if ( $original_post_id != $t->element_id ) {
90
+ $this->sync_custom_fields( $original_post_id, $t->element_id, $post->post_type );
91
+ }
92
+ }
93
+ }
94
+ }
95
+
96
+ }
97
+
98
+
99
+ function sync_custom_fields( $original_post_id, $post_id, $post_type ) {
100
+ global $sitepress;
101
+
102
+ $language = $sitepress->get_language_for_element( $post_id, 'post_' . $post_type );
103
+ if ( $post_type == 'quiz' ) {
104
+
105
+ //sync quiz lesson
106
+ $lesson_id = get_post_meta( $original_post_id, '_quiz_lesson', true );
107
+
108
+ if ( $lesson_id ) {
109
+ $tr_lesson_id = apply_filters( 'translate_object_id', $lesson_id, 'lesson', false, $language );
110
+
111
+ if ( ! is_null( $tr_lesson_id ) ) {
112
+ update_post_meta( $post_id, '_quiz_lesson', $tr_lesson_id );
113
+ }
114
+ } else {
115
+ delete_post_meta( $post_id, '_quiz_lesson' );
116
+ }
117
 
118
+ } elseif ( $post_type == 'lesson' ) {
119
+ //sync lesson course
120
+ $course_id = get_post_meta( $original_post_id, '_lesson_course', true );
121
 
122
+ if ( $course_id ) {
123
+ $tr_course_id = apply_filters( 'translate_object_id', $course_id, 'course', false, $language );
124
 
125
+ if ( ! is_null( $tr_course_id ) ) {
126
+ update_post_meta( $post_id, '_lesson_course', $tr_course_id );
127
+ }
128
+ } else {
129
+ delete_post_meta( $post_id, '_lesson_course' );
130
+ }
 
 
 
 
 
131
 
132
+ //sync lesson prerequisite
133
+ $lesson_id = get_post_meta( $original_post_id, '_lesson_prerequisite', true );
 
 
 
 
134
 
135
+ if ( $lesson_id ) {
136
+ $tr_lesson_id = apply_filters( 'translate_object_id', $lesson_id, 'lesson', false, $language );
 
137
 
138
+ if ( ! is_null( $tr_lesson_id ) ) {
139
+ update_post_meta( $post_id, '_lesson_prerequisite', $tr_lesson_id );
140
+ }
141
+ } else {
142
+ delete_post_meta( $post_id, '_lesson_prerequisite' );
143
+ }
144
 
145
+ } else {
 
 
 
 
 
146
 
147
+ //sync course woocommerce_product
148
+ $product_id = get_post_meta( $original_post_id, '_course_woocommerce_product', true );
149
 
150
+ if ( $product_id ) {
151
+ $tr_product_id = apply_filters( 'translate_object_id', $product_id, get_post_type( $product_id ), false, $language );
152
 
153
+ if ( ! is_null( $tr_product_id ) ) {
154
+ update_post_meta( $post_id, '_course_woocommerce_product', $tr_product_id );
155
+ }
156
+ } else {
157
+ delete_post_meta( $post_id, '_course_woocommerce_product' );
158
+ }
159
 
160
+ //sync course prerequisite
161
+ $course_id = get_post_meta( $original_post_id, '_course_prerequisite', true );
162
 
163
+ if ( $course_id ) {
164
+ $tr_course_id = apply_filters( 'translate_object_id', $course_id, 'course', false, $language );
165
 
166
+ if ( ! is_null( $tr_course_id ) ) {
167
+ update_post_meta( $post_id, '_course_prerequisite', $tr_course_id );
168
+ }
169
+ } else {
170
+ delete_post_meta( $post_id, '_course_prerequisite' );
171
+ }
172
 
173
+ }
 
 
 
 
 
174
 
175
+ }
 
176
 
177
+ function log_activity_after( $args, $data, $comment_id = false ) {
178
+ global $sitepress;
179
 
180
+ if ( ! $comment_id ) {
181
+ return false;
182
+ }
 
 
 
183
 
184
+ $comment_post_id = $data['comment_post_ID'];
185
+ $trid = $sitepress->get_element_trid( $comment_post_id, 'post_' . get_post_type( $comment_post_id ) );
186
+ $translations = $sitepress->get_element_translations( $trid, 'post_' . get_post_type( $comment_post_id ) );
187
 
188
+ foreach ( $translations as $translation ) {
189
 
190
+ if ( $comment_post_id != $translation->element_id ) {
191
+ $data['comment_post_ID'] = $translation->element_id;
192
 
193
+ $trid = $sitepress->get_element_trid( $comment_id, 'comment' );
 
 
194
 
195
+ $tr_comment_id = apply_filters( 'translate_object_id', $comment_id, 'comment', false, $translation->language_code );
196
+ if ( isset( $args['action'] ) && 'update' == $args['action'] && ! is_null( $tr_comment_id ) && get_comment( $tr_comment_id ) ) {
197
+ $data['comment_ID'] = $tr_comment_id;
198
+ $tr_comment_id = wp_update_comment( $data );
199
+ } else {
200
+ $tr_comment_id = wp_insert_comment( $data );
201
+ $sitepress->set_element_language_details( $tr_comment_id, 'comment', $trid, $translation->language_code );
202
+ }
203
+ }
204
 
205
+ }
206
 
207
+ }
 
208
 
209
+ function filter_bought_product_id( $product_id, $order ) {
210
 
211
+ $order_id = method_exists( 'WC_Order', 'get_id' ) ? $order->get_id() : $order->id;
212
+ $order_language = get_post_meta( $order_id, 'wpml_language', true );
 
 
 
 
 
 
 
213
 
214
+ $tr_product_id = apply_filters( 'translate_object_id', $product_id, get_post_type( $product_id ), false, $order_language );
215
 
216
+ if ( ! is_null( $tr_product_id ) ) {
217
+ return $tr_product_id;
218
+ } else {
219
+ return $product_id;
220
+ }
221
+ }
222
 
223
+ function delete_user_activity( $comment_id ) {
224
+ global $sitepress;
225
 
226
+ $comment_type = get_comment_type( $comment_id );
 
227
 
228
+ if ( strstr( $comment_type, "sensei" ) ) {
229
 
230
+ $trid = $sitepress->get_element_trid( $comment_id, 'comment' );
231
+ $translations = $sitepress->get_element_translations( $trid, 'comment' );
 
 
 
 
232
 
233
+ remove_action( 'delete_comment', array( $this, 'delete_user_activity' ) );
234
+ foreach ( $translations as $translation ) {
235
+ if ( $comment_id != $translation->element_id ) {
236
+ wp_delete_comment( $translation->element_id, true );
237
+ }
238
+ }
239
 
240
+ }
241
 
 
242
 
243
+ }
 
244
 
245
+ function pre_get_comments( $obj ) {
246
+ global $sitepress;
 
 
 
 
247
 
248
+ if ( $obj->query_vars['type'] == 'sensei_course_start' ) {
249
 
250
+ remove_filter( 'comments_clauses', array( $sitepress, 'comments_clauses' ), 10, 2 );
251
 
252
+ }
253
 
254
+ }
 
 
 
 
 
 
 
 
 
255
 
256
  }
compatibility/class-wcml-tab-manager.php CHANGED
@@ -7,41 +7,46 @@ class WCML_Tab_Manager {
7
  /**
8
  * @var WPML_Element_Translation_Package
9
  */
10
- public $tp;
11
 
12
  /**
13
  * @var SitePress
14
  */
15
- public $sitepress;
16
 
17
  /**
18
  * @var WooCommerce
19
  */
20
- public $woocommerce;
21
 
22
  /**
23
  * @var woocommerce_wpml
24
  */
25
- public $woocommerce_wpml;
26
 
27
  /**
28
  * @var wpdb
29
  */
30
- public $wpdb;
31
 
32
  /**
33
  * WCML_Tab_Manager constructor.
34
  *
35
- * @param $sitepress
36
- * @param $woocommerce
37
- * @param $woocommerce_wpml
38
- * @param $wpdb
 
39
  */
40
- function __construct( &$sitepress, &$woocommerce, &$woocommerce_wpml, &$wpdb ) {
41
- $this->sitepress = $sitepress;
42
- $this->woocommerce = $woocommerce;
43
  $this->woocommerce_wpml = $woocommerce_wpml;
44
- $this->wpdb = $wpdb;
 
 
 
 
45
  add_action( 'wcml_update_extra_fields', array( $this, 'sync_tabs' ), 10, 4 );
46
  add_action( 'wcml_gui_additional_box_html', array( $this, 'custom_box_html' ), 10, 3 );
47
  add_filter( 'wcml_gui_additional_box_data', array( $this, 'custom_box_html_data' ), 10, 4 );
@@ -50,14 +55,12 @@ class WCML_Tab_Manager {
50
 
51
  add_filter( 'wc_tab_manager_tab_id', array( $this, 'wc_tab_manager_tab_id' ), 10, 1 );
52
 
53
- if ( version_compare( WCML_VERSION, '3.7.2', '>' ) ) {
54
  add_filter( 'option_wpml_config_files_arr', array( $this, 'make__product_tabs_not_translatable_by_default' ), 0 );
55
  }
56
 
57
  if ( is_admin() ) {
58
 
59
- $this->tp = new WPML_Element_Translation_Package;
60
-
61
  add_action( 'save_post', array( $this, 'force_set_language_information_on_product_tabs' ), 10, 2 );
62
  add_action( 'save_post', array( $this, 'sync_product_tabs' ), 10, 2 );
63
 
@@ -65,6 +68,8 @@ class WCML_Tab_Manager {
65
  add_action( 'wpml_translation_job_saved', array( $this, 'save_custom_tabs_translation' ), 10, 3 );
66
  add_action( 'woocommerce_product_data_panels', array( $this, 'show_pointer_info' ) );
67
 
 
 
68
  }else{
69
  add_filter( 'option_wc_tab_manager_default_layout', array( $this, 'filter_default_layout' ) );
70
  }
@@ -717,4 +722,11 @@ class WCML_Tab_Manager {
717
  $pointer_ui->show();
718
 
719
  }
 
 
 
 
 
 
 
720
  }
7
  /**
8
  * @var WPML_Element_Translation_Package
9
  */
10
+ private $tp;
11
 
12
  /**
13
  * @var SitePress
14
  */
15
+ private $sitepress;
16
 
17
  /**
18
  * @var WooCommerce
19
  */
20
+ private $woocommerce;
21
 
22
  /**
23
  * @var woocommerce_wpml
24
  */
25
+ private $woocommerce_wpml;
26
 
27
  /**
28
  * @var wpdb
29
  */
30
+ private $wpdb;
31
 
32
  /**
33
  * WCML_Tab_Manager constructor.
34
  *
35
+ * @param SitePress $sitepress
36
+ * @param WooCommerce $woocommerce
37
+ * @param woocommerce_wpml $woocommerce_wpml
38
+ * @param wpdb $wpdb
39
+ * @param WPML_Element_Translation_Package $tp
40
  */
41
+ function __construct( SitePress $sitepress, WooCommerce $woocommerce, woocommerce_wpml $woocommerce_wpml, wpdb $wpdb, WPML_Element_Translation_Package $tp ) {
42
+ $this->sitepress = $sitepress;
43
+ $this->woocommerce = $woocommerce;
44
  $this->woocommerce_wpml = $woocommerce_wpml;
45
+ $this->wpdb = $wpdb;
46
+ $this->tp = $tp;
47
+ }
48
+
49
+ public function add_hooks(){
50
  add_action( 'wcml_update_extra_fields', array( $this, 'sync_tabs' ), 10, 4 );
51
  add_action( 'wcml_gui_additional_box_html', array( $this, 'custom_box_html' ), 10, 3 );
52
  add_filter( 'wcml_gui_additional_box_data', array( $this, 'custom_box_html_data' ), 10, 4 );
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
 
 
 
64
  add_action( 'save_post', array( $this, 'force_set_language_information_on_product_tabs' ), 10, 2 );
65
  add_action( 'save_post', array( $this, 'sync_product_tabs' ), 10, 2 );
66
 
68
  add_action( 'wpml_translation_job_saved', array( $this, 'save_custom_tabs_translation' ), 10, 3 );
69
  add_action( 'woocommerce_product_data_panels', array( $this, 'show_pointer_info' ) );
70
 
71
+ add_filter( 'wcml_do_not_display_custom_fields_for_product', array( $this, 'replace_tm_editor_custom_fields_with_own_sections' ) );
72
+
73
  }else{
74
  add_filter( 'option_wc_tab_manager_default_layout', array( $this, 'filter_default_layout' ) );
75
  }
722
  $pointer_ui->show();
723
 
724
  }
725
+
726
+ function replace_tm_editor_custom_fields_with_own_sections( $fields ){
727
+ $fields[] = '_product_tabs';
728
+
729
+ return $fields;
730
+ }
731
+
732
  }
inc/abstracts/class-wcml-exchange-rate-service.php CHANGED
@@ -10,8 +10,7 @@ abstract class WCML_Exchange_Rate_Service{
10
  private $settings = array();
11
 
12
  protected $api_key = '';
13
-
14
- const REQUIRES_KEY = false;
15
 
16
  public function __construct( $id, $name, $api_url, $url = '' ) {
17
 
@@ -78,7 +77,7 @@ abstract class WCML_Exchange_Rate_Service{
78
  * @return bool
79
  */
80
  public function is_key_required(){
81
- return self::REQUIRES_KEY;
82
  }
83
 
84
  /**
10
  private $settings = array();
11
 
12
  protected $api_key = '';
13
+ protected $requires_key = false;
 
14
 
15
  public function __construct( $id, $name, $api_url, $url = '' ) {
16
 
77
  * @return bool
78
  */
79
  public function is_key_required(){
80
+ return $this->requires_key;
81
  }
82
 
83
  /**
inc/class-wcml-attributes.php CHANGED
@@ -2,14 +2,27 @@
2
 
3
  class WCML_Attributes{
4
 
 
5
  private $woocommerce_wpml;
 
6
  private $sitepress;
 
7
  private $wpdb;
8
 
9
- public function __construct( &$woocommerce_wpml, &$sitepress, &$wpdb ){
 
 
 
 
 
 
 
10
  $this->woocommerce_wpml = $woocommerce_wpml;
11
  $this->sitepress = $sitepress;
12
  $this->wpdb = $wpdb;
 
 
 
13
 
14
  add_action( 'init', array( $this, 'init' ) );
15
 
@@ -23,12 +36,12 @@ class WCML_Attributes{
23
 
24
  add_action( 'woocommerce_before_attribute_delete', array( $this, 'refresh_taxonomy_translations_cache' ), 10, 3 );
25
 
26
- if( ( defined('WC_VERSION') && version_compare( WC_VERSION , '3.0.0', '<' ) ) ){
 
27
  add_filter( 'woocommerce_get_product_attributes', array( $this, 'filter_adding_to_cart_product_attributes_names' ) );
28
  }else{
29
  add_filter( 'woocommerce_product_get_attributes', array( $this, 'filter_adding_to_cart_product_attributes_names' ) );
30
  }
31
-
32
  }
33
 
34
  public function init(){
@@ -247,7 +260,7 @@ class WCML_Attributes{
247
  }elseif( !$orig_product_attr[ 'is_taxonomy' ] ){
248
  if( isset( $trnsl_product_attrs[ $key ] ) ){
249
  $orig_product_attrs[ $key_to_save ][ 'value' ] = $trnsl_product_attrs[ $key ][ 'value' ];
250
- }else{
251
  unset ( $orig_product_attrs[ $key_to_save ] );
252
  }
253
  }
@@ -532,4 +545,22 @@ class WCML_Attributes{
532
  return $attributes;
533
  }
534
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
535
  }
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
 
27
  add_action( 'init', array( $this, 'init' ) );
28
 
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
 
47
  public function init(){
260
  }elseif( !$orig_product_attr[ 'is_taxonomy' ] ){
261
  if( isset( $trnsl_product_attrs[ $key ] ) ){
262
  $orig_product_attrs[ $key_to_save ][ 'value' ] = $trnsl_product_attrs[ $key ][ 'value' ];
263
+ }elseif( !empty( $trnsl_product_attrs ) ){
264
  unset ( $orig_product_attrs[ $key_to_save ] );
265
  }
266
  }
545
  return $attributes;
546
  }
547
 
548
+ public function is_a_taxonomy( $attribute ){
549
+
550
+ if(
551
+ (
552
+ $attribute instanceof WC_Product_Attribute &&
553
+ $attribute->is_taxonomy()
554
+ ) ||
555
+ (
556
+ is_array( $attribute ) &&
557
+ $attribute['is_taxonomy']
558
+ )
559
+ ){
560
+ return true;
561
+ }
562
+
563
+ return false;
564
+ }
565
+
566
  }
inc/class-wcml-cart-sync-warnings.php ADDED
@@ -0,0 +1,117 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class WCML_Cart_Sync_Warnings{
4
+
5
+ /**
6
+ * @var woocommerce_wpml
7
+ */
8
+ private $woocommerce_wpml;
9
+ /**
10
+ * @var Sitepress
11
+ */
12
+ private $sitepress;
13
+ /**
14
+ * @var array
15
+ */
16
+ private $extensions_list = array(
17
+ 'WC_Subscriptions' => 'Woocommerce Subscriptions',
18
+ 'WC_Product_Addons' => 'Woocommerce Product Addons',
19
+ 'WC_Bookings' => 'Woocommerce Bookings',
20
+ 'WC_Accommodation_Bookings_Plugin' => 'Woocommerce Accommodation Bookings',
21
+ 'WC_Product_Bundle' => 'Woocommerce Product Bundles',
22
+ 'WC_Composite_Products' => 'Woocommerce Composite Products'
23
+ );
24
+
25
+ public function __construct( $woocommerce_wpml, $sitepress ){
26
+ $this->woocommerce_wpml = $woocommerce_wpml;
27
+ $this->sitepress = $sitepress;
28
+ }
29
+
30
+ public function add_hooks(){
31
+
32
+ if( $this->check_if_show_notices_needed() ){
33
+ add_action( 'admin_notices', array( $this, 'show_cart_notice' ) );
34
+ add_action( 'admin_enqueue_scripts', array( $this, 'register_styles' ) );
35
+ }
36
+
37
+ }
38
+
39
+ public function check_if_show_notices_needed(){
40
+
41
+ $cart_sync_settings = $this->woocommerce_wpml->settings['cart_sync'];
42
+
43
+ if(
44
+ (
45
+ $cart_sync_settings['lang_switch'] === $this->sitepress->get_wp_api()->constant( 'WCML_CART_SYNC' ) ||
46
+ $cart_sync_settings['currency_switch'] === $this->sitepress->get_wp_api()->constant( 'WCML_CART_SYNC' )
47
+ ) &&
48
+ !$this->woocommerce_wpml->settings[ 'dismiss_cart_warning' ] &&
49
+ $this->get_list_of_active_extensions()
50
+ ) {
51
+ return true;
52
+ }
53
+
54
+ return false;
55
+
56
+ }
57
+
58
+ public function register_styles(){
59
+ wp_enqueue_style( 'wcml-cart-warning', $this->sitepress->get_wp_api()->constant( 'WCML_PLUGIN_URL' ) . '/res/css/wcml-cart-warning.css' );
60
+ }
61
+
62
+ public function show_cart_notice(){
63
+
64
+ $list_of_extensions = $this->get_list_of_active_extensions();
65
+ $request_url = esc_url( $_SERVER['REQUEST_URI'] );
66
+
67
+ $admin_settings_url = esc_url( admin_url('admin.php?page=wpml-wcml&tab=settings#cart') );
68
+ $documentation_link = esc_url( 'https://wpml.org/documentation/related-projects/woocommerce-multilingual/clearing-cart-contents-when-language-or-currency-change/' );
69
+
70
+ $reset_cart_strings[] = esc_html_x( 'Because of some elements in your site configuration, when the users switch the currency or the language on the front end, the cart content might not be synchronized correctly.', 'Reset cart option warning 1', 'woocommerce-multilingual' );
71
+ $reset_cart_strings[] = esc_html_x( 'It is recommended that you %s with the option to reset the cart in a situation like this.', 'Reset cart option warning 2', 'woocommerce-multilingual' );
72
+
73
+ $reset_cart_configure_link = '<strong><a href="' . $admin_settings_url . '">' . esc_html__( 'configure WooCommerce Multilingual', 'woocommerce-multilingual' ) . '</a></strong>';
74
+
75
+ $reset_cart_message = $reset_cart_strings[0];
76
+ $reset_cart_message .= '</p>';
77
+ $reset_cart_message .= $list_of_extensions;
78
+ $reset_cart_message .= '<p>';
79
+ $reset_cart_message .= $reset_cart_strings[1];
80
+ $reset_cart_message .= '<strong><a href="' . $documentation_link . '" target="_blank">' . esc_html__( 'More details', 'woocommerce-multilingual' ) . '</a></strong>';
81
+
82
+ $message = '<div class="message error otgs-is-dismissible">';
83
+ $message .= '<p>';
84
+ $message .= sprintf( $reset_cart_message, $reset_cart_configure_link );
85
+ $message .= '</p>';
86
+ $message .= '<a class="notice-dismiss" href="' . $request_url . '&wcml_action=dismiss_cart_warning"><span class="screen-reader-text">' . esc_html__( 'Dismiss', 'woocommerce-multilingual' ) . '</a>';
87
+ $message .= '</div>';
88
+
89
+ echo $message;
90
+ }
91
+
92
+ public function get_list_of_active_extensions (){
93
+
94
+ $html = '';
95
+
96
+ foreach( $this->extensions_list as $extension_class => $display_name ){
97
+
98
+ if( class_exists( $extension_class ) ){
99
+
100
+ if( empty( $html ) ){
101
+ $html .= '<ul>';
102
+ }
103
+
104
+ $html .= '<li>'.$display_name.'</li>';
105
+
106
+ }
107
+ }
108
+
109
+ if( !empty( $html ) ){
110
+ $html .= '</ul>';
111
+ }
112
+
113
+ return $html;
114
+
115
+ }
116
+
117
+ }
inc/class-wcml-cart.php CHANGED
@@ -1,28 +1,40 @@
1
  <?php
2
  class WCML_Cart
3
  {
4
-
5
  private $woocommerce_wpml;
 
6
  private $sitepress;
 
7
  private $woocommerce;
8
 
9
- public function __construct( &$woocommerce_wpml, &$sitepress, &$woocommerce )
 
 
 
 
 
 
 
10
  {
11
  $this->woocommerce_wpml = $woocommerce_wpml;
12
  $this->sitepress = $sitepress;
13
  $this->woocommerce = $woocommerce;
 
 
 
 
 
14
 
15
- if( $this->woocommerce_wpml->settings[ 'cart_sync' ][ 'currency_switch' ] == WCML_CART_CLEAR || $this->woocommerce_wpml->settings[ 'cart_sync' ][ 'lang_switch' ] == WCML_CART_CLEAR ){
16
  $this->enqueue_dialog_ui();
17
 
18
  add_action( 'wcml_removed_cart_items', array( $this, 'wcml_removed_cart_items_widget' ) );
19
  add_action( 'wp_ajax_wcml_cart_clear_removed_items', array( $this, 'wcml_cart_clear_removed_items' ) );
20
  add_action( 'wp_ajax_nopriv_wcml_cart_clear_removed_items', array( $this, 'wcml_cart_clear_removed_items' ) );
21
 
22
- add_filter( 'wcml_switch_currency_exception', array( $this, 'cart_switching_currency' ), 10, 3 );
23
  add_action( 'wcml_before_switch_currency', array( $this, 'switching_currency_empty_cart_if_needed' ), 10, 2 );
24
- }
25
- else{
26
  //cart widget
27
  add_action( 'wp_ajax_woocommerce_get_refreshed_fragments', array( $this, 'wcml_refresh_fragments' ), 0 );
28
  add_action( 'wp_ajax_woocommerce_add_to_cart', array( $this, 'wcml_refresh_fragments' ), 0 );
@@ -31,7 +43,7 @@ class WCML_Cart
31
 
32
  //cart
33
  add_action( 'woocommerce_before_calculate_totals', array( $this, 'woocommerce_calculate_totals' ), 100 );
34
- add_action( 'woocommerce_get_cart_item_from_session', array( $this, 'translate_cart_contents' ), 10 );
35
  add_action( 'woocommerce_cart_loaded_from_session', array( $this, 'translate_cart_subtotal' ) );
36
  add_action( 'woocommerce_before_checkout_process', array( $this, 'wcml_refresh_cart_total' ) );
37
 
@@ -43,6 +55,20 @@ class WCML_Cart
43
 
44
  }
45
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
46
  public function enqueue_dialog_ui(){
47
 
48
  wp_enqueue_script( 'jquery-ui-dialog' );
@@ -352,14 +378,16 @@ class WCML_Cart
352
 
353
  // translate the product id and product data
354
  $item[ 'product_id' ] = apply_filters( 'translate_object_id', $item[ 'product_id' ], 'product', true );
355
- if ($item[ 'variation_id' ]) {
356
- $item[ 'variation_id' ] = apply_filters( 'translate_object_id',$item[ 'variation_id' ], 'product_variation', true );
357
  }
358
 
359
- if( version_compare( WC()->version, '3.0.0', '>=' ) ){
360
- $item[ 'data' ]->set_name( get_the_title( $item[ 'product_id' ] ) );
 
 
361
  } else {
362
- $item[ 'data' ]->post->post_title = get_the_title( $item[ 'product_id' ] );
363
  }
364
 
365
  return $item;
1
  <?php
2
  class WCML_Cart
3
  {
4
+ /** @var woocommerce_wpml */
5
  private $woocommerce_wpml;
6
+ /** @var Sitepress */
7
  private $sitepress;
8
+ /** @var WooCommerce */
9
  private $woocommerce;
10
 
11
+ /**
12
+ * WCML_Cart constructor.
13
+ *
14
+ * @param woocommerce_wpml $woocommerce_wpml
15
+ * @param SitePress $sitepress
16
+ * @param WooCommerce $woocommerce
17
+ */
18
+ public function __construct( woocommerce_wpml $woocommerce_wpml, SitePress $sitepress, WooCommerce $woocommerce )
19
  {
20
  $this->woocommerce_wpml = $woocommerce_wpml;
21
  $this->sitepress = $sitepress;
22
  $this->woocommerce = $woocommerce;
23
+ }
24
+
25
+ public function add_hooks(){
26
+
27
+ if( $this->is_clean_cart_enabled() ){
28
 
 
29
  $this->enqueue_dialog_ui();
30
 
31
  add_action( 'wcml_removed_cart_items', array( $this, 'wcml_removed_cart_items_widget' ) );
32
  add_action( 'wp_ajax_wcml_cart_clear_removed_items', array( $this, 'wcml_cart_clear_removed_items' ) );
33
  add_action( 'wp_ajax_nopriv_wcml_cart_clear_removed_items', array( $this, 'wcml_cart_clear_removed_items' ) );
34
 
35
+ add_filter( 'wcml_switch_currency_exception', array( $this, 'cart_switching_currency' ), 10, 4 );
36
  add_action( 'wcml_before_switch_currency', array( $this, 'switching_currency_empty_cart_if_needed' ), 10, 2 );
37
+ }else{
 
38
  //cart widget
39
  add_action( 'wp_ajax_woocommerce_get_refreshed_fragments', array( $this, 'wcml_refresh_fragments' ), 0 );
40
  add_action( 'wp_ajax_woocommerce_add_to_cart', array( $this, 'wcml_refresh_fragments' ), 0 );
43
 
44
  //cart
45
  add_action( 'woocommerce_before_calculate_totals', array( $this, 'woocommerce_calculate_totals' ), 100 );
46
+ add_action( 'woocommerce_get_cart_item_from_session', array( $this, 'translate_cart_contents' ) );
47
  add_action( 'woocommerce_cart_loaded_from_session', array( $this, 'translate_cart_subtotal' ) );
48
  add_action( 'woocommerce_before_checkout_process', array( $this, 'wcml_refresh_cart_total' ) );
49
 
55
 
56
  }
57
 
58
+ public function is_clean_cart_enabled(){
59
+
60
+ $cart_sync_settings = $this->woocommerce_wpml->settings['cart_sync'];
61
+
62
+ if(
63
+ $cart_sync_settings[ 'currency_switch' ] === $this->sitepress->get_wp_api()->constant( 'WCML_CART_CLEAR' ) ||
64
+ $cart_sync_settings[ 'lang_switch' ] === $this->sitepress->get_wp_api()->constant( 'WCML_CART_CLEAR' )
65
+ ){
66
+ return true;
67
+ }
68
+
69
+ return false;
70
+ }
71
+
72
  public function enqueue_dialog_ui(){
73
 
74
  wp_enqueue_script( 'jquery-ui-dialog' );
378
 
379
  // translate the product id and product data
380
  $item[ 'product_id' ] = apply_filters( 'translate_object_id', $item[ 'product_id' ], 'product', true );
381
+ if( $item[ 'variation_id' ] ) {
382
+ $item[ 'variation_id' ] = apply_filters( 'translate_object_id', $item[ 'variation_id' ], 'product_variation', true );
383
  }
384
 
385
+ $item_product_title = $item[ 'variation_id' ] ? get_the_title( $item[ 'variation_id' ] ) : get_the_title( $item[ 'product_id' ] );
386
+
387
+ if( $this->sitepress->get_wp_api()->version_compare( $this->sitepress->get_wp_api()->constant( 'WC_VERSION' ), '3.0.0', '>=' ) ) {
388
+ $item[ 'data' ]->set_name( $item_product_title );
389
  } else {
390
+ $item[ 'data' ]->post->post_title = $item_product_title;
391
  }
392
 
393
  return $item;
inc/class-wcml-compatibility.php CHANGED
@@ -2,203 +2,223 @@
2
 
3
  class WCML_Compatibility {
4
 
5
- /**
6
- * @var SitePress
7
- */
8
- public $sitepress;
9
-
10
- /**
11
- * @var woocommerce_wpml
12
- */
13
- public $woocommerce_wpml;
14
-
15
- /**
16
- * @var wpdb
17
- */
18
- public $wpdb;
19
-
20
- function __construct( &$sitepress, &$woocommerce_wpml, &$wpdb ) {
21
- $this->sitepress = $sitepress;
22
- $this->woocommerce_wpml = $woocommerce_wpml;
23
- $this->wpdb = $wpdb;
24
- $this->init();
25
-
26
- }
27
-
28
- function init(){
29
- //hardcoded list of extensions and check which ones the user has and then include the corresponding file from the ‘compatibility’ folder
30
-
31
- //WooCommerce Tab Manager plugin
32
- if(class_exists('WC_Tab_Manager')){
33
- global $woocommerce;
34
- $this->tab_manager = new WCML_Tab_Manager( $this->sitepress, $woocommerce, $this->woocommerce_wpml, $this->wpdb );
35
- }
36
-
37
- //WooCommerce Table Rate Shipping plugin
38
- if(defined('TABLE_RATE_SHIPPING_VERSION')){
39
- $this->table_rate_shipping = new WCML_Table_Rate_Shipping( $this->sitepress, $this->woocommerce_wpml );
40
- }
41
-
42
- //WooCommerce Subscriptions
43
- if(class_exists('WC_Subscriptions')){
44
- $this->wp_subscriptions = new WCML_WC_Subscriptions();
45
- }
46
-
47
- //WooCommerce Name Your Price
48
- if(class_exists('WC_Name_Your_Price')){
49
- $this->name_your_price = new WCML_WC_Name_Your_Price();
50
- }
51
-
52
- //Product Bundle
53
- if(class_exists('WC_Product_Bundle')){
54
- if( version_compare( WC_PB()->version, '5.0.0', '<' ) ){
55
- $this->product_bundles = new WCML_Product_Bundles_Legacy( $this->sitepress, $this->woocommerce_wpml );
56
- }else{
57
- $product_bundle_items = new WCML_WC_Product_Bundles_Items();
58
- $this->product_bundles = new WCML_Product_Bundles( $this->sitepress, $this->woocommerce_wpml, $product_bundle_items );
59
- }
60
- }
61
-
62
- // WooCommerce Variation Swatches and Photos
63
- if(class_exists('WC_SwatchesPlugin')){
64
- $this->variation_sp = new WCML_Variation_Swatches_and_Photos();
65
- }
66
-
67
- // Product Add-ons
68
- if(class_exists( 'Product_Addon_Display' )){
69
- $this->product_addons = new WCML_Product_Addons( $this->sitepress );
70
- }
71
-
72
- // Product Per Product Shipping
73
- if(defined( 'PER_PRODUCT_SHIPPING_VERSION' )){
74
- new WCML_Per_Product_Shipping();
75
- }
76
- //Store Exporter plugin
77
- if(defined('WOO_CE_PATH')){
78
- $this->wc_exporter = new WCML_wcExporter();
79
- }
80
-
81
- //Gravity Forms
82
- if(class_exists('GFForms')){
83
- $this->gravityforms = new WCML_gravityforms();
84
- }
85
-
86
- //Sensei WooThemes
87
- if(class_exists('WooThemes_Sensei')){
88
- $this->sensei = new WCML_sensei();
89
- }
90
-
91
- //Extra Product Options
92
- if(class_exists('TM_Extra_Product_Options')){
93
- $this->extra_product_options = new WCML_Extra_Product_Options();
94
- }
95
-
96
- // Dynamic Pricing
97
- if ( class_exists('WC_Dynamic_Pricing') ) {
98
- $this->dynamic_pricing = new WCML_Dynamic_Pricing( $this->sitepress );
99
- }
100
-
101
- // WooCommerce Bookings
102
- if(defined( 'WC_BOOKINGS_VERSION' ) && version_compare(WC_BOOKINGS_VERSION, '1.7.8', '>=') ){
103
- $this->bookings = new WCML_Bookings( $this->sitepress, $this->woocommerce_wpml, $this->wpdb );
104
-
105
- // WooCommerce Accommodation Bookings
106
- if( defined( 'WC_ACCOMMODATION_BOOKINGS_VERSION' ) ){
107
- $this->accomodation_bookings = new WCML_Accommodation_Bookings( $this->woocommerce_wpml );
108
- }
109
- }
110
-
111
- // WooCommerce Checkout Field Editor
112
- if ( function_exists( 'woocommerce_init_checkout_field_editor' ) ) {
113
- $this->checkout_field_editor = new WCML_Checkout_Field_Editor();
114
- }
115
-
116
- if (class_exists('WC_Bulk_Stock_Management')) {
117
- $this->wc_bulk_stock_management = new WCML_Bulk_Stock_Management();
118
- }
119
-
120
- // WooCommerce Advanced Ajax Layered Navigation
121
- include_once( ABSPATH . 'wp-admin/includes/plugin.php' );
122
- if ( is_plugin_active( 'woocommerce-ajax-layered-nav/ajax_layered_nav-widget.php' ) ) {
123
- $this->wc_ajax_layered_nav_widget = new WCML_Ajax_Layered_Nav_Widget();
124
- }
125
-
126
- if ( is_plugin_active( 'woocommerce-ajax-cart/wooajaxcart.php' ) ) {
127
- $this->wc_ajax_cart = new WCML_WC_Ajax_Cart();
128
- }
129
-
130
- // woocommerce composite products
131
- if ( isset( $GLOBALS[ 'woocommerce_composite_products' ] ) ) {
132
- $this->wc_composite_products = new WCML_Composite_Products( $this->sitepress, $this->woocommerce_wpml );
133
- }
134
-
135
- // woocommerce checkout addons
136
- if (function_exists('init_woocommerce_checkout_add_ons')) {
137
- $this->wc_checkout_addons = new WCML_Checkout_Addons();
138
- }
139
-
140
- // woocommerce checkout addons
141
- if ( wp_get_theme() == 'Flatsome' ) {
142
- $this->flatsome = new WCML_Flatsome();
143
- }
144
-
145
- if (class_exists('WC_Mix_and_Match')) {
146
- $this->mix_and_match_products = new WCML_Mix_and_Match_Products();
147
- }
148
-
149
- if ( defined( 'WPSEO_VERSION') ) {
150
- $this->wpseo = new WCML_WPSEO();
151
- }
152
-
153
- //Adventure Tours theme
154
- if( function_exists( 'adventure_tours_check' ) ){
155
- $this->adventure_tours = new WCML_Adventure_tours();
156
- }
157
-
158
- //Aurum Theme
159
- if( wp_get_theme() == 'Aurum' ){
160
- new WCML_Aurum();
161
- }
162
-
163
- // Visual Products Configurator
164
- if( class_exists( 'Vpc' ) ){
165
- $this->vpc = new WCML_Vpc();
166
- }
167
-
168
- // WooCommerce Show Single Variations
169
- if( defined( 'JCK_WSSV_PATH' ) ){
170
- new WCML_JCK_WSSV();
171
- }
172
-
173
- // WooCommerce Print Invoices
174
- if( class_exists( 'WC_PIP' ) ){
175
- $this->pip = new WCML_Pip();
176
- }
177
-
178
- // The Events Calendar
179
- if( class_exists( 'Tribe__Events__Main' ) ){
180
- new WCML_The_Events_Calendar( $this->sitepress, $this->woocommerce_wpml );
181
- }
182
-
183
- // Klarna Gateway
184
- if( class_exists( 'WC_Gateway_Klarna' ) ){
185
- $this->klarna_gateway = new WCML_Klarna_Gateway();
186
- $this->klarna_gateway->add_hooks();
187
- }
188
-
189
- // YITH_WCQV
190
- if( class_exists( 'YITH_WCQV' ) ){
191
- $this->yith_wcqv = new WCML_YITH_WCQV();
192
- $this->yith_wcqv->add_hooks();
193
- }
194
-
195
- // Woocommerce Memberships
196
- if( class_exists( 'WC_Memberships' ) ){
197
- $this->wc_memberships = new WCML_WC_Memberships();
198
- $this->wc_memberships->add_hooks();
199
- }
200
-
201
-
202
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
203
 
204
  }
2
 
3
  class WCML_Compatibility {
4
 
5
+ /**
6
+ * @var SitePress
7
+ */
8
+ private $sitepress;
9
+ /**
10
+ * @var woocommerce_wpml
11
+ */
12
+ private $woocommerce_wpml;
13
+ /**
14
+ * @var wpdb
15
+ */
16
+ private $wpdb;
17
+ /** @var WPML_Element_Translation_Package */
18
+ private $tp;
19
+
20
+ /**
21
+ * WCML_Compatibility constructor.
22
+ *
23
+ * @param SitePress $sitepress
24
+ * @param woocommerce_wpml $woocommerce_wpml
25
+ * @param wpdb $wpdb
26
+ * @param WPML_Element_Translation_Package $tp
27
+ */
28
+ function __construct( SitePress $sitepress, woocommerce_wpml $woocommerce_wpml, wpdb $wpdb, WPML_Element_Translation_Package $tp ) {
29
+ $this->sitepress = $sitepress;
30
+ $this->woocommerce_wpml = $woocommerce_wpml;
31
+ $this->wpdb = $wpdb;
32
+ $this->tp = $tp;
33
+ $this->init();
34
+
35
+ }
36
+
37
+ function init() {
38
+ //hardcoded list of extensions and check which ones the user has and then include the corresponding file from the ‘compatibility’ folder
39
+
40
+ //WooCommerce Tab Manager plugin
41
+ if ( class_exists( 'WC_Tab_Manager' ) ) {
42
+ global $woocommerce;
43
+ $this->tab_manager = new WCML_Tab_Manager( $this->sitepress, $woocommerce, $this->woocommerce_wpml, $this->wpdb, $this->tp );
44
+ $this->tab_manager->add_hooks();
45
+ }
46
+
47
+ //WooCommerce Table Rate Shipping plugin
48
+ if ( defined( 'TABLE_RATE_SHIPPING_VERSION' ) ) {
49
+ $this->table_rate_shipping = new WCML_Table_Rate_Shipping( $this->sitepress, $this->woocommerce_wpml );
50
+ }
51
+
52
+ //WooCommerce Subscriptions
53
+ if ( class_exists( 'WC_Subscriptions' ) ) {
54
+ $this->wp_subscriptions = new WCML_WC_Subscriptions();
55
+ }
56
+
57
+ //WooCommerce Name Your Price
58
+ if ( class_exists( 'WC_Name_Your_Price' ) ) {
59
+ $this->name_your_price = new WCML_WC_Name_Your_Price();
60
+ }
61
+
62
+ //Product Bundle
63
+ if ( class_exists( 'WC_Product_Bundle' ) ) {
64
+ if ( version_compare( WC_PB()->version, '5.0.0', '<' ) ) {
65
+ $this->product_bundles = new WCML_Product_Bundles_Legacy( $this->sitepress, $this->woocommerce_wpml, $this->tp );
66
+ $this->product_bundles->add_hooks();
67
+ } else {
68
+ $product_bundle_items = new WCML_WC_Product_Bundles_Items();
69
+ $this->product_bundles = new WCML_Product_Bundles( $this->sitepress, $this->woocommerce_wpml, $product_bundle_items );
70
+ }
71
+ }
72
+
73
+ // WooCommerce Variation Swatches and Photos
74
+ if ( class_exists( 'WC_SwatchesPlugin' ) ) {
75
+ $this->variation_sp = new WCML_Variation_Swatches_and_Photos();
76
+ }
77
+
78
+ // Product Add-ons
79
+ if ( class_exists( 'Product_Addon_Display' ) ) {
80
+ $this->product_addons = new WCML_Product_Addons( $this->sitepress );
81
+ $this->product_addons->add_hooks();
82
+ }
83
+
84
+ // Product Per Product Shipping
85
+ if ( defined( 'PER_PRODUCT_SHIPPING_VERSION' ) ) {
86
+ new WCML_Per_Product_Shipping();
87
+ }
88
+ //Store Exporter plugin
89
+ if ( defined( 'WOO_CE_PATH' ) ) {
90
+ $this->wc_exporter = new WCML_wcExporter();
91
+ }
92
+
93
+ //Gravity Forms
94
+ if ( class_exists( 'GFForms' ) ) {
95
+ $this->gravityforms = new WCML_gravityforms();
96
+ }
97
+
98
+ //Sensei WooThemes
99
+ if ( class_exists( 'WooThemes_Sensei' ) ) {
100
+ $this->sensei = new WCML_Sensei(
101
+ $this->sitepress,
102
+ $this->wpdb,
103
+ WPML_Custom_Columns( $this->wpdb, $this->sitepress )
104
+ );
105
+ $this->sensei->add_hooks();
106
+ }
107
+
108
+ //Extra Product Options
109
+ if ( class_exists( 'TM_Extra_Product_Options' ) ) {
110
+ $this->extra_product_options = new WCML_Extra_Product_Options();
111
+ }
112
+
113
+ // Dynamic Pricing
114
+ if ( class_exists( 'WC_Dynamic_Pricing' ) ) {
115
+ $this->dynamic_pricing = new WCML_Dynamic_Pricing( $this->sitepress );
116
+ }
117
+
118
+ // WooCommerce Bookings
119
+ if ( defined( 'WC_BOOKINGS_VERSION' ) && version_compare( WC_BOOKINGS_VERSION, '1.7.8', '>=' ) ) {
120
+ $this->bookings = new WCML_Bookings( $this->sitepress, $this->woocommerce_wpml, $this->wpdb, $this->tp );
121
+ $this->bookings->add_hooks();
122
+
123
+ // WooCommerce Accommodation Bookings
124
+ if ( defined( 'WC_ACCOMMODATION_BOOKINGS_VERSION' ) ) {
125
+ $this->accomodation_bookings = new WCML_Accommodation_Bookings( $this->woocommerce_wpml );
126
+ }
127
+ }
128
+
129
+ // WooCommerce Checkout Field Editor
130
+ if ( function_exists( 'woocommerce_init_checkout_field_editor' ) ) {
131
+ $this->checkout_field_editor = new WCML_Checkout_Field_Editor();
132
+ }
133
+
134
+ if ( class_exists( 'WC_Bulk_Stock_Management' ) ) {
135
+ $this->wc_bulk_stock_management = new WCML_Bulk_Stock_Management();
136
+ }
137
+
138
+ // WooCommerce Advanced Ajax Layered Navigation
139
+ include_once( ABSPATH . 'wp-admin/includes/plugin.php' );
140
+ if ( is_plugin_active( 'woocommerce-ajax-layered-nav/ajax_layered_nav-widget.php' ) ) {
141
+ $this->wc_ajax_layered_nav_widget = new WCML_Ajax_Layered_Nav_Widget();
142
+ }
143
+
144
+ if ( is_plugin_active( 'woocommerce-ajax-cart/wooajaxcart.php' ) ) {
145
+ $this->wc_ajax_cart = new WCML_WC_Ajax_Cart();
146
+ }
147
+
148
+ // woocommerce composite products
149
+ if ( isset( $GLOBALS['woocommerce_composite_products'] ) ) {
150
+ $this->wc_composite_products = new WCML_Composite_Products( $this->sitepress, $this->woocommerce_wpml, $this->tp );
151
+ $this->wc_composite_products->add_hooks();
152
+ }
153
+
154
+ // woocommerce checkout addons
155
+ if ( function_exists( 'init_woocommerce_checkout_add_ons' ) ) {
156
+ $this->wc_checkout_addons = new WCML_Checkout_Addons();
157
+ }
158
+
159
+ // woocommerce checkout addons
160
+ if ( wp_get_theme() == 'Flatsome' ) {
161
+ $this->flatsome = new WCML_Flatsome();
162
+ }
163
+
164
+ if ( class_exists( 'WC_Mix_and_Match' ) ) {
165
+ $this->mix_and_match_products = new WCML_Mix_and_Match_Products();
166
+ }
167
+
168
+ if ( defined( 'WPSEO_VERSION' ) ) {
169
+ $this->wpseo = new WCML_WPSEO();
170
+ }
171
+
172
+ //Adventure Tours theme
173
+ if ( function_exists( 'adventure_tours_check' ) ) {
174
+ $this->adventure_tours = new WCML_Adventure_tours( $this->woocommerce_wpml, $this->sitepress, $this->tp );
175
+ $this->adventure_tours->add_hooks();
176
+ }
177
+
178
+ //Aurum Theme
179
+ if ( wp_get_theme() == 'Aurum' ) {
180
+ new WCML_Aurum();
181
+ }
182
+
183
+ // Visual Products Configurator
184
+ if ( class_exists( 'Vpc' ) ) {
185
+ $this->vpc = new WCML_Vpc();
186
+ }
187
+
188
+ // WooCommerce Show Single Variations
189
+ if ( defined( 'JCK_WSSV_PATH' ) ) {
190
+ new WCML_JCK_WSSV();
191
+ }
192
+
193
+ // WooCommerce Print Invoices
194
+ if ( class_exists( 'WC_PIP' ) ) {
195
+ $this->pip = new WCML_Pip();
196
+ }
197
+
198
+ // The Events Calendar
199
+ if ( class_exists( 'Tribe__Events__Main' ) ) {
200
+ new WCML_The_Events_Calendar( $this->sitepress, $this->woocommerce_wpml );
201
+ }
202
+
203
+ // Klarna Gateway
204
+ if ( class_exists( 'WC_Gateway_Klarna' ) ) {
205
+ $this->klarna_gateway = new WCML_Klarna_Gateway();
206
+ $this->klarna_gateway->add_hooks();
207
+ }
208
+
209
+ // YITH_WCQV
210
+ if ( class_exists( 'YITH_WCQV' ) ) {
211
+ $this->yith_wcqv = new WCML_YITH_WCQV();
212
+ $this->yith_wcqv->add_hooks();
213
+ }
214
+
215
+ // Woocommerce Memberships
216
+ if ( class_exists( 'WC_Memberships' ) ) {
217
+ $this->wc_memberships = new WCML_WC_Memberships();
218
+ $this->wc_memberships->add_hooks();
219
+ }
220
+
221
+
222
+ }
223
 
224
  }
inc/class-wcml-emails.php CHANGED
@@ -63,8 +63,6 @@ class WCML_Emails{
63
  $this->set_emails_string_language();
64
  }
65
 
66
- add_filter( 'get_post_metadata', array( $this, 'filter_payment_method_string' ), 10, 4 );
67
-
68
  if(
69
  (
70
  !isset( $_GET['post_type'] ) ||
@@ -246,22 +244,6 @@ class WCML_Emails{
246
  }
247
  }
248
 
249
- function filter_payment_method_string( $title, $object_id, $meta_key, $single ){
250
-
251
- if( $object_id && 'shop_order' === get_post_type( $object_id ) && '_payment_method_title' === $meta_key ){
252
-
253
- remove_filter( 'get_post_metadata', array( $this, 'filter_payment_method_string' ), 10, 4 );
254
- $payment_gateway = wc_get_payment_gateway_by_order( $object_id );
255
- add_filter( 'get_post_metadata', array( $this, 'filter_payment_method_string' ), 10, 4 );
256
-
257
- if( $payment_gateway ){
258
- $title = $this->woocommerce_wpml->gateways->translate_gateway_title( $payment_gateway->title, $payment_gateway->id, $this->sitepress->get_current_language() );
259
- }
260
- }
261
-
262
- return $title;
263
- }
264
-
265
  function filter_formatted_items( $formatted_meta, $object ){
266
 
267
  if( isset( $object->product->variation_id ) ){
63
  $this->set_emails_string_language();
64
  }
65
 
 
 
66
  if(
67
  (
68
  !isset( $_GET['post_type'] ) ||
244
  }
245
  }
246
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
247
  function filter_formatted_items( $formatted_meta, $object ){
248
 
249
  if( isset( $object->product->variation_id ) ){
inc/class-wcml-endpoints.php CHANGED
@@ -12,6 +12,7 @@ class WCML_Endpoints{
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
 
16
  add_filter( 'page_link', array( $this, 'endpoint_permalink_filter' ), 10, 2 ); //after WPML
17
 
@@ -27,6 +28,51 @@ class WCML_Endpoints{
27
  add_filter( 'woocommerce_settings_saved', array( $this, 'update_original_endpoints_strings') );
28
  }
29
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
30
 
31
  function register_endpoints_translations( $language = null ){
32
 
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
 
28
  add_filter( 'woocommerce_settings_saved', array( $this, 'update_original_endpoints_strings') );
29
  }
30
 
31
+ public function reserved_requests( $requests, SitePress $sitepress ) {
32
+ $cache_key = 'reserved_requests';
33
+ $cache_group = 'wpml-endpoints';
34
+
35
+ $found = null;
36
+ $reserved_requests = wp_cache_get( $cache_key, $cache_group, false, $found );
37
+
38
+ if ( ! $found || ! $reserved_requests ) {
39
+ $reserved_requests = array();
40
+
41
+ $current_language = $sitepress->get_current_language();
42
+ $languages = $sitepress->get_active_languages();
43
+ $languages_codes = array_keys( $languages );
44
+ foreach ( $languages_codes as $language_code ) {
45
+ $sitepress->switch_lang( $language_code );
46
+
47
+ $my_account_page_id = get_option( 'woocommerce_myaccount_page_id' );
48
+ if ( $my_account_page_id ) {
49
+ $my_account_page = get_post( $my_account_page_id );
50
+ if ( $my_account_page ) {
51
+ $account_base = $my_account_page->post_name;
52
+
53
+ $reserved_requests[] = $account_base;
54
+
55
+ foreach ( $this->woocommerce_wpml->get_wc_query_vars() as $key => $endpoint ) {
56
+ $translated_endpoint = $this->get_endpoint_translation( $key, $endpoint, $language_code );
57
+
58
+ $reserved_requests[] = $account_base . '/' . $translated_endpoint;
59
+ }
60
+ }
61
+ }
62
+ }
63
+ $sitepress->switch_lang( $current_language );
64
+
65
+ if ( $reserved_requests ) {
66
+ wp_cache_set( $cache_key, $reserved_requests, $cache_group );
67
+ }
68
+ }
69
+
70
+ if ( $reserved_requests ) {
71
+ $requests = array_unique( array_merge( $requests, $reserved_requests ) );
72
+ }
73
+
74
+ return $requests;
75
+ }
76
 
77
  function register_endpoints_translations( $language = null ){
78
 
inc/class-wcml-orders.php CHANGED
@@ -31,7 +31,10 @@ class WCML_Orders{
31
  add_filter('icl_lang_sel_copy_parameters', array($this, 'append_query_parameters'));
32
 
33
  add_filter('the_comments', array($this, 'get_filtered_comments'));
34
- add_filter('gettext',array($this, 'filtered_woocommerce_new_order_note_data'),10,3);
 
 
 
35
 
36
  add_filter( 'woocommerce_order_get_items', array( $this, 'woocommerce_order_get_items' ), 10, 2 );
37
 
@@ -48,6 +51,13 @@ class WCML_Orders{
48
  add_filter( 'woocommerce_customer_get_downloadable_products', array( $this, 'filter_customer_get_downloadable_products' ), 10, 3 );
49
  }
50
 
 
 
 
 
 
 
 
51
  function filtered_woocommerce_new_order_note_data($translations, $text, $domain ){
52
  if(in_array($text,$this->standart_order_notes)){
53
 
@@ -183,7 +193,13 @@ class WCML_Orders{
183
  }
184
  }elseif( $item instanceof WC_Order_Item_Shipping ){
185
  if( $item->get_method_id() ){
186
- $item->set_method_title( $this->woocommerce_wpml->shipping->translate_shipping_method_title( $item->get_method_title(), $item->get_method_id(), $language_to_filter ) );
 
 
 
 
 
 
187
  }
188
  }
189
  }
31
  add_filter('icl_lang_sel_copy_parameters', array($this, 'append_query_parameters'));
32
 
33
  add_filter('the_comments', array($this, 'get_filtered_comments'));
34
+
35
+ if ( $this->should_attach_new_order_note_data_filter() ) {
36
+ add_filter( 'gettext', array( $this, 'filtered_woocommerce_new_order_note_data' ), 10, 3 );
37
+ }
38
 
39
  add_filter( 'woocommerce_order_get_items', array( $this, 'woocommerce_order_get_items' ), 10, 2 );
40
 
51
  add_filter( 'woocommerce_customer_get_downloadable_products', array( $this, 'filter_customer_get_downloadable_products' ), 10, 3 );
52
  }
53
 
54
+ public function should_attach_new_order_note_data_filter() {
55
+ $admin_language = $this->sitepress->get_user_admin_language( get_current_user_id(), true );
56
+ $all_strings_in_english = get_option( 'wpml-st-all-strings-are-in-english' );
57
+
58
+ return 'en' !== $admin_language || ! $all_strings_in_english;
59
+ }
60
+
61
  function filtered_woocommerce_new_order_note_data($translations, $text, $domain ){
62
  if(in_array($text,$this->standart_order_notes)){
63
 
193
  }
194
  }elseif( $item instanceof WC_Order_Item_Shipping ){
195
  if( $item->get_method_id() ){
196
+ $item->set_method_title(
197
+ $this->woocommerce_wpml->shipping->translate_shipping_method_title(
198
+ $item->get_method_title(),
199
+ $item->get_method_id(),
200
+ $language_to_filter
201
+ )
202
+ );
203
  }
204
  }
205
  }
inc/class-wcml-products.php CHANGED
@@ -2,11 +2,6 @@
2
 
3
  class WCML_Products{
4
 
5
- /**
6
- * @var WCML_TP_Support
7
- */
8
- public $tp_support;
9
-
10
  /**
11
  * @var woocommerce_wpml
12
  */
@@ -37,8 +32,6 @@ class WCML_Products{
37
 
38
  add_filter( 'post_row_actions', array( $this, 'filter_product_actions' ), 10, 2 );
39
 
40
- $this->tp_support = new WCML_TP_Support();
41
-
42
  add_action( 'wp_ajax_wpml_switch_post_language', array( $this, 'switch_product_variations_language' ), 9 );
43
 
44
  }else{
@@ -473,8 +466,7 @@ class WCML_Products{
473
  foreach( $products as $product ){
474
  if( $product->language_code == $language ) continue;
475
 
476
- $element_key = array( 'trid' => $product->trid, 'language_code' => $language );
477
- $translation_status = apply_filters( 'wpml_tm_translation_status', null, $element_key );
478
 
479
  if( in_array( $translation_status, array( ICL_TM_NOT_TRANSLATED, ICL_TM_WAITING_FOR_TRANSLATOR, ICL_TM_IN_PROGRESS ) ) ){
480
  $count++;
2
 
3
  class WCML_Products{
4
 
 
 
 
 
 
5
  /**
6
  * @var woocommerce_wpml
7
  */
32
 
33
  add_filter( 'post_row_actions', array( $this, 'filter_product_actions' ), 10, 2 );
34
 
 
 
35
  add_action( 'wp_ajax_wpml_switch_post_language', array( $this, 'switch_product_variations_language' ), 9 );
36
 
37
  }else{
466
  foreach( $products as $product ){
467
  if( $product->language_code == $language ) continue;
468
 
469
+ $translation_status = apply_filters( 'wpml_translation_status', null, $product->trid, $language );
 
470
 
471
  if( in_array( $translation_status, array( ICL_TM_NOT_TRANSLATED, ICL_TM_WAITING_FOR_TRANSLATOR, ICL_TM_IN_PROGRESS ) ) ){
472
  $count++;
inc/class-wcml-requests.php CHANGED
@@ -4,7 +4,6 @@ class WCML_Requests{
4
  function __construct(){
5
 
6
  add_action('init', array($this, 'run') );
7
-
8
 
9
  }
10
 
@@ -12,6 +11,21 @@ class WCML_Requests{
12
  global $woocommerce_wpml;
13
 
14
  $nonce = filter_input( INPUT_POST, 'wcml_nonce', FILTER_SANITIZE_FULL_SPECIAL_CHARS );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
15
 
16
  if(isset($_POST['wcml_save_settings']) && wp_verify_nonce($nonce, 'wcml_save_settings_nonce')){
17
  global $sitepress,$sitepress_settings;
@@ -28,8 +42,6 @@ class WCML_Requests{
28
  $woocommerce_wpml->settings['cart_sync']['lang_switch'] = intval( filter_input( INPUT_POST, 'cart_sync_lang', FILTER_SANITIZE_NUMBER_INT ) );
29
  $woocommerce_wpml->settings['cart_sync']['currency_switch'] = intval( filter_input( INPUT_POST, 'cart_sync_currencies', FILTER_SANITIZE_NUMBER_INT ) );
30
 
31
- $woocommerce_wpml->update_settings();
32
-
33
  $new_value = $wcml_file_path_sync == 0 ? 2 :$wcml_file_path_sync;
34
  $sitepress_settings['translation-management']['custom_fields_translation']['_downloadable_files'] = $new_value;
35
  $sitepress_settings['translation-management']['custom_fields_translation']['_file_paths'] = $new_value;
@@ -46,14 +58,11 @@ class WCML_Requests{
46
  'show_once' => true
47
  );
48
  ICL_AdminNotifier::add_message( $message );
 
 
49
  }
50
 
51
- if( isset( $_GET[ 'wcml_action' ] ) ){
52
- if( $_GET['wcml_action'] == 'dismiss' ){
53
- $woocommerce_wpml->settings['dismiss_doc_main'] = 1;
54
- }elseif( $_GET['wcml_action'] == 'dismiss_tm_warning' ){
55
- $woocommerce_wpml->settings['dismiss_tm_warning'] = 1;
56
- }
57
  $woocommerce_wpml->update_settings();
58
  }
59
 
4
  function __construct(){
5
 
6
  add_action('init', array($this, 'run') );
 
7
 
8
  }
9
 
11
  global $woocommerce_wpml;
12
 
13
  $nonce = filter_input( INPUT_POST, 'wcml_nonce', FILTER_SANITIZE_FULL_SPECIAL_CHARS );
14
+ $settings_needs_update = false;
15
+
16
+ if( isset( $_GET[ 'wcml_action' ] ) ){
17
+ $settings_needs_update = true;
18
+
19
+ if( $_GET['wcml_action'] == 'dismiss' ){
20
+ $woocommerce_wpml->settings['dismiss_doc_main'] = 1;
21
+ }elseif( $_GET['wcml_action'] == 'dismiss_tm_warning' ){
22
+ $woocommerce_wpml->settings['dismiss_tm_warning'] = 1;
23
+ }elseif( $_GET['wcml_action'] == 'dismiss_cart_warning' ){
24
+ $woocommerce_wpml->settings['dismiss_cart_warning'] = 1;
25
+ }else{
26
+ $settings_needs_update = false;
27
+ }
28
+ }
29
 
30
  if(isset($_POST['wcml_save_settings']) && wp_verify_nonce($nonce, 'wcml_save_settings_nonce')){
31
  global $sitepress,$sitepress_settings;
42
  $woocommerce_wpml->settings['cart_sync']['lang_switch'] = intval( filter_input( INPUT_POST, 'cart_sync_lang', FILTER_SANITIZE_NUMBER_INT ) );
43
  $woocommerce_wpml->settings['cart_sync']['currency_switch'] = intval( filter_input( INPUT_POST, 'cart_sync_currencies', FILTER_SANITIZE_NUMBER_INT ) );
44
 
 
 
45
  $new_value = $wcml_file_path_sync == 0 ? 2 :$wcml_file_path_sync;
46
  $sitepress_settings['translation-management']['custom_fields_translation']['_downloadable_files'] = $new_value;
47
  $sitepress_settings['translation-management']['custom_fields_translation']['_file_paths'] = $new_value;
58
  'show_once' => true
59
  );
60
  ICL_AdminNotifier::add_message( $message );
61
+
62
+ $settings_needs_update = true;
63
  }
64
 
65
+ if( $settings_needs_update ){
 
 
 
 
 
66
  $woocommerce_wpml->update_settings();
67
  }
68
 
inc/class-wcml-tp-support.php CHANGED
@@ -2,13 +2,28 @@
2
 
3
  class WCML_TP_Support {
4
 
 
 
 
 
5
  /** @var WPML_Element_Translation_Package */
6
  private $tp;
7
 
8
- public function __construct() {
9
-
10
- $this->tp = new WPML_Element_Translation_Package;
 
 
 
 
 
 
 
 
 
 
11
 
 
12
  add_filter( 'wpml_tm_translation_job_data', array( $this, 'append_custom_attributes_to_translation_package' ), 10, 2 );
13
  add_action( 'wpml_translation_job_saved', array( $this, 'save_custom_attribute_translations' ), 10, 2 );
14
 
@@ -20,15 +35,13 @@ class WCML_TP_Support {
20
 
21
  add_filter( 'wpml_tm_translation_job_data', array( $this, 'append_images_to_translation_package' ), 10, 2 );
22
  add_action( 'wpml_translation_job_saved', array( $this, 'save_images_translations' ), 10, 3 );
23
-
24
  }
25
 
26
  public function append_custom_attributes_to_translation_package( $package, $post ) {
27
 
28
- if ( $post->post_type == 'product' ) {
29
 
30
  $product = wc_get_product( $post->ID );
31
-
32
  $product_type = WooCommerce_Functions_Wrapper::get_product_type( $post->ID );
33
 
34
  if ( ! empty( $product ) && $product_type === 'variable' ) {
@@ -36,39 +49,34 @@ class WCML_TP_Support {
36
  $attributes = $product->get_attributes();
37
 
38
  foreach ( $attributes as $attribute_key => $attribute ) {
39
- if ( ! $attribute['is_taxonomy'] ) {
40
 
41
- $package['contents'][ 'wc_attribute_name:' . $attribute_key ] = array(
 
 
 
 
 
 
 
 
 
 
 
 
 
42
  'translate' => 1,
43
- 'data' => $this->tp->encode_field_data( $attribute['name'], 'base64' ),
44
  'format' => 'base64'
45
  );
46
-
47
- $values = explode( '|', $attribute['value'] );
48
- $values = array_map( 'trim', $values );
49
-
50
- foreach ( $values as $value_key => $value ) {
51
-
52
- $package['contents'][ 'wc_attribute_value:' . $value_key . ':' . $attribute_key ] = array(
53
- 'translate' => 1,
54
- 'data' => $this->tp->encode_field_data( $value, 'base64' ),
55
- 'format' => 'base64'
56
- );
57
-
58
- }
59
-
60
  }
61
  }
62
-
63
  }
64
-
65
  }
66
 
67
  return $package;
68
  }
69
 
70
  public function save_custom_attribute_translations( $post_id, $data ) {
71
- global $woocommerce_wpml;
72
 
73
  $translated_attributes = array();
74
 
@@ -101,7 +109,7 @@ class WCML_TP_Support {
101
 
102
  $product_attributes = get_post_meta( $post_id, '_product_attributes', true );
103
 
104
- $original_post_language = $woocommerce_wpml->products->get_original_product_language( $post_id );
105
  $original_post_id = apply_filters( 'translate_object_id', $post_id, 'product', false, $original_post_language );
106
 
107
  $original_attributes = get_post_meta( $original_post_id, '_product_attributes', true );
@@ -204,14 +212,13 @@ class WCML_TP_Support {
204
  }
205
 
206
  public function save_slug_translations( $post_id, $data ) {
207
- global $wpdb;
208
 
209
  foreach ( $data as $data_key => $value ) {
210
  if ( $value['finished'] && isset( $value['field_type'] ) && 'slug' === $value['field_type'] ) {
211
  $product = get_post( $post_id );
212
  if ( $product->post_type == 'product' ) {
213
  $new_slug = wp_unique_post_slug( sanitize_title( $value['data'] ), $post_id, $product->post_status, $product->post_type, $product->post_parent );
214
- $wpdb->update( $wpdb->posts, array( 'post_name' => $new_slug ), array( 'ID' => $post_id ) );
215
  break;
216
  }
217
  }
@@ -219,15 +226,13 @@ class WCML_TP_Support {
219
  }
220
 
221
  public function append_images_to_translation_package( $package, $post ) {
222
- global $wpdb;
223
 
224
  if ( $post->post_type == 'product' ) {
225
 
226
- $woocommerce_wpml = woocommerce_wpml::instance();
227
- $product_images = $woocommerce_wpml->media->product_images_ids( $post->ID );
228
- $product_images = $woocommerce_wpml->media->exclude_not_duplicated_attachments( $product_images, $post->ID );
229
  foreach ( $product_images as $image_id ) {
230
- $attachment_data = $wpdb->get_row( $wpdb->prepare( "SELECT post_title,post_excerpt,post_content FROM {$wpdb->posts} WHERE ID = %d", $image_id ) );
231
  if ( ! $attachment_data ) {
232
  continue;
233
  }
@@ -244,13 +249,10 @@ class WCML_TP_Support {
244
  }
245
 
246
  public function save_images_translations( $post_id, $data, $job ) {
247
- global $wpdb;
248
 
249
  $language = $job->language_code;
250
 
251
- $woocommerce_wpml = woocommerce_wpml::instance();
252
-
253
- $product_images = $woocommerce_wpml->media->product_images_ids( $job->original_doc_id );
254
  foreach ( $product_images as $image_id ) {
255
  $translated_prod_image = apply_filters( 'translate_object_id', $image_id, 'attachment', false, $language );
256
  $image_data = $this->get_image_data( $image_id, $data );
@@ -268,7 +270,7 @@ class WCML_TP_Support {
268
  }
269
 
270
  if( $translation ){
271
- $wpdb->update( $wpdb->posts, $translation, array( 'id' => $translated_prod_image ) );
272
  }
273
 
274
  if ( isset( $image_data['alt-text'] ) ) {
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
 
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' ) {
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
 
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 );
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
  }
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
+ $product_images = $this->woocommerce_wpml->media->exclude_not_duplicated_attachments( $product_images, $post->ID );
 
234
  foreach ( $product_images as $image_id ) {
235
+ $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 ) );
236
  if ( ! $attachment_data ) {
237
  continue;
238
  }
249
  }
250
 
251
  public function save_images_translations( $post_id, $data, $job ) {
 
252
 
253
  $language = $job->language_code;
254
 
255
+ $product_images = $this->woocommerce_wpml->media->product_images_ids( $job->original_doc_id );
 
 
256
  foreach ( $product_images as $image_id ) {
257
  $translated_prod_image = apply_filters( 'translate_object_id', $image_id, 'attachment', false, $language );
258
  $image_data = $this->get_image_data( $image_id, $data );
270
  }
271
 
272
  if( $translation ){
273
+ $this->wpdb->update( $this->wpdb->posts, $translation, array( 'id' => $translated_prod_image ) );
274
  }
275
 
276
  if ( isset( $image_data['alt-text'] ) ) {
inc/class-wcml-upgrade.php CHANGED
@@ -18,7 +18,8 @@ class WCML_Upgrade{
18
  '3.9',
19
  '3.9.1',
20
  '4.0',
21
- '4.1.0'
 
22
  );
23
 
24
  function __construct(){
@@ -592,5 +593,14 @@ class WCML_Upgrade{
592
  update_option('_wcml_settings', $wcml_settings );
593
  }
594
  }
 
 
 
 
 
 
 
 
 
595
 
596
  }
18
  '3.9',
19
  '3.9.1',
20
  '4.0',
21
+ '4.1.0',
22
+ '4.2.0'
23
  );
24
 
25
  function __construct(){
593
  update_option('_wcml_settings', $wcml_settings );
594
  }
595
  }
596
+
597
+ function upgrade_4_2_0(){
598
+
599
+ $wcml_settings = get_option( '_wcml_settings' );
600
+ $wcml_settings[ 'dismiss_cart_warning' ] = 0;
601
+
602
+ update_option( '_wcml_settings', $wcml_settings );
603
+
604
+ }
605
 
606
  }
inc/class-wcml-wc-shipping.php CHANGED
@@ -120,21 +120,34 @@ class WCML_WC_Shipping{
120
  return $available_methods;
121
  }
122
 
123
- function translate_shipping_method_title( $title, $shipping_id, $language = false ) {
124
-
125
- if( !is_admin() ){
126
-
127
- $shipping_id = str_replace( ':', '', $shipping_id );
128
- $translated_title = apply_filters( 'wpml_translate_single_string', $title, 'woocommerce', $shipping_id .'_shipping_method_title', $language ? $language : $this->current_language );
129
-
130
- if( $translated_title ){
131
- $title = $translated_title;
132
- }
133
-
134
- }
135
-
136
- return $title;
137
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
138
 
139
  function translate_woocommerce_rate_label( $label ){
140
 
120
  return $available_methods;
121
  }
122
 
123
+ function translate_shipping_method_title( $title, $shipping_id, $language = false ) {
124
+
125
+ if ( is_admin() ) {
126
+ $screen = get_current_screen();
127
+ $is_edit_order = $screen->id === 'shop_order';
128
+ } else {
129
+ $is_edit_order = false;
130
+ }
131
+
132
+ if ( ! is_admin() || $is_edit_order ) {
133
+
134
+ $shipping_id = str_replace( ':', '', $shipping_id );
135
+ $translated_title = apply_filters(
136
+ 'wpml_translate_single_string',
137
+ $title,
138
+ 'woocommerce',
139
+ $shipping_id . '_shipping_method_title',
140
+ $language ? $language : $this->current_language
141
+ );
142
+
143
+ if ( $translated_title ) {
144
+ $title = $translated_title;
145
+ }
146
+
147
+ }
148
+
149
+ return $title;
150
+ }
151
 
152
  function translate_woocommerce_rate_label( $label ){
153
 
inc/class-wcml-wc-strings.php CHANGED
@@ -6,25 +6,46 @@ class WCML_WC_Strings{
6
  private $mo_files = array();
7
  private $current_language;
8
 
9
- function __construct(){
 
 
 
10
 
11
- add_action( 'init', array( $this, 'init' ) );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
12
  add_action( 'registered_taxonomy', array ( $this, 'translate_attributes_label_in_wp_taxonomies' ), 100, 3 );
13
  }
14
 
15
- function init(){
16
- global $pagenow, $sitepress;
17
 
18
- $this->current_language = $sitepress->get_current_language();
19
  if( $this->current_language == 'all' ){
20
- $this->current_language = $sitepress->get_default_language();
21
  }
22
 
23
  //translate attribute label
24
  add_filter('woocommerce_attribute_label',array($this,'translated_attribute_label'),10,3);
25
- add_filter('woocommerce_cart_item_name',array($this,'translated_cart_item_name'),10,3);
26
  add_filter('woocommerce_checkout_product_title',array($this,'translated_checkout_product_title'),10,2);
27
 
 
 
 
 
28
  if( is_admin() && $pagenow == 'options-permalink.php' ){
29
  add_filter( 'gettext_with_context', array( $this, 'category_base_in_strings_language' ), 99, 3 );
30
  add_action( 'admin_footer', array( $this, 'show_custom_url_base_translation_links' ) );
@@ -40,13 +61,13 @@ class WCML_WC_Strings{
40
  }
41
 
42
  function translated_attribute_label($label, $name, $product_obj = false){
43
- global $sitepress, $product, $sitepress_settings, $woocommerce_wpml;
44
 
45
  $product_id = false;
46
- $lang = $sitepress->get_current_language();
47
 
48
  if( isset( $_GET[ 'post' ] ) && get_post_type( $_GET[ 'post' ] ) == 'shop_order' ){
49
- $lang = $sitepress->get_user_admin_language( get_current_user_id(), true );
50
  }
51
 
52
  if( $product && is_object( $product ) ){
@@ -57,11 +78,11 @@ class WCML_WC_Strings{
57
  $product_id = WooCommerce_Functions_Wrapper::get_product_id( $product_obj );
58
  }
59
 
60
- $name = $woocommerce_wpml->attributes->filter_attribute_name( $name, $product_id, true );
61
 
62
  if( $product_id ){
63
 
64
- $custom_attr_translation = $woocommerce_wpml->attributes->get_attr_label_translations( $product_id, $lang ) ;
65
 
66
  if( $custom_attr_translation ){
67
  if( isset( $custom_attr_translation[$name] ) ){
@@ -81,11 +102,11 @@ class WCML_WC_Strings{
81
 
82
  $string_language = $this->get_string_language( 'taxonomy singular name: '.$label, 'WordPress' );
83
 
84
- if($sitepress->get_user_admin_language( get_current_user_id(), true ) != $string_language){
85
  $string_id = icl_get_string_id( 'taxonomy singular name: '.$label, 'WordPress' );
86
  $strings = icl_get_string_translations_by_id($string_id);
87
  if($strings){
88
- return $strings[$sitepress->get_user_admin_language( get_current_user_id(), true )]['value'];
89
  }
90
  }else{
91
  return $label;
@@ -103,15 +124,14 @@ class WCML_WC_Strings{
103
  return $label;
104
  }
105
 
106
- function translated_cart_item_name($title, $values, $cart_item_key){
107
-
108
- if($values){
109
 
 
110
  $parent = wp_get_post_parent_id( $values['product_id'] );
111
- $tr_product_id = apply_filters( 'translate_object_id', $values['product_id'], 'product', true );
112
- $trnsl_title = get_the_title($tr_product_id);
113
 
114
- if($parent){
115
  $tr_parent = apply_filters( 'translate_object_id', $parent, 'product', true );
116
  $trnsl_title = get_the_title( $tr_parent ) . ' &rarr; ' . $trnsl_title;
117
  }
@@ -140,30 +160,29 @@ class WCML_WC_Strings{
140
 
141
  // Catch the default slugs for translation
142
  function translate_default_slug($translation, $text, $context, $domain) {
143
- global $sitepress, $woocommerce_wpml;
144
 
145
  if ($context == 'slug' || $context == 'default-slug') {
146
- $wc_slug = $woocommerce_wpml->url_translation->get_woocommerce_product_base();
147
  if(is_admin()){
148
- $admin_language = $sitepress->get_admin_language();
149
  }
150
- $current_language = $sitepress->get_current_language();
151
 
152
  $strings_language = $this->get_domain_language('woocommerce');
153
 
154
  if ($text == $wc_slug && $domain == 'woocommerce' && $strings_language) {
155
- $sitepress->switch_lang($strings_language);
156
  $translation = _x($text, 'URL slug', $domain);
157
- $sitepress->switch_lang($current_language);
158
  if(is_admin()){
159
- $sitepress->set_admin_language($admin_language);
160
  }
161
  }else{
162
  $translation = $text;
163
  }
164
 
165
  if(!is_admin()){
166
- $sitepress->switch_lang($current_language);
167
  }
168
  }
169
 
@@ -190,10 +209,10 @@ class WCML_WC_Strings{
190
  }
191
 
192
  function show_custom_url_base_translation_links(){
193
- global $woocommerce_wpml,$sitepress;
194
  $permalink_options = get_option( 'woocommerce_permalinks' );
195
 
196
- $lang_selector = new WPML_Simple_Language_Selector( $sitepress );
197
 
198
  $bases = array( 'tag_base' => 'product_tag', 'category_base' => 'product_cat', 'attribute_base' => 'attribute', 'product_base' => 'product' );
199
 
@@ -202,11 +221,11 @@ class WCML_WC_Strings{
202
  switch($base){
203
  case 'product_tag':
204
  $input_name = 'woocommerce_product_tag_slug';
205
- $value = !empty( $permalink_options['tag_base'] ) ? $permalink_options['tag_base'] : $woocommerce_wpml->url_translation->default_product_tag_base;
206
  break;
207
  case 'product_cat':
208
  $input_name = 'woocommerce_product_category_slug';
209
- $value = !empty( $permalink_options['category_base'] ) ? $permalink_options['category_base'] : $woocommerce_wpml->url_translation->default_product_category_base;
210
  break;
211
  case 'attribute':
212
  $input_name = 'woocommerce_product_attribute_slug';
@@ -223,10 +242,10 @@ class WCML_WC_Strings{
223
  break;
224
  }
225
 
226
- $language = $this->get_string_language( trim( $value, '/' ), $woocommerce_wpml->url_translation->url_strings_context(), $woocommerce_wpml->url_translation->url_string_name( $base ) );
227
 
228
  if( is_null($language) ){
229
- $language = $sitepress->get_default_language();
230
  }
231
 
232
  echo $lang_selector->render( array( 'id' => $key.'_language_selector', 'name' => $key.'_language', 'selected' => $language, 'show_please_select' => false ) ); ?>
@@ -274,9 +293,8 @@ class WCML_WC_Strings{
274
  }
275
 
276
  function get_domain_language( $domain ){
277
- global $sitepress;
278
 
279
- $lang_of_domain = new WPML_Language_Of_Domain( $sitepress );
280
  $domain_lang = $lang_of_domain->get_language( $domain );
281
 
282
  if ( $domain_lang ) {
@@ -333,10 +351,9 @@ class WCML_WC_Strings{
333
  *
334
  */
335
  function filter_woocommerce_breadcrumbs( $breadcrumbs, $object ){
336
- global $sitepress,$woocommerce_wpml;
337
 
338
- $current_language = $sitepress->get_current_language();
339
- $default_language = $sitepress->get_default_language();
340
 
341
  if( $current_language != $default_language || $default_language != 'en' ){
342
 
@@ -344,7 +361,7 @@ class WCML_WC_Strings{
344
 
345
  // If permalinks contain the shop page in the URI prepend the breadcrumb with shop
346
  // Similar to WC_Breadcrumb::prepend_shop_page
347
- $trnsl_base = $woocommerce_wpml->url_translation->get_base_translation( 'product', $current_language );
348
  if( $trnsl_base['translated_base'] === '' ){
349
  $trnsl_base['translated_base'] = $trnsl_base['original_value'];
350
  }
@@ -378,30 +395,28 @@ class WCML_WC_Strings{
378
  * Add notice message to users
379
  */
380
  function notice_after_woocommerce_product_options_attributes(){
381
- global $sitepress;
382
 
383
- if( isset( $_GET['post'] ) && $sitepress->get_default_language() != $sitepress->get_current_language() ){
384
- $original_product_id = apply_filters( 'translate_object_id', $_GET['post'], 'product', true, $sitepress->get_default_language() );
385
 
386
  printf( '<p>'.__('In order to edit custom attributes you need to use the <a href="%s">custom product translation editor</a>', 'woocommerce-multilingual').'</p>', admin_url('admin.php?page=wpml-wcml&tab=products&prid='.$original_product_id ) );
387
  }
388
  }
389
 
390
  function translate_attribute_taxonomies_labels( $attribute_taxonomies ){
391
- global $sitepress;
392
 
393
  if( is_admin() && !wpml_is_ajax() ){
394
 
395
  foreach( $attribute_taxonomies as $key => $attribute_taxonomy ){
396
  $string_language = $this->get_string_language( $attribute_taxonomy->attribute_name, 'WordPress', 'taxonomy singular name: '.$attribute_taxonomy->attribute_name );
397
 
398
- if( $sitepress->get_current_language() == $string_language ) continue;
399
 
400
  $string_id = icl_get_string_id( $attribute_taxonomy->attribute_name, 'WordPress', 'taxonomy singular name: '.$attribute_taxonomy->attribute_name );
401
  $strings = icl_get_string_translations_by_id( $string_id );
402
 
403
- if($strings && isset($strings[$sitepress->get_current_language()])) {
404
- $attribute_taxonomies[$key]->attribute_label = $strings[$sitepress->get_current_language()]['value'];
405
  }
406
  }
407
 
@@ -412,7 +427,6 @@ class WCML_WC_Strings{
412
  }
413
 
414
  function get_translation_from_woocommerce_mo_file( $string, $language, $return_original = true ){
415
- global $sitepress;
416
 
417
  $original_string = $string;
418
 
@@ -424,7 +438,7 @@ class WCML_WC_Strings{
424
 
425
  if ( ! isset( $this->mo_files[ $language ] ) ) {
426
  $mo = new MO();
427
- $mo_file = WP_LANG_DIR . '/plugins/woocommerce-' . $sitepress->get_locale( $language ) . '.mo';
428
  if( !file_exists( $mo_file ) ){
429
  return $return_original ? $string : null;
430
  }
@@ -449,10 +463,10 @@ class WCML_WC_Strings{
449
  }
450
 
451
  function translate_attributes_label_in_wp_taxonomies( $taxonomy, $obj_type, $args ){
452
- global $wp_taxonomies, $sitepress;
453
  $obj_type = array_unique( (array) $obj_type );
454
 
455
- $current_language = $sitepress->get_current_language();
456
 
457
  if( $current_language != 'all' && in_array( 'product', $obj_type ) && substr( $taxonomy, 0, 3) == 'pa_' && isset( $wp_taxonomies[ $taxonomy ] )){
458
 
6
  private $mo_files = array();
7
  private $current_language;
8
 
9
+ /** @var woocommerce_wpml */
10
+ private $woocommerce_wpml;
11
+ /** @var Sitepress */
12
+ private $sitepress;
13
 
14
+ public $settings = array();
15
+
16
+ /**
17
+ * WCML_WC_Strings constructor.
18
+ *
19
+ * @param woocommerce_wpml $woocommerce_wpml
20
+ * @param SitePress $sitepress
21
+ */
22
+ public function __construct( woocommerce_wpml $woocommerce_wpml, SitePress $sitepress ){
23
+ $this->woocommerce_wpml = $woocommerce_wpml;
24
+ $this->sitepress = $sitepress;
25
+ }
26
+
27
+ function add_hooks(){
28
+
29
+ add_action( 'init', array( $this, 'add_on_init_hooks' ) );
30
  add_action( 'registered_taxonomy', array ( $this, 'translate_attributes_label_in_wp_taxonomies' ), 100, 3 );
31
  }
32
 
33
+ function add_on_init_hooks(){
34
+ global $pagenow;
35
 
36
+ $this->current_language = $this->sitepress->get_current_language();
37
  if( $this->current_language == 'all' ){
38
+ $this->current_language = $this->sitepress->get_default_language();
39
  }
40
 
41
  //translate attribute label
42
  add_filter('woocommerce_attribute_label',array($this,'translated_attribute_label'),10,3);
 
43
  add_filter('woocommerce_checkout_product_title',array($this,'translated_checkout_product_title'),10,2);
44
 
45
+ if ( $this->sitepress->get_wp_api()->version_compare( $this->sitepress->get_wp_api()->constant( 'WC_VERSION' ), '3.0.0', '<' ) ) {
46
+ add_filter( 'woocommerce_cart_item_name', array( $this, 'translated_cart_item_name' ), 10, 3 );
47
+ }
48
+
49
  if( is_admin() && $pagenow == 'options-permalink.php' ){
50
  add_filter( 'gettext_with_context', array( $this, 'category_base_in_strings_language' ), 99, 3 );
51
  add_action( 'admin_footer', array( $this, 'show_custom_url_base_translation_links' ) );
61
  }
62
 
63
  function translated_attribute_label($label, $name, $product_obj = false){
64
+ global $product, $sitepress_settings;
65
 
66
  $product_id = false;
67
+ $lang = $this->sitepress->get_current_language();
68
 
69
  if( isset( $_GET[ 'post' ] ) && get_post_type( $_GET[ 'post' ] ) == 'shop_order' ){
70
+ $lang = $this->sitepress->get_user_admin_language( get_current_user_id(), true );
71
  }
72
 
73
  if( $product && is_object( $product ) ){
78
  $product_id = WooCommerce_Functions_Wrapper::get_product_id( $product_obj );
79
  }
80
 
81
+ $name = $this->woocommerce_wpml->attributes->filter_attribute_name( $name, $product_id, true );
82
 
83
  if( $product_id ){
84
 
85
+ $custom_attr_translation = $this->woocommerce_wpml->attributes->get_attr_label_translations( $product_id, $lang ) ;
86
 
87
  if( $custom_attr_translation ){
88
  if( isset( $custom_attr_translation[$name] ) ){
102
 
103
  $string_language = $this->get_string_language( 'taxonomy singular name: '.$label, 'WordPress' );
104
 
105
+ if($this->sitepress->get_user_admin_language( get_current_user_id(), true ) != $string_language){
106
  $string_id = icl_get_string_id( 'taxonomy singular name: '.$label, 'WordPress' );
107
  $strings = icl_get_string_translations_by_id($string_id);
108
  if($strings){
109
+ return $strings[$this->sitepress->get_user_admin_language( get_current_user_id(), true )]['value'];
110
  }
111
  }else{
112
  return $label;
124
  return $label;
125
  }
126
 
127
+ function translated_cart_item_name( $title, $values, $cart_item_key ){
 
 
128
 
129
+ if( $values ){
130
  $parent = wp_get_post_parent_id( $values['product_id'] );
131
+ $tr_product_id = apply_filters( 'translate_object_id', $values[ 'product_id' ], 'product', true );
132
+ $trnsl_title = get_the_title( $tr_product_id );
133
 
134
+ if( $parent ){
135
  $tr_parent = apply_filters( 'translate_object_id', $parent, 'product', true );
136
  $trnsl_title = get_the_title( $tr_parent ) . ' &rarr; ' . $trnsl_title;
137
  }
160
 
161
  // Catch the default slugs for translation
162
  function translate_default_slug($translation, $text, $context, $domain) {
 
163
 
164
  if ($context == 'slug' || $context == 'default-slug') {
165
+ $wc_slug = $this->woocommerce_wpml->url_translation->get_woocommerce_product_base();
166
  if(is_admin()){
167
+ $admin_language = $this->sitepress->get_admin_language();
168
  }
169
+ $current_language = $this->sitepress->get_current_language();
170
 
171
  $strings_language = $this->get_domain_language('woocommerce');
172
 
173
  if ($text == $wc_slug && $domain == 'woocommerce' && $strings_language) {
174
+ $this->sitepress->switch_lang($strings_language);
175
  $translation = _x($text, 'URL slug', $domain);
176
+ $this->sitepress->switch_lang($current_language);
177
  if(is_admin()){
178
+ $this->sitepress->set_admin_language($admin_language);
179
  }
180
  }else{
181
  $translation = $text;
182
  }
183
 
184
  if(!is_admin()){
185
+ $this->sitepress->switch_lang($current_language);
186
  }
187
  }
188
 
209
  }
210
 
211
  function show_custom_url_base_translation_links(){
212
+
213
  $permalink_options = get_option( 'woocommerce_permalinks' );
214
 
215
+ $lang_selector = new WPML_Simple_Language_Selector( $this->sitepress );
216
 
217
  $bases = array( 'tag_base' => 'product_tag', 'category_base' => 'product_cat', 'attribute_base' => 'attribute', 'product_base' => 'product' );
218
 
221
  switch($base){
222
  case 'product_tag':
223
  $input_name = 'woocommerce_product_tag_slug';
224
+ $value = !empty( $permalink_options['tag_base'] ) ? $permalink_options['tag_base'] : $this->woocommerce_wpml->url_translation->default_product_tag_base;
225
  break;
226
  case 'product_cat':
227
  $input_name = 'woocommerce_product_category_slug';
228
+ $value = !empty( $permalink_options['category_base'] ) ? $permalink_options['category_base'] : $this->woocommerce_wpml->url_translation->default_product_category_base;
229
  break;
230
  case 'attribute':
231
  $input_name = 'woocommerce_product_attribute_slug';
242
  break;
243
  }
244
 
245
+ $language = $this->get_string_language( trim( $value, '/' ), $this->woocommerce_wpml->url_translation->url_strings_context(), $this->woocommerce_wpml->url_translation->url_string_name( $base ) );
246
 
247
  if( is_null($language) ){
248
+ $language = $this->sitepress->get_default_language();
249
  }
250
 
251
  echo $lang_selector->render( array( 'id' => $key.'_language_selector', 'name' => $key.'_language', 'selected' => $language, 'show_please_select' => false ) ); ?>
293
  }
294
 
295
  function get_domain_language( $domain ){
 
296
 
297
+ $lang_of_domain = new WPML_Language_Of_Domain( $this->sitepress );
298
  $domain_lang = $lang_of_domain->get_language( $domain );
299
 
300
  if ( $domain_lang ) {
351
  *
352
  */
353
  function filter_woocommerce_breadcrumbs( $breadcrumbs, $object ){
 
354
 
355
+ $current_language = $this->sitepress->get_current_language();
356
+ $default_language = $this->sitepress->get_default_language();
357
 
358
  if( $current_language != $default_language || $default_language != 'en' ){
359
 
361
 
362
  // If permalinks contain the shop page in the URI prepend the breadcrumb with shop
363
  // Similar to WC_Breadcrumb::prepend_shop_page
364
+ $trnsl_base = $this->woocommerce_wpml->url_translation->get_base_translation( 'product', $current_language );
365
  if( $trnsl_base['translated_base'] === '' ){
366
  $trnsl_base['translated_base'] = $trnsl_base['original_value'];
367
  }
395
  * Add notice message to users
396
  */
397
  function notice_after_woocommerce_product_options_attributes(){
 
398
 
399
+ if( isset( $_GET['post'] ) && $this->sitepress->get_default_language() != $this->sitepress->get_current_language() ){
400
+ $original_product_id = apply_filters( 'translate_object_id', $_GET['post'], 'product', true, $this->sitepress->get_default_language() );
401
 
402
  printf( '<p>'.__('In order to edit custom attributes you need to use the <a href="%s">custom product translation editor</a>', 'woocommerce-multilingual').'</p>', admin_url('admin.php?page=wpml-wcml&tab=products&prid='.$original_product_id ) );
403
  }
404
  }
405
 
406
  function translate_attribute_taxonomies_labels( $attribute_taxonomies ){
 
407
 
408
  if( is_admin() && !wpml_is_ajax() ){
409
 
410
  foreach( $attribute_taxonomies as $key => $attribute_taxonomy ){
411
  $string_language = $this->get_string_language( $attribute_taxonomy->attribute_name, 'WordPress', 'taxonomy singular name: '.$attribute_taxonomy->attribute_name );
412
 
413
+ if( $this->sitepress->get_current_language() == $string_language ) continue;
414
 
415
  $string_id = icl_get_string_id( $attribute_taxonomy->attribute_name, 'WordPress', 'taxonomy singular name: '.$attribute_taxonomy->attribute_name );
416
  $strings = icl_get_string_translations_by_id( $string_id );
417
 
418
+ if($strings && isset($strings[$this->sitepress->get_current_language()])) {
419
+ $attribute_taxonomies[$key]->attribute_label = $strings[$this->sitepress->get_current_language()]['value'];
420
  }
421
  }
422
 
427
  }
428
 
429
  function get_translation_from_woocommerce_mo_file( $string, $language, $return_original = true ){
 
430
 
431
  $original_string = $string;
432
 
438
 
439
  if ( ! isset( $this->mo_files[ $language ] ) ) {
440
  $mo = new MO();
441
+ $mo_file = WP_LANG_DIR . '/plugins/woocommerce-' . $this->sitepress->get_locale( $language ) . '.mo';
442
  if( !file_exists( $mo_file ) ){
443
  return $return_original ? $string : null;
444
  }
463
  }
464
 
465
  function translate_attributes_label_in_wp_taxonomies( $taxonomy, $obj_type, $args ){
466
+ global $wp_taxonomies;
467
  $obj_type = array_unique( (array) $obj_type );
468
 
469
+ $current_language = $this->sitepress->get_current_language();
470
 
471
  if( $current_language != 'all' && in_array( 'product', $obj_type ) && substr( $taxonomy, 0, 3) == 'pa_' && isset( $wp_taxonomies[ $taxonomy ] )){
472
 
inc/class-woocommerce-wpml.php CHANGED
@@ -91,7 +91,8 @@ class woocommerce_wpml {
91
  add_action('init', array($this, 'init'),2);
92
 
93
  if( defined( 'ICL_SITEPRESS_VERSION' ) && !ICL_PLUGIN_INACTIVE && class_exists( 'SitePress' ) ){
94
- $this->cs_templates = new WCML_Currency_Switcher_Templates( $this );
 
95
  $this->cs_templates->init_hooks();
96
  }
97
 
@@ -111,6 +112,7 @@ class woocommerce_wpml {
111
  if ( is_null( self::$_instance ) ) {
112
  self::$_instance = new self();
113
  $woocommerce_wpml = self::$_instance;
 
114
  }
115
 
116
  return self::$_instance;
@@ -136,7 +138,7 @@ class woocommerce_wpml {
136
  return false;
137
  }
138
 
139
- $this->compatibility = new WCML_Compatibility( $sitepress, $this, $wpdb );
140
 
141
  $actions_that_need_mc = array(
142
  'save-mc-options',
@@ -151,6 +153,9 @@ class woocommerce_wpml {
151
  'wcml_delete_currency_switcher',
152
  'wcml_currencies_order'
153
  );
 
 
 
154
  if($this->settings['enable_multi_currency'] == WCML_MULTI_CURRENCIES_INDEPENDENT
155
  || ( isset($_GET['page']) && $_GET['page'] == 'wpml-wcml' && isset($_GET['tab']) && $_GET['tab'] == 'multi-currency' )
156
  || ( isset( $_POST[ 'action' ] ) && in_array( $_POST[ 'action' ], $actions_that_need_mc ) )
@@ -174,6 +179,7 @@ class woocommerce_wpml {
174
  }
175
 
176
  $this->sync_product_data = new WCML_Synchronize_Product_Data( $this, $sitepress, $wpdb );
 
177
  $this->duplicate_product = new WCML_WC_Admin_Duplicate_Product( $this, $sitepress, $wpdb );
178
  $this->products = new WCML_Products( $this, $sitepress, $wpdb );
179
  $this->products->add_hooks();
@@ -181,8 +187,10 @@ class woocommerce_wpml {
181
  $this->emails = new WCML_Emails( $this, $sitepress );
182
  $this->terms = new WCML_Terms( $this, $sitepress, $wpdb );
183
  $this->attributes = new WCML_Attributes( $this, $sitepress, $wpdb );
 
184
  $this->orders = new WCML_Orders( $this, $sitepress );
185
- $this->strings = new WCML_WC_Strings;
 
186
  $this->shipping = new WCML_WC_Shipping( $sitepress );
187
  $this->shipping->add_hooks();
188
  $this->gateways = new WCML_WC_Gateways( $this, $sitepress );
@@ -192,6 +200,7 @@ class woocommerce_wpml {
192
  $this->endpoints = new WCML_Endpoints( $this );
193
  $this->requests = new WCML_Requests;
194
  $this->cart = new WCML_Cart( $this, $sitepress, $woocommerce );
 
195
  $this->coupons = new WCML_Coupons( $this, $sitepress );
196
  $this->locale = new WCML_Locale( $this, $sitepress );
197
  $this->media = new WCML_Media( $this, $sitepress, $wpdb );
@@ -200,6 +209,11 @@ class woocommerce_wpml {
200
  $this->reports = new WCML_Reports;
201
  $this->wcml_products_screen = new WCML_Products_Screen_Options();
202
  $this->wcml_products_screen->init();
 
 
 
 
 
203
 
204
  new WCML_Ajax_Setup( $sitepress );
205
  new WCML_Fix_Copied_Custom_Fields_WPML353();
@@ -217,6 +231,9 @@ class woocommerce_wpml {
217
  if( is_admin() ){
218
  $taxonomy_translation_link_filters = new WCML_Taxonomy_Translation_Link_Filters( $this->attributes );
219
  $taxonomy_translation_link_filters->add_filters();
 
 
 
220
  }
221
  }
222
 
@@ -231,6 +248,7 @@ class woocommerce_wpml {
231
  'currency_options' => array(),
232
  'currency_switcher_product_visibility' => 1,
233
  'dismiss_tm_warning' => 0,
 
234
  'cart_sync' => array(
235
  'lang_switch' => WCML_CART_SYNC,
236
  'currency_switch' => WCML_CART_SYNC
@@ -317,4 +335,10 @@ class woocommerce_wpml {
317
 
318
  }
319
 
 
 
 
 
 
 
320
  }
91
  add_action('init', array($this, 'init'),2);
92
 
93
  if( defined( 'ICL_SITEPRESS_VERSION' ) && !ICL_PLUGIN_INACTIVE && class_exists( 'SitePress' ) ){
94
+ $this->cs_properties = new WCML_Currency_Switcher_Properties();
95
+ $this->cs_templates = new WCML_Currency_Switcher_Templates( $this, $sitepress->get_wp_api() );
96
  $this->cs_templates->init_hooks();
97
  }
98
 
112
  if ( is_null( self::$_instance ) ) {
113
  self::$_instance = new self();
114
  $woocommerce_wpml = self::$_instance;
115
+ do_action( 'wcml_loaded', $woocommerce_wpml );
116
  }
117
 
118
  return self::$_instance;
138
  return false;
139
  }
140
 
141
+ $this->compatibility = new WCML_Compatibility( $sitepress, $this, $wpdb, new WPML_Element_Translation_Package );
142
 
143
  $actions_that_need_mc = array(
144
  'save-mc-options',
153
  'wcml_delete_currency_switcher',
154
  'wcml_currencies_order'
155
  );
156
+
157
+ $this->cart = new WCML_Cart( $this, $sitepress, $woocommerce );
158
+
159
  if($this->settings['enable_multi_currency'] == WCML_MULTI_CURRENCIES_INDEPENDENT
160
  || ( isset($_GET['page']) && $_GET['page'] == 'wpml-wcml' && isset($_GET['tab']) && $_GET['tab'] == 'multi-currency' )
161
  || ( isset( $_POST[ 'action' ] ) && in_array( $_POST[ 'action' ], $actions_that_need_mc ) )
179
  }
180
 
181
  $this->sync_product_data = new WCML_Synchronize_Product_Data( $this, $sitepress, $wpdb );
182
+ $this->sync_product_data->add_hooks();
183
  $this->duplicate_product = new WCML_WC_Admin_Duplicate_Product( $this, $sitepress, $wpdb );
184
  $this->products = new WCML_Products( $this, $sitepress, $wpdb );
185
  $this->products->add_hooks();
187
  $this->emails = new WCML_Emails( $this, $sitepress );
188
  $this->terms = new WCML_Terms( $this, $sitepress, $wpdb );
189
  $this->attributes = new WCML_Attributes( $this, $sitepress, $wpdb );
190
+ $this->attributes->add_hooks();
191
  $this->orders = new WCML_Orders( $this, $sitepress );
192
+ $this->strings = new WCML_WC_Strings( $this, $sitepress );
193
+ $this->strings->add_hooks();
194
  $this->shipping = new WCML_WC_Shipping( $sitepress );
195
  $this->shipping->add_hooks();
196
  $this->gateways = new WCML_WC_Gateways( $this, $sitepress );
200
  $this->endpoints = new WCML_Endpoints( $this );
201
  $this->requests = new WCML_Requests;
202
  $this->cart = new WCML_Cart( $this, $sitepress, $woocommerce );
203
+ $this->cart->add_hooks();
204
  $this->coupons = new WCML_Coupons( $this, $sitepress );
205
  $this->locale = new WCML_Locale( $this, $sitepress );
206
  $this->media = new WCML_Media( $this, $sitepress, $wpdb );
209
  $this->reports = new WCML_Reports;
210
  $this->wcml_products_screen = new WCML_Products_Screen_Options();
211
  $this->wcml_products_screen->init();
212
+ $this->cart_sync_warnings = new WCML_Cart_Sync_Warnings( $this, $sitepress );
213
+ $this->cart_sync_warnings->add_hooks();
214
+
215
+ $payment_method_filter = new WCML_Payment_Method_Filter();
216
+ $payment_method_filter->add_hooks();
217
 
218
  new WCML_Ajax_Setup( $sitepress );
219
  new WCML_Fix_Copied_Custom_Fields_WPML353();
231
  if( is_admin() ){
232
  $taxonomy_translation_link_filters = new WCML_Taxonomy_Translation_Link_Filters( $this->attributes );
233
  $taxonomy_translation_link_filters->add_filters();
234
+
235
+ $tp_support = new WCML_TP_Support( $this, $wpdb , new WPML_Element_Translation_Package );
236
+ $tp_support->add_hooks();
237
  }
238
  }
239
 
248
  'currency_options' => array(),
249
  'currency_switcher_product_visibility' => 1,
250
  'dismiss_tm_warning' => 0,
251
+ 'dismiss_cart_warning' => 0,
252
  'cart_sync' => array(
253
  'lang_switch' => WCML_CART_SYNC,
254
  'currency_switch' => WCML_CART_SYNC
335
 
336
  }
337
 
338
+ /**
339
+ * @return array
340
+ */
341
+ function get_wc_query_vars() {
342
+ return WooCommerce::instance()->query->query_vars;
343
+ }
344
  }
inc/currencies/class-wcml-admin-currency-selector.php CHANGED
@@ -1,67 +1,70 @@
1
  <?php
2
 
3
- class WCML_Admin_Currency_Selector{
4
- private $woocommerce_wpml;
5
 
6
- public function __construct(){
7
 
8
- if( is_admin() ){
9
- add_filter('init', array($this, 'admin_currency_selector_init') );
10
- }
11
 
12
 
13
- }
14
 
15
- public function admin_currency_selector_init(){
16
- global $pagenow, $woocommerce_wpml;
17
 
18
- $this->woocommerce_wpml =& $woocommerce_wpml;
19
 
20
- //dashboard status screen
21
- if ( current_user_can( 'view_woocommerce_reports' ) || current_user_can( 'manage_woocommerce' ) || current_user_can( 'publish_shop_orders' ) ) {
22
- $this->set_dashboard_currency();
23
 
24
- if ( version_compare( WOOCOMMERCE_VERSION, '2.4', '<' ) && $pagenow == 'index.php' ) {
25
- add_action( 'admin_footer', array($this, 'show_dashboard_currency_selector') );
26
- } else {
27
- add_action( 'woocommerce_after_dashboard_status_widget', array($this, 'show_dashboard_currency_selector') );
28
- }
 
 
 
29
 
30
- add_action( 'wp_ajax_wcml_dashboard_set_currency', array($this, 'set_dashboard_currency_ajax') );
31
 
32
- add_filter( 'woocommerce_currency_symbol', array($this, 'filter_dashboard_currency_symbol') );
33
- }
34
 
35
- }
36
 
37
- /*
38
- * Add currency drop-down on dashboard page ( WooCommerce status block )
39
- */
40
- public function show_dashboard_currency_selector(){
41
 
42
- $current_dashboard_currency = $this->get_cookie_dashboard_currency();
43
 
44
- $wc_currencies = get_woocommerce_currencies();
45
- $order_currencies = $this->woocommerce_wpml->multi_currency->orders->get_orders_currencies();
46
- ?>
47
  <select id="dropdown_dashboard_currency" style="display: none; margin : 10px; ">
48
- <?php if(empty($order_currencies)): ?>
49
- <option value=""><?php _e('Currency - no orders found', 'woocommerce-multilingual') ?></option>
50
- <?php else: ?>
51
- <?php foreach($order_currencies as $currency => $count ): ?>
52
 
53
- <option value="<?php echo $currency ?>" <?php echo $current_dashboard_currency == $currency ? 'selected="selected"':''; ?>>
54
- <?php echo $wc_currencies[$currency]; ?>
55
  </option>
56
 
57
- <?php endforeach; ?>
58
- <?php endif; ?>
59
  </select>
60
- <?php
61
 
62
- $wcml_dashboard_set_currency_nonce = wp_create_nonce( 'dashboard_set_currency' );
63
 
64
- wc_enqueue_js( "
65
 
66
  jQuery(document).ready(function(){
67
 
@@ -79,7 +82,7 @@ class WCML_Admin_Currency_Selector{
79
  data: {
80
  action: 'wcml_dashboard_set_currency',
81
  currency: jQuery('#dropdown_dashboard_currency').val(),
82
- wcml_nonce: '".$wcml_dashboard_set_currency_nonce."'
83
  },
84
  success: function( response ){
85
  if(typeof response.error !== 'undefined'){
@@ -90,77 +93,75 @@ class WCML_Admin_Currency_Selector{
90
  }
91
  })
92
  });
93
- ");
94
- }
95
-
96
- public function set_dashboard_currency_ajax(){
97
-
98
- $nonce = filter_input( INPUT_POST, 'wcml_nonce', FILTER_SANITIZE_FULL_SPECIAL_CHARS );
99
- if(!$nonce || !wp_verify_nonce($nonce, 'dashboard_set_currency')){
100
- echo json_encode(array('error' => __('Invalid nonce', 'woocommerce-multilingual')));
101
- die();
102
- }
103
-
104
- $this->set_dashboard_currency(filter_input( INPUT_POST, 'currency', FILTER_SANITIZE_FULL_SPECIAL_CHARS ));
105
-
106
- die();
107
- }
108
-
109
- /*
110
- * Set dashboard currency cookie
111
- */
112
- public function set_dashboard_currency( $currency_code = false ){
113
-
114
- if( !$currency_code && !headers_sent()){
115
- $order_currencies = $this->woocommerce_wpml->multi_currency->orders->get_orders_currencies();
116
- $currency_code = get_woocommerce_currency();
117
- if(!isset($order_currencies[$currency_code])){
118
- foreach( $order_currencies as $currency_code => $count ){
119
- $currency_code = $currency_code;
120
- break;
121
- }
122
- }
123
-
124
- setcookie('_wcml_dashboard_currency', $currency_code , time() + 86400, COOKIEPATH, COOKIE_DOMAIN);
125
- }
126
- }
127
-
128
- /*
129
- * Get dashboard currency cookie
130
- *
131
- * @return string
132
- *
133
- */
134
- public function get_cookie_dashboard_currency(){
135
-
136
- if( isset( $_COOKIE [ '_wcml_dashboard_currency' ] ) ){
137
- $currency = $_COOKIE[ '_wcml_dashboard_currency' ];
138
- }else{
139
- $currency = get_woocommerce_currency();
140
- }
141
-
142
- return $currency;
143
- }
144
-
145
- /*
146
- * Filter currency symbol on dashboard page
147
- *
148
- * @param string $currency Currency code
149
- *
150
- * @return string
151
- *
152
- */
153
- public function filter_dashboard_currency_symbol( $currency ){
154
- global $pagenow;
155
-
156
- remove_filter( 'woocommerce_currency_symbol', array( $this, 'filter_dashboard_currency_symbol' ) );
157
- if( isset( $_COOKIE [ '_wcml_dashboard_currency' ] ) && $pagenow == 'index.php' ){
158
- $currency = get_woocommerce_currency_symbol( $_COOKIE [ '_wcml_dashboard_currency' ] );
159
- }
160
- add_filter( 'woocommerce_currency_symbol', array( $this, 'filter_dashboard_currency_symbol' ) );
161
-
162
- return $currency;
163
- }
164
 
165
 
166
  }
1
  <?php
2
 
3
+ class WCML_Admin_Currency_Selector {
4
+ private $woocommerce_wpml;
5
 
6
+ public function __construct() {
7
 
8
+ if ( is_admin() ) {
9
+ add_filter( 'init', array( $this, 'admin_currency_selector_init' ) );
10
+ }
11
 
12
 
13
+ }
14
 
15
+ public function admin_currency_selector_init() {
16
+ global $pagenow, $woocommerce_wpml;
17
 
18
+ $this->woocommerce_wpml =& $woocommerce_wpml;
19
 
20
+ //dashboard status screen
21
+ if ( current_user_can( 'view_woocommerce_reports' ) || current_user_can( 'manage_woocommerce' ) || current_user_can( 'publish_shop_orders' ) ) {
22
+ $this->set_dashboard_currency();
23
 
24
+ if ( version_compare( WOOCOMMERCE_VERSION, '2.4', '<' ) && $pagenow == 'index.php' ) {
25
+ add_action( 'admin_footer', array( $this, 'show_dashboard_currency_selector' ) );
26
+ } else {
27
+ add_action( 'woocommerce_after_dashboard_status_widget', array(
28
+ $this,
29
+ 'show_dashboard_currency_selector'
30
+ ) );
31
+ }
32
 
33
+ add_action( 'wp_ajax_wcml_dashboard_set_currency', array( $this, 'set_dashboard_currency_ajax' ) );
34
 
35
+ add_filter( 'woocommerce_currency_symbol', array( $this, 'filter_dashboard_currency_symbol' ) );
36
+ }
37
 
38
+ }
39
 
40
+ /*
41
+ * Add currency drop-down on dashboard page ( WooCommerce status block )
42
+ */
43
+ public function show_dashboard_currency_selector() {
44
 
45
+ $current_dashboard_currency = $this->get_cookie_dashboard_currency();
46
 
47
+ $wc_currencies = get_woocommerce_currencies();
48
+ $order_currencies = $this->woocommerce_wpml->multi_currency->orders->get_orders_currencies();
49
+ ?>
50
  <select id="dropdown_dashboard_currency" style="display: none; margin : 10px; ">
51
+ <?php if ( empty( $order_currencies ) ): ?>
52
+ <option value=""><?php _e( 'Currency - no orders found', 'woocommerce-multilingual' ) ?></option>
53
+ <?php else: ?>
54
+ <?php foreach ( $order_currencies as $currency => $count ): ?>
55
 
56
+ <option value="<?php echo $currency ?>" <?php echo $current_dashboard_currency == $currency ? 'selected="selected"' : ''; ?>>
57
+ <?php echo $wc_currencies[ $currency ]; ?>
58
  </option>
59
 
60
+ <?php endforeach; ?>
61
+ <?php endif; ?>
62
  </select>
63
+ <?php
64
 
65
+ $wcml_dashboard_set_currency_nonce = wp_create_nonce( 'dashboard_set_currency' );
66
 
67
+ wc_enqueue_js( "
68
 
69
  jQuery(document).ready(function(){
70
 
82
  data: {
83
  action: 'wcml_dashboard_set_currency',
84
  currency: jQuery('#dropdown_dashboard_currency').val(),
85
+ wcml_nonce: '" . $wcml_dashboard_set_currency_nonce . "'
86
  },
87
  success: function( response ){
88
  if(typeof response.error !== 'undefined'){
93
  }
94
  })
95
  });
96
+ " );
97
+ }
98
+
99
+ public function set_dashboard_currency_ajax() {
100
+
101
+ $nonce = filter_input( INPUT_POST, 'wcml_nonce', FILTER_SANITIZE_FULL_SPECIAL_CHARS );
102
+ if ( ! $nonce || ! wp_verify_nonce( $nonce, 'dashboard_set_currency' ) ) {
103
+ echo json_encode( array( 'error' => __( 'Invalid nonce', 'woocommerce-multilingual' ) ) );
104
+ die();
105
+ }
106
+
107
+ $this->set_dashboard_currency( filter_input( INPUT_POST, 'currency', FILTER_SANITIZE_FULL_SPECIAL_CHARS ) );
108
+
109
+ die();
110
+ }
111
+
112
+ /*
113
+ * Set dashboard currency cookie
114
+ * @param string $currency_code
115
+ */
116
+ public function set_dashboard_currency( $currency_code = '' ) {
117
+
118
+ if ( ! $currency_code && ! headers_sent() ) {
119
+ $order_currencies = $this->woocommerce_wpml->multi_currency->orders->get_orders_currencies();
120
+ $currency_code = get_woocommerce_currency();
121
+ if ( ! isset( $order_currencies[ $currency_code ] ) ) {
122
+ $currency_code = key( $order_currencies );
123
+ }
124
+ }
125
+
126
+ setcookie( '_wcml_dashboard_currency', $currency_code, time() + DAY_IN_SECONDS, COOKIEPATH, COOKIE_DOMAIN );
127
+ }
128
+
129
+ /*
130
+ * Get dashboard currency cookie
131
+ *
132
+ * @return string
133
+ *
134
+ */
135
+ public function get_cookie_dashboard_currency() {
136
+
137
+ if ( isset( $_COOKIE ['_wcml_dashboard_currency'] ) ) {
138
+ $currency = $_COOKIE['_wcml_dashboard_currency'];
139
+ } else {
140
+ $currency = get_woocommerce_currency();
141
+ }
142
+
143
+ return $currency;
144
+ }
145
+
146
+ /*
147
+ * Filter currency symbol on dashboard page
148
+ *
149
+ * @param string $currency Currency code
150
+ *
151
+ * @return string
152
+ *
153
+ */
154
+ public function filter_dashboard_currency_symbol( $currency ) {
155
+ global $pagenow;
156
+
157
+ remove_filter( 'woocommerce_currency_symbol', array( $this, 'filter_dashboard_currency_symbol' ) );
158
+ if ( isset( $_COOKIE ['_wcml_dashboard_currency'] ) && $pagenow == 'index.php' ) {
159
+ $currency = get_woocommerce_currency_symbol( $_COOKIE ['_wcml_dashboard_currency'] );
160
+ }
161
+ add_filter( 'woocommerce_currency_symbol', array( $this, 'filter_dashboard_currency_symbol' ) );
162
+
163
+ return $currency;
164
+ }
 
 
165
 
166
 
167
  }
inc/currencies/class-wcml-multi-currency-orders.php CHANGED
@@ -1,215 +1,228 @@
1
  <?php
2
 
3
- class WCML_Multi_Currency_Orders{
4
 
5
- /**
6
- * @var WCML_Multi_Currency
7
- */
8
- private $multi_currency;
9
 
10
- public function __construct( &$multi_currency, &$woocommerce_wpml ){
11
- $this->multi_currency =& $multi_currency;
12
- $this->woocommerce_wpml =& $woocommerce_wpml;
13
 
14
- if( is_admin() ){
15
- add_filter( 'init', array( $this, 'orders_init' ) );
16
- }
 
 
 
17
 
18
- add_action( 'woocommerce_view_order', array( $this, 'show_price_in_client_currency' ), 9 );
19
- }
20
 
21
- public function orders_init(){
22
- global $wp;
23
 
24
- add_action( 'restrict_manage_posts', array($this, 'show_orders_currencies_selector') );
25
- $wp->add_query_var( '_order_currency' );
26
 
27
- add_filter( 'posts_join', array($this, 'filter_orders_by_currency_join') );
28
- add_filter( 'posts_where', array($this, 'filter_orders_by_currency_where') );
29
 
30
- // override current currency value when viewing order in admin
31
- add_filter( 'woocommerce_currency_symbol', array($this, '_use_order_currency_symbol') );
 
32
 
33
- //new order currency/language switchers
34
- add_action( 'woocommerce_process_shop_order_meta', array($this, 'set_order_currency_on_update'), 10, 2 );
35
- add_action( 'woocommerce_order_actions_start', array($this, 'show_order_currency_selector') );
36
 
37
- add_filter( 'woocommerce_ajax_order_item', array($this, 'filter_ajax_order_item'), 10, 2 );
38
 
39
- add_action( 'wp_ajax_wcml_order_set_currency', array($this, 'set_order_currency_on_ajax_update') );
 
 
 
 
40
 
41
- //dashboard status screen
42
- if ( current_user_can( 'view_woocommerce_reports' ) || current_user_can( 'manage_woocommerce' ) || current_user_can( 'publish_shop_orders' ) ) {
43
- //filter query to get order by status
44
- add_filter( 'query', array($this, 'filter_order_status_query') );
45
- }
46
 
47
- add_action( 'woocommerce_email_before_order_table', array($this, 'fix_currency_before_order_email') );
48
- add_action( 'woocommerce_email_after_order_table', array($this, 'fix_currency_after_order_email') );
 
49
 
50
- if( is_admin() ){
51
- add_filter( 'woocommerce_order_get_currency', array( $this, 'get_currency_for_new_order' ), 10, 2 );
52
- }
53
 
54
- }
 
55
 
56
- public function get_orders_currencies(){
57
- global $wpdb;
 
 
 
58
 
59
- $currencies = array();
60
 
61
- $results = $wpdb->get_results("
62
  SELECT m.meta_value AS currency, COUNT(m.post_id) AS c
63
  FROM {$wpdb->posts} p JOIN {$wpdb->postmeta} m ON p.ID = m.post_id
64
  WHERE meta_key='_order_currency' AND p.post_type='shop_order'
65
  GROUP BY meta_value
66
- ");
 
 
 
 
67
 
68
- foreach($results as $row){
69
- $currencies[$row->currency] = intval($row->c);
70
- }
71
 
72
- return $currencies;
73
 
74
- }
75
 
76
- public function show_orders_currencies_selector(){
77
- global $wp_query, $typenow;
78
 
79
- if($typenow != 'shop_order') return false;
 
 
80
 
81
- $order_currencies = $this->get_orders_currencies();
82
- $currencies = get_woocommerce_currencies();
83
- ?>
84
  <select id="dropdown_shop_order_currency" name="_order_currency">
85
  <option value=""><?php _e( 'Show all currencies', 'woocommerce-multilingual' ) ?></option>
86
- <?php foreach($order_currencies as $currency => $count): ?>
87
  <option value="<?php echo $currency ?>" <?php
88
- if ( isset( $wp_query->query['_order_currency'] ) ) selected( $currency, $wp_query->query['_order_currency'] );
89
- ?> ><?php printf("%s (%s) (%d)", $currencies[$currency], get_woocommerce_currency_symbol($currency), $count) ?></option>
90
- <?php endforeach; ?>
 
 
91
  </select>
92
- <?php
93
-
94
- }
95
 
96
- public function filter_orders_by_currency_join($join){
97
- global $wp_query, $typenow, $wpdb;
98
-
99
- if($typenow == 'shop_order' &&!empty($wp_query->query['_order_currency'])){
100
- $join .= " JOIN {$wpdb->postmeta} wcml_pm ON {$wpdb->posts}.ID = wcml_pm.post_id AND wcml_pm.meta_key='_order_currency'";
101
- }
102
 
103
- return $join;
104
- }
105
 
106
- public function filter_orders_by_currency_where($where){
107
- global $wp_query, $typenow;
 
108
 
109
- if($typenow == 'shop_order' &&!empty($wp_query->query['_order_currency'])){
110
- $where .= " AND wcml_pm.meta_value = '" . esc_sql($wp_query->query['_order_currency']) . "'";
111
- }
112
 
113
- return $where;
114
- }
115
 
116
- public function _use_order_currency_symbol($currency){
 
 
117
 
118
- if(!function_exists('get_current_screen')){
119
- return $currency;
120
- }
121
 
122
- $current_screen = get_current_screen();
123
 
124
- remove_filter('woocommerce_currency_symbol', array($this, '_use_order_currency_symbol'));
125
- if( !empty($current_screen) && $current_screen->id == 'shop_order' ){
 
126
 
127
- $the_order = new WC_Order( get_the_ID() );
128
- if( $the_order ){
129
- $order_currency = WooCommerce_Functions_Wrapper::get_order_currency( $the_order );
130
 
131
- if( !$order_currency && isset( $_COOKIE[ '_wcml_order_currency' ] ) ){
132
- $order_currency = $_COOKIE[ '_wcml_order_currency' ];
133
- }
134
 
135
- $currency = get_woocommerce_currency_symbol( $order_currency );
136
- }
 
137
 
138
- }elseif(
139
- (
140
- isset( $_POST['action'] ) &&
141
- in_array( $_POST['action'], array(
142
- 'woocommerce_add_order_item',
143
- 'woocommerce_calc_line_taxes',
144
- 'woocommerce_save_order_items' )
145
- ) )
146
- || (
147
- isset( $_GET[ 'action' ] ) &&
148
- $_GET[ 'action' ] == 'woocommerce_json_search_products_and_variations'
149
- )
150
- ){
151
 
 
 
152
 
153
- if( isset( $_COOKIE[ '_wcml_order_currency' ] ) ){
154
- $currency = get_woocommerce_currency_symbol($_COOKIE[ '_wcml_order_currency' ]);
155
- }elseif( isset( $_POST[ 'order_id' ] ) && $order_currency = get_post_meta( sanitize_text_field( $_POST[ 'order_id' ] ), '_order_currency', true ) ){
156
- $currency = get_woocommerce_currency_symbol( $order_currency );
157
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
158
 
159
- if( isset( $_SERVER[ 'HTTP_REFERER' ] ) ){
160
- $arg = parse_url( $_SERVER[ 'HTTP_REFERER' ] );
161
- if( isset( $arg[ 'query' ] ) ){
162
- parse_str( $arg[ 'query' ], $arg );
163
- if( isset( $arg[ 'post' ] ) && get_post_type( $arg[ 'post' ] ) == 'shop_order' ){
164
- $currency = get_woocommerce_currency_symbol( get_post_meta( $arg[ 'post' ], '_order_currency', true ) );
165
- }
166
- }
167
- }
168
- }
169
 
170
- add_filter('woocommerce_currency_symbol', array($this, '_use_order_currency_symbol'));
171
 
172
- return $currency;
173
- }
174
 
175
- public function set_order_currency_on_update( $post_id, $post ){
176
 
177
- if( isset( $_POST['wcml_shop_order_currency'] ) ){
178
- update_post_meta( $post_id, '_order_currency', filter_input( INPUT_POST, 'wcml_shop_order_currency', FILTER_SANITIZE_FULL_SPECIAL_CHARS ) );
179
- }
180
 
181
- }
182
 
183
- public function show_order_currency_selector($order_id){
184
- if( !get_post_meta( $order_id, '_order_currency') ){
185
 
186
- $current_order_currency = $this->get_order_currency_cookie();
187
 
188
- $wc_currencies = get_woocommerce_currencies();
189
- $currencies = $this->multi_currency->get_currency_codes();
190
 
191
- ?>
192
  <li class="wide">
193
- <label><?php _e('Order currency:', 'woocommerce-multilingual'); ?></label>
194
  <select id="dropdown_shop_order_currency" name="wcml_shop_order_currency">
195
 
196
- <?php foreach($currencies as $currency): ?>
197
 
198
- <option value="<?php echo $currency ?>" <?php echo $current_order_currency == $currency ? 'selected="selected"':''; ?>><?php echo $wc_currencies[$currency]; ?></option>
199
 
200
- <?php endforeach; ?>
201
 
202
  </select>
203
  </li>
204
- <?php
205
- $wcml_order_set_currency_nonce = wp_create_nonce( 'set_order_currency' );
206
 
207
- wc_enqueue_js( "
208
  var order_currency_current_value = jQuery('#dropdown_shop_order_currency option:selected').val();
209
 
210
  jQuery('#dropdown_shop_order_currency').on('change', function(){
211
 
212
- if(confirm('" . esc_js(__("All the products will be removed from the current order in order to change the currency", 'woocommerce-multilingual')). "')){
213
  jQuery.ajax({
214
  url: ajaxurl,
215
  type: 'post',
@@ -217,7 +230,7 @@ class WCML_Multi_Currency_Orders{
217
  data: {
218
  action: 'wcml_order_set_currency',
219
  currency: jQuery('#dropdown_shop_order_currency option:selected').val(),
220
- wcml_nonce: '".$wcml_order_set_currency_nonce."'
221
  },
222
  success: function( response ){
223
  if(typeof response.error !== 'undefined'){
@@ -234,140 +247,144 @@ class WCML_Multi_Currency_Orders{
234
 
235
  });
236
 
237
- ");
238
 
239
- }
240
 
241
- }
242
 
243
- public function filter_ajax_order_item( $item, $item_id ){
244
- if( !get_post_meta( $_POST['order_id'], '_order_currency') ){
245
- $order_currency = $this->get_order_currency_cookie();
246
- }else{
247
- $order_currency = get_post_meta( $_POST['order_id'], '_order_currency', true);
248
- }
249
 
250
- $original_product_id = $this->woocommerce_wpml->products->get_original_product_id( sanitize_text_field( $_POST['item_to_add'][ 0 ] ) );
251
- $custom_price = get_post_meta( $original_product_id, '_price_'.$order_currency, true );
252
 
253
- if( !isset( $this->multi_currency->prices ) ){
254
- $this->multi_currency->prices = new WCML_Multi_Currency_Prices( $this->multi_currency );
255
- $this->multi_currency->prices->prices_init();
256
- }
257
 
258
- if( $custom_price ){
259
- $item['line_subtotal'] = $custom_price;
260
- $item['line_total'] = $custom_price;
261
- }else{
262
- $item['line_subtotal'] = $this->multi_currency->prices->raw_price_filter( $item['line_subtotal'], $order_currency );
263
- $item['line_total'] = $this->multi_currency->prices->raw_price_filter( $item['line_total'], $order_currency );
264
- }
265
 
266
- wc_update_order_item_meta( $item_id, '_line_subtotal', $item['line_subtotal'] );
267
- $item['line_subtotal_tax'] = $this->multi_currency->prices->convert_price_amount( $item['line_subtotal_tax'], $order_currency );
268
- wc_update_order_item_meta( $item_id, '_line_subtotal_tax', $item['line_subtotal_tax'] );
269
- wc_update_order_item_meta( $item_id, '_line_total', $item['line_total'] );
270
- $item['line_tax'] = $this->multi_currency->prices->convert_price_amount( $item['line_tax'], $order_currency );
271
- wc_update_order_item_meta( $item_id, '_line_tax', $item['line_tax'] );
272
 
273
- return $item;
274
- }
275
 
276
- public function get_order_currency_cookie(){
277
 
278
- if( isset( $_COOKIE[ '_wcml_order_currency' ] ) ){
279
- return $_COOKIE['_wcml_order_currency'] ;
280
- }else{
281
- return get_option('woocommerce_currency');
282
- }
283
 
284
- }
285
 
286
- public function set_order_currency_on_ajax_update(){
287
- $nonce = filter_input( INPUT_POST, 'wcml_nonce', FILTER_SANITIZE_FULL_SPECIAL_CHARS );
288
- if(!$nonce || !wp_verify_nonce($nonce, 'set_order_currency')){
289
- echo json_encode(array('error' => __('Invalid nonce', 'woocommerce-multilingual')));
290
- die();
291
- }
292
- $currency = filter_input( INPUT_POST, 'currency', FILTER_SANITIZE_FULL_SPECIAL_CHARS );
293
 
294
- setcookie('_wcml_order_currency', $currency, time() + 86400, COOKIEPATH, COOKIE_DOMAIN);
295
 
296
- $return['currency'] = $currency;
297
 
298
- echo json_encode($return);
299
 
300
- die();
301
- }
302
 
303
- /*
304
- * Filter status query
305
- *
306
- * @param string $query
307
- *
308
- * @return string
309
- *
310
- */
311
- public function filter_order_status_query( $query ){
312
- global $pagenow,$wpdb;
313
 
314
- if( $pagenow == 'index.php' ){
315
- $sql = "SELECT post_status, COUNT( * ) AS num_posts FROM {$wpdb->posts} WHERE post_type = 'shop_order' GROUP BY post_status";
316
 
317
- if( $query == $sql){
318
 
319
- $currency = $this->multi_currency->admin_currency_selector->get_cookie_dashboard_currency();
320
- $query = "SELECT post_status, COUNT( * ) AS num_posts FROM {$wpdb->posts}
321
  WHERE post_type = 'shop_order' AND ID IN
322
  ( SELECT order_currency.post_id FROM {$wpdb->postmeta} AS order_currency
323
  WHERE order_currency.meta_key = '_order_currency'
324
  AND order_currency.meta_value = '{$currency}' )
325
  GROUP BY post_status";
326
 
327
- }
328
- }
 
 
 
329
 
330
- return $query;
331
- }
332
 
333
- // handle currency in order emails before handled in woocommerce
334
- public function fix_currency_before_order_email($order){
335
 
336
- $order_currency = WooCommerce_Functions_Wrapper::get_order_currency( $order );
 
 
337
 
338
- if( !$order_currency ) return;
 
 
339
 
340
- $this->order_currency = $order_currency;
341
- add_filter('woocommerce_currency', array($this, '_override_woocommerce_order_currency_temporarily'));
342
- }
 
343
 
344
- public function fix_currency_after_order_email($order){
345
- unset($this->order_currency);
346
- remove_filter('woocommerce_currency', array($this, '_override_woocommerce_order_currency_temporarily'));
347
- }
348
 
349
- public function _override_woocommerce_order_currency_temporarily($currency){
350
- if(isset($this->order_currency)){
351
- $currency = $this->order_currency;
352
- }
353
- return $currency;
354
- }
355
 
356
- public function show_price_in_client_currency( $order_id ){
357
- $currency_code = get_post_meta( $order_id, '_order_currency', true );
358
 
359
- $this->client_currency = $currency_code;
360
- }
361
 
362
- public function get_currency_for_new_order( $value, $order ){
363
- $current_screen = get_current_screen();
364
- if( !empty($current_screen) && $current_screen->id == 'shop_order' ){
365
- $order_id = method_exists( $order, 'get_id' ) ? $order->get_id() : $order->id;
366
  $order_currency = get_post_meta( $order_id, '_order_currency', true );
367
- if( empty( $order_currency ) ){
368
  $value = $this->get_order_currency_cookie();
369
  }
370
  }
 
371
  return $value;
372
  }
373
 
1
  <?php
2
 
3
+ class WCML_Multi_Currency_Orders {
4
 
5
+ /**
6
+ * @var WCML_Multi_Currency
7
+ */
8
+ private $multi_currency;
9
 
10
+ public function __construct( &$multi_currency, &$woocommerce_wpml ) {
11
+ $this->multi_currency =& $multi_currency;
12
+ $this->woocommerce_wpml =& $woocommerce_wpml;
13
 
14
+ if ( is_admin() ) {
15
+ add_filter( 'init', array( $this, 'orders_init' ) );
16
+ }
17
+
18
+ add_action( 'woocommerce_view_order', array( $this, 'show_price_in_client_currency' ), 9 );
19
+ }
20
 
21
+ public function orders_init() {
22
+ global $wp;
23
 
24
+ add_action( 'restrict_manage_posts', array( $this, 'show_orders_currencies_selector' ) );
25
+ $wp->add_query_var( '_order_currency' );
26
 
27
+ add_filter( 'posts_join', array( $this, 'filter_orders_by_currency_join' ) );
28
+ add_filter( 'posts_where', array( $this, 'filter_orders_by_currency_where' ) );
29
 
30
+ // override current currency value when viewing order in admin
31
+ add_filter( 'woocommerce_currency_symbol', array( $this, '_use_order_currency_symbol' ) );
32
 
33
+ //new order currency/language switchers
34
+ add_action( 'woocommerce_process_shop_order_meta', array( $this, 'set_order_currency_on_update' ), 10, 2 );
35
+ add_action( 'woocommerce_order_actions_start', array( $this, 'show_order_currency_selector' ) );
36
 
37
+ add_filter( 'woocommerce_ajax_order_item', array( $this, 'filter_ajax_order_item' ), 10, 2 );
 
 
38
 
39
+ add_action( 'wp_ajax_wcml_order_set_currency', array( $this, 'set_order_currency_on_ajax_update' ) );
40
 
41
+ //dashboard status screen
42
+ if ( current_user_can( 'view_woocommerce_reports' ) || current_user_can( 'manage_woocommerce' ) || current_user_can( 'publish_shop_orders' ) ) {
43
+ //filter query to get order by status
44
+ add_filter( 'query', array( $this, 'filter_order_status_query' ) );
45
+ }
46
 
47
+ add_action( 'woocommerce_email_before_order_table', array( $this, 'fix_currency_before_order_email' ) );
48
+ add_action( 'woocommerce_email_after_order_table', array( $this, 'fix_currency_after_order_email' ) );
 
 
 
49
 
50
+ if ( is_admin() ) {
51
+ add_filter( 'woocommerce_order_get_currency', array( $this, 'get_currency_for_new_order' ), 10, 2 );
52
+ }
53
 
54
+ }
 
 
55
 
56
+ public function get_orders_currencies() {
57
+ global $wpdb;
58
 
59
+ $cache_key = 'wcml_get_orders_currencies';
60
+ $temp_orders_currencies = wp_cache_get( $cache_key );
61
+ if ( $temp_orders_currencies ) {
62
+ return $temp_orders_currencies;
63
+ }
64
 
65
+ $currencies = array();
66
 
67
+ $results = $wpdb->get_results( "
68
  SELECT m.meta_value AS currency, COUNT(m.post_id) AS c
69
  FROM {$wpdb->posts} p JOIN {$wpdb->postmeta} m ON p.ID = m.post_id
70
  WHERE meta_key='_order_currency' AND p.post_type='shop_order'
71
  GROUP BY meta_value
72
+ " );
73
+
74
+ foreach ( $results as $row ) {
75
+ $currencies[ $row->currency ] = (int) $row->c;
76
+ }
77
 
78
+ wp_cache_set( $cache_key, $currencies );
 
 
79
 
80
+ return $currencies;
81
 
82
+ }
83
 
84
+ public function show_orders_currencies_selector() {
85
+ global $wp_query, $typenow;
86
 
87
+ if ( $typenow != 'shop_order' ) {
88
+ return false;
89
+ }
90
 
91
+ $order_currencies = $this->get_orders_currencies();
92
+ $currencies = get_woocommerce_currencies();
93
+ ?>
94
  <select id="dropdown_shop_order_currency" name="_order_currency">
95
  <option value=""><?php _e( 'Show all currencies', 'woocommerce-multilingual' ) ?></option>
96
+ <?php foreach ( $order_currencies as $currency => $count ): ?>
97
  <option value="<?php echo $currency ?>" <?php
98
+ if ( isset( $wp_query->query['_order_currency'] ) ) {
99
+ selected( $currency, $wp_query->query['_order_currency'] );
100
+ }
101
+ ?> ><?php printf( "%s (%s) (%d)", $currencies[ $currency ], get_woocommerce_currency_symbol( $currency ), $count ) ?></option>
102
+ <?php endforeach; ?>
103
  </select>
104
+ <?php
 
 
105
 
106
+ }
 
 
 
 
 
107
 
108
+ public function filter_orders_by_currency_join( $join ) {
109
+ global $wp_query, $typenow, $wpdb;
110
 
111
+ if ( $typenow == 'shop_order' && ! empty( $wp_query->query['_order_currency'] ) ) {
112
+ $join .= " JOIN {$wpdb->postmeta} wcml_pm ON {$wpdb->posts}.ID = wcml_pm.post_id AND wcml_pm.meta_key='_order_currency'";
113
+ }
114
 
115
+ return $join;
116
+ }
 
117
 
118
+ public function filter_orders_by_currency_where( $where ) {
119
+ global $wp_query, $typenow;
120
 
121
+ if ( $typenow == 'shop_order' && ! empty( $wp_query->query['_order_currency'] ) ) {
122
+ $where .= " AND wcml_pm.meta_value = '" . esc_sql( $wp_query->query['_order_currency'] ) . "'";
123
+ }
124
 
125
+ return $where;
126
+ }
 
127
 
128
+ public function _use_order_currency_symbol( $currency ) {
129
 
130
+ if ( ! function_exists( 'get_current_screen' ) ) {
131
+ return $currency;
132
+ }
133
 
134
+ $current_screen = get_current_screen();
 
 
135
 
136
+ remove_filter( 'woocommerce_currency_symbol', array( $this, '_use_order_currency_symbol' ) );
137
+ if ( ! empty( $current_screen ) && $current_screen->id == 'shop_order' ) {
 
138
 
139
+ $the_order = new WC_Order( get_the_ID() );
140
+ if ( $the_order ) {
141
+ $order_currency = WooCommerce_Functions_Wrapper::get_order_currency( $the_order );
142
 
143
+ if ( ! $order_currency && isset( $_COOKIE['_wcml_order_currency'] ) ) {
144
+ $order_currency = $_COOKIE['_wcml_order_currency'];
145
+ }
 
 
 
 
 
 
 
 
 
 
146
 
147
+ $currency = get_woocommerce_currency_symbol( $order_currency );
148
+ }
149
 
150
+ } elseif (
151
+ (
152
+ isset( $_POST['action'] ) &&
153
+ in_array( $_POST['action'], array(
154
+ 'woocommerce_add_order_item',
155
+ 'woocommerce_calc_line_taxes',
156
+ 'woocommerce_save_order_items'
157
+ )
158
+ ) )
159
+ || (
160
+ isset( $_GET['action'] ) &&
161
+ $_GET['action'] == 'woocommerce_json_search_products_and_variations'
162
+ )
163
+ ) {
164
+
165
+
166
+ if ( isset( $_COOKIE['_wcml_order_currency'] ) ) {
167
+ $currency = get_woocommerce_currency_symbol( $_COOKIE['_wcml_order_currency'] );
168
+ } elseif ( isset( $_POST['order_id'] ) && $order_currency = get_post_meta( sanitize_text_field( $_POST['order_id'] ), '_order_currency', true ) ) {
169
+ $currency = get_woocommerce_currency_symbol( $order_currency );
170
+ }
171
 
172
+ if ( isset( $_SERVER['HTTP_REFERER'] ) ) {
173
+ $arg = parse_url( $_SERVER['HTTP_REFERER'] );
174
+ if ( isset( $arg['query'] ) ) {
175
+ parse_str( $arg['query'], $arg );
176
+ if ( isset( $arg['post'] ) && get_post_type( $arg['post'] ) == 'shop_order' ) {
177
+ $currency = get_woocommerce_currency_symbol( get_post_meta( $arg['post'], '_order_currency', true ) );
178
+ }
179
+ }
180
+ }
181
+ }
182
 
183
+ add_filter( 'woocommerce_currency_symbol', array( $this, '_use_order_currency_symbol' ) );
184
 
185
+ return $currency;
186
+ }
187
 
188
+ public function set_order_currency_on_update( $post_id, $post ) {
189
 
190
+ if ( isset( $_POST['wcml_shop_order_currency'] ) ) {
191
+ update_post_meta( $post_id, '_order_currency', filter_input( INPUT_POST, 'wcml_shop_order_currency', FILTER_SANITIZE_FULL_SPECIAL_CHARS ) );
192
+ }
193
 
194
+ }
195
 
196
+ public function show_order_currency_selector( $order_id ) {
197
+ if ( ! get_post_meta( $order_id, '_order_currency' ) ) {
198
 
199
+ $current_order_currency = $this->get_order_currency_cookie();
200
 
201
+ $wc_currencies = get_woocommerce_currencies();
202
+ $currencies = $this->multi_currency->get_currency_codes();
203
 
204
+ ?>
205
  <li class="wide">
206
+ <label><?php _e( 'Order currency:', 'woocommerce-multilingual' ); ?></label>
207
  <select id="dropdown_shop_order_currency" name="wcml_shop_order_currency">
208
 
209
+ <?php foreach ( $currencies as $currency ): ?>
210
 
211
+ <option value="<?php echo $currency ?>" <?php echo $current_order_currency == $currency ? 'selected="selected"' : ''; ?>><?php echo $wc_currencies[ $currency ]; ?></option>
212
 
213
+ <?php endforeach; ?>
214
 
215
  </select>
216
  </li>
217
+ <?php
218
+ $wcml_order_set_currency_nonce = wp_create_nonce( 'set_order_currency' );
219
 
220
+ wc_enqueue_js( "
221
  var order_currency_current_value = jQuery('#dropdown_shop_order_currency option:selected').val();
222
 
223
  jQuery('#dropdown_shop_order_currency').on('change', function(){
224
 
225
+ if(confirm('" . esc_js( __( "All the products will be removed from the current order in order to change the currency", 'woocommerce-multilingual' ) ) . "')){
226
  jQuery.ajax({
227
  url: ajaxurl,
228
  type: 'post',
230
  data: {
231
  action: 'wcml_order_set_currency',
232
  currency: jQuery('#dropdown_shop_order_currency option:selected').val(),
233
+ wcml_nonce: '" . $wcml_order_set_currency_nonce . "'
234
  },
235
  success: function( response ){
236
  if(typeof response.error !== 'undefined'){
247
 
248
  });
249
 
250
+ " );
251
 
252
+ }
253
 
254
+ }
255
 
256
+ public function filter_ajax_order_item( $item, $item_id ) {
257
+ if ( ! get_post_meta( $_POST['order_id'], '_order_currency' ) ) {
258
+ $order_currency = $this->get_order_currency_cookie();
259
+ } else {
260
+ $order_currency = get_post_meta( $_POST['order_id'], '_order_currency', true );
261
+ }
262
 
263
+ $original_product_id = $this->woocommerce_wpml->products->get_original_product_id( sanitize_text_field( $_POST['item_to_add'][0] ) );
264
+ $custom_price = get_post_meta( $original_product_id, '_price_' . $order_currency, true );
265
 
266
+ if ( ! isset( $this->multi_currency->prices ) ) {
267
+ $this->multi_currency->prices = new WCML_Multi_Currency_Prices( $this->multi_currency );
268
+ $this->multi_currency->prices->prices_init();
269
+ }
270
 
271
+ if ( $custom_price ) {
272
+ $item['line_subtotal'] = $custom_price;
273
+ $item['line_total'] = $custom_price;
274
+ } else {
275
+ $item['line_subtotal'] = $this->multi_currency->prices->raw_price_filter( $item['line_subtotal'], $order_currency );
276
+ $item['line_total'] = $this->multi_currency->prices->raw_price_filter( $item['line_total'], $order_currency );
277
+ }
278
 
279
+ wc_update_order_item_meta( $item_id, '_line_subtotal', $item['line_subtotal'] );
280
+ $item['line_subtotal_tax'] = $this->multi_currency->prices->convert_price_amount( $item['line_subtotal_tax'], $order_currency );
281
+ wc_update_order_item_meta( $item_id, '_line_subtotal_tax', $item['line_subtotal_tax'] );
282
+ wc_update_order_item_meta( $item_id, '_line_total', $item['line_total'] );
283
+ $item['line_tax'] = $this->multi_currency->prices->convert_price_amount( $item['line_tax'], $order_currency );
284
+ wc_update_order_item_meta( $item_id, '_line_tax', $item['line_tax'] );
285
 
286
+ return $item;
287
+ }
288
 
289
+ public function get_order_currency_cookie() {
290
 
291
+ if ( isset( $_COOKIE['_wcml_order_currency'] ) ) {
292
+ return $_COOKIE['_wcml_order_currency'];
293
+ } else {
294
+ return get_option( 'woocommerce_currency' );
295
+ }
296
 
297
+ }
298
 
299
+ public function set_order_currency_on_ajax_update() {
300
+ $nonce = filter_input( INPUT_POST, 'wcml_nonce', FILTER_SANITIZE_FULL_SPECIAL_CHARS );
301
+ if ( ! $nonce || ! wp_verify_nonce( $nonce, 'set_order_currency' ) ) {
302
+ echo json_encode( array( 'error' => __( 'Invalid nonce', 'woocommerce-multilingual' ) ) );
303
+ die();
304
+ }
305
+ $currency = filter_input( INPUT_POST, 'currency', FILTER_SANITIZE_FULL_SPECIAL_CHARS );
306
 
307
+ setcookie( '_wcml_order_currency', $currency, time() + 86400, COOKIEPATH, COOKIE_DOMAIN );
308
 
309
+ $return['currency'] = $currency;
310
 
311
+ echo json_encode( $return );
312
 
313
+ die();
314
+ }
315
 
316
+ /*
317
+ * Filter status query
318
+ *
319
+ * @param string $query
320
+ *
321
+ * @return string
322
+ *
323
+ */
324
+ public function filter_order_status_query( $query ) {
325
+ global $pagenow, $wpdb;
326
 
327
+ if ( $pagenow == 'index.php' ) {
328
+ $sql = "SELECT post_status, COUNT( * ) AS num_posts FROM {$wpdb->posts} WHERE post_type = 'shop_order' GROUP BY post_status";
329
 
330
+ if ( $query == $sql ) {
331
 
332
+ $currency = $this->multi_currency->admin_currency_selector->get_cookie_dashboard_currency();
333
+ $query = "SELECT post_status, COUNT( * ) AS num_posts FROM {$wpdb->posts}
334
  WHERE post_type = 'shop_order' AND ID IN
335
  ( SELECT order_currency.post_id FROM {$wpdb->postmeta} AS order_currency
336
  WHERE order_currency.meta_key = '_order_currency'
337
  AND order_currency.meta_value = '{$currency}' )
338
  GROUP BY post_status";
339
 
340
+ }
341
+ }
342
+
343
+ return $query;
344
+ }
345
 
346
+ // handle currency in order emails before handled in woocommerce
347
+ public function fix_currency_before_order_email( $order ) {
348
 
349
+ $order_currency = WooCommerce_Functions_Wrapper::get_order_currency( $order );
 
350
 
351
+ if ( ! $order_currency ) {
352
+ return;
353
+ }
354
 
355
+ $this->order_currency = $order_currency;
356
+ add_filter( 'woocommerce_currency', array( $this, '_override_woocommerce_order_currency_temporarily' ) );
357
+ }
358
 
359
+ public function fix_currency_after_order_email( $order ) {
360
+ unset( $this->order_currency );
361
+ remove_filter( 'woocommerce_currency', array( $this, '_override_woocommerce_order_currency_temporarily' ) );
362
+ }
363
 
364
+ public function _override_woocommerce_order_currency_temporarily( $currency ) {
365
+ if ( isset( $this->order_currency ) ) {
366
+ $currency = $this->order_currency;
367
+ }
368
 
369
+ return $currency;
370
+ }
 
 
 
 
371
 
372
+ public function show_price_in_client_currency( $order_id ) {
373
+ $currency_code = get_post_meta( $order_id, '_order_currency', true );
374
 
375
+ $this->client_currency = $currency_code;
376
+ }
377
 
378
+ public function get_currency_for_new_order( $value, $order ) {
379
+ $current_screen = get_current_screen();
380
+ if ( ! empty( $current_screen ) && $current_screen->id == 'shop_order' ) {
381
+ $order_id = method_exists( $order, 'get_id' ) ? $order->get_id() : $order->id;
382
  $order_currency = get_post_meta( $order_id, '_order_currency', true );
383
+ if ( empty( $order_currency ) ) {
384
  $value = $this->get_order_currency_cookie();
385
  }
386
  }
387
+
388
  return $value;
389
  }
390
 
inc/currencies/class-wcml-multi-currency-reports.php CHANGED
@@ -1,52 +1,87 @@
1
  <?php
2
 
3
- class WCML_Multi_Currency_Reports{
4
-
5
- private $woocommerce_wpml;
6
-
7
- private $reports_currency;
8
-
9
- public function __construct(){
10
-
11
- if( is_admin() ){
12
- add_filter( 'init', array( $this, 'reports_init' ) );
13
- add_action( 'wp_ajax_wcml_reports_set_currency', array($this, 'set_reports_currency') );
14
-
15
- add_action( 'wc_reports_tabs', array($this, 'reports_currency_selector') );
16
-
17
- if ( current_user_can( 'view_woocommerce_reports' ) ||
18
- current_user_can( 'manage_woocommerce' ) ||
19
- current_user_can( 'publish_shop_orders' ) ) {
20
-
21
- add_filter( 'woocommerce_dashboard_status_widget_sales_query', array($this, 'filter_dashboard_status_widget_sales_query') );
22
- add_filter( 'woocommerce_dashboard_status_widget_top_seller_query', array($this, 'filter_dashboard_status_widget_sales_query') );
23
- }
24
-
25
- add_action( 'current_screen', array($this, 'admin_screen_loaded'), 10, 1 );
26
- }
27
-
28
- }
29
-
30
- public function admin_screen_loaded( $screen ){
31
-
32
- if( $screen->id === 'dashboard'){
33
- add_filter( 'woocommerce_reports_get_order_report_query', array($this, 'filter_dashboard_status_widget_sales_query') ); // woocommerce 2.6
34
- }
35
-
36
- }
37
-
38
- public function reports_init(){
39
- global $woocommerce_wpml;
40
-
41
- $this->woocommerce_wpml =& $woocommerce_wpml;
42
-
43
- if(isset($_GET['page']) && $_GET['page'] == 'wc-reports'){ //wc-reports - 2.1.x, woocommerce_reports 2.0.x
44
-
45
- add_filter('woocommerce_reports_get_order_report_query', array($this, 'admin_reports_query_filter'));
46
-
47
- $wcml_reports_set_currency_nonce = wp_create_nonce( 'reports_set_currency' );
48
-
49
- wc_enqueue_js( "
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
50
  jQuery('#dropdown_shop_report_currency').on('change', function(){
51
  jQuery('#dropdown_shop_report_currency_chosen').after('&nbsp;' + icl_ajxloaderimg);
52
  jQuery('#dropdown_shop_report_currency_chosen a.chosen-single').css('color', '#aaa');
@@ -56,7 +91,7 @@ class WCML_Multi_Currency_Reports{
56
  data: {
57
  action: 'wcml_reports_set_currency',
58
  currency: jQuery('#dropdown_shop_report_currency').val(),
59
- wcml_nonce: '".$wcml_reports_set_currency_nonce."'
60
  },
61
  success: function( response ){
62
  if(typeof response.error !== 'undefined'){
@@ -67,124 +102,146 @@ class WCML_Multi_Currency_Reports{
67
  }
68
  })
69
  });
70
- ");
 
 
 
 
 
 
 
71
 
72
- $this->reports_currency = isset($_COOKIE['_wcml_reports_currency']) ? $_COOKIE['_wcml_reports_currency'] : get_option('woocommerce_currency');
73
- //validation
74
- $orders_currencies = $this->woocommerce_wpml->multi_currency->orders->get_orders_currencies();
75
- if(!isset($orders_currencies[$this->reports_currency])){
76
- $this->reports_currency = !empty($orders_currencies) ? key($orders_currencies) : false;
77
- }
78
 
79
- add_filter('woocommerce_currency_symbol', array($this, '_set_reports_currency_symbol'));
80
- add_filter('woocommerce_report_sales_by_category_get_products_in_category', array($this, '_use_categories_in_all_languages'), 10, 2);
81
 
82
- }
83
- }
84
 
85
- public function admin_reports_query_filter( $query ){
86
- global $wpdb;
 
87
 
88
- $query['join'] .= " LEFT JOIN {$wpdb->postmeta} AS meta_order_currency ON meta_order_currency.post_id = posts.ID ";
89
- $query['where'] .= sprintf(" AND meta_order_currency.meta_key='_order_currency' AND meta_order_currency.meta_value = '%s' ",
90
- $this->reports_currency);
91
 
92
- return $query;
93
- }
 
 
 
 
 
94
 
95
- public function _set_reports_currency_symbol( $currency ){
96
- static $no_recur = false;
97
- if(!empty($this->reports_currency) && empty($no_recur)){
98
- $no_recur= true;
99
- $currency = get_woocommerce_currency_symbol($this->reports_currency);
100
- $no_recur= false;
101
- }
102
- return $currency;
103
- }
104
 
105
- public function _use_categories_in_all_languages( $product_ids, $category_id ){
106
- global $sitepress;
107
 
108
- $category_term = $this->woocommerce_wpml->terms->wcml_get_term_by_id( $category_id, 'product_cat' );
109
 
110
- if( !is_wp_error($category_term) ){
111
- $trid = $sitepress->get_element_trid( $category_term->term_taxonomy_id, 'tax_product_cat' );
112
- $translations = $sitepress->get_element_translations( $trid, 'tax_product_cat', true );
113
 
114
- foreach($translations as $translation){
115
- if($translation->term_id != $category_id){
116
- $term_ids = get_term_children( $translation->term_id, 'product_cat' );
117
- $term_ids[] = $translation->term_id;
118
- $product_ids = array_merge(array_unique($product_ids), get_objects_in_term( $term_ids, 'product_cat' ));
119
- }
120
- }
121
- }
122
 
123
- return $product_ids;
124
- }
125
 
126
- public function set_reports_currency(){
127
 
128
- $nonce = filter_input( INPUT_POST, 'wcml_nonce', FILTER_SANITIZE_FULL_SPECIAL_CHARS );
129
- if(!$nonce || !wp_verify_nonce($nonce, 'reports_set_currency')){
130
- echo json_encode( array('error' => __('Invalid nonce', 'woocommerce-multilingual') ) );
131
- die();
132
- }
133
 
134
- setcookie('_wcml_reports_currency', filter_input( INPUT_POST, 'currency', FILTER_SANITIZE_FULL_SPECIAL_CHARS ),
135
- time() + 86400, COOKIEPATH, COOKIE_DOMAIN);
136
 
137
- exit;
138
 
139
- }
140
 
141
- public function reports_currency_selector(){
142
 
143
- $orders_currencies = $this->woocommerce_wpml->multi_currency->orders->get_orders_currencies();
144
- $currencies = get_woocommerce_currencies();
145
 
146
- // remove temporary
147
- remove_filter('woocommerce_currency_symbol', array($this, '_set_reports_currency_symbol'));
148
 
149
- ?>
150
 
151
  <select id="dropdown_shop_report_currency" style="margin-left:5px;">
152
- <?php if(empty($orders_currencies)): ?>
153
- <option value=""><?php _e('Currency - no orders found', 'woocommerce-multilingual') ?></option>
154
- <?php else: ?>
155
- <?php foreach($orders_currencies as $currency => $count): ?>
156
  <option value="<?php echo $currency ?>" <?php selected( $currency, $this->reports_currency ); ?>>
157
- <?php printf("%s (%s)", $currencies[$currency], get_woocommerce_currency_symbol($currency)) ?>
158
  </option>
159
- <?php endforeach; ?>
160
- <?php endif; ?>
161
  </select>
162
 
163
- <?php
164
- // add back
165
- add_filter('woocommerce_currency_symbol', array($this, '_set_reports_currency_symbol'));
 
 
 
 
 
 
 
 
 
 
 
 
166
 
167
- }
168
 
169
- /*
170
- * Filter WC dashboard status query
171
- *
172
- * @param string $query Query to filter
173
- *
174
- * @return string
175
- */
176
- public function filter_dashboard_status_widget_sales_query( $query ){
177
- global $wpdb;
178
- $currency = $this->woocommerce_wpml->multi_currency->admin_currency_selector->get_cookie_dashboard_currency();
179
- $query['where'] .= " AND posts.ID IN ( SELECT order_currency.post_id FROM {$wpdb->postmeta} AS order_currency
180
- WHERE order_currency.meta_key = '_order_currency' AND order_currency.meta_value = '{$currency}' ) ";
181
 
182
- return $query;
183
- }
184
 
 
185
 
 
 
 
186
 
 
 
 
 
 
 
 
 
 
 
 
187
 
 
 
188
 
 
 
189
 
190
  }
1
  <?php
2
 
3
+ class WCML_Multi_Currency_Reports {
4
+
5
+ /** @var woocommerce_wpml */
6
+ private $woocommerce_wpml;
7
+ /** @var Sitepress */
8
+ private $sitepress;
9
+ /** @var wpdb */
10
+ private $wpdb;
11
+ /** @var WPML_WP_Cache */
12
+ private $wpml_cache;
13
+
14
+ /** @var string $reports_currency */
15
+ private $reports_currency;
16
+
17
+ /**
18
+ * WCML_Multi_Currency_Reports constructor.
19
+ *
20
+ * @param woocommerce_wpml $woocommerce_wpml
21
+ * @param SitePress $sitepress
22
+ * @param wpdb $wpdb
23
+ * @param WPML_WP_Cache $wpml_cache
24
+ */
25
+ public function __construct( woocommerce_wpml $woocommerce_wpml, Sitepress $sitepress, wpdb $wpdb, WPML_WP_Cache $wpml_cache = null ) {
26
+
27
+ $this->woocommerce_wpml = $woocommerce_wpml;
28
+ $this->sitepress = $sitepress;
29
+ $this->wpdb = $wpdb;
30
+
31
+ $cache_group = 'WCML_Multi_Currency_Reports';
32
+ $this->wpml_cache = $wpml_cache;
33
+ if ( null === $wpml_cache ) {
34
+ $this->wpml_cache = new WPML_WP_Cache( $cache_group );
35
+ }
36
+
37
+ }
38
+
39
+ public function add_hooks() {
40
+ if ( is_admin() ) {
41
+ add_filter( 'init', array( $this, 'reports_init' ) );
42
+ add_action( 'wp_ajax_wcml_reports_set_currency', array( $this, 'set_reports_currency' ) );
43
+
44
+ add_action( 'wc_reports_tabs', array( $this, 'reports_currency_selector' ) );
45
+
46
+ if ( current_user_can( 'view_woocommerce_reports' ) ||
47
+ current_user_can( 'manage_woocommerce' ) ||
48
+ current_user_can( 'publish_shop_orders' )
49
+ ) {
50
+
51
+ add_filter( 'woocommerce_dashboard_status_widget_sales_query', array(
52
+ $this,
53
+ 'filter_dashboard_status_widget_sales_query'
54
+ ) );
55
+ add_filter( 'woocommerce_dashboard_status_widget_top_seller_query', array(
56
+ $this,
57
+ 'filter_dashboard_status_widget_sales_query'
58
+ ) );
59
+ }
60
+
61
+ add_action( 'current_screen', array( $this, 'admin_screen_loaded' ), 10, 1 );
62
+ }
63
+ }
64
+
65
+ public function admin_screen_loaded( $screen ) {
66
+
67
+ if ( $screen->id === 'dashboard' ) {
68
+ add_filter( 'woocommerce_reports_get_order_report_query', array(
69
+ $this,
70
+ 'filter_dashboard_status_widget_sales_query'
71
+ ) ); // woocommerce 2.6
72
+ }
73
+
74
+ }
75
+
76
+ public function reports_init() {
77
+
78
+ if ( isset( $_GET['page'] ) && $_GET['page'] == 'wc-reports' ) { //wc-reports - 2.1.x, woocommerce_reports 2.0.x
79
+
80
+ add_filter( 'woocommerce_reports_get_order_report_query', array( $this, 'admin_reports_query_filter' ) );
81
+
82
+ $wcml_reports_set_currency_nonce = wp_create_nonce( 'reports_set_currency' );
83
+
84
+ wc_enqueue_js( "
85
  jQuery('#dropdown_shop_report_currency').on('change', function(){
86
  jQuery('#dropdown_shop_report_currency_chosen').after('&nbsp;' + icl_ajxloaderimg);
87
  jQuery('#dropdown_shop_report_currency_chosen a.chosen-single').css('color', '#aaa');
91
  data: {
92
  action: 'wcml_reports_set_currency',
93
  currency: jQuery('#dropdown_shop_report_currency').val(),
94
+ wcml_nonce: '" . $wcml_reports_set_currency_nonce . "'
95
  },
96
  success: function( response ){
97
  if(typeof response.error !== 'undefined'){
102
  }
103
  })
104
  });
105
+ " );
106
+
107
+ $this->reports_currency = isset( $_COOKIE['_wcml_reports_currency'] ) ? $_COOKIE['_wcml_reports_currency'] : get_option( 'woocommerce_currency' );
108
+ //validation
109
+ $orders_currencies = $this->woocommerce_wpml->multi_currency->orders->get_orders_currencies();
110
+ if ( ! isset( $orders_currencies[ $this->reports_currency ] ) ) {
111
+ $this->reports_currency = ! empty( $orders_currencies ) ? key( $orders_currencies ) : false;
112
+ }
113
 
114
+ add_filter( 'woocommerce_currency_symbol', array( $this, '_set_reports_currency_symbol' ) );
115
+ add_filter( 'woocommerce_report_sales_by_category_get_products_in_category', array(
116
+ $this,
117
+ '_use_categories_in_all_languages'
118
+ ), 10, 2 );
 
119
 
120
+ }
121
+ }
122
 
123
+ public function admin_reports_query_filter( $query ) {
 
124
 
125
+ $query['join'] .= " LEFT JOIN {$this->wpdb->postmeta} AS meta_order_currency ON meta_order_currency.post_id = posts.ID ";
126
+ $query['where'] .= sprintf( " AND meta_order_currency.meta_key='_order_currency' AND meta_order_currency.meta_value = '%s' ",
127
+ $this->reports_currency );
128
 
129
+ return $query;
130
+ }
 
131
 
132
+ public function _set_reports_currency_symbol( $currency ) {
133
+ static $no_recur = false;
134
+ if ( ! empty( $this->reports_currency ) && empty( $no_recur ) ) {
135
+ $no_recur = true;
136
+ $currency = get_woocommerce_currency_symbol( $this->reports_currency );
137
+ $no_recur = false;
138
+ }
139
 
140
+ return $currency;
141
+ }
 
 
 
 
 
 
 
142
 
143
+ public function _use_categories_in_all_languages( $product_ids, $category_id ) {
 
144
 
145
+ $category_term = $this->woocommerce_wpml->terms->wcml_get_term_by_id( $category_id, 'product_cat' );
146
 
147
+ if ( ! is_wp_error( $category_term ) ) {
148
+ $trid = $this->sitepress->get_element_trid( $category_term->term_taxonomy_id, 'tax_product_cat' );
149
+ $translations = $this->sitepress->get_element_translations( $trid, 'tax_product_cat', true );
150
 
151
+ foreach ( $translations as $translation ) {
152
+ if ( $translation->term_id != $category_id ) {
153
+ $term_ids = get_term_children( $translation->term_id, 'product_cat' );
154
+ $term_ids[] = $translation->term_id;
155
+ $product_ids = array_merge( array_unique( $product_ids ), get_objects_in_term( $term_ids, 'product_cat' ) );
156
+ }
157
+ }
158
+ }
159
 
160
+ return $product_ids;
161
+ }
162
 
163
+ public function set_reports_currency() {
164
 
165
+ $nonce = filter_input( INPUT_POST, 'wcml_nonce', FILTER_SANITIZE_FULL_SPECIAL_CHARS );
166
+ if ( ! $nonce || ! wp_verify_nonce( $nonce, 'reports_set_currency' ) ) {
167
+ echo json_encode( array( 'error' => __( 'Invalid nonce', 'woocommerce-multilingual' ) ) );
168
+ die();
169
+ }
170
 
171
+ setcookie( '_wcml_reports_currency', filter_input( INPUT_POST, 'currency', FILTER_SANITIZE_FULL_SPECIAL_CHARS ),
172
+ time() + 86400, COOKIEPATH, COOKIE_DOMAIN );
173
 
174
+ exit;
175
 
176
+ }
177
 
178
+ public function reports_currency_selector() {
179
 
180
+ $orders_currencies = $this->woocommerce_wpml->multi_currency->orders->get_orders_currencies();
181
+ $currencies = get_woocommerce_currencies();
182
 
183
+ // remove temporary
184
+ remove_filter( 'woocommerce_currency_symbol', array( $this, '_set_reports_currency_symbol' ) );
185
 
186
+ ?>
187
 
188
  <select id="dropdown_shop_report_currency" style="margin-left:5px;">
189
+ <?php if ( empty( $orders_currencies ) ): ?>
190
+ <option value=""><?php _e( 'Currency - no orders found', 'woocommerce-multilingual' ) ?></option>
191
+ <?php else: ?>
192
+ <?php foreach ( $orders_currencies as $currency => $count ): ?>
193
  <option value="<?php echo $currency ?>" <?php selected( $currency, $this->reports_currency ); ?>>
194
+ <?php printf( "%s (%s)", $currencies[ $currency ], get_woocommerce_currency_symbol( $currency ) ) ?>
195
  </option>
196
+ <?php endforeach; ?>
197
+ <?php endif; ?>
198
  </select>
199
 
200
+ <?php
201
+ // add back
202
+ add_filter( 'woocommerce_currency_symbol', array( $this, '_set_reports_currency_symbol' ) );
203
+
204
+ }
205
+
206
+ /*
207
+ * Filter WC dashboard status query
208
+ *
209
+ * @param string $query Query to filter
210
+ *
211
+ * @return string
212
+ */
213
+ public function filter_dashboard_status_widget_sales_query( $query ) {
214
+ $order_ids_list = $this->get_dashboard_currency_list_of_orders_ids();
215
 
216
+ $query['where'] .= " AND posts.ID IN ( " . $order_ids_list . " ) ";
217
 
218
+ return $query;
219
+ }
 
 
 
 
 
 
 
 
 
 
220
 
221
+ public function get_dashboard_currency_list_of_orders_ids() {
 
222
 
223
+ $currency = $this->woocommerce_wpml->multi_currency->admin_currency_selector->get_cookie_dashboard_currency();
224
 
225
+ $cache_key = $currency . '_list_of_orders_ids';
226
+ $found = false;
227
+ $orders_ids = $this->wpml_cache->get( $cache_key, $found );
228
 
229
+ if ( ! $found ) {
230
+ $order_ids_array = $this->wpdb->get_col(
231
+ $this->wpdb->prepare( "
232
+ SELECT order_currency.post_id
233
+ FROM {$this->wpdb->postmeta} AS order_currency
234
+ WHERE order_currency.meta_key = '_order_currency'
235
+ AND order_currency.meta_value = %s
236
+ ", $currency
237
+ )
238
+ );
239
+ $orders_ids = implode( ',', $order_ids_array );
240
 
241
+ $this->wpml_cache->set( $cache_key, $orders_ids );
242
+ }
243
 
244
+ return $orders_ids;
245
+ }
246
 
247
  }
inc/currencies/class-wcml-multi-currency-resources.php CHANGED
@@ -2,16 +2,22 @@
2
 
3
  class WCML_Multi_Currency_Resources{
4
 
 
 
 
5
  static $multi_currency;
 
 
 
6
  static $woocommerce_wpml;
7
 
8
- public static function set_up( &$multi_currency, &$woocommerce_wpml ){
9
  global $pagenow;
10
 
11
- self::$multi_currency =& $multi_currency;
12
- self::$woocommerce_wpml =& $woocommerce_wpml;
13
 
14
- if(!is_admin() && $pagenow != 'wp-login.php' ){
15
  self::load_inline_js();
16
  }
17
 
2
 
3
  class WCML_Multi_Currency_Resources{
4
 
5
+ /**
6
+ * @var WCML_Multi_Currency
7
+ */
8
  static $multi_currency;
9
+ /**
10
+ * @var woocommerce_wpml
11
+ */
12
  static $woocommerce_wpml;
13
 
14
+ public static function set_up( WCML_Multi_Currency $multi_currency, woocommerce_wpml $woocommerce_wpml ){
15
  global $pagenow;
16
 
17
+ self::$multi_currency = $multi_currency;
18
+ self::$woocommerce_wpml = $woocommerce_wpml;
19
 
20
+ if( !is_admin() && $pagenow != 'wp-login.php' && $woocommerce_wpml->cs_templates->get_active_templates() ){
21
  self::load_inline_js();
22
  }
23
 
inc/currencies/class-wcml-multi-currency.php CHANGED
@@ -80,12 +80,17 @@ class WCML_Multi_Currency{
80
  */
81
  public $load_filters;
82
 
 
 
 
 
 
83
 
84
  /**
85
  * WCML_Multi_Currency constructor.
86
  */
87
  public function __construct(){
88
- global $woocommerce_wpml, $sitepress;
89
 
90
  $this->woocommerce_wpml =& $woocommerce_wpml;
91
 
@@ -100,11 +105,13 @@ class WCML_Multi_Currency{
100
  $this->coupons = new WCML_Multi_Currency_Coupons();
101
  $this->shipping = new WCML_Multi_Currency_Shipping( $this );
102
  }
103
- $this->reports = new WCML_Multi_Currency_Reports();
 
104
  $this->orders = new WCML_Multi_Currency_Orders( $this, $woocommerce_wpml );
105
  $this->admin_currency_selector = new WCML_Admin_Currency_Selector();
106
  $this->custom_prices = new WCML_Custom_Prices( $woocommerce_wpml );
107
  $this->currency_switcher = new WCML_Currency_Switcher( $woocommerce_wpml, $sitepress );
 
108
  $this->currency_switcher_ajax = new WCML_Currency_Switcher_Ajax( $woocommerce_wpml );
109
 
110
  $this->exchange_rate_services = new WCML_Exchange_Rates( $this->woocommerce_wpml );
@@ -166,6 +173,7 @@ class WCML_Multi_Currency{
166
  public function init() {
167
 
168
  add_filter( 'wcml_get_client_currency', array($this, 'get_client_currency') );
 
169
 
170
  }
171
 
@@ -343,6 +351,10 @@ class WCML_Multi_Currency{
343
  public function get_client_currency(){
344
  global $woocommerce, $sitepress, $wpdb;
345
 
 
 
 
 
346
  $default_currencies = $this->woocommerce_wpml->settings['default_currencies'];
347
  $current_language = $sitepress->get_current_language();
348
  $current_language = ( $current_language != 'all' && !is_null( $current_language ) ) ? $current_language : $sitepress->get_default_language();
@@ -371,6 +383,7 @@ class WCML_Multi_Currency{
371
  $this->client_currency = get_option('woocommerce_currency');
372
  }
373
 
 
374
  }
375
 
376
  if( isset($_GET['pay_for_order']) && $_GET['pay_for_order'] == true && isset($_GET['key']) ){
@@ -378,6 +391,7 @@ class WCML_Multi_Currency{
378
  if( $order_id ){
379
  $this->client_currency = get_post_meta( $order_id, '_order_currency', true );
380
  }
 
381
  }
382
 
383
  if(
@@ -406,7 +420,16 @@ class WCML_Multi_Currency{
406
  !empty($woocommerce->session) &&
407
  $current_language != $woocommerce->session->get('client_currency_language') )
408
  {
409
- $this->client_currency = $default_currencies[$current_language];
 
 
 
 
 
 
 
 
 
410
  }
411
 
412
  //edit order page
@@ -424,8 +447,10 @@ class WCML_Multi_Currency{
424
  if( is_null( $this->client_currency ) && !empty( $woocommerce->session ) ){
425
  $session_currency = $woocommerce->session->get('client_currency');
426
  if($session_currency && !empty($this->currencies[$session_currency]['languages'][$current_language])){
 
427
  $this->client_currency = $woocommerce->session->get('client_currency');
428
  }
 
429
  }
430
 
431
  if( is_null( $this->client_currency ) ){
@@ -453,6 +478,13 @@ class WCML_Multi_Currency{
453
  return apply_filters('wcml_client_currency', $this->client_currency);
454
  }
455
 
 
 
 
 
 
 
 
456
  public function set_client_currency($currency){
457
  global $woocommerce,$sitepress;
458
 
@@ -477,7 +509,7 @@ class WCML_Multi_Currency{
477
  die();
478
  }
479
 
480
- $this->set_client_currency($currency);
481
 
482
  // force set user cookie when user is not logged in
483
  global $woocommerce, $current_user;
80
  */
81
  public $load_filters;
82
 
83
+ /**
84
+ * @var string
85
+ */
86
+ public $switching_currency_html;
87
+
88
 
89
  /**
90
  * WCML_Multi_Currency constructor.
91
  */
92
  public function __construct(){
93
+ global $woocommerce_wpml, $sitepress, $wpdb;
94
 
95
  $this->woocommerce_wpml =& $woocommerce_wpml;
96
 
105
  $this->coupons = new WCML_Multi_Currency_Coupons();
106
  $this->shipping = new WCML_Multi_Currency_Shipping( $this );
107
  }
108
+ $this->reports = new WCML_Multi_Currency_Reports( $woocommerce_wpml, $sitepress, $wpdb );
109
+ $this->reports->add_hooks();
110
  $this->orders = new WCML_Multi_Currency_Orders( $this, $woocommerce_wpml );
111
  $this->admin_currency_selector = new WCML_Admin_Currency_Selector();
112
  $this->custom_prices = new WCML_Custom_Prices( $woocommerce_wpml );
113
  $this->currency_switcher = new WCML_Currency_Switcher( $woocommerce_wpml, $sitepress );
114
+ $this->currency_switcher->add_hooks();
115
  $this->currency_switcher_ajax = new WCML_Currency_Switcher_Ajax( $woocommerce_wpml );
116
 
117
  $this->exchange_rate_services = new WCML_Exchange_Rates( $this->woocommerce_wpml );
173
  public function init() {
174
 
175
  add_filter( 'wcml_get_client_currency', array($this, 'get_client_currency') );
176
+ add_action( 'wp_footer', array( $this, 'maybe_show_switching_currency_prompt_dialog' ) );
177
 
178
  }
179
 
351
  public function get_client_currency(){
352
  global $woocommerce, $sitepress, $wpdb;
353
 
354
+ if( WCML_REST_API_Support::is_rest_api_request() ){
355
+ return get_option('woocommerce_currency');
356
+ }
357
+
358
  $default_currencies = $this->woocommerce_wpml->settings['default_currencies'];
359
  $current_language = $sitepress->get_current_language();
360
  $current_language = ( $current_language != 'all' && !is_null( $current_language ) ) ? $current_language : $sitepress->get_default_language();
383
  $this->client_currency = get_option('woocommerce_currency');
384
  }
385
 
386
+
387
  }
388
 
389
  if( isset($_GET['pay_for_order']) && $_GET['pay_for_order'] == true && isset($_GET['key']) ){
391
  if( $order_id ){
392
  $this->client_currency = get_post_meta( $order_id, '_order_currency', true );
393
  }
394
+
395
  }
396
 
397
  if(
420
  !empty($woocommerce->session) &&
421
  $current_language != $woocommerce->session->get('client_currency_language') )
422
  {
423
+
424
+ $current_currency = $woocommerce->session->get('client_currency');
425
+ $client_currency = $default_currencies[ $current_language ];
426
+ $prevent_switching = apply_filters( 'wcml_switch_currency_exception', false, $current_currency, $client_currency, true );
427
+
428
+ $this->client_currency = $client_currency;
429
+ if ( ! array_key_exists( 'force_switch', $_POST ) && $prevent_switching ) {
430
+ $this->switching_currency_html = $prevent_switching['prevent_switching'];
431
+ }
432
+
433
  }
434
 
435
  //edit order page
447
  if( is_null( $this->client_currency ) && !empty( $woocommerce->session ) ){
448
  $session_currency = $woocommerce->session->get('client_currency');
449
  if($session_currency && !empty($this->currencies[$session_currency]['languages'][$current_language])){
450
+
451
  $this->client_currency = $woocommerce->session->get('client_currency');
452
  }
453
+
454
  }
455
 
456
  if( is_null( $this->client_currency ) ){
478
  return apply_filters('wcml_client_currency', $this->client_currency);
479
  }
480
 
481
+ public function maybe_show_switching_currency_prompt_dialog(){
482
+ if( $this->switching_currency_html ){
483
+ echo $this->switching_currency_html;
484
+ }
485
+
486
+ }
487
+
488
  public function set_client_currency($currency){
489
  global $woocommerce,$sitepress;
490
 
509
  die();
510
  }
511
 
512
+ $this->set_client_currency($currency, $force_switch);
513
 
514
  // force set user cookie when user is not logged in
515
  global $woocommerce, $current_user;
inc/currencies/class-wcml-price-filter.php CHANGED
@@ -24,7 +24,9 @@ class WCML_Price_Filter {
24
  ?>
25
  <script type="text/javascript">
26
  /* <![CDATA[ */
27
- woocommerce_price_slider_params.currency_format_symbol = wcml_mc_settings.current_currency.symbol;
 
 
28
  /* ]]> */
29
  </script>
30
  <?php
24
  ?>
25
  <script type="text/javascript">
26
  /* <![CDATA[ */
27
+ if( typeof woocommerce_price_slider_params !== 'undefined' ) {
28
+ woocommerce_price_slider_params.currency_format_symbol = wcml_mc_settings.current_currency.symbol;
29
+ }
30
  /* ]]> */
31
  </script>
32
  <?php
inc/currencies/currency-switcher/class-wcml-currency-switcher-properties.php ADDED
@@ -0,0 +1,22 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Class WCML_Currency_Switcher_Properties
5
+ *
6
+ * Main class
7
+ */
8
+ class WCML_Currency_Switcher_Properties{
9
+
10
+ public function is_currency_switcher_active( $switcher_id, $wcml_settings ){
11
+
12
+ $product_page_switcher_is_active = 'product' === $switcher_id && 1 === $wcml_settings[ 'currency_switcher_product_visibility' ];
13
+ $sidebar_switcher_is_active = 'product' !== $switcher_id && is_active_sidebar( $switcher_id );
14
+
15
+ if( $product_page_switcher_is_active || $sidebar_switcher_is_active ){
16
+ return true;
17
+ }
18
+
19
+ return false;
20
+ }
21
+
22
+ }
inc/currencies/currency-switcher/class-wcml-currency-switcher-templates.php CHANGED
@@ -9,6 +9,11 @@ class WCML_Currency_Switcher_Templates {
9
  */
10
  private $woocommerce_wpml;
11
 
 
 
 
 
 
12
  /** @var string $uploads_path */
13
  private $uploads_path;
14
 
@@ -23,9 +28,10 @@ class WCML_Currency_Switcher_Templates {
23
  /* @var string $ds */
24
  private $ds = DIRECTORY_SEPARATOR;
25
 
26
- public function __construct( &$woocommerce_wpml, WCML_File $wpml_file = null ) {
27
 
28
  $this->woocommerce_wpml = $woocommerce_wpml;
 
29
 
30
  if ( ! $wpml_file ) {
31
  //TODO: use WPML_FILE class instead after changing requirements for WPML >= 3.6.0
@@ -36,9 +42,15 @@ class WCML_Currency_Switcher_Templates {
36
  }
37
 
38
  public function init_hooks() {
 
39
  add_action( 'after_setup_theme', array( $this, 'after_setup_theme_action' ) );
40
- add_action( 'wp_enqueue_scripts', array( $this, 'enqueue_template_resources' ) );
41
  add_action( 'admin_head', array( $this, 'admin_enqueue_template_resources' ) );
 
 
 
 
 
 
42
  }
43
 
44
  public function after_setup_theme_action() {
@@ -62,24 +74,26 @@ class WCML_Currency_Switcher_Templates {
62
  /**
63
  * @return array of active WCML_CS_Templates
64
  */
65
- public function get_active_templates() {
66
 
67
  $templates = array();
68
  $wcml_settings = $this->woocommerce_wpml->get_settings();
69
 
70
- if( isset( $wcml_settings[ 'currency_switchers' ] ) ){
71
- foreach( $wcml_settings[ 'currency_switchers' ] as $switcher_id => $switcher ){
72
- if( 'product' === $switcher_id && 0 === $wcml_settings[ 'currency_switcher_product_visibility' ] ){
73
  continue;
74
  }
75
 
76
- foreach( $this->templates as $key => $template ){
77
- if( $switcher['switcher_style'] == $key && !isset( $templates[$key] ) ){
78
- $templates[$key] = $template;
79
  }
80
  }
81
  }
82
- }else{
 
 
83
  //set default template to active
84
  $templates['wcml-dropdown'] = $this->templates['wcml-dropdown'];
85
  }
@@ -421,7 +435,7 @@ class WCML_Currency_Switcher_Templates {
421
  public function check_is_active( $template ){
422
  $is_active = false;
423
 
424
- $active_templates = $this->get_active_templates();
425
 
426
  foreach( $active_templates as $template_key => $active_template ){
427
  if ( $template === $template_key ){
@@ -435,8 +449,7 @@ class WCML_Currency_Switcher_Templates {
435
  }
436
 
437
  public function get_first_active( ){
438
-
439
- return current( array_keys( $this->get_active_templates() ) );
440
 
441
  }
442
  }
9
  */
10
  private $woocommerce_wpml;
11
 
12
+ /*
13
+ * @var WPML_WP_API $wp_api
14
+ */
15
+ private $wp_api;
16
+
17
  /** @var string $uploads_path */
18
  private $uploads_path;
19
 
28
  /* @var string $ds */
29
  private $ds = DIRECTORY_SEPARATOR;
30
 
31
+ public function __construct( woocommerce_wpml $woocommerce_wpml, WPML_WP_API $wp_api, WCML_File $wpml_file = null ) {
32
 
33
  $this->woocommerce_wpml = $woocommerce_wpml;
34
+ $this->wp_api = $wp_api;
35
 
36
  if ( ! $wpml_file ) {
37
  //TODO: use WPML_FILE class instead after changing requirements for WPML >= 3.6.0
42
  }
43
 
44
  public function init_hooks() {
45
+
46
  add_action( 'after_setup_theme', array( $this, 'after_setup_theme_action' ) );
 
47
  add_action( 'admin_head', array( $this, 'admin_enqueue_template_resources' ) );
48
+
49
+ //enqueue front resources only when MC enabled
50
+ $wcml_settings = $this->woocommerce_wpml->get_settings();
51
+ if( $wcml_settings['enable_multi_currency'] === $this->wp_api->constant( 'WCML_MULTI_CURRENCIES_INDEPENDENT' ) ){
52
+ add_action( 'wp_enqueue_scripts', array( $this, 'enqueue_template_resources' ) );
53
+ }
54
  }
55
 
56
  public function after_setup_theme_action() {
74
  /**
75
  * @return array of active WCML_CS_Templates
76
  */
77
+ public function get_active_templates( $load_default = false ) {
78
 
79
  $templates = array();
80
  $wcml_settings = $this->woocommerce_wpml->get_settings();
81
 
82
+ if ( isset( $wcml_settings['currency_switchers'] ) ) {
83
+ foreach ( $wcml_settings['currency_switchers'] as $switcher_id => $switcher ) {
84
+ if ( ! $this->woocommerce_wpml->cs_properties->is_currency_switcher_active( $switcher_id, $wcml_settings ) ) {
85
  continue;
86
  }
87
 
88
+ foreach ( $this->templates as $key => $template ) {
89
+ if ( $switcher['switcher_style'] === $key && ! isset( $templates[ $key ] ) ) {
90
+ $templates[ $key ] = $template;
91
  }
92
  }
93
  }
94
+ }
95
+
96
+ if( !$templates && $load_default ){
97
  //set default template to active
98
  $templates['wcml-dropdown'] = $this->templates['wcml-dropdown'];
99
  }
435
  public function check_is_active( $template ){
436
  $is_active = false;
437
 
438
+ $active_templates = $this->get_active_templates( true );
439
 
440
  foreach( $active_templates as $template_key => $active_template ){
441
  if ( $template === $template_key ){
449
  }
450
 
451
  public function get_first_active( ){
452
+ return current( array_keys( $this->get_active_templates( true ) ) );
 
453
 
454
  }
455
  }
inc/currencies/currency-switcher/class-wcml-currency-switcher.php CHANGED
@@ -7,29 +7,31 @@
7
  */
8
  class WCML_Currency_Switcher{
9
 
 
10
  private $woocommerce_wpml;
 
11
  private $sitepress;
 
12
  private $is_touch_screen;
13
 
14
- public function __construct( &$woocommerce_wpml, &$sitepress ) {
15
 
16
  $this->woocommerce_wpml = $woocommerce_wpml;
17
- $this->sitepress = $sitepress;
18
 
19
- add_action( 'init', array($this, 'init'), 5 );
20
  }
21
 
22
- public function init() {
 
 
23
 
24
- add_action( 'wcml_currency_switcher', array($this, 'wcml_currency_switcher') );
 
25
  //@deprecated 3.9
26
- add_action( 'currency_switcher', array($this, 'currency_switcher') );
27
-
28
- add_shortcode( 'currency_switcher', array($this, 'currency_switcher_shortcode') );
29
-
30
  // Built in currency switcher
31
- add_action( 'woocommerce_product_meta_start', array($this, 'show_currency_switcher') );
32
-
33
  add_action( 'pre_update_option_sidebars_widgets', array( $this, 'update_option_sidebars_widgets' ), 10, 2 );
34
  }
35
 
7
  */
8
  class WCML_Currency_Switcher{
9
 
10
+ /** @var woocommerce_wpml */
11
  private $woocommerce_wpml;
12
+ /** @var Sitepress */
13
  private $sitepress;
14
+ /** @var boolean */
15
  private $is_touch_screen;
16
 
17
+ public function __construct( woocommerce_wpml $woocommerce_wpml, Sitepress $sitepress ) {
18
 
19
  $this->woocommerce_wpml = $woocommerce_wpml;
20
+ $this->sitepress = $sitepress;
21
 
 
22
  }
23
 
24
+ public function add_hooks() {
25
+ add_action( 'init', array( $this, 'on_init' ), 5 );
26
+ }
27
 
28
+ public function on_init() {
29
+ add_action( 'wcml_currency_switcher', array( $this, 'wcml_currency_switcher' ) );
30
  //@deprecated 3.9
31
+ add_action( 'currency_switcher', array( $this, 'currency_switcher' ) );
32
+ add_shortcode( 'currency_switcher', array( $this, 'currency_switcher_shortcode' ) );
 
 
33
  // Built in currency switcher
34
+ add_action( 'woocommerce_product_meta_start', array( $this, 'show_currency_switcher' ) );
 
35
  add_action( 'pre_update_option_sidebars_widgets', array( $this, 'update_option_sidebars_widgets' ), 10, 2 );
36
  }
37
 
inc/currencies/exchange-rate-services/class-wcml-exchange-rates-currencylayer.php CHANGED
@@ -10,19 +10,18 @@ class WCML_Exchange_Rates_Currencylayer extends WCML_Exchange_Rate_Service{
10
  protected $api_key = '';
11
  protected $requires_key = true;
12
 
13
- const REQUIRES_KEY = true;
14
-
15
  function __construct() {
16
  parent::__construct( $this->id, $this->name, $this->api_url, $this->url );
17
  }
18
 
19
- /**
20
- * @param $from string
21
- * @param $to array
22
- * @return array
23
- * @throws Exception
24
- */
25
- public function get_rates( $from, $tos ){
 
26
 
27
  parent::clear_last_error( );
28
  $rates = array();
10
  protected $api_key = '';
11
  protected $requires_key = true;
12
 
 
 
13
  function __construct() {
14
  parent::__construct( $this->id, $this->name, $this->api_url, $this->url );
15
  }
16
 
17
+ /**
18
+ * @param string $from
19
+ * @param array $tos
20
+ *
21
+ * @return array
22
+ * @throws Exception
23
+ */
24
+ public function get_rates( $from, $tos ) {
25
 
26
  parent::clear_last_error( );
27
  $rates = array();
inc/missing-php-functions.php CHANGED
@@ -1,76 +1,89 @@
1
  <?php
2
-
3
  /* PHP 5.3 - start */
4
 
5
- if(false === function_exists('lcfirst'))
6
- {
7
- /**
8
- * Make a string's first character lowercase
9
- *
10
- * @param string $str
11
- * @return string the resulting string.
12
- */
13
- function lcfirst( $str ) {
14
- $str[0] = strtolower($str[0]);
15
- return (string)$str;
16
- }
 
17
  }
18
 
19
- if (get_magic_quotes_gpc()) {
20
- if(!function_exists('stripslashes_deep')){
21
- function stripslashes_deep($value)
22
- {
23
- $value = is_array($value) ?
24
- array_map('stripslashes_deep', $value) :
25
- stripslashes($value);
26
-
27
- return $value;
28
- }
29
- }
30
-
31
- $_POST = array_map('stripslashes_deep', $_POST);
32
- $_GET = array_map('stripslashes_deep', $_GET);
33
- $_COOKIE = array_map('stripslashes_deep', $_COOKIE);
34
  }
35
  /* PHP 5.3 - end */
36
 
37
- add_action('plugins_loaded', 'wcml_check_wpml_functions');
38
 
39
- function wcml_check_wpml_functions(){
40
 
41
- if( !has_filter( 'translate_object_id' ) ){
42
- add_filter( 'translate_object_id', 'icl_object_id', 10, 4 );
43
- }
44
 
45
- if( !has_action( 'wpml_register_single_string' ) ){
46
- if( function_exists( 'wpml_register_single_string_action' ) ) {
47
- add_action('wpml_register_single_string', 'wpml_register_single_string_action', 10, 4);
48
- }elseif ( function_exists( 'icl_register_string' ) ){
49
- add_action('wpml_register_single_string', 'icl_register_string', 10, 4);
50
- }
51
- }
52
 
53
  }
54
 
55
  // two WordPress functions that were added in 4.4.0
56
- if( version_compare( $GLOBALS['wp_version'], '4.4.0' , '<' ) ){
57
-
58
- if( !function_exists( 'get_the_post_thumbnail_url' ) ){
59
- function get_the_post_thumbnail_url( $post = null, $size = 'post-thumbnail' ) {
60
- $post_thumbnail_id = get_post_thumbnail_id( $post );
61
- if ( ! $post_thumbnail_id ) {
62
- return false;
63
- }
64
- return wp_get_attachment_image_url( $post_thumbnail_id, $size );
65
- }
66
- }
67
-
68
- if( !function_exists( 'wp_get_attachment_image_url' ) ) {
69
- function wp_get_attachment_image_url( $attachment_id, $size = 'thumbnail', $icon = false ) {
70
- $image = wp_get_attachment_image_src( $attachment_id, $size, $icon );
71
- return isset( $image['0'] ) ? $image['0'] : false;
72
- }
73
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
74
 
75
  }
76
 
1
  <?php
2
+
3
  /* PHP 5.3 - start */
4
 
5
+ if ( false === function_exists( 'lcfirst' ) ) {
6
+ /**
7
+ * Make a string's first character lowercase
8
+ *
9
+ * @param string $str
10
+ *
11
+ * @return string the resulting string.
12
+ */
13
+ function lcfirst( $str ) {
14
+ $str[0] = strtolower( $str[0] );
15
+
16
+ return (string) $str;
17
+ }
18
  }
19
 
20
+ if ( get_magic_quotes_gpc() ) {
21
+ if ( ! function_exists( 'stripslashes_deep' ) ) {
22
+ function stripslashes_deep( $value ) {
23
+ $value = is_array( $value ) ?
24
+ array_map( 'stripslashes_deep', $value ) :
25
+ stripslashes( $value );
26
+
27
+ return $value;
28
+ }
29
+ }
30
+
31
+ $_POST = array_map( 'stripslashes_deep', $_POST );
32
+ $_GET = array_map( 'stripslashes_deep', $_GET );
33
+ $_COOKIE = array_map( 'stripslashes_deep', $_COOKIE );
 
34
  }
35
  /* PHP 5.3 - end */
36
 
37
+ add_action( 'plugins_loaded', 'wcml_check_wpml_functions' );
38
 
39
+ function wcml_check_wpml_functions() {
40
 
41
+ if ( ! has_filter( 'translate_object_id' ) ) {
42
+ add_filter( 'translate_object_id', 'icl_object_id', 10, 4 );
43
+ }
44
 
45
+ if ( ! has_action( 'wpml_register_single_string' ) ) {
46
+ if ( function_exists( 'wpml_register_single_string_action' ) ) {
47
+ add_action( 'wpml_register_single_string', 'wpml_register_single_string_action', 10, 4 );
48
+ } elseif ( function_exists( 'icl_register_string' ) ) {
49
+ add_action( 'wpml_register_single_string', 'icl_register_string', 10, 4 );
50
+ }
51
+ }
52
 
53
  }
54
 
55
  // two WordPress functions that were added in 4.4.0
56
+ if ( version_compare( $GLOBALS['wp_version'], '4.4.0', '<' ) ) {
57
+
58
+ if ( ! function_exists( 'get_the_post_thumbnail_url' ) ) {
59
+ function get_the_post_thumbnail_url( $post = null, $size = 'post-thumbnail' ) {
60
+ $post_thumbnail_id = get_post_thumbnail_id( $post );
61
+ if ( ! $post_thumbnail_id ) {
62
+ return false;
63
+ }
64
+
65
+ return wp_get_attachment_image_url( $post_thumbnail_id, $size );
66
+ }
67
+ }
68
+
69
+ if ( ! function_exists( 'wp_get_attachment_image_url' ) ) {
70
+ function wp_get_attachment_image_url( $attachment_id, $size = 'thumbnail', $icon = false ) {
71
+ $image = wp_get_attachment_image_src( $attachment_id, $size, $icon );
72
+
73
+ return isset( $image['0'] ) ? $image['0'] : false;
74
+ }
75
+ }
76
+
77
+ if ( ! function_exists( 'rest_get_url_prefix' ) ) {
78
+ function rest_get_url_prefix() {
79
+ /**
80
+ * Filters the REST URL prefix.
81
+ *
82
+ * @param string $prefix URL prefix. Default 'wp-json'.
83
+ */
84
+ return apply_filters( 'rest_url_prefix', 'wp-json' );
85
+ }
86
+ }
87
 
88
  }
89
 
inc/template-classes/class-wcml-settings-ui.php CHANGED
@@ -2,14 +2,22 @@
2
 
3
  class WCML_Settings_UI extends WPML_Templates_Factory {
4
 
 
5
  private $woocommerce_wpml;
 
6
  private $sitepress;
7
 
8
- function __construct( &$woocommerce_wpml, &$sitepress ){
 
 
 
 
 
 
9
  parent::__construct();
10
 
11
- $this->woocommerce_wpml = &$woocommerce_wpml;
12
- $this->sitepress = &$sitepress;
13
 
14
  }
15
 
@@ -22,7 +30,7 @@ class WCML_Settings_UI extends WPML_Templates_Factory {
22
  'translation_interface' => array(
23
  'heading' => __('Product Translation Interface','woocommerce-multilingual'),
24
  'tip' => __( 'The recommended way is using the WPML Translation Editor. It is streamlined for making the translation process much easier while also providing a much better integration with various WooCommerce extensions.',
25
- 'woocommerce-multilingual' ),
26
  'wcml' => array(
27
  'label' => __('WPML Translation Editor', 'woocommerce-multilingual'),
28
 
@@ -72,6 +80,11 @@ class WCML_Settings_UI extends WPML_Templates_Factory {
72
  'clear_label' => __('Prompt for a confirmation and reset the cart', 'woocommerce-multilingual'),
73
  'value' => $this->woocommerce_wpml->settings['cart_sync']['currency_switch']
74
  ),
 
 
 
 
 
75
  'doc_link' => sprintf( __( 'Not sure which option to choose? Read about %spotential issues when switching languages and currencies while the cart has items%s.',
76
  'woocommerce-multilingual' ),
77
  '<a href="https://wpml.org/documentation/related-projects/woocommerce-multilingual/clearing-cart-contents-when-language-or-currency-change/" target="_blank">', '</a>'
2
 
3
  class WCML_Settings_UI extends WPML_Templates_Factory {
4
 
5
+ /** @var woocommerce_wpml */
6
  private $woocommerce_wpml;
7
+ /** @var Sitepress */
8
  private $sitepress;
9
 
10
+ /**
11
+ * WCML_Settings_UI constructor.
12
+ *
13
+ * @param woocommerce_wpml $woocommerce_wpml
14
+ * @param SitePress $sitepress
15
+ */
16
+ function __construct( woocommerce_wpml $woocommerce_wpml, Sitepress $sitepress ){
17
  parent::__construct();
18
 
19
+ $this->woocommerce_wpml = $woocommerce_wpml;
20
+ $this->sitepress = $sitepress;
21
 
22
  }
23
 
30
  'translation_interface' => array(
31
  'heading' => __('Product Translation Interface','woocommerce-multilingual'),
32
  'tip' => __( 'The recommended way is using the WPML Translation Editor. It is streamlined for making the translation process much easier while also providing a much better integration with various WooCommerce extensions.',
33
+ 'woocommerce-multilingual' ),
34
  'wcml' => array(
35
  'label' => __('WPML Translation Editor', 'woocommerce-multilingual'),
36
 
80
  'clear_label' => __('Prompt for a confirmation and reset the cart', 'woocommerce-multilingual'),
81
  'value' => $this->woocommerce_wpml->settings['cart_sync']['currency_switch']
82
  ),
83
+ 'wpml_cookie_enabled' => $this->sitepress->get_setting( WPML_Cookie_Setting::COOKIE_SETTING_FIELD ),
84
+ 'cookie_not_enabled_message' => sprintf( __( 'This feature was disabled. Please enable %sWPML cookies%s to continue.',
85
+ 'woocommerce-multilingual' ),
86
+ '<a href="'. admin_url( '?page='.WPML_PLUGIN_FOLDER.'/menu/languages.php#cookie' ) .'" target="_blank">', '</a>'
87
+ ),
88
  'doc_link' => sprintf( __( 'Not sure which option to choose? Read about %spotential issues when switching languages and currencies while the cart has items%s.',
89
  'woocommerce-multilingual' ),
90
  '<a href="https://wpml.org/documentation/related-projects/woocommerce-multilingual/clearing-cart-contents-when-language-or-currency-change/" target="_blank">', '</a>'
inc/template-classes/multi-currency/class-wcml-multi-currency-ui.php CHANGED
@@ -305,6 +305,8 @@ class WCML_Multi_Currency_UI extends WPML_Templates_Factory {
305
 
306
  foreach( $currency_switchers as $switcher_id => $currency_switcher ){
307
 
 
 
308
  if( $switcher_id == 'product'){
309
  $dialog_title = __('Edit Product Currency Switcher', 'woocommerce-multilingual');
310
  }elseif( $switcher_id == 'new_widget' ){
305
 
306
  foreach( $currency_switchers as $switcher_id => $currency_switcher ){
307
 
308
+ if ( 'new_widget' !== $switcher_id && !$this->woocommerce_wpml->cs_properties->is_currency_switcher_active( $switcher_id, $wcml_settings ) ) continue;
309
+
310
  if( $switcher_id == 'product'){
311
  $dialog_title = __('Edit Product Currency Switcher', 'woocommerce-multilingual');
312
  }elseif( $switcher_id == 'new_widget' ){
inc/translation-editor/class-wcml-editor-ui-product-job.php CHANGED
@@ -21,6 +21,7 @@ class WCML_Editor_UI_Product_Job extends WPML_Editor_UI_Job {
21
  private $product_id;
22
  private $product_type;
23
  private $not_display_fields_for_variables_product;
 
24
 
25
  function __construct( $job_details, &$woocommerce_wpml, &$sitepress, &$wpdb ) {
26
  global $iclTranslationManagement;
@@ -34,6 +35,8 @@ class WCML_Editor_UI_Product_Job extends WPML_Editor_UI_Job {
34
  '_min_variation_regular_price', '_max_variation_regular_price',
35
  '_min_variation_sale_price', '_max_variation_sale_price','_downloadable_files' );
36
 
 
 
37
  $this->job_details = $job_details;
38
  $this->product = wc_get_product( $job_details[ 'job_id' ] );
39
  $this->original_post = get_post( $job_details[ 'job_id' ] );
@@ -152,7 +155,6 @@ class WCML_Editor_UI_Product_Job extends WPML_Editor_UI_Job {
152
 
153
  $custom_fields = $this->get_product_custom_fields_to_translate( $this->product_id );
154
 
155
-
156
  if( $this->product_type === 'external' ){
157
  $custom_fields = array_diff( $custom_fields, array( '_product_url', '_button_text' ) );
158
  }
@@ -163,19 +165,38 @@ class WCML_Editor_UI_Product_Job extends WPML_Editor_UI_Job {
163
 
164
  foreach( $custom_fields as $custom_field ){
165
 
166
- $cf_settings = new WPML_Post_Custom_Field_Setting( $this->tm_instance, $custom_field );
167
- switch( $cf_settings->get_editor_style() ){
168
- case 'visual':
169
- $cf_field = new WPML_Editor_UI_WYSIWYG_Field( $custom_field, $cf_settings->get_editor_label(), $this->data, true );
170
- break;
171
- case 'textarea':
172
- $cf_field = new WPML_Editor_UI_TextArea_Field( $custom_field, $cf_settings->get_editor_label(), $this->data, true );
173
- break;
174
- default: //line
175
- $cf_field = new WPML_Editor_UI_Single_Line_Field( $custom_field, $cf_settings->get_editor_label(), $this->data, true );
176
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
177
 
178
- $custom_fields_section->add_field( $cf_field );
179
 
180
  }
181
 
@@ -278,6 +299,44 @@ class WCML_Editor_UI_Product_Job extends WPML_Editor_UI_Job {
278
 
279
  }
280
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
281
  public function add_custom_fields_ui_section( $custom_fields_section, $custom_fields, $variation_id = false ){
282
 
283
  foreach( $custom_fields as $custom_field ) {
@@ -453,7 +512,7 @@ class WCML_Editor_UI_Product_Job extends WPML_Editor_UI_Job {
453
  continue;
454
  }
455
 
456
- $element_data[ 't_'.$term->term_taxonomy_id ] = array( 'original' => $term->name );
457
  $element_data[ 't_'.$term->term_taxonomy_id ][ 'translation' ] = $translated_term->term_taxonomy_id != $term->term_taxonomy_id ? $translated_term->name : '';
458
  }
459
  }
@@ -468,11 +527,11 @@ class WCML_Editor_UI_Product_Job extends WPML_Editor_UI_Job {
468
  if( $custom_fields ){
469
  foreach( $custom_fields as $custom_field ) {
470
  $orig_custom_field_values = get_post_meta( $element_id, $custom_field );
471
- $trnsl_custom_field_values = array();
472
  $trnsl_mid_ids = array();
473
 
474
  if ( $translation_id ) {
475
- $trnsl_custom_field_values = get_post_meta( $translation_id, $custom_field );
476
  $trnsl_mid_ids = $this->woocommerce_wpml->products->get_mid_ids_by_key( $translation_id, $custom_field );
477
  }
478
 
@@ -481,15 +540,36 @@ class WCML_Editor_UI_Product_Job extends WPML_Editor_UI_Job {
481
  }
482
 
483
  foreach( $orig_custom_field_values as $val_key => $orig_custom_field_value ){
484
- if( count( $orig_custom_field_values ) == 1 ){
485
- $element_data[ $custom_field ] = array( 'original' => $orig_custom_field_value );
486
- $element_data[ $custom_field ][ 'translation' ] = ( $translation_id && isset( $trnsl_custom_field_values[ $val_key ] ) ) ? $trnsl_custom_field_values[ $val_key ] : '';
 
 
 
 
 
 
 
 
 
 
 
487
  }else{
488
 
489
- $custom_field_key = $custom_field.':'. ( isset( $trnsl_mid_ids[ $val_key ] ) ? $trnsl_mid_ids[ $val_key ] : 'new_'. $val_key );
 
 
 
 
 
 
490
 
491
- $element_data[ $custom_field ][ $custom_field_key ] = array( 'original' => $orig_custom_field_value );
492
- $element_data[ $custom_field ][ $custom_field_key ][ 'translation' ] = ($translation_id && isset( $trnsl_custom_field_values[ $val_key ] ) ) ? $trnsl_custom_field_values[ $val_key ] : '';
 
 
 
 
493
  }
494
  }
495
  }
@@ -741,12 +821,11 @@ class WCML_Editor_UI_Product_Job extends WPML_Editor_UI_Job {
741
  $settings = $sitepress->get_settings();
742
  $label = '';
743
  if ( isset( $settings['translation-management']['custom_fields_translation'][ $field ] ) && $settings['translation-management']['custom_fields_translation'][ $field ] == WPML_TRANSLATE_CUSTOM_FIELD ) {
744
- if ( in_array( $field, $this->not_display_fields_for_variables_product, true ) ) {
745
  return false;
746
  }
747
 
748
- $exception = apply_filters('wcml_product_content_exception', true, $this->product_id, $field);
749
- if ( !$exception ) {
750
  return false;
751
  }
752
 
@@ -804,11 +883,8 @@ class WCML_Editor_UI_Product_Job extends WPML_Editor_UI_Job {
804
  if ( in_array( $meta_key, apply_filters( 'wcml_not_display_single_fields_to_translate', $this->not_display_fields_for_variables_product ), true ) ) {
805
  continue;
806
  }
807
- }else{
808
- $exception = apply_filters( 'wcml_product_content_exception', true, $product_id, $meta_key );
809
- if( $exception ) {
810
- continue;
811
- }
812
  }
813
  $contents[] = $meta_key;
814
  }
21
  private $product_id;
22
  private $product_type;
23
  private $not_display_fields_for_variables_product;
24
+ private $not_display_custom_fields_for_product;
25
 
26
  function __construct( $job_details, &$woocommerce_wpml, &$sitepress, &$wpdb ) {
27
  global $iclTranslationManagement;
35
  '_min_variation_regular_price', '_max_variation_regular_price',
36
  '_min_variation_sale_price', '_max_variation_sale_price','_downloadable_files' );
37
 
38
+ $this->not_display_custom_fields_for_product = array( '_upsell_ids', '_crosssell_ids','_downloadable_files' );
39
+
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' ] );
155
 
156
  $custom_fields = $this->get_product_custom_fields_to_translate( $this->product_id );
157
 
 
158
  if( $this->product_type === 'external' ){
159
  $custom_fields = array_diff( $custom_fields, array( '_product_url', '_button_text' ) );
160
  }
165
 
166
  foreach( $custom_fields as $custom_field ){
167
 
168
+ if( $this->check_custom_field_is_single_value( $this->product_id, $custom_field ) ){
169
+
170
+ $cf_settings = new WPML_Post_Custom_Field_Setting( $this->tm_instance, $custom_field );
171
+
172
+ switch( $cf_settings->get_editor_style() ){
173
+ case 'visual':
174
+ $cf_field = new WPML_Editor_UI_WYSIWYG_Field( $custom_field, $cf_settings->get_editor_label(), $this->data, true );
175
+ break;
176
+ case 'textarea':
177
+ $cf_field = new WPML_Editor_UI_TextArea_Field( $custom_field, $cf_settings->get_editor_label(), $this->data, true );
178
+ break;
179
+ default: //line
180
+ $cf_field = new WPML_Editor_UI_Single_Line_Field( $custom_field, $cf_settings->get_editor_label(), $this->data, true );
181
+ }
182
+
183
+ $custom_fields_section->add_field( $cf_field );
184
+
185
+ }else{
186
+
187
+ $custom_fields_values = array_values( array_filter( get_post_meta($this->product_id, $custom_field , true ) ) );
188
+
189
+ if( $custom_fields_values ){
190
+ $cf_fields_group = new WPML_Editor_UI_Field_Group();
191
+
192
+ foreach( $custom_fields_values as $custom_field_index => $custom_field_val ){
193
+ $cf_fields_group = $this->add_single_custom_field_content( $cf_fields_group, $custom_field, $custom_field_index, $custom_field_val );
194
+ }
195
+
196
+ $custom_fields_section->add_field( $cf_fields_group );
197
+ }
198
 
199
+ }
200
 
201
  }
202
 
299
 
300
  }
301
 
302
+ public function add_single_custom_field_content( $cf_fields_group, $custom_field, $custom_field_index, $custom_field_val ){
303
+
304
+ if( is_scalar( $custom_field_val ) ){
305
+ $key_index = $custom_field . '-' . $custom_field_index;
306
+ $cf = 'field-' . $key_index;
307
+
308
+ $cf_field = new WPML_Editor_UI_Single_Line_Field( $cf, $cf, $this->data, false );
309
+ $cf_fields_group->add_field( $cf_field );
310
+
311
+ }else{
312
+ foreach ( $custom_field_val as $ind => $value ) {
313
+ $cf_fields_group = $this->add_single_custom_field_content( $cf_fields_group, $custom_field, $custom_field_index . '-' . str_replace( '-', ':::', $ind ), $value );
314
+ }
315
+ }
316
+
317
+ return $cf_fields_group;
318
+
319
+ }
320
+
321
+ public function add_single_custom_field_content_value( $element_data, $custom_field, $custom_field_index, $custom_field_val, $trnsl_custom_field_value ){
322
+
323
+ if( is_scalar( $custom_field_val ) ){
324
+ $key_index = $custom_field . '-' . $custom_field_index;
325
+ $cf = 'field-' . $key_index;
326
+ $element_data[ $cf ] = array( 'original' => $custom_field_val );
327
+ $element_data[ $cf ][ 'translation' ] = ( $trnsl_custom_field_value ) ? $trnsl_custom_field_value : '';
328
+
329
+ }else{
330
+ foreach ( $custom_field_val as $ind => $value ) {
331
+ $translated_value = isset( $trnsl_custom_field_value[ $ind ] ) ? $trnsl_custom_field_value[ $ind ] : '';
332
+ $element_data = $this->add_single_custom_field_content_value( $element_data, $custom_field, $custom_field_index . '-' . str_replace( '-', ':::', $ind ), $value, $translated_value );
333
+ }
334
+ }
335
+
336
+ return $element_data;
337
+
338
+ }
339
+
340
  public function add_custom_fields_ui_section( $custom_fields_section, $custom_fields, $variation_id = false ){
341
 
342
  foreach( $custom_fields as $custom_field ) {
512
  continue;
513
  }
514
 
515
+ $element_data[ 't_'.$term->term_taxonomy_id ] = array( 'original' => htmlspecialchars_decode( $term->name ) );
516
  $element_data[ 't_'.$term->term_taxonomy_id ][ 'translation' ] = $translated_term->term_taxonomy_id != $term->term_taxonomy_id ? $translated_term->name : '';
517
  }
518
  }
527
  if( $custom_fields ){
528
  foreach( $custom_fields as $custom_field ) {
529
  $orig_custom_field_values = get_post_meta( $element_id, $custom_field );
530
+ $translated_custom_field_values = array();
531
  $trnsl_mid_ids = array();
532
 
533
  if ( $translation_id ) {
534
+ $translated_custom_field_values = get_post_meta( $translation_id, $custom_field );
535
  $trnsl_mid_ids = $this->woocommerce_wpml->products->get_mid_ids_by_key( $translation_id, $custom_field );
536
  }
537
 
540
  }
541
 
542
  foreach( $orig_custom_field_values as $val_key => $orig_custom_field_value ){
543
+
544
+ if( $this->check_custom_field_is_single_value( $element_id, $custom_field ) ){
545
+
546
+ if( count( $orig_custom_field_values ) == 1 ){
547
+ $element_data[ $custom_field ] = array( 'original' => $orig_custom_field_value );
548
+ $element_data[ $custom_field ][ 'translation' ] = ( $translation_id && isset( $translated_custom_field_values[ $val_key ] ) ) ? $translated_custom_field_values[ $val_key ] : '';
549
+ }else{
550
+
551
+ $custom_field_key = $custom_field.':'. ( isset( $trnsl_mid_ids[ $val_key ] ) ? $trnsl_mid_ids[ $val_key ] : 'new_'. $val_key );
552
+
553
+ $element_data[ $custom_field ][ $custom_field_key ] = array( 'original' => $orig_custom_field_value );
554
+ $element_data[ $custom_field ][ $custom_field_key ][ 'translation' ] = ($translation_id && isset( $translated_custom_field_values[ $val_key ] ) ) ? $translated_custom_field_values[ $val_key ] : '';
555
+ }
556
+
557
  }else{
558
 
559
+ $custom_fields_values = array_values( array_filter( get_post_meta($this->product_id, $custom_field, true ) ) );
560
+
561
+ if( $custom_fields_values ){
562
+ if ( $translation_id ) {
563
+ $translated_custom_field_values = array_values( array_filter( get_post_meta( $translation_id, $custom_field , true ) ) );
564
+ }
565
+ foreach( $custom_fields_values as $custom_field_index => $custom_field_val ){
566
 
567
+ $translated_custom_field_value = isset( $translated_custom_field_values[ $custom_field_index ] )? $translated_custom_field_values[ $custom_field_index ] : '';
568
+
569
+ $element_data = $this->add_single_custom_field_content_value( $element_data, $custom_field, $custom_field_index, $custom_field_val, $translated_custom_field_value );
570
+
571
+ }
572
+ }
573
  }
574
  }
575
  }
821
  $settings = $sitepress->get_settings();
822
  $label = '';
823
  if ( isset( $settings['translation-management']['custom_fields_translation'][ $field ] ) && $settings['translation-management']['custom_fields_translation'][ $field ] == WPML_TRANSLATE_CUSTOM_FIELD ) {
824
+ if ( in_array( $field, apply_filters( 'wcml_not_display_single_fields_to_translate', $this->not_display_fields_for_variables_product ), true ) ) {
825
  return false;
826
  }
827
 
828
+ if ( in_array( $field, apply_filters( 'wcml_do_not_display_custom_fields_for_product', $this->not_display_custom_fields_for_product ), true ) ) {
 
829
  return false;
830
  }
831
 
883
  if ( in_array( $meta_key, apply_filters( 'wcml_not_display_single_fields_to_translate', $this->not_display_fields_for_variables_product ), true ) ) {
884
  continue;
885
  }
886
+ }elseif( in_array( $meta_key, apply_filters( 'wcml_do_not_display_custom_fields_for_product', $this->not_display_custom_fields_for_product ), true ) ) {
887
+ continue;
 
 
 
888
  }
889
  $contents[] = $meta_key;
890
  }
inc/translation-editor/class-wcml-synchronize-product-data.php CHANGED
@@ -2,26 +2,46 @@
2
 
3
  class WCML_Synchronize_Product_Data{
4
 
 
 
 
5
  private $woocommerce_wpml;
6
  /**
7
  * @var SitePress
8
  */
9
  private $sitepress;
 
10
  private $wpdb;
11
 
12
- public function __construct( &$woocommerce_wpml, &$sitepress, &$wpdb ) {
 
 
 
 
 
 
 
 
13
  $this->woocommerce_wpml = $woocommerce_wpml;
14
- $this->sitepress = $sitepress;
15
- $this->wpdb = $wpdb;
 
16
 
 
17
  if( is_admin() ){
18
  // filters to sync variable products
19
- add_action( 'save_post', array( $this, 'synchronize_products' ), 110, 2 ); // After WPML
20
 
21
  add_action( 'icl_pro_translation_completed', array( $this, 'icl_pro_translation_completed' ) );
22
 
23
  add_filter( 'icl_make_duplicate', array( $this, 'icl_make_duplicate'), 110, 4 );
24
 
 
 
 
 
 
 
25
  //quick & bulk edit
26
  add_action( 'woocommerce_product_quick_edit_save', array( $this, 'woocommerce_product_quick_edit_save' ) );
27
  add_action( 'woocommerce_product_bulk_edit_save', array( $this, 'woocommerce_product_quick_edit_save' ) );
@@ -60,7 +80,9 @@ class WCML_Synchronize_Product_Data{
60
  //set trid for variations
61
  if ( $post_type == 'product_variation' ) {
62
  $var_lang = $this->sitepress->get_language_for_element( wp_get_post_parent_id( $post_id ), 'post_product' );
63
- if( $this->woocommerce_wpml->products->is_original_product( wp_get_post_parent_id( $post_id ) ) ){
 
 
64
  $this->sitepress->set_element_language_details( $post_id, 'post_product_variation', false, $var_lang );
65
  }
66
  }
@@ -77,7 +99,7 @@ class WCML_Synchronize_Product_Data{
77
  return;
78
  }
79
  // Remove filter to avoid double sync
80
- remove_action( 'save_post', array( $this, 'synchronize_products' ), 110, 2 );
81
 
82
  do_action( 'wcml_before_sync_product', $original_product_id, $post_id );
83
 
@@ -440,7 +462,7 @@ class WCML_Synchronize_Product_Data{
440
  }elseif ( $data ) {
441
  if ( isset( $settings[ $key ] ) && $settings[ $key ] == WPML_TRANSLATE_CUSTOM_FIELD ) {
442
 
443
- $post_fields = $this->sync_custom_field_value( $key, $data, $trnsl_product_id, $post_fields );
444
  }
445
  }
446
  }
@@ -469,15 +491,25 @@ class WCML_Synchronize_Product_Data{
469
  unset( $post_fields[ $custom_filed_key ] );
470
  }else{
471
  foreach( $post_fields as $post_field_key => $post_field ){
472
- $meta_value = $translation_data[ md5( $post_field_key ) ];
473
- $field_key = explode( ':', $post_field_key );
474
- if( $field_key[0] == $custom_filed_key ){
475
- if( substr( $field_key[1], 0, 3 ) == 'new' ){
476
- add_post_meta( $trnsl_product_id, $custom_field, $meta_value );
477
- }else{
478
- update_meta( $field_key[1], $custom_field, $meta_value );
 
 
 
 
 
 
 
 
 
 
 
479
  }
480
- unset( $post_fields[ $post_field_key ] );
481
  }
482
  }
483
  }
@@ -485,6 +517,125 @@ class WCML_Synchronize_Product_Data{
485
  return $post_fields;
486
  }
487
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
488
 
489
  public function icl_connect_translations_action(){
490
  if( isset( $_POST[ 'icl_ajx_action' ] ) && $_POST[ 'icl_ajx_action' ] == 'connect_translations' ) {
2
 
3
  class WCML_Synchronize_Product_Data{
4
 
5
+ const CUSTOM_FIELD_KEY_SEPARATOR = ':::';
6
+
7
+ /** @var woocommerce_wpml */
8
  private $woocommerce_wpml;
9
  /**
10
  * @var SitePress
11
  */
12
  private $sitepress;
13
+ /** @var wpdb */
14
  private $wpdb;
15
 
16
+
17
+ /**
18
+ * WCML_Synchronize_Product_Data constructor.
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() ){
32
  // filters to sync variable products
33
+ add_action( 'save_post', array( $this, 'synchronize_products' ), PHP_INT_MAX, 2 ); // After WPML
34
 
35
  add_action( 'icl_pro_translation_completed', array( $this, 'icl_pro_translation_completed' ) );
36
 
37
  add_filter( 'icl_make_duplicate', array( $this, 'icl_make_duplicate'), 110, 4 );
38
 
39
+ if ( $this->sitepress->get_wp_api()->version_compare( $this->sitepress->get_wp_api()->constant( 'WC_VERSION' ), '3.0.0', '<' ) ) {
40
+ add_action('woocommerce_duplicate_product', array($this, 'woocommerce_duplicate_product'), 10, 2);
41
+ }else{
42
+ add_action( 'woocommerce_product_duplicate', array( $this, 'woocommerce_duplicate_product' ), 10, 2 );
43
+ }
44
+
45
  //quick & bulk edit
46
  add_action( 'woocommerce_product_quick_edit_save', array( $this, 'woocommerce_product_quick_edit_save' ) );
47
  add_action( 'woocommerce_product_bulk_edit_save', array( $this, 'woocommerce_product_quick_edit_save' ) );
80
  //set trid for variations
81
  if ( $post_type == 'product_variation' ) {
82
  $var_lang = $this->sitepress->get_language_for_element( wp_get_post_parent_id( $post_id ), 'post_product' );
83
+ $is_parent_original = $this->woocommerce_wpml->products->is_original_product( wp_get_post_parent_id( $post_id ) );
84
+ $variation_language_details = $this->sitepress->get_element_language_details( $post_id, 'post_product_variation' );
85
+ if( $is_parent_original && !$variation_language_details ){
86
  $this->sitepress->set_element_language_details( $post_id, 'post_product_variation', false, $var_lang );
87
  }
88
  }
99
  return;
100
  }
101
  // Remove filter to avoid double sync
102
+ remove_action( 'save_post', array( $this, 'synchronize_products' ), PHP_INT_MAX, 2 );
103
 
104
  do_action( 'wcml_before_sync_product', $original_product_id, $post_id );
105
 
462
  }elseif ( $data ) {
463
  if ( isset( $settings[ $key ] ) && $settings[ $key ] == WPML_TRANSLATE_CUSTOM_FIELD ) {
464
 
465
+ $post_fields = $this->sync_custom_field_value( $key, $data, $trnsl_product_id, $post_fields, $original_product_id );
466
  }
467
  }
468
  }
491
  unset( $post_fields[ $custom_filed_key ] );
492
  }else{
493
  foreach( $post_fields as $post_field_key => $post_field ){
494
+
495
+ if( 1 === preg_match( '/field-' . $custom_field . '-.*?/', $post_field_key ) ){
496
+ $custom_fields_values = array_values( array_filter( get_post_meta( $original_product_id, $custom_field, true ) ) );
497
+ foreach( $custom_fields_values as $custom_field_index => $custom_field_value ) {
498
+ $custom_fields_values = $this->get_translated_custom_field_values( $custom_fields_values, $translation_data, $custom_field, $custom_field_value, $custom_field_index );
499
+ }
500
+
501
+ update_post_meta( $trnsl_product_id, $custom_field, $custom_fields_values );
502
+ }else{
503
+ $meta_value = $translation_data[ md5( $post_field_key ) ];
504
+ $field_key = explode( ':', $post_field_key );
505
+ if( $field_key[0] == $custom_filed_key ){
506
+ if( 'new' === substr( $field_key[1], 0, 3 ) ){
507
+ add_post_meta( $trnsl_product_id, $custom_field, $meta_value );
508
+ }else{
509
+ update_meta( $field_key[1], $custom_field, $meta_value );
510
+ }
511
+ unset( $post_fields[ $post_field_key ] );
512
  }
 
513
  }
514
  }
515
  }
517
  return $post_fields;
518
  }
519
 
520
+ public function get_translated_custom_field_values( $custom_fields_values, $translation_data, $custom_field, $custom_field_value, $custom_field_index ){
521
+
522
+ if( is_scalar( $custom_field_value ) ){
523
+ $key_index = $custom_field . '-' .$custom_field_index;
524
+ $cf = 'field-' . $key_index;
525
+ $meta_keys = explode( '-', $custom_field_index );
526
+ $meta_keys = array_map( array( $this, 'replace_separator' ), $meta_keys );
527
+ $custom_fields_values = $this->insert_under_keys(
528
+ $meta_keys, $custom_fields_values, $translation_data[ md5( $cf ) ]
529
+ );
530
+ }else{
531
+ foreach ( $custom_field_value as $ind => $value ) {
532
+ $field_index = $custom_field_index. '-' . str_replace( '-', self::CUSTOM_FIELD_KEY_SEPARATOR, $ind );
533
+ $custom_fields_values = $this->get_translated_custom_field_values( $custom_fields_values, $translation_data, $custom_field, $value, $field_index );
534
+ }
535
+ }
536
+
537
+ return $custom_fields_values;
538
+
539
+ }
540
+
541
+ private function replace_separator( $el ) {
542
+ return str_replace( self::CUSTOM_FIELD_KEY_SEPARATOR, '-', $el );
543
+ }
544
+
545
+ /**
546
+ * Inserts an element into an array, nested by keys.
547
+ * Input ['a', 'b'] for the keys, an empty array for $array and $x for the value would lead to
548
+ * [ 'a' => ['b' => $x ] ] being returned.
549
+ *
550
+ * @param array $keys indexes ordered from highest to lowest level
551
+ * @param array $array array into which the value is to be inserted
552
+ * @param mixed $value to be inserted
553
+ *
554
+ * @return array
555
+ */
556
+ private function insert_under_keys( $keys, $array, $value ) {
557
+ $array[ $keys[0] ] = count( $keys ) === 1
558
+ ? $value
559
+ : $this->insert_under_keys(
560
+ array_slice($keys, 1),
561
+ ( isset( $array[ $keys[0] ] ) ? $array[ $keys[0] ] : array() ),
562
+ $value );
563
+
564
+ return $array;
565
+ }
566
+
567
+
568
+ public function woocommerce_duplicate_product( $new_id, $post ){
569
+ $duplicated_products = array();
570
+
571
+ //duplicate original first
572
+ $trid = $this->sitepress->get_element_trid( $post->ID, 'post_' . $post->post_type );
573
+ $orig_id = $this->sitepress->get_original_element_id_by_trid( $trid );
574
+ $orig_lang = $this->woocommerce_wpml->products->get_original_product_language( $post->ID );
575
+
576
+ $wc_admin = new WC_Admin_Duplicate_Product();
577
+
578
+ if( $orig_id == $post->ID ){
579
+ $this->sitepress->set_element_language_details( $new_id, 'post_' . $post->post_type, false, $orig_lang );
580
+ $new_trid = $this->sitepress->get_element_trid( $new_id, 'post_' . $post->post_type );
581
+ $new_orig_id = $new_id;
582
+ }else{
583
+ $post_to_duplicate = $this->wpdb->get_row( $this->wpdb->prepare( "SELECT * FROM {$this->wpdb->posts} WHERE ID=%d", $orig_id ) );
584
+ if ( ! empty( $post_to_duplicate ) ) {
585
+ $new_orig_id = $wc_admin->duplicate_product( $post_to_duplicate );
586
+ do_action( 'wcml_after_duplicate_product' , $new_id, $post_to_duplicate );
587
+ $this->sitepress->set_element_language_details( $new_orig_id, 'post_' . $post->post_type, false, $orig_lang );
588
+ $new_trid = $this->sitepress->get_element_trid( $new_orig_id, 'post_' . $post->post_type );
589
+ if( get_post_meta( $orig_id, '_icl_lang_duplicate_of' ) ){
590
+ update_post_meta( $new_id, '_icl_lang_duplicate_of', $new_orig_id );
591
+ }
592
+ $this->sitepress->set_element_language_details( $new_id, 'post_' . $post->post_type, $new_trid, $this->sitepress->get_current_language() );
593
+ }
594
+ }
595
+
596
+ // Set language info for variations
597
+ if ( $children_products = get_children( 'post_parent=' . $new_orig_id . '&post_type=product_variation' ) ) {
598
+ foreach ( $children_products as $child ) {
599
+ $this->sitepress->set_element_language_details( $child->ID, 'post_product_variation', false, $orig_lang );
600
+ }
601
+ }
602
+
603
+ $translations = $this->sitepress->get_element_translations( $trid, 'post_' . $post->post_type );
604
+ $duplicated_products[ 'translations' ] = array();
605
+ if( $translations ){
606
+ foreach( $translations as $translation ){
607
+ if( !$translation->original && $translation->element_id != $post->ID ){
608
+ $post_to_duplicate = $this->wpdb->get_row( $this->wpdb->prepare( "SELECT * FROM {$this->wpdb->posts} WHERE ID=%d", $translation->element_id ) );
609
+
610
+ if( ! empty( $post_to_duplicate ) ) {
611
+ $new_id = $wc_admin->duplicate_product( $post_to_duplicate );
612
+ $new_id_obj = get_post( $new_id );
613
+ $new_slug = wp_unique_post_slug( sanitize_title( $new_id_obj->post_title ), $new_id, $post_to_duplicate->post_status, $post_to_duplicate->post_type, $new_id_obj->post_parent );
614
+
615
+ $this->wpdb->update(
616
+ $this->wpdb->posts,
617
+ array(
618
+ 'post_name' => $new_slug,
619
+ 'post_status' => 'draft'
620
+ ),
621
+ array( 'ID' => $new_id )
622
+ );
623
+
624
+ do_action( 'wcml_after_duplicate_product' , $new_id, $post_to_duplicate );
625
+ $this->sitepress->set_element_language_details( $new_id, 'post_' . $post->post_type, $new_trid, $translation->language_code );
626
+ if( get_post_meta( $translation->element_id, '_icl_lang_duplicate_of' ) ){
627
+ update_post_meta( $new_id, '_icl_lang_duplicate_of', $new_orig_id );
628
+ }
629
+ $duplicated_products[ 'translations' ][] = $new_id;
630
+ }
631
+ }
632
+ }
633
+ }
634
+
635
+ $duplicated_products[ 'original' ] = $new_orig_id;
636
+
637
+ return $duplicated_products;
638
+ }
639
 
640
  public function icl_connect_translations_action(){
641
  if( isset( $_POST[ 'icl_ajx_action' ] ) && $_POST[ 'icl_ajx_action' ] == 'connect_translations' ) {
inc/wcml-switch-lang-request.php CHANGED
@@ -2,19 +2,28 @@
2
 
3
  class WCML_Switch_Lang_Request{
4
 
 
5
  protected $default_language;
 
6
  protected $wp_api;
 
7
  private $cookie;
 
 
8
 
9
- function __construct( $cookie, $wp_api ){
10
 
11
  if( !is_admin() ){
12
- global $sitepress;
13
-
14
  $this->cookie = $cookie;
15
  $this->wp_api = $wp_api;
16
- $this->default_language = $sitepress->get_default_language();
 
 
 
 
 
17
 
 
18
  add_action( 'wpml_before_init', array( $this, 'detect_user_switch_language' ) );
19
  }
20
  }
2
 
3
  class WCML_Switch_Lang_Request{
4
 
5
+ /** @var string $default_language */
6
  protected $default_language;
7
+ /** @var WPML_WP_API */
8
  protected $wp_api;
9
+ /** @var WPML_Cookie */
10
  private $cookie;
11
+ /** @var Sitepress */
12
+ private $sitepress;
13
 
14
+ function __construct( WPML_Cookie $cookie, WPML_WP_API $wp_api, Sitepress $sitepress ){
15
 
16
  if( !is_admin() ){
 
 
17
  $this->cookie = $cookie;
18
  $this->wp_api = $wp_api;
19
+ $this->sitepress = $sitepress;
20
+ $this->default_language = $this->sitepress->get_default_language();
21
+ }
22
+ }
23
+
24
+ public function add_hooks(){
25
 
26
+ if( !is_admin() && $this->sitepress->get_setting( $this->wp_api->constant( 'WPML_Cookie_Setting::COOKIE_SETTING_FIELD' ) ) ) {
27
  add_action( 'wpml_before_init', array( $this, 'detect_user_switch_language' ) );
28
  }
29
  }
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.8.0
8
- Stable tag: 4.1.4
9
 
10
  Allows running fully multilingual e-commerce sites using WooCommerce and WPML.
11
 
@@ -142,53 +142,44 @@ WooCommerce Multilingual is compatible with all major WooCommerce extensions. We
142
 
143
  == Changelog ==
144
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
145
  = 4.1.4 =
146
- * Fix: A PHP warning was shown on a product bundle page on the front end (when using WooCommerce Product Bundles)
147
- * Fix: Added possibility to filter available Currency Switcher templates paths via "wcml_cs_directories_to_scan" filter
148
- * Fix: The "Copy to a new draft" link was showing two times on the product edit page
149
- * Fix: For taxonomies having the term_id distinct from term_taxonomy_id, the translations could have been accidentally overwritten
150
- * Fix: In some conditions, a fatal error could come up when editing a product
151
- * Fix: In some circustances, disabling currency switcher on product page produced a fatal error
152
- * Fix: Custom attributes in the translations were reset after editing the original product
153
- * Fix: Sometimes, the translated product category pages were returning a 404 error
154
- * Fix: It was not possible to filter products by price on the shop page using the WooCommerce Price Filter widget
155
-
156
- = 4.1.3 =
157
- * Improvements for the REST API support (compliant with WooCommerce REST API v2)
158
- * Bug fix: Order confirmation emails were not translated correctly when using WooCommerce 3.0
159
- * Bug fix: The admin language switcher was displayed in a wrong place when using the Swish
160
- * Bug fix: Composite products were displaying the wrong price amount in secondary currencies
161
- * Bug fix: Sometimes switching the currency on the front end didn't work when using a caching plugin
162
- * Bug fix: Don't enforce the REST API support (added in 4.1) for legacy WooCommerce REST calls
163
- * Bug fix: In some conditions, variations custom fields were double-serialized when copied to the translations
164
- * Bug fix: Sometimes the currency switcher preview was not displaying correctly
165
- * Bug fix: Manually adding a product to an order was sometimes causing a fatal error
166
- * Bug fix: A fatal error was occurring when trying to translate a bookable product with Persons
167
- * Bug fix: The RTL styles were loaded incorrectly on the translation management when Yoast SEO was active
168
- * Bug fix: Trying to display the currency switcher with the 'do_action' function was causing a fatal error
169
- * Bug fix: Product urls were incorrect when permalink structure was set to /index.php/%postname%/
170
- * Bug fix: Product variation custom fields were double-serialized when copied to translations
171
- * Bug fix: Language switcher was misplaced when using the Swish Gateway extension
172
- * Bug fix: Downloadable files were not available in secondary languages
173
- * Bug fix: Using The Events Calendar without Tribe Tickets RSVP and Tribe Tickets Plus caused errors
174
- * Bug fix: Incorrect currency was shown in the backend for orders placed in a secondary currency
175
- * Bug fix: In some circumstances, the shipping tax was rounded incorrectly in the secondary currencies
176
- * Bug fix: After duplicating a variable product, the variations weren't showing on the translated product edit page
177
- * Added the option to synchronize the products stock information on the troubleshooting section
178
- * Fixed a compatibility issue with WooCommerce Bookings and WooCommerce Product addons (both active)
179
- * Fixed a compatibility issue with WooCommerce Subscriptions (shipping costs incorrectly displayed)
180
- * Fixed a compatibility issue with WooCommerce Product Bundles (removed items were not synced with translations)
181
- * Fixed a compatibility issue with WooCommerce Membership
182
- * Fixed a compatibility issue with WooCommerce Print Invoices/Packing Lists (PHP notices and possible a fatal error)
183
- * Fixed compatibility issues with Aelia Currency Switcher and Aelia Foundation
184
- * Fixed a compatibility issue with Visual Composer: shortcodes were not parsed in the translation editor
185
 
186
  = 4.1.2 =
187
  * Fixed `Fatal error: Call to undefined method WPML_WP_API::defined`
188
  * Fixed the currency switcher not being displayed correctly when using the Storefront theme
189
  * Fixed `Fatal error: Call to undefined function wc_format_decimal()`
190
  * Fixed a bug causing an error when upgrading WooCommerce Multilingual to version 4.1 with WooCommerce inactive.
191
- * Fixed the currency switcher css being loaded when no currency switcher was displayed
192
 
193
  = 4.1.1 =
194
  * Fixed a pre PHP 5.4 compatibility issue
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.8
8
+ Stable tag: 4.2.0
9
 
10
  Allows running fully multilingual e-commerce sites using WooCommerce and WPML.
11
 
142
 
143
  == Changelog ==
144
 
145
+ = 4.2.0 =
146
+ * Added the ability to translate Sensei question custom post types
147
+ * Added the ability to translate serialized custom fields in the Translation Editor
148
+ * Payment method title not displaying in emails Mollie Payment's payment processor compatibility
149
+ * Show an admin notice for environments in which switching the language or currency on the front end, could corrupt the cart contents
150
+ * When selecting the currencylayer provider for automatic exchange rate, the API KEY filter was not visible
151
+ * The multi-currency component made the admin dashboard page loading unnecessarily slow
152
+ * Variations with custom attributes could not be duplicated as translations
153
+ * A fatal error occurred when using old WordPress versions (before 4.4.0) - rest_get_url_prefix didn't exist
154
+ * The admin orders page was loading slower than necessary
155
+ * A PHP fatal error was occurring when using the Adventure Tours extension
156
+ * A product addon was added to the cart more then once in combination with Bookings
157
+ * For translated products, the product variation names were displayed in the old format (before WooCommerce 3.0)
158
+ * The prices in the secondary currencies for products in secondary languages for products read via the REST API were incorrect
159
+ * CSS for the currency switcher was loaded when the multi-currency was not enabled
160
+ * Fixed a javascript error on the shop page
161
+ * It was not possible to use the clear cart feature with enabled WPML Ajax cookies only
162
+ * WooCommerce Product Bundles: Bundled items filtering by variation was not synced with translations
163
+ * Bookings max availability value was changing after adding bookable product to cart few times
164
+ * In some cases the option to prompt for a confirmation about resetting the cart when switching the language was not working
165
+ * The variation names were, sometimes, displayed in the wrong language in the orders, on the back-end
166
+
167
  = 4.1.4 =
168
+ * Added possibility to filter available Currency Switcher templates paths via "wcml_cs_directories_to_scan" filter
169
+ * The "Copy to a new draft" link was showing two times on the product edit page
170
+ * For taxonomies having the term_id distinct from term_taxonomy_id, the translations could have been accidentally overwritten
171
+ * In some conditions, a fatal error could come up when editing a product
172
+ * In some circustances, disabling currency switcher on product page produced a fatal error
173
+ * Custom attributes in the translations were reset after editing the original product
174
+ * Sometimes, the translated product category pages were returning a 404 error
175
+ * It was not possible to filter products by price on the shop page using the WooCommerce Price Filter widget
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
176
 
177
  = 4.1.2 =
178
  * Fixed `Fatal error: Call to undefined method WPML_WP_API::defined`
179
  * Fixed the currency switcher not being displayed correctly when using the Storefront theme
180
  * Fixed `Fatal error: Call to undefined function wc_format_decimal()`
181
  * Fixed a bug causing an error when upgrading WooCommerce Multilingual to version 4.1 with WooCommerce inactive.
182
+ * ixed the currency switcher css being loaded when no currency switcher was displayed
183
 
184
  = 4.1.1 =
185
  * Fixed a pre PHP 5.4 compatibility issue
res/css/wcml-cart-warning.css ADDED
@@ -0,0 +1,15 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*===================================================================*/
2
+ .otgs-is-dismissible {
3
+ position: relative;
4
+ padding-right: 38px;
5
+ }
6
+ .otgs-is-dismissible .notice-dismiss {
7
+ text-decoration: none;
8
+ }
9
+ .otgs-is-dismissible p [class*="button-"] {
10
+ margin: -5px 5px;
11
+ }
12
+ .otgs-is-dismissible ul {
13
+ list-style-type: disc;
14
+ margin: 0.5em 1.5em;
15
+ }
res/js/wcml-multi-currency.js CHANGED
@@ -11,7 +11,7 @@ jQuery(document).ready(function(){
11
  wcml_load_currency( jQuery(this).attr('rel') );
12
  });
13
 
14
- if( typeof woocommerce_price_slider_params != 'undefined' ){
15
  woocommerce_price_slider_params.currency_symbol = wcml_mc_settings.current_currency.symbol;
16
  }
17
  });
11
  wcml_load_currency( jQuery(this).attr('rel') );
12
  });
13
 
14
+ if( typeof woocommerce_price_slider_params !== 'undefined' ){
15
  woocommerce_price_slider_params.currency_symbol = wcml_mc_settings.current_currency.symbol;
16
  }
17
  });
templates/settings-ui.twig CHANGED
@@ -12,12 +12,12 @@
12
  <ul>
13
  <li>
14
  <input type="radio" name="trnsl_interface" value="{{ wpml_translation }}"
15
- {% if form.translation_interface.controls_value == wpml_translation %} checked="checked"{% endif %} id="wcml_trsl_interface_wcml" />
16
  <label for="wcml_trsl_interface_wcml">{{ form.translation_interface.wcml.label }}</label>
17
  </li>
18
  <li>
19
  <input type="radio" name="trnsl_interface" value="{{ native_translation }}"
20
- {% if form.translation_interface.controls_value == native_translation %} checked="checked"{% endif %} id="wcml_trsl_interface_native" />
21
  <label for="wcml_trsl_interface_native">{{ form.translation_interface.native.label|raw }}</label>
22
  </li>
23
  </ul>
@@ -40,12 +40,12 @@
40
  <ul>
41
  <li>
42
  <input type="checkbox" name="products_sync_date" value="1"
43
- {% if form.synchronization.sync_date.value == 1 %} checked="checked"{% endif %} id="wcml_products_sync_date" />
44
  <label for="wcml_products_sync_date">{{ form.synchronization.sync_date.label }}</label>
45
  </li>
46
  <li>
47
  <input type="checkbox" name="products_sync_order" value="1"
48
- {% if form.synchronization.sync_order.value == 1 %} checked="checked"{% endif %} id="wcml_products_sync_order" />
49
  <label for="wcml_products_sync_order">{{ form.synchronization.sync_order.label }}</label>
50
  </li>
51
  </ul>
@@ -69,12 +69,12 @@
69
  <ul>
70
  <li>
71
  <input type="radio" name="wcml_file_path_sync" value="1"
72
- {% if form.file_sync.value == 1 %} checked="checked"{% endif %} id="wcml_file_path_sync_auto" />
73
  <label for="wcml_file_path_sync_auto">{{ form.file_sync.label_same }}</label>
74
  </li>
75
  <li>
76
  <input type="radio" name="wcml_file_path_sync" value="0"
77
- {% if form.file_sync.value == 0 %} checked="checked"{% endif %} id="wcml_file_path_sync_self" />
78
  <label for="wcml_file_path_sync_self">{{ form.file_sync.label_diff }}</label>
79
  </li>
80
  </ul>
@@ -85,7 +85,7 @@
85
  </div> <!-- .wcml-section -->
86
 
87
 
88
- <div class="wcml-section">
89
  <div class="wcml-section-header">
90
  <h3>
91
  {{ form.cart_sync.heading }}
@@ -93,6 +93,12 @@
93
  </h3>
94
  </div>
95
  <div class="wcml-section-content">
 
 
 
 
 
 
96
  <div class="wcml-section-content-inner">
97
  <h4>
98
  {{ form.cart_sync.lang_switch.heading }}
@@ -100,12 +106,16 @@
100
  <ul>
101
  <li>
102
  <input type="radio" name="cart_sync_lang" value="{{ wcml_cart_sync }}"
103
- {% if form.cart_sync.lang_switch.value == wcml_cart_sync %} checked="checked"{% endif %} id="wcml_cart_sync_lang_sync" />
 
 
104
  <label for="wcml_cart_sync_lang_sync">{{ form.cart_sync.lang_switch.sync_label|raw }}</label>
105
  </li>
106
  <li>
107
  <input type="radio" name="cart_sync_lang" value="{{ wcml_cart_clear }}"
108
- {% if form.cart_sync.lang_switch.value == wcml_cart_clear %} checked="checked"{% endif %} id="wcml_cart_sync_lang_clear" />
 
 
109
  <label for="wcml_cart_sync_lang_clear">{{ form.cart_sync.lang_switch.clear_label|raw }}</label>
110
  </li>
111
  </ul>
@@ -117,12 +127,16 @@
117
  <ul>
118
  <li>
119
  <input type="radio" name="cart_sync_currencies" value="{{ wcml_cart_sync }}"
120
- {% if form.cart_sync.currency_switch.value == wcml_cart_sync %} checked="checked"{% endif %} id="wcml_cart_sync_curr_sync" />
 
 
121
  <label for="wcml_cart_sync_curr_sync">{{ form.cart_sync.currency_switch.sync_label|raw }}</label>
122
  </li>
123
  <li>
124
  <input type="radio" name="cart_sync_currencies" value="{{ wcml_cart_clear }}"
125
- {% if form.cart_sync.currency_switch.value == wcml_cart_clear %} checked="checked"{% endif %} id="wcml_cart_sync_curr_clear" />
 
 
126
  <label for="wcml_cart_sync_curr_clear">{{ form.cart_sync.currency_switch.clear_label|raw }}</label>
127
  </li>
128
  </ul>
@@ -139,4 +153,4 @@
139
  <input type='submit' name="wcml_save_settings" value='{{ form.save_label }}' class='button-primary'/>
140
  </p>
141
  </form>
142
- <a class="alignright" href="{{ troubleshooting.url }}">{{ troubleshooting.label }}</a>
12
  <ul>
13
  <li>
14
  <input type="radio" name="trnsl_interface" value="{{ wpml_translation }}"
15
+ {% if form.translation_interface.controls_value == wpml_translation %} checked="checked"{% endif %} id="wcml_trsl_interface_wcml" />
16
  <label for="wcml_trsl_interface_wcml">{{ form.translation_interface.wcml.label }}</label>
17
  </li>
18
  <li>
19
  <input type="radio" name="trnsl_interface" value="{{ native_translation }}"
20
+ {% if form.translation_interface.controls_value == native_translation %} checked="checked"{% endif %} id="wcml_trsl_interface_native" />
21
  <label for="wcml_trsl_interface_native">{{ form.translation_interface.native.label|raw }}</label>
22
  </li>
23
  </ul>
40
  <ul>
41
  <li>
42
  <input type="checkbox" name="products_sync_date" value="1"
43
+ {% if form.synchronization.sync_date.value == 1 %} checked="checked"{% endif %} id="wcml_products_sync_date" />
44
  <label for="wcml_products_sync_date">{{ form.synchronization.sync_date.label }}</label>
45
  </li>
46
  <li>
47
  <input type="checkbox" name="products_sync_order" value="1"
48
+ {% if form.synchronization.sync_order.value == 1 %} checked="checked"{% endif %} id="wcml_products_sync_order" />
49
  <label for="wcml_products_sync_order">{{ form.synchronization.sync_order.label }}</label>
50
  </li>
51
  </ul>
69
  <ul>
70
  <li>
71
  <input type="radio" name="wcml_file_path_sync" value="1"
72
+ {% if form.file_sync.value == 1 %} checked="checked"{% endif %} id="wcml_file_path_sync_auto" />
73
  <label for="wcml_file_path_sync_auto">{{ form.file_sync.label_same }}</label>
74
  </li>
75
  <li>
76
  <input type="radio" name="wcml_file_path_sync" value="0"
77
+ {% if form.file_sync.value == 0 %} checked="checked"{% endif %} id="wcml_file_path_sync_self" />
78
  <label for="wcml_file_path_sync_self">{{ form.file_sync.label_diff }}</label>
79
  </li>
80
  </ul>
85
  </div> <!-- .wcml-section -->
86
 
87
 
88
+ <div class="wcml-section cart-sync-section">
89
  <div class="wcml-section-header">
90
  <h3>
91
  {{ form.cart_sync.heading }}
93
  </h3>
94
  </div>
95
  <div class="wcml-section-content">
96
+
97
+ {% if not form.cart_sync.wpml_cookie_enabled %}
98
+ <i class="otgs-ico-warning"></i>
99
+ <strong>{{ form.cart_sync.cookie_not_enabled_message|raw }}</strong>
100
+ {% endif %}
101
+
102
  <div class="wcml-section-content-inner">
103
  <h4>
104
  {{ form.cart_sync.lang_switch.heading }}
106
  <ul>
107
  <li>
108
  <input type="radio" name="cart_sync_lang" value="{{ wcml_cart_sync }}"
109
+ {% if form.cart_sync.lang_switch.value == wcml_cart_sync %} checked="checked"{% endif %}
110
+ {% if not form.cart_sync.wpml_cookie_enabled %} disabled="disabled"{% endif %}
111
+ id="wcml_cart_sync_lang_sync" />
112
  <label for="wcml_cart_sync_lang_sync">{{ form.cart_sync.lang_switch.sync_label|raw }}</label>
113
  </li>
114
  <li>
115
  <input type="radio" name="cart_sync_lang" value="{{ wcml_cart_clear }}"
116
+ {% if form.cart_sync.lang_switch.value == wcml_cart_clear %} checked="checked"{% endif %}
117
+ {% if not form.cart_sync.wpml_cookie_enabled %} disabled="disabled"{% endif %}
118
+ id="wcml_cart_sync_lang_clear" />
119
  <label for="wcml_cart_sync_lang_clear">{{ form.cart_sync.lang_switch.clear_label|raw }}</label>
120
  </li>
121
  </ul>
127
  <ul>
128
  <li>
129
  <input type="radio" name="cart_sync_currencies" value="{{ wcml_cart_sync }}"
130
+ {% if form.cart_sync.currency_switch.value == wcml_cart_sync %} checked="checked"{% endif %}
131
+ {% if not form.cart_sync.wpml_cookie_enabled %} disabled="disabled"{% endif %}
132
+ id="wcml_cart_sync_curr_sync" />
133
  <label for="wcml_cart_sync_curr_sync">{{ form.cart_sync.currency_switch.sync_label|raw }}</label>
134
  </li>
135
  <li>
136
  <input type="radio" name="cart_sync_currencies" value="{{ wcml_cart_clear }}"
137
+ {% if form.cart_sync.currency_switch.value == wcml_cart_clear %} checked="checked"{% endif %}
138
+ {% if not form.cart_sync.wpml_cookie_enabled %} disabled="disabled"{% endif %}
139
+ id="wcml_cart_sync_curr_clear" />
140
  <label for="wcml_cart_sync_curr_clear">{{ form.cart_sync.currency_switch.clear_label|raw }}</label>
141
  </li>
142
  </ul>
153
  <input type='submit' name="wcml_save_settings" value='{{ form.save_label }}' class='button-primary'/>
154
  </p>
155
  </form>
156
+ <a class="alignright" href="{{ troubleshooting.url }}">{{ troubleshooting.label }}</a>
templates/status/store-pages.twig CHANGED
@@ -1,4 +1,4 @@
1
- <div class="wcml-section">
2
  <div class="wcml-section-header">
3
  <h3>
4
  {{ strings.store_pages }}
1
+ <div class="wcml-section wc-store-pages-section">
2
  <div class="wcml-section-header">
3
  <h3>
4
  {{ strings.store_pages }}
templates/status/taxonomies.twig CHANGED
@@ -1,4 +1,4 @@
1
- <div class="wcml-section">
2
  <div class="wcml-section-header">
3
  <h3>
4
  {{ strings.tax_missing }}
1
+ <div class="wcml-section wc-missing-translation-section">
2
  <div class="wcml-section-header">
3
  <h3>
4
  {{ strings.tax_missing }}
vendor/autoload.php CHANGED
@@ -4,4 +4,4 @@
4
 
5
  require_once __DIR__ . '/composer/autoload_real.php';
6
 
7
- return ComposerAutoloaderInit3d46cc8388475e6b99b9a4c2356d4330::getLoader();
4
 
5
  require_once __DIR__ . '/composer/autoload_real.php';
6
 
7
+ return ComposerAutoloaderInit1e950a3498b2b701753514ff78661529::getLoader();
vendor/autoload_52.php CHANGED
@@ -4,4 +4,4 @@
4
 
5
  require_once dirname(__FILE__) . '/composer'.'/autoload_real_52.php';
6
 
7
- return ComposerAutoloaderInit226a7f3fe2d604eac20e142d7118628a::getLoader();
4
 
5
  require_once dirname(__FILE__) . '/composer'.'/autoload_real_52.php';
6
 
7
+ return ComposerAutoloaderInit47e7b07dd515551e87cf2efd9df54aba::getLoader();
vendor/composer/autoload_classmap.php CHANGED
@@ -27,6 +27,7 @@ return array(
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\\ExpressionEngineInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/ExpressionEngineInstaller.php',
31
  'Composer\\Installers\\FuelInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/FuelInstaller.php',
32
  'Composer\\Installers\\FuelphpInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/FuelphpInstaller.php',
@@ -34,21 +35,26 @@ return array(
34
  'Composer\\Installers\\HuradInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/HuradInstaller.php',
35
  'Composer\\Installers\\ImageCMSInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/ImageCMSInstaller.php',
36
  'Composer\\Installers\\Installer' => $vendorDir . '/composer/installers/src/Composer/Installers/Installer.php',
 
37
  'Composer\\Installers\\JoomlaInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/JoomlaInstaller.php',
 
38
  'Composer\\Installers\\KirbyInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/KirbyInstaller.php',
39
  'Composer\\Installers\\KodiCMSInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/KodiCMSInstaller.php',
40
  'Composer\\Installers\\KohanaInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/KohanaInstaller.php',
41
  'Composer\\Installers\\LaravelInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/LaravelInstaller.php',
 
42
  'Composer\\Installers\\LithiumInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/LithiumInstaller.php',
43
  'Composer\\Installers\\MODULEWorkInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/MODULEWorkInstaller.php',
44
  'Composer\\Installers\\MODXEvoInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/MODXEvoInstaller.php',
45
  'Composer\\Installers\\MagentoInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/MagentoInstaller.php',
46
  'Composer\\Installers\\MakoInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/MakoInstaller.php',
47
  'Composer\\Installers\\MauticInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/MauticInstaller.php',
 
48
  'Composer\\Installers\\MediaWikiInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/MediaWikiInstaller.php',
49
  'Composer\\Installers\\MicroweberInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/MicroweberInstaller.php',
50
  'Composer\\Installers\\MoodleInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/MoodleInstaller.php',
51
  'Composer\\Installers\\OctoberInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/OctoberInstaller.php',
 
52
  'Composer\\Installers\\OxidInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/OxidInstaller.php',
53
  'Composer\\Installers\\PPIInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/PPIInstaller.php',
54
  'Composer\\Installers\\PhiftyInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/PhiftyInstaller.php',
@@ -57,6 +63,7 @@ return array(
57
  'Composer\\Installers\\PiwikInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/PiwikInstaller.php',
58
  'Composer\\Installers\\PlentymarketsInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/PlentymarketsInstaller.php',
59
  'Composer\\Installers\\Plugin' => $vendorDir . '/composer/installers/src/Composer/Installers/Plugin.php',
 
60
  'Composer\\Installers\\PrestashopInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/PrestashopInstaller.php',
61
  'Composer\\Installers\\PuppetInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/PuppetInstaller.php',
62
  'Composer\\Installers\\RadPHPInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/RadPHPInstaller.php',
@@ -66,18 +73,190 @@ return array(
66
  'Composer\\Installers\\SMFInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/SMFInstaller.php',
67
  'Composer\\Installers\\ShopwareInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/ShopwareInstaller.php',
68
  'Composer\\Installers\\SilverStripeInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/SilverStripeInstaller.php',
 
69
  'Composer\\Installers\\Symfony1Installer' => $vendorDir . '/composer/installers/src/Composer/Installers/Symfony1Installer.php',
70
  'Composer\\Installers\\TYPO3CmsInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/TYPO3CmsInstaller.php',
71
  'Composer\\Installers\\TYPO3FlowInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/TYPO3FlowInstaller.php',
72
  'Composer\\Installers\\TheliaInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/TheliaInstaller.php',
73
  'Composer\\Installers\\TuskInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/TuskInstaller.php',
74
  'Composer\\Installers\\VanillaInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/VanillaInstaller.php',
 
75
  'Composer\\Installers\\WHMCSInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/WHMCSInstaller.php',
76
  'Composer\\Installers\\WolfCMSInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/WolfCMSInstaller.php',
77
  'Composer\\Installers\\WordPressInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/WordPressInstaller.php',
78
  'Composer\\Installers\\YawikInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/YawikInstaller.php',
79
  'Composer\\Installers\\ZendInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/ZendInstaller.php',
80
  'Composer\\Installers\\ZikulaInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/ZikulaInstaller.php',
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
81
  'Twig_Autoloader' => $vendorDir . '/twig/twig/lib/Twig/Autoloader.php',
82
  'Twig_BaseNodeVisitor' => $vendorDir . '/twig/twig/lib/Twig/BaseNodeVisitor.php',
83
  'Twig_CacheInterface' => $vendorDir . '/twig/twig/lib/Twig/CacheInterface.php',
@@ -217,6 +396,7 @@ return array(
217
  'Twig_Node_With' => $vendorDir . '/twig/twig/lib/Twig/Node/With.php',
218
  'Twig_Parser' => $vendorDir . '/twig/twig/lib/Twig/Parser.php',
219
  'Twig_ParserInterface' => $vendorDir . '/twig/twig/lib/Twig/ParserInterface.php',
 
220
  'Twig_Profiler_Dumper_Blackfire' => $vendorDir . '/twig/twig/lib/Twig/Profiler/Dumper/Blackfire.php',
221
  'Twig_Profiler_Dumper_Html' => $vendorDir . '/twig/twig/lib/Twig/Profiler/Dumper/Html.php',
222
  'Twig_Profiler_Dumper_Text' => $vendorDir . '/twig/twig/lib/Twig/Profiler/Dumper/Text.php',
@@ -290,6 +470,7 @@ return array(
290
  'WCML_Cart' => $baseDir . '/inc/class-wcml-cart.php',
291
  'WCML_Cart_Removed_Items_Widget' => $baseDir . '/inc/class-wcml-cart-removed-items-widget.php',
292
  'WCML_Cart_Switch_Lang_Functions' => $baseDir . '/inc/wcml-cart-switch-lang-functions.php',
 
293
  'WCML_Checkout_Addons' => $baseDir . '/compatibility/class-wcml-checkout-addons.php',
294
  'WCML_Checkout_Field_Editor' => $baseDir . '/compatibility/class-wcml-checkout-field-editor.php',
295
  'WCML_Compatibility' => $baseDir . '/inc/class-wcml-compatibility.php',
@@ -300,6 +481,7 @@ return array(
300
  'WCML_Currency_Switcher' => $baseDir . '/inc/currencies/currency-switcher/class-wcml-currency-switcher.php',
301
  'WCML_Currency_Switcher_Ajax' => $baseDir . '/inc/currencies/currency-switcher/class-wcml-currency-switcher-ajax.php',
302
  'WCML_Currency_Switcher_Options_Dialog' => $baseDir . '/inc/template-classes/currency-switcher/class-wcml-currency-switcher-options-dialog.php',
 
303
  'WCML_Currency_Switcher_Template' => $baseDir . '/inc/template-classes/currency-switcher/class-wcml-currency-switcher-template.php',
304
  'WCML_Currency_Switcher_Templates' => $baseDir . '/inc/currencies/currency-switcher/class-wcml-currency-switcher-templates.php',
305
  'WCML_Currency_Switcher_Widget' => $baseDir . '/inc/currencies/currency-switcher/class-wcml-currency-switcher-widget.php',
@@ -351,6 +533,7 @@ return array(
351
  'WCML_Not_Translatable_Attributes' => $baseDir . '/inc/template-classes/class-wcml-not-translatable-attributes.php',
352
  'WCML_Orders' => $baseDir . '/inc/class-wcml-orders.php',
353
  'WCML_Page_Builders' => $baseDir . '/inc/translation-editor/class-wcml-page-builders.php',
 
354
  'WCML_Per_Product_Shipping' => $baseDir . '/compatibility/class-wcml-per-product-shipping.php',
355
  'WCML_Pip' => $baseDir . '/compatibility/class-wcml-pip.php',
356
  'WCML_Plugins_Wrap' => $baseDir . '/inc/template-classes/class-wcml-plugins-wrap.php',
@@ -369,6 +552,7 @@ return array(
369
  'WCML_Reports' => $baseDir . '/inc/class-wcml-reports.php',
370
  'WCML_Requests' => $baseDir . '/inc/class-wcml-requests.php',
371
  'WCML_Resources' => $baseDir . '/inc/class-wcml-resources.php',
 
372
  'WCML_Settings_UI' => $baseDir . '/inc/template-classes/class-wcml-settings-ui.php',
373
  'WCML_Setup' => $baseDir . '/inc/admin-menus/class-wcml-setup.php',
374
  'WCML_Setup_Attributes_UI' => $baseDir . '/inc/template-classes/setup/class-wcml-setup-attributes-ui.php',
@@ -419,7 +603,6 @@ return array(
419
  'WCML_WooCommerce_Rest_API_Support' => $baseDir . '/inc/class-wcml-woocommerce-rest-api-support.php',
420
  'WCML_YITH_WCQV' => $baseDir . '/compatibility/class-wcml-yith-wcqv.php',
421
  'WCML_gravityforms' => $baseDir . '/compatibility/class-wcml-gravityforms.php',
422
- 'WCML_sensei' => $baseDir . '/compatibility/class-wcml-sensei.php',
423
  'WCML_wcExporter' => $baseDir . '/compatibility/class-wcml-wcexporter.php',
424
  'WCML_xDomain_Data' => $baseDir . '/inc/class-wcml-xdomain-data.php',
425
  'WooCommerce_Functions_Wrapper' => $baseDir . '/inc/woocommerce-functions-wrapper.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\\FuelInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/FuelInstaller.php',
33
  'Composer\\Installers\\FuelphpInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/FuelphpInstaller.php',
35
  'Composer\\Installers\\HuradInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/HuradInstaller.php',
36
  'Composer\\Installers\\ImageCMSInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/ImageCMSInstaller.php',
37
  'Composer\\Installers\\Installer' => $vendorDir . '/composer/installers/src/Composer/Installers/Installer.php',
38
+ 'Composer\\Installers\\ItopInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/ItopInstaller.php',
39
  'Composer\\Installers\\JoomlaInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/JoomlaInstaller.php',
40
+ 'Composer\\Installers\\KanboardInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/KanboardInstaller.php',
41
  'Composer\\Installers\\KirbyInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/KirbyInstaller.php',
42
  'Composer\\Installers\\KodiCMSInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/KodiCMSInstaller.php',
43
  'Composer\\Installers\\KohanaInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/KohanaInstaller.php',
44
  'Composer\\Installers\\LaravelInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/LaravelInstaller.php',
45
+ 'Composer\\Installers\\LavaLiteInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/LavaLiteInstaller.php',
46
  'Composer\\Installers\\LithiumInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/LithiumInstaller.php',
47
  'Composer\\Installers\\MODULEWorkInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/MODULEWorkInstaller.php',
48
  'Composer\\Installers\\MODXEvoInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/MODXEvoInstaller.php',
49
  'Composer\\Installers\\MagentoInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/MagentoInstaller.php',
50
  'Composer\\Installers\\MakoInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/MakoInstaller.php',
51
  'Composer\\Installers\\MauticInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/MauticInstaller.php',
52
+ 'Composer\\Installers\\MayaInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/MayaInstaller.php',
53
  'Composer\\Installers\\MediaWikiInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/MediaWikiInstaller.php',
54
  'Composer\\Installers\\MicroweberInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/MicroweberInstaller.php',
55
  'Composer\\Installers\\MoodleInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/MoodleInstaller.php',
56
  'Composer\\Installers\\OctoberInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/OctoberInstaller.php',
57
+ 'Composer\\Installers\\OntoWikiInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/OntoWikiInstaller.php',
58
  'Composer\\Installers\\OxidInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/OxidInstaller.php',
59
  'Composer\\Installers\\PPIInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/PPIInstaller.php',
60
  'Composer\\Installers\\PhiftyInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/PhiftyInstaller.php',
63
  'Composer\\Installers\\PiwikInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/PiwikInstaller.php',
64
  'Composer\\Installers\\PlentymarketsInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/PlentymarketsInstaller.php',
65
  'Composer\\Installers\\Plugin' => $vendorDir . '/composer/installers/src/Composer/Installers/Plugin.php',
66
+ 'Composer\\Installers\\PortoInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/PortoInstaller.php',
67
  'Composer\\Installers\\PrestashopInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/PrestashopInstaller.php',
68
  'Composer\\Installers\\PuppetInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/PuppetInstaller.php',
69
  'Composer\\Installers\\RadPHPInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/RadPHPInstaller.php',
73
  'Composer\\Installers\\SMFInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/SMFInstaller.php',
74
  'Composer\\Installers\\ShopwareInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/ShopwareInstaller.php',
75
  'Composer\\Installers\\SilverStripeInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/SilverStripeInstaller.php',
76
+ 'Composer\\Installers\\SyDESInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/SyDESInstaller.php',
77
  'Composer\\Installers\\Symfony1Installer' => $vendorDir . '/composer/installers/src/Composer/Installers/Symfony1Installer.php',
78
  'Composer\\Installers\\TYPO3CmsInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/TYPO3CmsInstaller.php',
79
  'Composer\\Installers\\TYPO3FlowInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/TYPO3FlowInstaller.php',
80
  'Composer\\Installers\\TheliaInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/TheliaInstaller.php',
81
  'Composer\\Installers\\TuskInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/TuskInstaller.php',
82
  'Composer\\Installers\\VanillaInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/VanillaInstaller.php',
83
+ 'Composer\\Installers\\VgmcpInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/VgmcpInstaller.php',
84
  'Composer\\Installers\\WHMCSInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/WHMCSInstaller.php',
85
  'Composer\\Installers\\WolfCMSInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/WolfCMSInstaller.php',
86
  'Composer\\Installers\\WordPressInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/WordPressInstaller.php',
87
  'Composer\\Installers\\YawikInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/YawikInstaller.php',
88
  'Composer\\Installers\\ZendInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/ZendInstaller.php',
89
  'Composer\\Installers\\ZikulaInstaller' => $vendorDir . '/composer/installers/src/Composer/Installers/ZikulaInstaller.php',
90
+ 'Twig\\Cache\\CacheInterface' => $vendorDir . '/twig/twig/src/Cache/CacheInterface.php',
91
+ 'Twig\\Cache\\FilesystemCache' => $vendorDir . '/twig/twig/src/Cache/FilesystemCache.php',
92
+ 'Twig\\Cache\\NullCache' => $vendorDir . '/twig/twig/src/Cache/NullCache.php',
93
+ 'Twig\\Compiler' => $vendorDir . '/twig/twig/src/Compiler.php',
94
+ 'Twig\\Environment' => $vendorDir . '/twig/twig/src/Environment.php',
95
+ 'Twig\\Error\\Error' => $vendorDir . '/twig/twig/src/Error/Error.php',
96
+ 'Twig\\Error\\LoaderError' => $vendorDir . '/twig/twig/src/Error/LoaderError.php',
97
+ 'Twig\\Error\\RuntimeError' => $vendorDir . '/twig/twig/src/Error/RuntimeError.php',
98
+ 'Twig\\Error\\SyntaxError' => $vendorDir . '/twig/twig/src/Error/SyntaxError.php',
99
+ 'Twig\\ExpressionParser' => $vendorDir . '/twig/twig/src/ExpressionParser.php',
100
+ 'Twig\\Extension\\AbstractExtension' => $vendorDir . '/twig/twig/src/Extension/AbstractExtension.php',
101
+ 'Twig\\Extension\\CoreExtension' => $vendorDir . '/twig/twig/src/Extension/CoreExtension.php',
102
+ 'Twig\\Extension\\DebugExtension' => $vendorDir . '/twig/twig/src/Extension/DebugExtension.php',
103
+ 'Twig\\Extension\\EscaperExtension' => $vendorDir . '/twig/twig/src/Extension/EscaperExtension.php',
104
+ 'Twig\\Extension\\ExtensionInterface' => $vendorDir . '/twig/twig/src/Extension/ExtensionInterface.php',
105
+ 'Twig\\Extension\\GlobalsInterface' => $vendorDir . '/twig/twig/src/Extension/GlobalsInterface.php',
106
+ 'Twig\\Extension\\InitRuntimeInterface' => $vendorDir . '/twig/twig/src/Extension/InitRuntimeInterface.php',
107
+ 'Twig\\Extension\\OptimizerExtension' => $vendorDir . '/twig/twig/src/Extension/OptimizerExtension.php',
108
+ 'Twig\\Extension\\ProfilerExtension' => $vendorDir . '/twig/twig/src/Extension/ProfilerExtension.php',
109
+ 'Twig\\Extension\\SandboxExtension' => $vendorDir . '/twig/twig/src/Extension/SandboxExtension.php',
110
+ 'Twig\\Extension\\StagingExtension' => $vendorDir . '/twig/twig/src/Extension/StagingExtension.php',
111
+ 'Twig\\Extension\\StringLoaderExtension' => $vendorDir . '/twig/twig/src/Extension/StringLoaderExtension.php',
112
+ 'Twig\\FileExtensionEscapingStrategy' => $vendorDir . '/twig/twig/src/FileExtensionEscapingStrategy.php',
113
+ 'Twig\\Lexer' => $vendorDir . '/twig/twig/src/Lexer.php',
114
+ 'Twig\\Loader\\ArrayLoader' => $vendorDir . '/twig/twig/src/Loader/ArrayLoader.php',
115
+ 'Twig\\Loader\\ChainLoader' => $vendorDir . '/twig/twig/src/Loader/ChainLoader.php',
116
+ 'Twig\\Loader\\ExistsLoaderInterface' => $vendorDir . '/twig/twig/src/Loader/ExistsLoaderInterface.php',
117
+ 'Twig\\Loader\\FilesystemLoader' => $vendorDir . '/twig/twig/src/Loader/FilesystemLoader.php',
118
+ 'Twig\\Loader\\LoaderInterface' => $vendorDir . '/twig/twig/src/Loader/LoaderInterface.php',
119
+ 'Twig\\Loader\\SourceContextLoaderInterface' => $vendorDir . '/twig/twig/src/Loader/SourceContextLoaderInterface.php',
120
+ 'Twig\\Markup' => $vendorDir . '/twig/twig/src/Markup.php',
121
+ 'Twig\\NodeTraverser' => $vendorDir . '/twig/twig/src/NodeTraverser.php',
122
+ 'Twig\\NodeVisitor\\AbstractNodeVisitor' => $vendorDir . '/twig/twig/src/NodeVisitor/AbstractNodeVisitor.php',
123
+ 'Twig\\NodeVisitor\\EscaperNodeVisitor' => $vendorDir . '/twig/twig/src/NodeVisitor/EscaperNodeVisitor.php',
124
+ 'Twig\\NodeVisitor\\NodeVisitorInterface' => $vendorDir . '/twig/twig/src/NodeVisitor/NodeVisitorInterface.php',
125
+ 'Twig\\NodeVisitor\\OptimizerNodeVisitor' => $vendorDir . '/twig/twig/src/NodeVisitor/OptimizerNodeVisitor.php',
126
+ 'Twig\\NodeVisitor\\SafeAnalysisNodeVisitor' => $vendorDir . '/twig/twig/src/NodeVisitor/SafeAnalysisNodeVisitor.php',
127
+ 'Twig\\NodeVisitor\\SandboxNodeVisitor' => $vendorDir . '/twig/twig/src/NodeVisitor/SandboxNodeVisitor.php',
128
+ 'Twig\\Node\\AutoEscapeNode' => $vendorDir . '/twig/twig/src/Node/AutoEscapeNode.php',
129
+ 'Twig\\Node\\BlockNode' => $vendorDir . '/twig/twig/src/Node/BlockNode.php',
130
+ 'Twig\\Node\\BlockReferenceNode' => $vendorDir . '/twig/twig/src/Node/BlockReferenceNode.php',
131
+ 'Twig\\Node\\BodyNode' => $vendorDir . '/twig/twig/src/Node/BodyNode.php',
132
+ 'Twig\\Node\\CheckSecurityNode' => $vendorDir . '/twig/twig/src/Node/CheckSecurityNode.php',
133
+ 'Twig\\Node\\DoNode' => $vendorDir . '/twig/twig/src/Node/DoNode.php',
134
+ 'Twig\\Node\\EmbedNode' => $vendorDir . '/twig/twig/src/Node/EmbedNode.php',
135
+ 'Twig\\Node\\Expression\\AbstractExpression' => $vendorDir . '/twig/twig/src/Node/Expression/AbstractExpression.php',
136
+ 'Twig\\Node\\Expression\\ArrayExpression' => $vendorDir . '/twig/twig/src/Node/Expression/ArrayExpression.php',
137
+ 'Twig\\Node\\Expression\\AssignNameExpression' => $vendorDir . '/twig/twig/src/Node/Expression/AssignNameExpression.php',
138
+ 'Twig\\Node\\Expression\\Binary\\AbstractBinary' => $vendorDir . '/twig/twig/src/Node/Expression/Binary/AbstractBinary.php',
139
+ 'Twig\\Node\\Expression\\Binary\\AddBinary' => $vendorDir . '/twig/twig/src/Node/Expression/Binary/AddBinary.php',
140
+ 'Twig\\Node\\Expression\\Binary\\AndBinary' => $vendorDir . '/twig/twig/src/Node/Expression/Binary/AndBinary.php',
141
+ 'Twig\\Node\\Expression\\Binary\\BitwiseAndBinary' => $vendorDir . '/twig/twig/src/Node/Expression/Binary/BitwiseAndBinary.php',
142
+ 'Twig\\Node\\Expression\\Binary\\BitwiseOrBinary' => $vendorDir . '/twig/twig/src/Node/Expression/Binary/BitwiseOrBinary.php',
143
+ 'Twig\\Node\\Expression\\Binary\\BitwiseXorBinary' => $vendorDir . '/twig/twig/src/Node/Expression/Binary/BitwiseXorBinary.php',
144
+ 'Twig\\Node\\Expression\\Binary\\ConcatBinary' => $vendorDir . '/twig/twig/src/Node/Expression/Binary/ConcatBinary.php',
145
+ 'Twig\\Node\\Expression\\Binary\\DivBinary' => $vendorDir . '/twig/twig/src/Node/Expression/Binary/DivBinary.php',
146
+ 'Twig\\Node\\Expression\\Binary\\EndsWithBinary' => $vendorDir . '/twig/twig/src/Node/Expression/Binary/EndsWithBinary.php',
147
+ 'Twig\\Node\\Expression\\Binary\\EqualBinary' => $vendorDir . '/twig/twig/src/Node/Expression/Binary/EqualBinary.php',
148
+ 'Twig\\Node\\Expression\\Binary\\FloorDivBinary' => $vendorDir . '/twig/twig/src/Node/Expression/Binary/FloorDivBinary.php',
149
+ 'Twig\\Node\\Expression\\Binary\\GreaterBinary' => $vendorDir . '/twig/twig/src/Node/Expression/Binary/GreaterBinary.php',
150
+ 'Twig\\Node\\Expression\\Binary\\GreaterEqualBinary' => $vendorDir . '/twig/twig/src/Node/Expression/Binary/GreaterEqualBinary.php',
151
+ 'Twig\\Node\\Expression\\Binary\\InBinary' => $vendorDir . '/twig/twig/src/Node/Expression/Binary/InBinary.php',
152
+ 'Twig\\Node\\Expression\\Binary\\LessBinary' => $vendorDir . '/twig/twig/src/Node/Expression/Binary/LessBinary.php',
153
+ 'Twig\\Node\\Expression\\Binary\\LessEqualBinary' => $vendorDir . '/twig/twig/src/Node/Expression/Binary/LessEqualBinary.php',
154
+ 'Twig\\Node\\Expression\\Binary\\MatchesBinary' => $vendorDir . '/twig/twig/src/Node/Expression/Binary/MatchesBinary.php',
155
+ 'Twig\\Node\\Expression\\Binary\\ModBinary' => $vendorDir . '/twig/twig/src/Node/Expression/Binary/ModBinary.php',
156
+ 'Twig\\Node\\Expression\\Binary\\MulBinary' => $vendorDir . '/twig/twig/src/Node/Expression/Binary/MulBinary.php',
157
+ 'Twig\\Node\\Expression\\Binary\\NotEqualBinary' => $vendorDir . '/twig/twig/src/Node/Expression/Binary/NotEqualBinary.php',
158
+ 'Twig\\Node\\Expression\\Binary\\NotInBinary' => $vendorDir . '/twig/twig/src/Node/Expression/Binary/NotInBinary.php',
159
+ 'Twig\\Node\\Expression\\Binary\\OrBinary' => $vendorDir . '/twig/twig/src/Node/Expression/Binary/OrBinary.php',
160
+ 'Twig\\Node\\Expression\\Binary\\PowerBinary' => $vendorDir . '/twig/twig/src/Node/Expression/Binary/PowerBinary.php',
161
+ 'Twig\\Node\\Expression\\Binary\\RangeBinary' => $vendorDir . '/twig/twig/src/Node/Expression/Binary/RangeBinary.php',
162
+ 'Twig\\Node\\Expression\\Binary\\StartsWithBinary' => $vendorDir . '/twig/twig/src/Node/Expression/Binary/StartsWithBinary.php',
163
+ 'Twig\\Node\\Expression\\Binary\\SubBinary' => $vendorDir . '/twig/twig/src/Node/Expression/Binary/SubBinary.php',
164
+ 'Twig\\Node\\Expression\\BlockReferenceExpression' => $vendorDir . '/twig/twig/src/Node/Expression/BlockReferenceExpression.php',
165
+ 'Twig\\Node\\Expression\\CallExpression' => $vendorDir . '/twig/twig/src/Node/Expression/CallExpression.php',
166
+ 'Twig\\Node\\Expression\\ConditionalExpression' => $vendorDir . '/twig/twig/src/Node/Expression/ConditionalExpression.php',
167
+ 'Twig\\Node\\Expression\\ConstantExpression' => $vendorDir . '/twig/twig/src/Node/Expression/ConstantExpression.php',
168
+ 'Twig\\Node\\Expression\\FilterExpression' => $vendorDir . '/twig/twig/src/Node/Expression/FilterExpression.php',
169
+ 'Twig\\Node\\Expression\\Filter\\DefaultFilter' => $vendorDir . '/twig/twig/src/Node/Expression/Filter/DefaultFilter.php',
170
+ 'Twig\\Node\\Expression\\FunctionExpression' => $vendorDir . '/twig/twig/src/Node/Expression/FunctionExpression.php',
171
+ 'Twig\\Node\\Expression\\GetAttrExpression' => $vendorDir . '/twig/twig/src/Node/Expression/GetAttrExpression.php',
172
+ 'Twig\\Node\\Expression\\MethodCallExpression' => $vendorDir . '/twig/twig/src/Node/Expression/MethodCallExpression.php',
173
+ 'Twig\\Node\\Expression\\NameExpression' => $vendorDir . '/twig/twig/src/Node/Expression/NameExpression.php',
174
+ 'Twig\\Node\\Expression\\NullCoalesceExpression' => $vendorDir . '/twig/twig/src/Node/Expression/NullCoalesceExpression.php',
175
+ 'Twig\\Node\\Expression\\ParentExpression' => $vendorDir . '/twig/twig/src/Node/Expression/ParentExpression.php',
176
+ 'Twig\\Node\\Expression\\TempNameExpression' => $vendorDir . '/twig/twig/src/Node/Expression/TempNameExpression.php',
177
+ 'Twig\\Node\\Expression\\TestExpression' => $vendorDir . '/twig/twig/src/Node/Expression/TestExpression.php',
178
+ 'Twig\\Node\\Expression\\Test\\ConstantTest' => $vendorDir . '/twig/twig/src/Node/Expression/Test/ConstantTest.php',
179
+ 'Twig\\Node\\Expression\\Test\\DefinedTest' => $vendorDir . '/twig/twig/src/Node/Expression/Test/DefinedTest.php',
180
+ 'Twig\\Node\\Expression\\Test\\DivisiblebyTest' => $vendorDir . '/twig/twig/src/Node/Expression/Test/DivisiblebyTest.php',
181
+ 'Twig\\Node\\Expression\\Test\\EvenTest' => $vendorDir . '/twig/twig/src/Node/Expression/Test/EvenTest.php',
182
+ 'Twig\\Node\\Expression\\Test\\NullTest' => $vendorDir . '/twig/twig/src/Node/Expression/Test/NullTest.php',
183
+ 'Twig\\Node\\Expression\\Test\\OddTest' => $vendorDir . '/twig/twig/src/Node/Expression/Test/OddTest.php',
184
+ 'Twig\\Node\\Expression\\Test\\SameasTest' => $vendorDir . '/twig/twig/src/Node/Expression/Test/SameasTest.php',
185
+ 'Twig\\Node\\Expression\\Unary\\AbstractUnary' => $vendorDir . '/twig/twig/src/Node/Expression/Unary/AbstractUnary.php',
186
+ 'Twig\\Node\\Expression\\Unary\\NegUnary' => $vendorDir . '/twig/twig/src/Node/Expression/Unary/NegUnary.php',
187
+ 'Twig\\Node\\Expression\\Unary\\NotUnary' => $vendorDir . '/twig/twig/src/Node/Expression/Unary/NotUnary.php',
188
+ 'Twig\\Node\\Expression\\Unary\\PosUnary' => $vendorDir . '/twig/twig/src/Node/Expression/Unary/PosUnary.php',
189
+ 'Twig\\Node\\FlushNode' => $vendorDir . '/twig/twig/src/Node/FlushNode.php',
190
+ 'Twig\\Node\\ForLoopNode' => $vendorDir . '/twig/twig/src/Node/ForLoopNode.php',
191
+ 'Twig\\Node\\ForNode' => $vendorDir . '/twig/twig/src/Node/ForNode.php',
192
+ 'Twig\\Node\\IfNode' => $vendorDir . '/twig/twig/src/Node/IfNode.php',
193
+ 'Twig\\Node\\ImportNode' => $vendorDir . '/twig/twig/src/Node/ImportNode.php',
194
+ 'Twig\\Node\\IncludeNode' => $vendorDir . '/twig/twig/src/Node/IncludeNode.php',
195
+ 'Twig\\Node\\MacroNode' => $vendorDir . '/twig/twig/src/Node/MacroNode.php',
196
+ 'Twig\\Node\\ModuleNode' => $vendorDir . '/twig/twig/src/Node/ModuleNode.php',
197
+ 'Twig\\Node\\Node' => $vendorDir . '/twig/twig/src/Node/Node.php',
198
+ 'Twig\\Node\\NodeCaptureInterface' => $vendorDir . '/twig/twig/src/Node/NodeCaptureInterface.php',
199
+ 'Twig\\Node\\NodeOutputInterface' => $vendorDir . '/twig/twig/src/Node/NodeOutputInterface.php',
200
+ 'Twig\\Node\\PrintNode' => $vendorDir . '/twig/twig/src/Node/PrintNode.php',
201
+ 'Twig\\Node\\SandboxNode' => $vendorDir . '/twig/twig/src/Node/SandboxNode.php',
202
+ 'Twig\\Node\\SandboxedPrintNode' => $vendorDir . '/twig/twig/src/Node/SandboxedPrintNode.php',
203
+ 'Twig\\Node\\SetNode' => $vendorDir . '/twig/twig/src/Node/SetNode.php',
204
+ 'Twig\\Node\\SetTempNode' => $vendorDir . '/twig/twig/src/Node/SetTempNode.php',
205
+ 'Twig\\Node\\SpacelessNode' => $vendorDir . '/twig/twig/src/Node/SpacelessNode.php',
206
+ 'Twig\\Node\\TextNode' => $vendorDir . '/twig/twig/src/Node/TextNode.php',
207
+ 'Twig\\Node\\WithNode' => $vendorDir . '/twig/twig/src/Node/WithNode.php',
208
+ 'Twig\\Parser' => $vendorDir . '/twig/twig/src/Parser.php',
209
+ 'Twig\\Profiler\\Dumper\\BaseDumper' => $vendorDir . '/twig/twig/src/Profiler/Dumper/BaseDumper.php',
210
+ 'Twig\\Profiler\\Dumper\\BlackfireDumper' => $vendorDir . '/twig/twig/src/Profiler/Dumper/BlackfireDumper.php',
211
+ 'Twig\\Profiler\\Dumper\\HtmlDumper' => $vendorDir . '/twig/twig/src/Profiler/Dumper/HtmlDumper.php',
212
+ 'Twig\\Profiler\\Dumper\\TextDumper' => $vendorDir . '/twig/twig/src/Profiler/Dumper/TextDumper.php',
213
+ 'Twig\\Profiler\\NodeVisitor\\ProfilerNodeVisitor' => $vendorDir . '/twig/twig/src/Profiler/NodeVisitor/ProfilerNodeVisitor.php',
214
+ 'Twig\\Profiler\\Node\\EnterProfileNode' => $vendorDir . '/twig/twig/src/Profiler/Node/EnterProfileNode.php',
215
+ 'Twig\\Profiler\\Node\\LeaveProfileNode' => $vendorDir . '/twig/twig/src/Profiler/Node/LeaveProfileNode.php',
216
+ 'Twig\\Profiler\\Profile' => $vendorDir . '/twig/twig/src/Profiler/Profile.php',
217
+ 'Twig\\RuntimeLoader\\ContainerRuntimeLoader' => $vendorDir . '/twig/twig/src/RuntimeLoader/ContainerRuntimeLoader.php',
218
+ 'Twig\\RuntimeLoader\\FactoryRuntimeLoader' => $vendorDir . '/twig/twig/src/RuntimeLoader/FactoryRuntimeLoader.php',
219
+ 'Twig\\RuntimeLoader\\RuntimeLoaderInterface' => $vendorDir . '/twig/twig/src/RuntimeLoader/RuntimeLoaderInterface.php',
220
+ 'Twig\\Sandbox\\SecurityError' => $vendorDir . '/twig/twig/src/Sandbox/SecurityError.php',
221
+ 'Twig\\Sandbox\\SecurityNotAllowedFilterError' => $vendorDir . '/twig/twig/src/Sandbox/SecurityNotAllowedFilterError.php',
222
+ 'Twig\\Sandbox\\SecurityNotAllowedFunctionError' => $vendorDir . '/twig/twig/src/Sandbox/SecurityNotAllowedFunctionError.php',
223
+ 'Twig\\Sandbox\\SecurityNotAllowedMethodError' => $vendorDir . '/twig/twig/src/Sandbox/SecurityNotAllowedMethodError.php',
224
+ 'Twig\\Sandbox\\SecurityNotAllowedPropertyError' => $vendorDir . '/twig/twig/src/Sandbox/SecurityNotAllowedPropertyError.php',
225
+ 'Twig\\Sandbox\\SecurityNotAllowedTagError' => $vendorDir . '/twig/twig/src/Sandbox/SecurityNotAllowedTagError.php',
226
+ 'Twig\\Sandbox\\SecurityPolicy' => $vendorDir . '/twig/twig/src/Sandbox/SecurityPolicy.php',
227
+ 'Twig\\Sandbox\\SecurityPolicyInterface' => $vendorDir . '/twig/twig/src/Sandbox/SecurityPolicyInterface.php',
228
+ 'Twig\\Source' => $vendorDir . '/twig/twig/src/Source.php',
229
+ 'Twig\\Template' => $vendorDir . '/twig/twig/src/Template.php',
230
+ 'Twig\\TemplateWrapper' => $vendorDir . '/twig/twig/src/TemplateWrapper.php',
231
+ 'Twig\\Test\\IntegrationTestCase' => $vendorDir . '/twig/twig/src/Test/IntegrationTestCase.php',
232
+ 'Twig\\Test\\NodeTestCase' => $vendorDir . '/twig/twig/src/Test/NodeTestCase.php',
233
+ 'Twig\\Token' => $vendorDir . '/twig/twig/src/Token.php',
234
+ 'Twig\\TokenParser\\AbstractTokenParser' => $vendorDir . '/twig/twig/src/TokenParser/AbstractTokenParser.php',
235
+ 'Twig\\TokenParser\\AutoEscapeTokenParser' => $vendorDir . '/twig/twig/src/TokenParser/AutoEscapeTokenParser.php',
236
+ 'Twig\\TokenParser\\BlockTokenParser' => $vendorDir . '/twig/twig/src/TokenParser/BlockTokenParser.php',
237
+ 'Twig\\TokenParser\\DoTokenParser' => $vendorDir . '/twig/twig/src/TokenParser/DoTokenParser.php',
238
+ 'Twig\\TokenParser\\EmbedTokenParser' => $vendorDir . '/twig/twig/src/TokenParser/EmbedTokenParser.php',
239
+ 'Twig\\TokenParser\\ExtendsTokenParser' => $vendorDir . '/twig/twig/src/TokenParser/ExtendsTokenParser.php',
240
+ 'Twig\\TokenParser\\FilterTokenParser' => $vendorDir . '/twig/twig/src/TokenParser/FilterTokenParser.php',
241
+ 'Twig\\TokenParser\\FlushTokenParser' => $vendorDir . '/twig/twig/src/TokenParser/FlushTokenParser.php',
242
+ 'Twig\\TokenParser\\ForTokenParser' => $vendorDir . '/twig/twig/src/TokenParser/ForTokenParser.php',
243
+ 'Twig\\TokenParser\\FromTokenParser' => $vendorDir . '/twig/twig/src/TokenParser/FromTokenParser.php',
244
+ 'Twig\\TokenParser\\IfTokenParser' => $vendorDir . '/twig/twig/src/TokenParser/IfTokenParser.php',
245
+ 'Twig\\TokenParser\\ImportTokenParser' => $vendorDir . '/twig/twig/src/TokenParser/ImportTokenParser.php',
246
+ 'Twig\\TokenParser\\IncludeTokenParser' => $vendorDir . '/twig/twig/src/TokenParser/IncludeTokenParser.php',
247
+ 'Twig\\TokenParser\\MacroTokenParser' => $vendorDir . '/twig/twig/src/TokenParser/MacroTokenParser.php',
248
+ 'Twig\\TokenParser\\SandboxTokenParser' => $vendorDir . '/twig/twig/src/TokenParser/SandboxTokenParser.php',
249
+ 'Twig\\TokenParser\\SetTokenParser' => $vendorDir . '/twig/twig/src/TokenParser/SetTokenParser.php',
250
+ 'Twig\\TokenParser\\SpacelessTokenParser' => $vendorDir . '/twig/twig/src/TokenParser/SpacelessTokenParser.php',
251
+ 'Twig\\TokenParser\\TokenParserInterface' => $vendorDir . '/twig/twig/src/TokenParser/TokenParserInterface.php',
252
+ 'Twig\\TokenParser\\UseTokenParser' => $vendorDir . '/twig/twig/src/TokenParser/UseTokenParser.php',
253
+ 'Twig\\TokenParser\\WithTokenParser' => $vendorDir . '/twig/twig/src/TokenParser/WithTokenParser.php',
254
+ 'Twig\\TokenStream' => $vendorDir . '/twig/twig/src/TokenStream.php',
255
+ 'Twig\\TwigFilter' => $vendorDir . '/twig/twig/src/TwigFilter.php',
256
+ 'Twig\\TwigFunction' => $vendorDir . '/twig/twig/src/TwigFunction.php',
257
+ 'Twig\\TwigTest' => $vendorDir . '/twig/twig/src/TwigTest.php',
258
+ 'Twig\\Util\\DeprecationCollector' => $vendorDir . '/twig/twig/src/Util/DeprecationCollector.php',
259
+ 'Twig\\Util\\TemplateDirIterator' => $vendorDir . '/twig/twig/src/Util/TemplateDirIterator.php',
260
  'Twig_Autoloader' => $vendorDir . '/twig/twig/lib/Twig/Autoloader.php',
261
  'Twig_BaseNodeVisitor' => $vendorDir . '/twig/twig/lib/Twig/BaseNodeVisitor.php',
262
  'Twig_CacheInterface' => $vendorDir . '/twig/twig/lib/Twig/CacheInterface.php',
396
  'Twig_Node_With' => $vendorDir . '/twig/twig/lib/Twig/Node/With.php',
397
  'Twig_Parser' => $vendorDir . '/twig/twig/lib/Twig/Parser.php',
398
  'Twig_ParserInterface' => $vendorDir . '/twig/twig/lib/Twig/ParserInterface.php',
399
+ 'Twig_Profiler_Dumper_Base' => $vendorDir . '/twig/twig/lib/Twig/Profiler/Dumper/Base.php',
400
  'Twig_Profiler_Dumper_Blackfire' => $vendorDir . '/twig/twig/lib/Twig/Profiler/Dumper/Blackfire.php',
401
  'Twig_Profiler_Dumper_Html' => $vendorDir . '/twig/twig/lib/Twig/Profiler/Dumper/Html.php',
402
  'Twig_Profiler_Dumper_Text' => $vendorDir . '/twig/twig/lib/Twig/Profiler/Dumper/Text.php',
470
  'WCML_Cart' => $baseDir . '/inc/class-wcml-cart.php',
471
  'WCML_Cart_Removed_Items_Widget' => $baseDir . '/inc/class-wcml-cart-removed-items-widget.php',
472
  'WCML_Cart_Switch_Lang_Functions' => $baseDir . '/inc/wcml-cart-switch-lang-functions.php',
473
+ 'WCML_Cart_Sync_Warnings' => $baseDir . '/inc/class-wcml-cart-sync-warnings.php',
474
  'WCML_Checkout_Addons' => $baseDir . '/compatibility/class-wcml-checkout-addons.php',
475
  'WCML_Checkout_Field_Editor' => $baseDir . '/compatibility/class-wcml-checkout-field-editor.php',
476
  'WCML_Compatibility' => $baseDir . '/inc/class-wcml-compatibility.php',
481
  'WCML_Currency_Switcher' => $baseDir . '/inc/currencies/currency-switcher/class-wcml-currency-switcher.php',
482
  'WCML_Currency_Switcher_Ajax' => $baseDir . '/inc/currencies/currency-switcher/class-wcml-currency-switcher-ajax.php',
483
  'WCML_Currency_Switcher_Options_Dialog' => $baseDir . '/inc/template-classes/currency-switcher/class-wcml-currency-switcher-options-dialog.php',
484
+ 'WCML_Currency_Switcher_Properties' => $baseDir . '/inc/currencies/currency-switcher/class-wcml-currency-switcher-properties.php',
485
  'WCML_Currency_Switcher_Template' => $baseDir . '/inc/template-classes/currency-switcher/class-wcml-currency-switcher-template.php',
486
  'WCML_Currency_Switcher_Templates' => $baseDir . '/inc/currencies/currency-switcher/class-wcml-currency-switcher-templates.php',
487
  'WCML_Currency_Switcher_Widget' => $baseDir . '/inc/currencies/currency-switcher/class-wcml-currency-switcher-widget.php',
533
  'WCML_Not_Translatable_Attributes' => $baseDir . '/inc/template-classes/class-wcml-not-translatable-attributes.php',
534
  'WCML_Orders' => $baseDir . '/inc/class-wcml-orders.php',
535
  'WCML_Page_Builders' => $baseDir . '/inc/translation-editor/class-wcml-page-builders.php',
536
+ 'WCML_Payment_Method_Filter' => $baseDir . '/classes/order-property-filter/class-wcml-payment-method-filter.php',
537
  'WCML_Per_Product_Shipping' => $baseDir . '/compatibility/class-wcml-per-product-shipping.php',
538
  'WCML_Pip' => $baseDir . '/compatibility/class-wcml-pip.php',
539
  'WCML_Plugins_Wrap' => $baseDir . '/inc/template-classes/class-wcml-plugins-wrap.php',
552
  'WCML_Reports' => $baseDir . '/inc/class-wcml-reports.php',
553
  'WCML_Requests' => $baseDir . '/inc/class-wcml-requests.php',
554
  'WCML_Resources' => $baseDir . '/inc/class-wcml-resources.php',
555
+ 'WCML_Sensei' => $baseDir . '/compatibility/class-wcml-sensei.php',
556
  'WCML_Settings_UI' => $baseDir . '/inc/template-classes/class-wcml-settings-ui.php',
557
  'WCML_Setup' => $baseDir . '/inc/admin-menus/class-wcml-setup.php',
558
  'WCML_Setup_Attributes_UI' => $baseDir . '/inc/template-classes/setup/class-wcml-setup-attributes-ui.php',
603
  'WCML_WooCommerce_Rest_API_Support' => $baseDir . '/inc/class-wcml-woocommerce-rest-api-support.php',
604
  'WCML_YITH_WCQV' => $baseDir . '/compatibility/class-wcml-yith-wcqv.php',
605
  'WCML_gravityforms' => $baseDir . '/compatibility/class-wcml-gravityforms.php',
 
606
  'WCML_wcExporter' => $baseDir . '/compatibility/class-wcml-wcexporter.php',
607
  'WCML_xDomain_Data' => $baseDir . '/inc/class-wcml-xdomain-data.php',
608
  'WooCommerce_Functions_Wrapper' => $baseDir . '/inc/woocommerce-functions-wrapper.php',
vendor/composer/autoload_psr4.php CHANGED
@@ -6,5 +6,6 @@ $vendorDir = dirname(dirname(__FILE__));
6
  $baseDir = dirname($vendorDir);
7
 
8
  return array(
 
9
  'Composer\\Installers\\' => array($vendorDir . '/composer/installers/src/Composer/Installers'),
10
  );
6
  $baseDir = dirname($vendorDir);
7
 
8
  return array(
9
+ 'Twig\\' => array($vendorDir . '/twig/twig/src'),
10
  'Composer\\Installers\\' => array($vendorDir . '/composer/installers/src/Composer/Installers'),
11
  );
vendor/composer/autoload_real.php CHANGED
@@ -2,7 +2,7 @@
2
 
3
  // autoload_real.php @generated by Composer
4
 
5
- class ComposerAutoloaderInit3d46cc8388475e6b99b9a4c2356d4330
6
  {
7
  private static $loader;
8
 
@@ -19,15 +19,15 @@ class ComposerAutoloaderInit3d46cc8388475e6b99b9a4c2356d4330
19
  return self::$loader;
20
  }
21
 
22
- spl_autoload_register(array('ComposerAutoloaderInit3d46cc8388475e6b99b9a4c2356d4330', 'loadClassLoader'), true, true);
23
  self::$loader = $loader = new \Composer\Autoload\ClassLoader();
24
- spl_autoload_unregister(array('ComposerAutoloaderInit3d46cc8388475e6b99b9a4c2356d4330', '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\ComposerStaticInit3d46cc8388475e6b99b9a4c2356d4330::getInitializer($loader));
31
  } else {
32
  $map = require __DIR__ . '/autoload_namespaces.php';
33
  foreach ($map as $namespace => $path) {
2
 
3
  // autoload_real.php @generated by Composer
4
 
5
+ class ComposerAutoloaderInit1e950a3498b2b701753514ff78661529
6
  {
7
  private static $loader;
8
 
19
  return self::$loader;
20
  }
21
 
22
+ spl_autoload_register(array('ComposerAutoloaderInit1e950a3498b2b701753514ff78661529', 'loadClassLoader'), true, true);
23
  self::$loader = $loader = new \Composer\Autoload\ClassLoader();
24
+ spl_autoload_unregister(array('ComposerAutoloaderInit1e950a3498b2b701753514ff78661529', '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\ComposerStaticInit1e950a3498b2b701753514ff78661529::getInitializer($loader));
31
  } else {
32
  $map = require __DIR__ . '/autoload_namespaces.php';
33
  foreach ($map as $namespace => $path) {
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 ComposerAutoloaderInit226a7f3fe2d604eac20e142d7118628a {
6
  private static $loader;
7
 
8
  public static function loadClassLoader($class) {
@@ -19,9 +19,9 @@ class ComposerAutoloaderInit226a7f3fe2d604eac20e142d7118628a {
19
  return self::$loader;
20
  }
21
 
22
- spl_autoload_register(array('ComposerAutoloaderInit226a7f3fe2d604eac20e142d7118628a', 'loadClassLoader'), true /*, true */);
23
  self::$loader = $loader = new xrstf_Composer52_ClassLoader();
24
- spl_autoload_unregister(array('ComposerAutoloaderInit226a7f3fe2d604eac20e142d7118628a', 'loadClassLoader'));
25
 
26
  $vendorDir = dirname(dirname(__FILE__));
27
  $baseDir = dirname($vendorDir);
2
 
3
  // autoload_real_52.php generated by xrstf/composer-php52
4
 
5
+ class ComposerAutoloaderInit47e7b07dd515551e87cf2efd9df54aba {
6
  private static $loader;
7
 
8
  public static function loadClassLoader($class) {
19
  return self::$loader;
20
  }
21
 
22
+ spl_autoload_register(array('ComposerAutoloaderInit47e7b07dd515551e87cf2efd9df54aba', 'loadClassLoader'), true /*, true */);
23
  self::$loader = $loader = new xrstf_Composer52_ClassLoader();
24
+ spl_autoload_unregister(array('ComposerAutoloaderInit47e7b07dd515551e87cf2efd9df54aba', 'loadClassLoader'));
25
 
26
  $vendorDir = dirname(dirname(__FILE__));
27
  $baseDir = dirname($vendorDir);
vendor/composer/autoload_static.php CHANGED
@@ -4,9 +4,13 @@
4
 
5
  namespace Composer\Autoload;
6
 
7
- class ComposerStaticInit3d46cc8388475e6b99b9a4c2356d4330
8
  {
9
  public static $prefixLengthsPsr4 = array (
 
 
 
 
10
  'C' =>
11
  array (
12
  'Composer\\Installers\\' => 20,
@@ -14,6 +18,10 @@ class ComposerStaticInit3d46cc8388475e6b99b9a4c2356d4330
14
  );
15
 
16
  public static $prefixDirsPsr4 = array (
 
 
 
 
17
  'Composer\\Installers\\' =>
18
  array (
19
  0 => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers',
@@ -59,6 +67,7 @@ class ComposerStaticInit3d46cc8388475e6b99b9a4c2356d4330
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\\ExpressionEngineInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/ExpressionEngineInstaller.php',
63
  'Composer\\Installers\\FuelInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/FuelInstaller.php',
64
  'Composer\\Installers\\FuelphpInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/FuelphpInstaller.php',
@@ -66,21 +75,26 @@ class ComposerStaticInit3d46cc8388475e6b99b9a4c2356d4330
66
  'Composer\\Installers\\HuradInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/HuradInstaller.php',
67
  'Composer\\Installers\\ImageCMSInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/ImageCMSInstaller.php',
68
  'Composer\\Installers\\Installer' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/Installer.php',
 
69
  'Composer\\Installers\\JoomlaInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/JoomlaInstaller.php',
 
70
  'Composer\\Installers\\KirbyInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/KirbyInstaller.php',
71
  'Composer\\Installers\\KodiCMSInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/KodiCMSInstaller.php',
72
  'Composer\\Installers\\KohanaInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/KohanaInstaller.php',
73
  'Composer\\Installers\\LaravelInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/LaravelInstaller.php',
 
74
  'Composer\\Installers\\LithiumInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/LithiumInstaller.php',
75
  'Composer\\Installers\\MODULEWorkInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/MODULEWorkInstaller.php',
76
  'Composer\\Installers\\MODXEvoInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/MODXEvoInstaller.php',
77
  'Composer\\Installers\\MagentoInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/MagentoInstaller.php',
78
  'Composer\\Installers\\MakoInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/MakoInstaller.php',
79
  'Composer\\Installers\\MauticInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/MauticInstaller.php',
 
80
  'Composer\\Installers\\MediaWikiInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/MediaWikiInstaller.php',
81
  'Composer\\Installers\\MicroweberInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/MicroweberInstaller.php',
82
  'Composer\\Installers\\MoodleInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/MoodleInstaller.php',
83
  'Composer\\Installers\\OctoberInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/OctoberInstaller.php',
 
84
  'Composer\\Installers\\OxidInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/OxidInstaller.php',
85
  'Composer\\Installers\\PPIInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/PPIInstaller.php',
86
  'Composer\\Installers\\PhiftyInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/PhiftyInstaller.php',
@@ -89,6 +103,7 @@ class ComposerStaticInit3d46cc8388475e6b99b9a4c2356d4330
89
  'Composer\\Installers\\PiwikInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/PiwikInstaller.php',
90
  'Composer\\Installers\\PlentymarketsInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/PlentymarketsInstaller.php',
91
  'Composer\\Installers\\Plugin' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/Plugin.php',
 
92
  'Composer\\Installers\\PrestashopInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/PrestashopInstaller.php',
93
  'Composer\\Installers\\PuppetInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/PuppetInstaller.php',
94
  'Composer\\Installers\\RadPHPInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/RadPHPInstaller.php',
@@ -98,18 +113,190 @@ class ComposerStaticInit3d46cc8388475e6b99b9a4c2356d4330
98
  'Composer\\Installers\\SMFInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/SMFInstaller.php',
99
  'Composer\\Installers\\ShopwareInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/ShopwareInstaller.php',
100
  'Composer\\Installers\\SilverStripeInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/SilverStripeInstaller.php',
 
101
  'Composer\\Installers\\Symfony1Installer' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/Symfony1Installer.php',
102
  'Composer\\Installers\\TYPO3CmsInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/TYPO3CmsInstaller.php',
103
  'Composer\\Installers\\TYPO3FlowInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/TYPO3FlowInstaller.php',
104
  'Composer\\Installers\\TheliaInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/TheliaInstaller.php',
105
  'Composer\\Installers\\TuskInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/TuskInstaller.php',
106
  'Composer\\Installers\\VanillaInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/VanillaInstaller.php',
 
107
  'Composer\\Installers\\WHMCSInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/WHMCSInstaller.php',
108
  'Composer\\Installers\\WolfCMSInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/WolfCMSInstaller.php',
109
  'Composer\\Installers\\WordPressInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/WordPressInstaller.php',
110
  'Composer\\Installers\\YawikInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/YawikInstaller.php',
111
  'Composer\\Installers\\ZendInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/ZendInstaller.php',
112
  'Composer\\Installers\\ZikulaInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/ZikulaInstaller.php',
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
113
  'Twig_Autoloader' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Autoloader.php',
114
  'Twig_BaseNodeVisitor' => __DIR__ . '/..' . '/twig/twig/lib/Twig/BaseNodeVisitor.php',
115
  'Twig_CacheInterface' => __DIR__ . '/..' . '/twig/twig/lib/Twig/CacheInterface.php',
@@ -249,6 +436,7 @@ class ComposerStaticInit3d46cc8388475e6b99b9a4c2356d4330
249
  'Twig_Node_With' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Node/With.php',
250
  'Twig_Parser' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Parser.php',
251
  'Twig_ParserInterface' => __DIR__ . '/..' . '/twig/twig/lib/Twig/ParserInterface.php',
 
252
  'Twig_Profiler_Dumper_Blackfire' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Profiler/Dumper/Blackfire.php',
253
  'Twig_Profiler_Dumper_Html' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Profiler/Dumper/Html.php',
254
  'Twig_Profiler_Dumper_Text' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Profiler/Dumper/Text.php',
@@ -322,6 +510,7 @@ class ComposerStaticInit3d46cc8388475e6b99b9a4c2356d4330
322
  'WCML_Cart' => __DIR__ . '/../..' . '/inc/class-wcml-cart.php',
323
  'WCML_Cart_Removed_Items_Widget' => __DIR__ . '/../..' . '/inc/class-wcml-cart-removed-items-widget.php',
324
  'WCML_Cart_Switch_Lang_Functions' => __DIR__ . '/../..' . '/inc/wcml-cart-switch-lang-functions.php',
 
325
  'WCML_Checkout_Addons' => __DIR__ . '/../..' . '/compatibility/class-wcml-checkout-addons.php',
326
  'WCML_Checkout_Field_Editor' => __DIR__ . '/../..' . '/compatibility/class-wcml-checkout-field-editor.php',
327
  'WCML_Compatibility' => __DIR__ . '/../..' . '/inc/class-wcml-compatibility.php',
@@ -332,6 +521,7 @@ class ComposerStaticInit3d46cc8388475e6b99b9a4c2356d4330
332
  'WCML_Currency_Switcher' => __DIR__ . '/../..' . '/inc/currencies/currency-switcher/class-wcml-currency-switcher.php',
333
  'WCML_Currency_Switcher_Ajax' => __DIR__ . '/../..' . '/inc/currencies/currency-switcher/class-wcml-currency-switcher-ajax.php',
334
  'WCML_Currency_Switcher_Options_Dialog' => __DIR__ . '/../..' . '/inc/template-classes/currency-switcher/class-wcml-currency-switcher-options-dialog.php',
 
335
  'WCML_Currency_Switcher_Template' => __DIR__ . '/../..' . '/inc/template-classes/currency-switcher/class-wcml-currency-switcher-template.php',
336
  'WCML_Currency_Switcher_Templates' => __DIR__ . '/../..' . '/inc/currencies/currency-switcher/class-wcml-currency-switcher-templates.php',
337
  'WCML_Currency_Switcher_Widget' => __DIR__ . '/../..' . '/inc/currencies/currency-switcher/class-wcml-currency-switcher-widget.php',
@@ -383,6 +573,7 @@ class ComposerStaticInit3d46cc8388475e6b99b9a4c2356d4330
383
  'WCML_Not_Translatable_Attributes' => __DIR__ . '/../..' . '/inc/template-classes/class-wcml-not-translatable-attributes.php',
384
  'WCML_Orders' => __DIR__ . '/../..' . '/inc/class-wcml-orders.php',
385
  'WCML_Page_Builders' => __DIR__ . '/../..' . '/inc/translation-editor/class-wcml-page-builders.php',
 
386
  'WCML_Per_Product_Shipping' => __DIR__ . '/../..' . '/compatibility/class-wcml-per-product-shipping.php',
387
  'WCML_Pip' => __DIR__ . '/../..' . '/compatibility/class-wcml-pip.php',
388
  'WCML_Plugins_Wrap' => __DIR__ . '/../..' . '/inc/template-classes/class-wcml-plugins-wrap.php',
@@ -401,6 +592,7 @@ class ComposerStaticInit3d46cc8388475e6b99b9a4c2356d4330
401
  'WCML_Reports' => __DIR__ . '/../..' . '/inc/class-wcml-reports.php',
402
  'WCML_Requests' => __DIR__ . '/../..' . '/inc/class-wcml-requests.php',
403
  'WCML_Resources' => __DIR__ . '/../..' . '/inc/class-wcml-resources.php',
 
404
  'WCML_Settings_UI' => __DIR__ . '/../..' . '/inc/template-classes/class-wcml-settings-ui.php',
405
  'WCML_Setup' => __DIR__ . '/../..' . '/inc/admin-menus/class-wcml-setup.php',
406
  'WCML_Setup_Attributes_UI' => __DIR__ . '/../..' . '/inc/template-classes/setup/class-wcml-setup-attributes-ui.php',
@@ -451,7 +643,6 @@ class ComposerStaticInit3d46cc8388475e6b99b9a4c2356d4330
451
  'WCML_WooCommerce_Rest_API_Support' => __DIR__ . '/../..' . '/inc/class-wcml-woocommerce-rest-api-support.php',
452
  'WCML_YITH_WCQV' => __DIR__ . '/../..' . '/compatibility/class-wcml-yith-wcqv.php',
453
  'WCML_gravityforms' => __DIR__ . '/../..' . '/compatibility/class-wcml-gravityforms.php',
454
- 'WCML_sensei' => __DIR__ . '/../..' . '/compatibility/class-wcml-sensei.php',
455
  'WCML_wcExporter' => __DIR__ . '/../..' . '/compatibility/class-wcml-wcexporter.php',
456
  'WCML_xDomain_Data' => __DIR__ . '/../..' . '/inc/class-wcml-xdomain-data.php',
457
  'WooCommerce_Functions_Wrapper' => __DIR__ . '/../..' . '/inc/woocommerce-functions-wrapper.php',
@@ -463,10 +654,10 @@ class ComposerStaticInit3d46cc8388475e6b99b9a4c2356d4330
463
  public static function getInitializer(ClassLoader $loader)
464
  {
465
  return \Closure::bind(function () use ($loader) {
466
- $loader->prefixLengthsPsr4 = ComposerStaticInit3d46cc8388475e6b99b9a4c2356d4330::$prefixLengthsPsr4;
467
- $loader->prefixDirsPsr4 = ComposerStaticInit3d46cc8388475e6b99b9a4c2356d4330::$prefixDirsPsr4;
468
- $loader->prefixesPsr0 = ComposerStaticInit3d46cc8388475e6b99b9a4c2356d4330::$prefixesPsr0;
469
- $loader->classMap = ComposerStaticInit3d46cc8388475e6b99b9a4c2356d4330::$classMap;
470
 
471
  }, null, ClassLoader::class);
472
  }
4
 
5
  namespace Composer\Autoload;
6
 
7
+ class ComposerStaticInit1e950a3498b2b701753514ff78661529
8
  {
9
  public static $prefixLengthsPsr4 = array (
10
+ 'T' =>
11
+ array (
12
+ 'Twig\\' => 5,
13
+ ),
14
  'C' =>
15
  array (
16
  'Composer\\Installers\\' => 20,
18
  );
19
 
20
  public static $prefixDirsPsr4 = array (
21
+ 'Twig\\' =>
22
+ array (
23
+ 0 => __DIR__ . '/..' . '/twig/twig/src',
24
+ ),
25
  'Composer\\Installers\\' =>
26
  array (
27
  0 => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers',
67
  'Composer\\Installers\\DolibarrInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/DolibarrInstaller.php',
68
  'Composer\\Installers\\DrupalInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/DrupalInstaller.php',
69
  'Composer\\Installers\\ElggInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/ElggInstaller.php',
70
+ 'Composer\\Installers\\EliasisInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/EliasisInstaller.php',
71
  'Composer\\Installers\\ExpressionEngineInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/ExpressionEngineInstaller.php',
72
  'Composer\\Installers\\FuelInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/FuelInstaller.php',
73
  'Composer\\Installers\\FuelphpInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/FuelphpInstaller.php',
75
  'Composer\\Installers\\HuradInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/HuradInstaller.php',
76
  'Composer\\Installers\\ImageCMSInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/ImageCMSInstaller.php',
77
  'Composer\\Installers\\Installer' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/Installer.php',
78
+ 'Composer\\Installers\\ItopInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/ItopInstaller.php',
79
  'Composer\\Installers\\JoomlaInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/JoomlaInstaller.php',
80
+ 'Composer\\Installers\\KanboardInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/KanboardInstaller.php',
81
  'Composer\\Installers\\KirbyInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/KirbyInstaller.php',
82
  'Composer\\Installers\\KodiCMSInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/KodiCMSInstaller.php',
83
  'Composer\\Installers\\KohanaInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/KohanaInstaller.php',
84
  'Composer\\Installers\\LaravelInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/LaravelInstaller.php',
85
+ 'Composer\\Installers\\LavaLiteInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/LavaLiteInstaller.php',
86
  'Composer\\Installers\\LithiumInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/LithiumInstaller.php',
87
  'Composer\\Installers\\MODULEWorkInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/MODULEWorkInstaller.php',
88
  'Composer\\Installers\\MODXEvoInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/MODXEvoInstaller.php',
89
  'Composer\\Installers\\MagentoInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/MagentoInstaller.php',
90
  'Composer\\Installers\\MakoInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/MakoInstaller.php',
91
  'Composer\\Installers\\MauticInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/MauticInstaller.php',
92
+ 'Composer\\Installers\\MayaInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/MayaInstaller.php',
93
  'Composer\\Installers\\MediaWikiInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/MediaWikiInstaller.php',
94
  'Composer\\Installers\\MicroweberInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/MicroweberInstaller.php',
95
  'Composer\\Installers\\MoodleInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/MoodleInstaller.php',
96
  'Composer\\Installers\\OctoberInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/OctoberInstaller.php',
97
+ 'Composer\\Installers\\OntoWikiInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/OntoWikiInstaller.php',
98
  'Composer\\Installers\\OxidInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/OxidInstaller.php',
99
  'Composer\\Installers\\PPIInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/PPIInstaller.php',
100
  'Composer\\Installers\\PhiftyInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/PhiftyInstaller.php',
103
  'Composer\\Installers\\PiwikInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/PiwikInstaller.php',
104
  'Composer\\Installers\\PlentymarketsInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/PlentymarketsInstaller.php',
105
  'Composer\\Installers\\Plugin' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/Plugin.php',
106
+ 'Composer\\Installers\\PortoInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/PortoInstaller.php',
107
  'Composer\\Installers\\PrestashopInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/PrestashopInstaller.php',
108
  'Composer\\Installers\\PuppetInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/PuppetInstaller.php',
109
  'Composer\\Installers\\RadPHPInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/RadPHPInstaller.php',
113
  'Composer\\Installers\\SMFInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/SMFInstaller.php',
114
  'Composer\\Installers\\ShopwareInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/ShopwareInstaller.php',
115
  'Composer\\Installers\\SilverStripeInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/SilverStripeInstaller.php',
116
+ 'Composer\\Installers\\SyDESInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/SyDESInstaller.php',
117
  'Composer\\Installers\\Symfony1Installer' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/Symfony1Installer.php',
118
  'Composer\\Installers\\TYPO3CmsInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/TYPO3CmsInstaller.php',
119
  'Composer\\Installers\\TYPO3FlowInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/TYPO3FlowInstaller.php',
120
  'Composer\\Installers\\TheliaInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/TheliaInstaller.php',
121
  'Composer\\Installers\\TuskInstaller' => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers/TuskInstaller.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\\Cache\\CacheInterface' => __DIR__ . '/..' . '/twig/twig/src/Cache/CacheInterface.php',
131
+ 'Twig\\Cache\\FilesystemCache' => __DIR__ . '/..' . '/twig/twig/src/Cache/FilesystemCache.php',
132
+ 'Twig\\Cache\\NullCache' => __DIR__ . '/..' . '/twig/twig/src/Cache/NullCache.php',
133
+ 'Twig\\Compiler' => __DIR__ . '/..' . '/twig/twig/src/Compiler.php',
134
+ 'Twig\\Environment' => __DIR__ . '/..' . '/twig/twig/src/Environment.php',
135
+ 'Twig\\Error\\Error' => __DIR__ . '/..' . '/twig/twig/src/Error/Error.php',
136
+ 'Twig\\Error\\LoaderError' => __DIR__ . '/..' . '/twig/twig/src/Error/LoaderError.php',
137
+ 'Twig\\Error\\RuntimeError' => __DIR__ . '/..' . '/twig/twig/src/Error/RuntimeError.php',
138
+ 'Twig\\Error\\SyntaxError' => __DIR__ . '/..' . '/twig/twig/src/Error/SyntaxError.php',
139
+ 'Twig\\ExpressionParser' => __DIR__ . '/..' . '/twig/twig/src/ExpressionParser.php',
140
+ 'Twig\\Extension\\AbstractExtension' => __DIR__ . '/..' . '/twig/twig/src/Extension/AbstractExtension.php',
141
+ 'Twig\\Extension\\CoreExtension' => __DIR__ . '/..' . '/twig/twig/src/Extension/CoreExtension.php',
142
+ 'Twig\\Extension\\DebugExtension' => __DIR__ . '/..' . '/twig/twig/src/Extension/DebugExtension.php',
143
+ 'Twig\\Extension\\EscaperExtension' => __DIR__ . '/..' . '/twig/twig/src/Extension/EscaperExtension.php',
144
+ 'Twig\\Extension\\ExtensionInterface' => __DIR__ . '/..' . '/twig/twig/src/Extension/ExtensionInterface.php',
145
+ 'Twig\\Extension\\GlobalsInterface' => __DIR__ . '/..' . '/twig/twig/src/Extension/GlobalsInterface.php',
146
+ 'Twig\\Extension\\InitRuntimeInterface' => __DIR__ . '/..' . '/twig/twig/src/Extension/InitRuntimeInterface.php',
147
+ 'Twig\\Extension\\OptimizerExtension' => __DIR__ . '/..' . '/twig/twig/src/Extension/OptimizerExtension.php',
148
+ 'Twig\\Extension\\ProfilerExtension' => __DIR__ . '/..' . '/twig/twig/src/Extension/ProfilerExtension.php',
149
+ 'Twig\\Extension\\SandboxExtension' => __DIR__ . '/..' . '/twig/twig/src/Extension/SandboxExtension.php',
150
+ 'Twig\\Extension\\StagingExtension' => __DIR__ . '/..' . '/twig/twig/src/Extension/StagingExtension.php',
151
+ 'Twig\\Extension\\StringLoaderExtension' => __DIR__ . '/..' . '/twig/twig/src/Extension/StringLoaderExtension.php',
152
+ 'Twig\\FileExtensionEscapingStrategy' => __DIR__ . '/..' . '/twig/twig/src/FileExtensionEscapingStrategy.php',
153
+ 'Twig\\Lexer' => __DIR__ . '/..' . '/twig/twig/src/Lexer.php',
154
+ 'Twig\\Loader\\ArrayLoader' => __DIR__ . '/..' . '/twig/twig/src/Loader/ArrayLoader.php',
155
+ 'Twig\\Loader\\ChainLoader' => __DIR__ . '/..' . '/twig/twig/src/Loader/ChainLoader.php',
156
+ 'Twig\\Loader\\ExistsLoaderInterface' => __DIR__ . '/..' . '/twig/twig/src/Loader/ExistsLoaderInterface.php',
157
+ 'Twig\\Loader\\FilesystemLoader' => __DIR__ . '/..' . '/twig/twig/src/Loader/FilesystemLoader.php',
158
+ 'Twig\\Loader\\LoaderInterface' => __DIR__ . '/..' . '/twig/twig/src/Loader/LoaderInterface.php',
159
+ 'Twig\\Loader\\SourceContextLoaderInterface' => __DIR__ . '/..' . '/twig/twig/src/Loader/SourceContextLoaderInterface.php',
160
+ 'Twig\\Markup' => __DIR__ . '/..' . '/twig/twig/src/Markup.php',
161
+ 'Twig\\NodeTraverser' => __DIR__ . '/..' . '/twig/twig/src/NodeTraverser.php',
162
+ 'Twig\\NodeVisitor\\AbstractNodeVisitor' => __DIR__ . '/..' . '/twig/twig/src/NodeVisitor/AbstractNodeVisitor.php',
163
+ 'Twig\\NodeVisitor\\EscaperNodeVisitor' => __DIR__ . '/..' . '/twig/twig/src/NodeVisitor/EscaperNodeVisitor.php',
164
+ 'Twig\\NodeVisitor\\NodeVisitorInterface' => __DIR__ . '/..' . '/twig/twig/src/NodeVisitor/NodeVisitorInterface.php',
165
+ 'Twig\\NodeVisitor\\OptimizerNodeVisitor' => __DIR__ . '/..' . '/twig/twig/src/NodeVisitor/OptimizerNodeVisitor.php',
166
+ 'Twig\\NodeVisitor\\SafeAnalysisNodeVisitor' => __DIR__ . '/..' . '/twig/twig/src/NodeVisitor/SafeAnalysisNodeVisitor.php',
167
+ 'Twig\\NodeVisitor\\SandboxNodeVisitor' => __DIR__ . '/..' . '/twig/twig/src/NodeVisitor/SandboxNodeVisitor.php',
168
+ 'Twig\\Node\\AutoEscapeNode' => __DIR__ . '/..' . '/twig/twig/src/Node/AutoEscapeNode.php',
169
+ 'Twig\\Node\\BlockNode' => __DIR__ . '/..' . '/twig/twig/src/Node/BlockNode.php',
170
+ 'Twig\\Node\\BlockReferenceNode' => __DIR__ . '/..' . '/twig/twig/src/Node/BlockReferenceNode.php',
171
+ 'Twig\\Node\\BodyNode' => __DIR__ . '/..' . '/twig/twig/src/Node/BodyNode.php',
172
+ 'Twig\\Node\\CheckSecurityNode' => __DIR__ . '/..' . '/twig/twig/src/Node/CheckSecurityNode.php',
173
+ 'Twig\\Node\\DoNode' => __DIR__ . '/..' . '/twig/twig/src/Node/DoNode.php',
174
+ 'Twig\\Node\\EmbedNode' => __DIR__ . '/..' . '/twig/twig/src/Node/EmbedNode.php',
175
+ 'Twig\\Node\\Expression\\AbstractExpression' => __DIR__ . '/..' . '/twig/twig/src/Node/Expression/AbstractExpression.php',
176
+ 'Twig\\Node\\Expression\\ArrayExpression' => __DIR__ . '/..' . '/twig/twig/src/Node/Expression/ArrayExpression.php',
177
+ 'Twig\\Node\\Expression\\AssignNameExpression' => __DIR__ . '/..' . '/twig/twig/src/Node/Expression/AssignNameExpression.php',
178
+ 'Twig\\Node\\Expression\\Binary\\AbstractBinary' => __DIR__ . '/..' . '/twig/twig/src/Node/Expression/Binary/AbstractBinary.php',
179
+ 'Twig\\Node\\Expression\\Binary\\AddBinary' => __DIR__ . '/..' . '/twig/twig/src/Node/Expression/Binary/AddBinary.php',
180
+ 'Twig\\Node\\Expression\\Binary\\AndBinary' => __DIR__ . '/..' . '/twig/twig/src/Node/Expression/Binary/AndBinary.php',
181
+ 'Twig\\Node\\Expression\\Binary\\BitwiseAndBinary' => __DIR__ . '/..' . '/twig/twig/src/Node/Expression/Binary/BitwiseAndBinary.php',
182
+ 'Twig\\Node\\Expression\\Binary\\BitwiseOrBinary' => __DIR__ . '/..' . '/twig/twig/src/Node/Expression/Binary/BitwiseOrBinary.php',
183
+ 'Twig\\Node\\Expression\\Binary\\BitwiseXorBinary' => __DIR__ . '/..' . '/twig/twig/src/Node/Expression/Binary/BitwiseXorBinary.php',
184
+ 'Twig\\Node\\Expression\\Binary\\ConcatBinary' => __DIR__ . '/..' . '/twig/twig/src/Node/Expression/Binary/ConcatBinary.php',
185
+ 'Twig\\Node\\Expression\\Binary\\DivBinary' => __DIR__ . '/..' . '/twig/twig/src/Node/Expression/Binary/DivBinary.php',
186
+ 'Twig\\Node\\Expression\\Binary\\EndsWithBinary' => __DIR__ . '/..' . '/twig/twig/src/Node/Expression/Binary/EndsWithBinary.php',
187
+ 'Twig\\Node\\Expression\\Binary\\EqualBinary' => __DIR__ . '/..' . '/twig/twig/src/Node/Expression/Binary/EqualBinary.php',
188
+ 'Twig\\Node\\Expression\\Binary\\FloorDivBinary' => __DIR__ . '/..' . '/twig/twig/src/Node/Expression/Binary/FloorDivBinary.php',
189
+ 'Twig\\Node\\Expression\\Binary\\GreaterBinary' => __DIR__ . '/..' . '/twig/twig/src/Node/Expression/Binary/GreaterBinary.php',
190
+ 'Twig\\Node\\Expression\\Binary\\GreaterEqualBinary' => __DIR__ . '/..' . '/twig/twig/src/Node/Expression/Binary/GreaterEqualBinary.php',
191
+ 'Twig\\Node\\Expression\\Binary\\InBinary' => __DIR__ . '/..' . '/twig/twig/src/Node/Expression/Binary/InBinary.php',
192
+ 'Twig\\Node\\Expression\\Binary\\LessBinary' => __DIR__ . '/..' . '/twig/twig/src/Node/Expression/Binary/LessBinary.php',
193
+ 'Twig\\Node\\Expression\\Binary\\LessEqualBinary' => __DIR__ . '/..' . '/twig/twig/src/Node/Expression/Binary/LessEqualBinary.php',
194
+ 'Twig\\Node\\Expression\\Binary\\MatchesBinary' => __DIR__ . '/..' . '/twig/twig/src/Node/Expression/Binary/MatchesBinary.php',
195
+ 'Twig\\Node\\Expression\\Binary\\ModBinary' => __DIR__ . '/..' . '/twig/twig/src/Node/Expression/Binary/ModBinary.php',
196
+ 'Twig\\Node\\Expression\\Binary\\MulBinary' => __DIR__ . '/..' . '/twig/twig/src/Node/Expression/Binary/MulBinary.php',
197
+ 'Twig\\Node\\Expression\\Binary\\NotEqualBinary' => __DIR__ . '/..' . '/twig/twig/src/Node/Expression/Binary/NotEqualBinary.php',
198
+ 'Twig\\Node\\Expression\\Binary\\NotInBinary' => __DIR__ . '/..' . '/twig/twig/src/Node/Expression/Binary/NotInBinary.php',
199
+ 'Twig\\Node\\Expression\\Binary\\OrBinary' => __DIR__ . '/..' . '/twig/twig/src/Node/Expression/Binary/OrBinary.php',
200
+ 'Twig\\Node\\Expression\\Binary\\PowerBinary' => __DIR__ . '/..' . '/twig/twig/src/Node/Expression/Binary/PowerBinary.php',
201
+ 'Twig\\Node\\Expression\\Binary\\RangeBinary' => __DIR__ . '/..' . '/twig/twig/src/Node/Expression/Binary/RangeBinary.php',
202
+ 'Twig\\Node\\Expression\\Binary\\StartsWithBinary' => __DIR__ . '/..' . '/twig/twig/src/Node/Expression/Binary/StartsWithBinary.php',
203
+ 'Twig\\Node\\Expression\\Binary\\SubBinary' => __DIR__ . '/..' . '/twig/twig/src/Node/Expression/Binary/SubBinary.php',
204
+ 'Twig\\Node\\Expression\\BlockReferenceExpression' => __DIR__ . '/..' . '/twig/twig/src/Node/Expression/BlockReferenceExpression.php',
205
+ 'Twig\\Node\\Expression\\CallExpression' => __DIR__ . '/..' . '/twig/twig/src/Node/Expression/CallExpression.php',
206
+ 'Twig\\Node\\Expression\\ConditionalExpression' => __DIR__ . '/..' . '/twig/twig/src/Node/Expression/ConditionalExpression.php',
207
+ 'Twig\\Node\\Expression\\ConstantExpression' => __DIR__ . '/..' . '/twig/twig/src/Node/Expression/ConstantExpression.php',
208
+ 'Twig\\Node\\Expression\\FilterExpression' => __DIR__ . '/..' . '/twig/twig/src/Node/Expression/FilterExpression.php',
209
+ 'Twig\\Node\\Expression\\Filter\\DefaultFilter' => __DIR__ . '/..' . '/twig/twig/src/Node/Expression/Filter/DefaultFilter.php',
210
+ 'Twig\\Node\\Expression\\FunctionExpression' => __DIR__ . '/..' . '/twig/twig/src/Node/Expression/FunctionExpression.php',
211
+ 'Twig\\Node\\Expression\\GetAttrExpression' => __DIR__ . '/..' . '/twig/twig/src/Node/Expression/GetAttrExpression.php',
212
+ 'Twig\\Node\\Expression\\MethodCallExpression' => __DIR__ . '/..' . '/twig/twig/src/Node/Expression/MethodCallExpression.php',
213
+ 'Twig\\Node\\Expression\\NameExpression' => __DIR__ . '/..' . '/twig/twig/src/Node/Expression/NameExpression.php',
214
+ 'Twig\\Node\\Expression\\NullCoalesceExpression' => __DIR__ . '/..' . '/twig/twig/src/Node/Expression/NullCoalesceExpression.php',
215
+ 'Twig\\Node\\Expression\\ParentExpression' => __DIR__ . '/..' . '/twig/twig/src/Node/Expression/ParentExpression.php',
216
+ 'Twig\\Node\\Expression\\TempNameExpression' => __DIR__ . '/..' . '/twig/twig/src/Node/Expression/TempNameExpression.php',
217
+ 'Twig\\Node\\Expression\\TestExpression' => __DIR__ . '/..' . '/twig/twig/src/Node/Expression/TestExpression.php',
218
+ 'Twig\\Node\\Expression\\Test\\ConstantTest' => __DIR__ . '/..' . '/twig/twig/src/Node/Expression/Test/ConstantTest.php',
219
+ 'Twig\\Node\\Expression\\Test\\DefinedTest' => __DIR__ . '/..' . '/twig/twig/src/Node/Expression/Test/DefinedTest.php',
220
+ 'Twig\\Node\\Expression\\Test\\DivisiblebyTest' => __DIR__ . '/..' . '/twig/twig/src/Node/Expression/Test/DivisiblebyTest.php',
221
+ 'Twig\\Node\\Expression\\Test\\EvenTest' => __DIR__ . '/..' . '/twig/twig/src/Node/Expression/Test/EvenTest.php',
222
+ 'Twig\\Node\\Expression\\Test\\NullTest' => __DIR__ . '/..' . '/twig/twig/src/Node/Expression/Test/NullTest.php',
223
+ 'Twig\\Node\\Expression\\Test\\OddTest' => __DIR__ . '/..' . '/twig/twig/src/Node/Expression/Test/OddTest.php',
224
+ 'Twig\\Node\\Expression\\Test\\SameasTest' => __DIR__ . '/..' . '/twig/twig/src/Node/Expression/Test/SameasTest.php',
225
+ 'Twig\\Node\\Expression\\Unary\\AbstractUnary' => __DIR__ . '/..' . '/twig/twig/src/Node/Expression/Unary/AbstractUnary.php',
226
+ 'Twig\\Node\\Expression\\Unary\\NegUnary' => __DIR__ . '/..' . '/twig/twig/src/Node/Expression/Unary/NegUnary.php',
227
+ 'Twig\\Node\\Expression\\Unary\\NotUnary' => __DIR__ . '/..' . '/twig/twig/src/Node/Expression/Unary/NotUnary.php',
228
+ 'Twig\\Node\\Expression\\Unary\\PosUnary' => __DIR__ . '/..' . '/twig/twig/src/Node/Expression/Unary/PosUnary.php',
229
+ 'Twig\\Node\\FlushNode' => __DIR__ . '/..' . '/twig/twig/src/Node/FlushNode.php',
230
+ 'Twig\\Node\\ForLoopNode' => __DIR__ . '/..' . '/twig/twig/src/Node/ForLoopNode.php',
231
+ 'Twig\\Node\\ForNode' => __DIR__ . '/..' . '/twig/twig/src/Node/ForNode.php',
232
+ 'Twig\\Node\\IfNode' => __DIR__ . '/..' . '/twig/twig/src/Node/IfNode.php',
233
+ 'Twig\\Node\\ImportNode' => __DIR__ . '/..' . '/twig/twig/src/Node/ImportNode.php',
234
+ 'Twig\\Node\\IncludeNode' => __DIR__ . '/..' . '/twig/twig/src/Node/IncludeNode.php',
235
+ 'Twig\\Node\\MacroNode' => __DIR__ . '/..' . '/twig/twig/src/Node/MacroNode.php',
236
+ 'Twig\\Node\\ModuleNode' => __DIR__ . '/..' . '/twig/twig/src/Node/ModuleNode.php',
237
+ 'Twig\\Node\\Node' => __DIR__ . '/..' . '/twig/twig/src/Node/Node.php',
238
+ 'Twig\\Node\\NodeCaptureInterface' => __DIR__ . '/..' . '/twig/twig/src/Node/NodeCaptureInterface.php',
239
+ 'Twig\\Node\\NodeOutputInterface' => __DIR__ . '/..' . '/twig/twig/src/Node/NodeOutputInterface.php',
240
+ 'Twig\\Node\\PrintNode' => __DIR__ . '/..' . '/twig/twig/src/Node/PrintNode.php',
241
+ 'Twig\\Node\\SandboxNode' => __DIR__ . '/..' . '/twig/twig/src/Node/SandboxNode.php',
242
+ 'Twig\\Node\\SandboxedPrintNode' => __DIR__ . '/..' . '/twig/twig/src/Node/SandboxedPrintNode.php',
243
+ 'Twig\\Node\\SetNode' => __DIR__ . '/..' . '/twig/twig/src/Node/SetNode.php',
244
+ 'Twig\\Node\\SetTempNode' => __DIR__ . '/..' . '/twig/twig/src/Node/SetTempNode.php',
245
+ 'Twig\\Node\\SpacelessNode' => __DIR__ . '/..' . '/twig/twig/src/Node/SpacelessNode.php',
246
+ 'Twig\\Node\\TextNode' => __DIR__ . '/..' . '/twig/twig/src/Node/TextNode.php',
247
+ 'Twig\\Node\\WithNode' => __DIR__ . '/..' . '/twig/twig/src/Node/WithNode.php',
248
+ 'Twig\\Parser' => __DIR__ . '/..' . '/twig/twig/src/Parser.php',
249
+ 'Twig\\Profiler\\Dumper\\BaseDumper' => __DIR__ . '/..' . '/twig/twig/src/Profiler/Dumper/BaseDumper.php',
250
+ 'Twig\\Profiler\\Dumper\\BlackfireDumper' => __DIR__ . '/..' . '/twig/twig/src/Profiler/Dumper/BlackfireDumper.php',
251
+ 'Twig\\Profiler\\Dumper\\HtmlDumper' => __DIR__ . '/..' . '/twig/twig/src/Profiler/Dumper/HtmlDumper.php',
252
+ 'Twig\\Profiler\\Dumper\\TextDumper' => __DIR__ . '/..' . '/twig/twig/src/Profiler/Dumper/TextDumper.php',
253
+ 'Twig\\Profiler\\NodeVisitor\\ProfilerNodeVisitor' => __DIR__ . '/..' . '/twig/twig/src/Profiler/NodeVisitor/ProfilerNodeVisitor.php',
254
+ 'Twig\\Profiler\\Node\\EnterProfileNode' => __DIR__ . '/..' . '/twig/twig/src/Profiler/Node/EnterProfileNode.php',
255
+ 'Twig\\Profiler\\Node\\LeaveProfileNode' => __DIR__ . '/..' . '/twig/twig/src/Profiler/Node/LeaveProfileNode.php',
256
+ 'Twig\\Profiler\\Profile' => __DIR__ . '/..' . '/twig/twig/src/Profiler/Profile.php',
257
+ 'Twig\\RuntimeLoader\\ContainerRuntimeLoader' => __DIR__ . '/..' . '/twig/twig/src/RuntimeLoader/ContainerRuntimeLoader.php',
258
+ 'Twig\\RuntimeLoader\\FactoryRuntimeLoader' => __DIR__ . '/..' . '/twig/twig/src/RuntimeLoader/FactoryRuntimeLoader.php',
259
+ 'Twig\\RuntimeLoader\\RuntimeLoaderInterface' => __DIR__ . '/..' . '/twig/twig/src/RuntimeLoader/RuntimeLoaderInterface.php',
260
+ 'Twig\\Sandbox\\SecurityError' => __DIR__ . '/..' . '/twig/twig/src/Sandbox/SecurityError.php',
261
+ 'Twig\\Sandbox\\SecurityNotAllowedFilterError' => __DIR__ . '/..' . '/twig/twig/src/Sandbox/SecurityNotAllowedFilterError.php',
262
+ 'Twig\\Sandbox\\SecurityNotAllowedFunctionError' => __DIR__ . '/..' . '/twig/twig/src/Sandbox/SecurityNotAllowedFunctionError.php',
263
+ 'Twig\\Sandbox\\SecurityNotAllowedMethodError' => __DIR__ . '/..' . '/twig/twig/src/Sandbox/SecurityNotAllowedMethodError.php',
264
+ 'Twig\\Sandbox\\SecurityNotAllowedPropertyError' => __DIR__ . '/..' . '/twig/twig/src/Sandbox/SecurityNotAllowedPropertyError.php',
265
+ 'Twig\\Sandbox\\SecurityNotAllowedTagError' => __DIR__ . '/..' . '/twig/twig/src/Sandbox/SecurityNotAllowedTagError.php',
266
+ 'Twig\\Sandbox\\SecurityPolicy' => __DIR__ . '/..' . '/twig/twig/src/Sandbox/SecurityPolicy.php',
267
+ 'Twig\\Sandbox\\SecurityPolicyInterface' => __DIR__ . '/..' . '/twig/twig/src/Sandbox/SecurityPolicyInterface.php',
268
+ 'Twig\\Source' => __DIR__ . '/..' . '/twig/twig/src/Source.php',
269
+ 'Twig\\Template' => __DIR__ . '/..' . '/twig/twig/src/Template.php',
270
+ 'Twig\\TemplateWrapper' => __DIR__ . '/..' . '/twig/twig/src/TemplateWrapper.php',
271
+ 'Twig\\Test\\IntegrationTestCase' => __DIR__ . '/..' . '/twig/twig/src/Test/IntegrationTestCase.php',
272
+ 'Twig\\Test\\NodeTestCase' => __DIR__ . '/..' . '/twig/twig/src/Test/NodeTestCase.php',
273
+ 'Twig\\Token' => __DIR__ . '/..' . '/twig/twig/src/Token.php',
274
+ 'Twig\\TokenParser\\AbstractTokenParser' => __DIR__ . '/..' . '/twig/twig/src/TokenParser/AbstractTokenParser.php',
275
+ 'Twig\\TokenParser\\AutoEscapeTokenParser' => __DIR__ . '/..' . '/twig/twig/src/TokenParser/AutoEscapeTokenParser.php',
276
+ 'Twig\\TokenParser\\BlockTokenParser' => __DIR__ . '/..' . '/twig/twig/src/TokenParser/BlockTokenParser.php',
277
+ 'Twig\\TokenParser\\DoTokenParser' => __DIR__ . '/..' . '/twig/twig/src/TokenParser/DoTokenParser.php',
278
+ 'Twig\\TokenParser\\EmbedTokenParser' => __DIR__ . '/..' . '/twig/twig/src/TokenParser/EmbedTokenParser.php',
279
+ 'Twig\\TokenParser\\ExtendsTokenParser' => __DIR__ . '/..' . '/twig/twig/src/TokenParser/ExtendsTokenParser.php',
280
+ 'Twig\\TokenParser\\FilterTokenParser' => __DIR__ . '/..' . '/twig/twig/src/TokenParser/FilterTokenParser.php',
281
+ 'Twig\\TokenParser\\FlushTokenParser' => __DIR__ . '/..' . '/twig/twig/src/TokenParser/FlushTokenParser.php',
282
+ 'Twig\\TokenParser\\ForTokenParser' => __DIR__ . '/..' . '/twig/twig/src/TokenParser/ForTokenParser.php',
283
+ 'Twig\\TokenParser\\FromTokenParser' => __DIR__ . '/..' . '/twig/twig/src/TokenParser/FromTokenParser.php',
284
+ 'Twig\\TokenParser\\IfTokenParser' => __DIR__ . '/..' . '/twig/twig/src/TokenParser/IfTokenParser.php',
285
+ 'Twig\\TokenParser\\ImportTokenParser' => __DIR__ . '/..' . '/twig/twig/src/TokenParser/ImportTokenParser.php',
286
+ 'Twig\\TokenParser\\IncludeTokenParser' => __DIR__ . '/..' . '/twig/twig/src/TokenParser/IncludeTokenParser.php',
287
+ 'Twig\\TokenParser\\MacroTokenParser' => __DIR__ . '/..' . '/twig/twig/src/TokenParser/MacroTokenParser.php',
288
+ 'Twig\\TokenParser\\SandboxTokenParser' => __DIR__ . '/..' . '/twig/twig/src/TokenParser/SandboxTokenParser.php',
289
+ 'Twig\\TokenParser\\SetTokenParser' => __DIR__ . '/..' . '/twig/twig/src/TokenParser/SetTokenParser.php',
290
+ 'Twig\\TokenParser\\SpacelessTokenParser' => __DIR__ . '/..' . '/twig/twig/src/TokenParser/SpacelessTokenParser.php',
291
+ 'Twig\\TokenParser\\TokenParserInterface' => __DIR__ . '/..' . '/twig/twig/src/TokenParser/TokenParserInterface.php',
292
+ 'Twig\\TokenParser\\UseTokenParser' => __DIR__ . '/..' . '/twig/twig/src/TokenParser/UseTokenParser.php',
293
+ 'Twig\\TokenParser\\WithTokenParser' => __DIR__ . '/..' . '/twig/twig/src/TokenParser/WithTokenParser.php',
294
+ 'Twig\\TokenStream' => __DIR__ . '/..' . '/twig/twig/src/TokenStream.php',
295
+ 'Twig\\TwigFilter' => __DIR__ . '/..' . '/twig/twig/src/TwigFilter.php',
296
+ 'Twig\\TwigFunction' => __DIR__ . '/..' . '/twig/twig/src/TwigFunction.php',
297
+ 'Twig\\TwigTest' => __DIR__ . '/..' . '/twig/twig/src/TwigTest.php',
298
+ 'Twig\\Util\\DeprecationCollector' => __DIR__ . '/..' . '/twig/twig/src/Util/DeprecationCollector.php',
299
+ 'Twig\\Util\\TemplateDirIterator' => __DIR__ . '/..' . '/twig/twig/src/Util/TemplateDirIterator.php',
300
  'Twig_Autoloader' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Autoloader.php',
301
  'Twig_BaseNodeVisitor' => __DIR__ . '/..' . '/twig/twig/lib/Twig/BaseNodeVisitor.php',
302
  'Twig_CacheInterface' => __DIR__ . '/..' . '/twig/twig/lib/Twig/CacheInterface.php',
436
  'Twig_Node_With' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Node/With.php',
437
  'Twig_Parser' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Parser.php',
438
  'Twig_ParserInterface' => __DIR__ . '/..' . '/twig/twig/lib/Twig/ParserInterface.php',
439
+ 'Twig_Profiler_Dumper_Base' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Profiler/Dumper/Base.php',
440
  'Twig_Profiler_Dumper_Blackfire' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Profiler/Dumper/Blackfire.php',
441
  'Twig_Profiler_Dumper_Html' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Profiler/Dumper/Html.php',
442
  'Twig_Profiler_Dumper_Text' => __DIR__ . '/..' . '/twig/twig/lib/Twig/Profiler/Dumper/Text.php',
510
  'WCML_Cart' => __DIR__ . '/../..' . '/inc/class-wcml-cart.php',
511
  'WCML_Cart_Removed_Items_Widget' => __DIR__ . '/../..' . '/inc/class-wcml-cart-removed-items-widget.php',
512
  'WCML_Cart_Switch_Lang_Functions' => __DIR__ . '/../..' . '/inc/wcml-cart-switch-lang-functions.php',
513
+ 'WCML_Cart_Sync_Warnings' => __DIR__ . '/../..' . '/inc/class-wcml-cart-sync-warnings.php',
514
  'WCML_Checkout_Addons' => __DIR__ . '/../..' . '/compatibility/class-wcml-checkout-addons.php',
515
  'WCML_Checkout_Field_Editor' => __DIR__ . '/../..' . '/compatibility/class-wcml-checkout-field-editor.php',
516
  'WCML_Compatibility' => __DIR__ . '/../..' . '/inc/class-wcml-compatibility.php',
521
  'WCML_Currency_Switcher' => __DIR__ . '/../..' . '/inc/currencies/currency-switcher/class-wcml-currency-switcher.php',
522
  'WCML_Currency_Switcher_Ajax' => __DIR__ . '/../..' . '/inc/currencies/currency-switcher/class-wcml-currency-switcher-ajax.php',
523
  'WCML_Currency_Switcher_Options_Dialog' => __DIR__ . '/../..' . '/inc/template-classes/currency-switcher/class-wcml-currency-switcher-options-dialog.php',
524
+ 'WCML_Currency_Switcher_Properties' => __DIR__ . '/../..' . '/inc/currencies/currency-switcher/class-wcml-currency-switcher-properties.php',
525
  'WCML_Currency_Switcher_Template' => __DIR__ . '/../..' . '/inc/template-classes/currency-switcher/class-wcml-currency-switcher-template.php',
526
  'WCML_Currency_Switcher_Templates' => __DIR__ . '/../..' . '/inc/currencies/currency-switcher/class-wcml-currency-switcher-templates.php',
527
  'WCML_Currency_Switcher_Widget' => __DIR__ . '/../..' . '/inc/currencies/currency-switcher/class-wcml-currency-switcher-widget.php',
573
  'WCML_Not_Translatable_Attributes' => __DIR__ . '/../..' . '/inc/template-classes/class-wcml-not-translatable-attributes.php',
574
  'WCML_Orders' => __DIR__ . '/../..' . '/inc/class-wcml-orders.php',
575
  'WCML_Page_Builders' => __DIR__ . '/../..' . '/inc/translation-editor/class-wcml-page-builders.php',
576
+ 'WCML_Payment_Method_Filter' => __DIR__ . '/../..' . '/classes/order-property-filter/class-wcml-payment-method-filter.php',
577
  'WCML_Per_Product_Shipping' => __DIR__ . '/../..' . '/compatibility/class-wcml-per-product-shipping.php',
578
  'WCML_Pip' => __DIR__ . '/../..' . '/compatibility/class-wcml-pip.php',
579
  'WCML_Plugins_Wrap' => __DIR__ . '/../..' . '/inc/template-classes/class-wcml-plugins-wrap.php',
592
  'WCML_Reports' => __DIR__ . '/../..' . '/inc/class-wcml-reports.php',
593
  'WCML_Requests' => __DIR__ . '/../..' . '/inc/class-wcml-requests.php',
594
  'WCML_Resources' => __DIR__ . '/../..' . '/inc/class-wcml-resources.php',
595
+ 'WCML_Sensei' => __DIR__ . '/../..' . '/compatibility/class-wcml-sensei.php',
596
  'WCML_Settings_UI' => __DIR__ . '/../..' . '/inc/template-classes/class-wcml-settings-ui.php',
597
  'WCML_Setup' => __DIR__ . '/../..' . '/inc/admin-menus/class-wcml-setup.php',
598
  'WCML_Setup_Attributes_UI' => __DIR__ . '/../..' . '/inc/template-classes/setup/class-wcml-setup-attributes-ui.php',
643
  'WCML_WooCommerce_Rest_API_Support' => __DIR__ . '/../..' . '/inc/class-wcml-woocommerce-rest-api-support.php',
644
  'WCML_YITH_WCQV' => __DIR__ . '/../..' . '/compatibility/class-wcml-yith-wcqv.php',
645
  'WCML_gravityforms' => __DIR__ . '/../..' . '/compatibility/class-wcml-gravityforms.php',
 
646
  'WCML_wcExporter' => __DIR__ . '/../..' . '/compatibility/class-wcml-wcexporter.php',
647
  'WCML_xDomain_Data' => __DIR__ . '/../..' . '/inc/class-wcml-xdomain-data.php',
648
  'WooCommerce_Functions_Wrapper' => __DIR__ . '/../..' . '/inc/woocommerce-functions-wrapper.php',
654
  public static function getInitializer(ClassLoader $loader)
655
  {
656
  return \Closure::bind(function () use ($loader) {
657
+ $loader->prefixLengthsPsr4 = ComposerStaticInit1e950a3498b2b701753514ff78661529::$prefixLengthsPsr4;
658
+ $loader->prefixDirsPsr4 = ComposerStaticInit1e950a3498b2b701753514ff78661529::$prefixDirsPsr4;
659
+ $loader->prefixesPsr0 = ComposerStaticInit1e950a3498b2b701753514ff78661529::$prefixesPsr0;
660
+ $loader->classMap = ComposerStaticInit1e950a3498b2b701753514ff78661529::$classMap;
661
 
662
  }, null, ClassLoader::class);
663
  }
vendor/composer/installers/src/Composer/Installers/CakePHPInstaller.php CHANGED
@@ -75,7 +75,6 @@ class CakePHPInstaller extends BaseInstaller
75
  $installed = new $constraintClass('=', $package->getVersion());
76
  if ($cake3->matches($installed)) {
77
  return true;
78
- break;
79
  }
80
  }
81
  }
75
  $installed = new $constraintClass('=', $package->getVersion());
76
  if ($cake3->matches($installed)) {
77
  return true;
 
78
  }
79
  }
80
  }
vendor/composer/installers/src/Composer/Installers/Concrete5Installer.php CHANGED
@@ -4,9 +4,10 @@ namespace Composer\Installers;
4
  class Concrete5Installer extends BaseInstaller
5
  {
6
  protected $locations = array(
7
- 'block' => 'blocks/{$name}/',
 
8
  'package' => 'packages/{$name}/',
9
- 'theme' => 'themes/{$name}/',
10
  'update' => 'updates/{$name}/',
11
  );
12
  }
4
  class Concrete5Installer extends BaseInstaller
5
  {
6
  protected $locations = array(
7
+ 'core' => 'concrete/',
8
+ 'block' => 'application/blocks/{$name}/',
9
  'package' => 'packages/{$name}/',
10
+ 'theme' => 'application/themes/{$name}/',
11
  'update' => 'updates/{$name}/',
12
  );
13
  }
vendor/composer/installers/src/Composer/Installers/EliasisInstaller.php ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace Composer\Installers;
3
+
4
+ class EliasisInstaller extends BaseInstaller
5
+ {
6
+ protected $locations = array(
7
+ 'module' => 'modules/{$name}/'
8
+ );
9
+ }
vendor/composer/installers/src/Composer/Installers/Installer.php CHANGED
@@ -34,6 +34,7 @@ class Installer extends LibraryInstaller
34
  'decibel' => 'DecibelInstaller',
35
  'drupal' => 'DrupalInstaller',
36
  'elgg' => 'ElggInstaller',
 
37
  'ee3' => 'ExpressionEngineInstaller',
38
  'ee2' => 'ExpressionEngineInstaller',
39
  'fuel' => 'FuelInstaller',
@@ -41,14 +42,18 @@ class Installer extends LibraryInstaller
41
  'grav' => 'GravInstaller',
42
  'hurad' => 'HuradInstaller',
43
  'imagecms' => 'ImageCMSInstaller',
 
44
  'joomla' => 'JoomlaInstaller',
 
45
  'kirby' => 'KirbyInstaller',
46
  'kodicms' => 'KodiCMSInstaller',
47
  'kohana' => 'KohanaInstaller',
48
  'laravel' => 'LaravelInstaller',
 
49
  'lithium' => 'LithiumInstaller',
50
  'magento' => 'MagentoInstaller',
51
  'mako' => 'MakoInstaller',
 
52
  'mautic' => 'MauticInstaller',
53
  'mediawiki' => 'MediaWikiInstaller',
54
  'microweber' => 'MicroweberInstaller',
@@ -56,6 +61,7 @@ class Installer extends LibraryInstaller
56
  'modxevo' => 'MODXEvoInstaller',
57
  'moodle' => 'MoodleInstaller',
58
  'october' => 'OctoberInstaller',
 
59
  'oxid' => 'OxidInstaller',
60
  'phpbb' => 'PhpBBInstaller',
61
  'pimcore' => 'PimcoreInstaller',
@@ -65,12 +71,14 @@ class Installer extends LibraryInstaller
65
  'puppet' => 'PuppetInstaller',
66
  'radphp' => 'RadPHPInstaller',
67
  'phifty' => 'PhiftyInstaller',
 
68
  'redaxo' => 'RedaxoInstaller',
69
  'reindex' => 'ReIndexInstaller',
70
  'roundcube' => 'RoundcubeInstaller',
71
  'shopware' => 'ShopwareInstaller',
72
  'silverstripe' => 'SilverStripeInstaller',
73
  'smf' => 'SMFInstaller',
 
74
  'symfony1' => 'Symfony1Installer',
75
  'thelia' => 'TheliaInstaller',
76
  'tusk' => 'TuskInstaller',
34
  'decibel' => 'DecibelInstaller',
35
  'drupal' => 'DrupalInstaller',
36
  'elgg' => 'ElggInstaller',
37
+ 'eliasis' => 'EliasisInstaller',
38
  'ee3' => 'ExpressionEngineInstaller',
39
  'ee2' => 'ExpressionEngineInstaller',
40
  'fuel' => 'FuelInstaller',
42
  'grav' => 'GravInstaller',
43
  'hurad' => 'HuradInstaller',
44
  'imagecms' => 'ImageCMSInstaller',
45
+ 'itop' => 'ItopInstaller',
46
  'joomla' => 'JoomlaInstaller',
47
+ 'kanboard' => 'KanboardInstaller',
48
  'kirby' => 'KirbyInstaller',
49
  'kodicms' => 'KodiCMSInstaller',
50
  'kohana' => 'KohanaInstaller',
51
  'laravel' => 'LaravelInstaller',
52
+ 'lavalite' => 'LavaLiteInstaller',
53
  'lithium' => 'LithiumInstaller',
54
  'magento' => 'MagentoInstaller',
55
  'mako' => 'MakoInstaller',
56
+ 'maya' => 'MayaInstaller',
57
  'mautic' => 'MauticInstaller',
58
  'mediawiki' => 'MediaWikiInstaller',
59
  'microweber' => 'MicroweberInstaller',
61
  'modxevo' => 'MODXEvoInstaller',
62
  'moodle' => 'MoodleInstaller',
63
  'october' => 'OctoberInstaller',
64
+ 'ontowiki' => 'OntoWikiInstaller',
65
  'oxid' => 'OxidInstaller',
66
  'phpbb' => 'PhpBBInstaller',
67
  'pimcore' => 'PimcoreInstaller',
71
  'puppet' => 'PuppetInstaller',
72
  'radphp' => 'RadPHPInstaller',
73
  'phifty' => 'PhiftyInstaller',
74
+ 'porto' => 'PortoInstaller',
75
  'redaxo' => 'RedaxoInstaller',
76
  'reindex' => 'ReIndexInstaller',
77
  'roundcube' => 'RoundcubeInstaller',
78
  'shopware' => 'ShopwareInstaller',
79
  'silverstripe' => 'SilverStripeInstaller',
80
  'smf' => 'SMFInstaller',
81
+ 'sydes' => 'SyDESInstaller',
82
  'symfony1' => 'Symfony1Installer',
83
  'thelia' => 'TheliaInstaller',
84
  'tusk' => 'TuskInstaller',
vendor/composer/installers/src/Composer/Installers/ItopInstaller.php ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace Composer\Installers;
3
+
4
+ class ItopInstaller extends BaseInstaller
5
+ {
6
+ protected $locations = array(
7
+ 'extension' => 'extensions/{$name}/',
8
+ );
9
+ }
vendor/composer/installers/src/Composer/Installers/KanboardInstaller.php ADDED
@@ -0,0 +1,18 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace Composer\Installers;
3
+
4
+ /**
5
+ *
6
+ * Installer for kanboard plugins
7
+ *
8
+ * kanboard.net
9
+ *
10
+ * Class KanboardInstaller
11
+ * @package Composer\Installers
12
+ */
13
+ class KanboardInstaller extends BaseInstaller
14
+ {
15
+ protected $locations = array(
16
+ 'plugin' => 'plugins/{$name}/',
17
+ );
18
+ }
vendor/composer/installers/src/Composer/Installers/LavaLiteInstaller.php ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace Composer\Installers;
3
+
4
+ class LavaLiteInstaller extends BaseInstaller
5
+ {
6
+ protected $locations = array(
7
+ 'package' => 'packages/{$name}/',
8
+ 'theme' => 'public/themes/{$name}/',
9
+ );
10
+ }
vendor/composer/installers/src/Composer/Installers/MayaInstaller.php ADDED
@@ -0,0 +1,33 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace Composer\Installers;
3
+
4
+ class MayaInstaller extends BaseInstaller
5
+ {
6
+ protected $locations = array(
7
+ 'module' => 'modules/{$name}/',
8
+ );
9
+
10
+ /**
11
+ * Format package name.
12
+ *
13
+ * For package type maya-module, cut off a trailing '-module' if present.
14
+ *
15
+ */
16
+ public function inflectPackageVars($vars)
17
+ {
18
+ if ($vars['type'] === 'maya-module') {
19
+ return $this->inflectModuleVars($vars);
20
+ }
21
+
22
+ return $vars;
23
+ }
24
+
25
+ protected function inflectModuleVars($vars)
26
+ {
27
+ $vars['name'] = preg_replace('/-module$/', '', $vars['name']);
28
+ $vars['name'] = str_replace(array('-', '_'), ' ', $vars['name']);
29
+ $vars['name'] = str_replace(' ', '', ucwords($vars['name']));
30
+
31
+ return $vars;
32
+ }
33
+ }
vendor/composer/installers/src/Composer/Installers/MoodleInstaller.php CHANGED
@@ -45,6 +45,7 @@ class MoodleInstaller extends BaseInstaller
45
  'report' => 'report/{$name}/',
46
  'repository' => 'repository/{$name}/',
47
  'scormreport' => 'mod/scorm/report/{$name}/',
 
48
  'theme' => 'theme/{$name}/',
49
  'tinymce' => 'lib/editor/tinymce/plugins/{$name}/',
50
  'profilefield' => 'user/profile/field/{$name}/',
45
  'report' => 'report/{$name}/',
46
  'repository' => 'repository/{$name}/',
47
  'scormreport' => 'mod/scorm/report/{$name}/',
48
+ 'search' => 'search/engine/{$name}/',
49
  'theme' => 'theme/{$name}/',
50
  'tinymce' => 'lib/editor/tinymce/plugins/{$name}/',
51
  'profilefield' => 'user/profile/field/{$name}/',
vendor/composer/installers/src/Composer/Installers/OntoWikiInstaller.php ADDED
@@ -0,0 +1,24 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace Composer\Installers;
3
+
4
+ class OntoWikiInstaller extends BaseInstaller
5
+ {
6
+ protected $locations = array(
7
+ 'extension' => 'extensions/{$name}/',
8
+ 'theme' => 'extensions/themes/{$name}/',
9
+ 'translation' => 'extensions/translations/{$name}/',
10
+ );
11
+
12
+ /**
13
+ * Format package name to lower case and remove ".ontowiki" suffix
14
+ */
15
+ public function inflectPackageVars($vars)
16
+ {
17
+ $vars['name'] = strtolower($vars['name']);
18
+ $vars['name'] = preg_replace('/.ontowiki$/', '', $vars['name']);
19
+ $vars['name'] = preg_replace('/-theme$/', '', $vars['name']);
20
+ $vars['name'] = preg_replace('/-translation$/', '', $vars['name']);
21
+
22
+ return $vars;
23
+ }
24
+ }
vendor/composer/installers/src/Composer/Installers/PortoInstaller.php ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace Composer\Installers;
3
+
4
+ class PortoInstaller extends BaseInstaller
5
+ {
6
+ protected $locations = array(
7
+ 'container' => 'app/Containers/{$name}/',
8
+ );
9
+ }
vendor/composer/installers/src/Composer/Installers/SyDESInstaller.php ADDED
@@ -0,0 +1,49 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace Composer\Installers;
3
+
4
+ class SyDESInstaller extends BaseInstaller
5
+ {
6
+ protected $locations = array(
7
+ 'module' => 'app/modules/{$name}/',
8
+ 'theme' => 'themes/{$name}/',
9
+ );
10
+
11
+ /**
12
+ * Format module name.
13
+ *
14
+ * Strip `sydes-` prefix and a trailing '-theme' or '-module' from package name if present.
15
+ *
16
+ * @param array @vars
17
+ *
18
+ * @return array
19
+ */
20
+ public function inflectPackageVars($vars)
21
+ {
22
+ if ($vars['type'] == 'sydes-module') {
23
+ return $this->inflectModuleVars($vars);
24
+ }
25
+
26
+ if ($vars['type'] === 'sydes-theme') {
27
+ return $this->inflectThemeVars($vars);
28
+ }
29
+
30
+ return $vars;
31
+ }
32
+
33
+ public function inflectModuleVars($vars)
34
+ {
35
+ $vars['name'] = preg_replace('/(^sydes-|-module$)/i', '', $vars['name']);
36
+ $vars['name'] = str_replace(array('-', '_'), ' ', $vars['name']);
37
+ $vars['name'] = str_replace(' ', '', ucwords($vars['name']));
38
+
39
+ return $vars;
40
+ }
41
+
42
+ protected function inflectThemeVars($vars)
43
+ {
44
+ $vars['name'] = preg_replace('/(^sydes-|-theme$)/', '', $vars['name']);
45
+ $vars['name'] = strtolower($vars['name']);
46
+
47
+ return $vars;
48
+ }
49
+ }
vendor/composer/installers/src/Composer/Installers/VgmcpInstaller.php ADDED
@@ -0,0 +1,49 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace Composer\Installers;
3
+
4
+ class VgmcpInstaller extends BaseInstaller
5
+ {
6
+ protected $locations = array(
7
+ 'bundle' => 'src/{$vendor}/{$name}/',
8
+ 'theme' => 'themes/{$name}/'
9
+ );
10
+
11
+ /**
12
+ * Format package name.
13
+ *
14
+ * For package type vgmcp-bundle, cut off a trailing '-bundle' if present.
15
+ *
16
+ * For package type vgmcp-theme, cut off a trailing '-theme' if present.
17
+ *
18
+ */
19
+ public function inflectPackageVars($vars)
20
+ {
21
+ if ($vars['type'] === 'vgmcp-bundle') {
22
+ return $this->inflectPluginVars($vars);
23
+ }
24
+
25
+ if ($vars['type'] === 'vgmcp-theme') {
26
+ return $this->inflectThemeVars($vars);
27
+ }
28
+
29
+ return $vars;
30
+ }
31
+
32
+ protected function inflectPluginVars($vars)
33
+ {
34
+ $vars['name'] = preg_replace('/-bundle$/', '', $vars['name']);
35
+ $vars['name'] = str_replace(array('-', '_'), ' ', $vars['name']);
36
+ $vars['name'] = str_replace(' ', '', ucwords($vars['name']));
37
+
38
+ return $vars;
39
+ }
40
+
41
+ protected function inflectThemeVars($vars)
42
+ {
43
+ $vars['name'] = preg_replace('/-theme$/', '', $vars['name']);
44
+ $vars['name'] = str_replace(array('-', '_'), ' ', $vars['name']);
45
+ $vars['name'] = str_replace(' ', '', ucwords($vars['name']));
46
+
47
+ return $vars;
48
+ }
49
+ }
vendor/otgs/installer/includes/class-installer-dependencies.php CHANGED
@@ -1,280 +1,288 @@
1
  <?php
2
 
3
- class Installer_Dependencies{
4
 
5
- private $uploading_allowed = null;
6
- private $is_win_paths_exception = array();
7
 
8
 
9
- function __construct(){
10
 
11
- add_action( 'admin_init', array( $this, 'prevent_plugins_update_on_plugins_page' ), 100);
12
 
13
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
14
 
15
- global $pagenow;
16
- if($pagenow == 'update.php'){
17
- if(isset($_GET['action']) && $_GET['action'] == 'update-selected'){
18
- add_action('admin_head', array($this, 'prevent_plugins_update_on_updates_screen')); //iframe/bulk
19
- }else{
20
- add_action('all_admin_notices', array($this, 'prevent_plugins_update_on_updates_screen')); //regular/singular
21
- }
22
- }
23
- add_action('wp_ajax_update-plugin', array($this, 'prevent_plugins_update_on_updates_screen'), 0); // high priority, before WP
24
 
25
- }
26
 
27
- public function is_win_paths_exception($repository_id){
28
 
29
- if(!isset($this->is_win_paths_exception[$repository_id])) {
30
 
31
- $this->is_win_paths_exception[$repository_id] = false;
32
 
33
- if ( strtoupper( substr( PHP_OS, 0, 3 ) ) === 'WIN' ) {
 
 
34
 
35
- $windows_max_path_length = 256;
36
- $longest_path['wpml'] = 109;
37
- $longest_path['toolset'] = 99;
38
 
39
- $margin = 15;
40
 
41
- $upgrade_path_length = strlen( WP_CONTENT_DIR . '/upgrade' );
42
-
43
- $installer_settings = WP_Installer()->settings;
44
 
45
  if ( isset($installer_settings['repositories'][$repository_id]['data']) && is_array( $installer_settings['repositories'][$repository_id]['data']['downloads']['plugins'] ) ) {
46
  $a_plugin = current( $installer_settings['repositories'][$repository_id]['data']['downloads']['plugins'] );
47
  $url = WP_Installer()->append_site_key_to_download_url( $a_plugin['url'], 'xxxxxx', $repository_id );
48
  $tmpfname = wp_tempnam( $url );
49
 
50
- $tmpname_length = strlen( basename( $tmpfname ) ) - 4; // -.tmp
51
 
52
- if ( $upgrade_path_length + $tmpname_length + $longest_path[$repository_id] + $margin > $windows_max_path_length ) {
53
 
54
- $this->is_win_paths_exception[$repository_id] = true;
55
 
56
- }
57
 
58
- }
59
 
60
 
61
- }
62
 
63
- }
64
 
65
- return $this->is_win_paths_exception[$repository_id];
66
 
67
- }
68
 
69
- public function is_uploading_allowed(){
70
 
71
- if(!isset($this->uploading_allowed)){
72
- require_once ABSPATH . 'wp-admin/includes/class-wp-upgrader.php';
73
- require_once WP_Installer()->plugin_path() . '/includes/installer-upgrader-skins.php';
74
 
75
- $upgrader_skins = new Installer_Upgrader_Skins(); //use our custom (mute) Skin
76
- $upgrader = new Plugin_Upgrader($upgrader_skins);
77
 
78
- ob_start();
79
- $res = $upgrader->fs_connect( array(WP_CONTENT_DIR, WP_PLUGIN_DIR) );
80
- ob_end_clean();
81
 
82
- if ( ! $res || is_wp_error( $res ) ) {
83
- $this->uploading_allowed = false;
84
- }else{
85
- $this->uploading_allowed = true;
86
- }
87
- }
88
 
89
- return $this->uploading_allowed;
90
 
91
- }
92
 
93
- public function cant_download($repository_id){
94
 
95
- return !$this->is_uploading_allowed() || $this->is_win_paths_exception($repository_id);
96
 
97
- }
98
 
99
- public function win_paths_exception_message(){
100
- return __('Downloading is not possible. WordPress cannot create required folders because of the
101
- 256 characters limitation of the current Windows environment.', 'installer');
102
- }
103
 
104
- public function prevent_plugins_update_on_plugins_page(){
105
 
106
- $plugins = get_site_transient( 'update_plugins' );
107
- if ( isset($plugins->response) && is_array($plugins->response) ) {
108
- $plugins_with_updates = array_keys( $plugins->response );
109
- }
110
 
111
- if( !empty($plugins_with_updates) ) {
112
 
113
- $plugins = get_plugins();
114
 
115
- $installer_settings = WP_Installer()->settings;
116
- if ( isset( $installer_settings['repositories'] ) ) {
117
- foreach ( $installer_settings['repositories'] as $repository_id => $repository ) {
118
 
119
- if ( $this->is_win_paths_exception( $repository_id ) ) {
120
 
121
- $repositories_plugins = array();
122
- foreach ( $repository['data']['packages'] as $package ) {
123
- foreach ( $package['products'] as $product ) {
124
- foreach ( $product['plugins'] as $plugin_slug ) {
125
- $download = $installer_settings['repositories'][ $repository_id ]['data']['downloads']['plugins'][ $plugin_slug ];
126
- if ( empty( $download['free-on-wporg'] ) ) {
127
- $repositories_plugins[ $download['slug'] ] = $download['name'];
128
- }
129
- }
130
- }
131
- }
132
 
133
- foreach ( $plugins as $plugin_id => $plugin ) {
134
 
135
- if ( in_array( $plugin_id, $plugins_with_updates ) ) {
136
 
137
- $wp_plugin_slug = dirname( $plugin_id );
138
- if ( empty( $wp_plugin_slug ) ) {
139
- $wp_plugin_slug = basename( $plugin_id, '.php' );
140
- }
141
 
142
- foreach ( $repositories_plugins as $slug => $name ) {
143
- if ( $wp_plugin_slug == $slug || $name == $plugin['Name'] || $name == $plugin['Title'] ) { //match order: slug, name, title
144
 
145
- remove_action( "after_plugin_row_$plugin_id", 'wp_plugin_update_row', 10, 2 );
146
- add_action( "after_plugin_row_$plugin_id", array(
147
- $this,
148
- 'wp_plugin_update_row_win_exception',
149
- ), 10, 2 );
150
 
151
- }
152
- }
153
 
154
- }
155
 
156
- }
157
 
158
- }
159
 
160
 
161
- }
162
- }
163
 
164
- }
165
 
166
- }
167
 
168
- public function wp_plugin_update_row_win_exception(){
169
- $wp_list_table = _get_list_table('WP_Plugins_List_Table');
170
- echo '<tr class="plugin-update-tr">';
171
- echo '<td class="plugin-update colspanchange" colspan="' . esc_attr( $wp_list_table->get_column_count() ) .
172
- '"><div class="update-message">' . $this->win_paths_exception_message() . '</div></td>';
173
- echo '</tr>';
174
- }
175
 
176
- public function prevent_plugins_update_on_updates_screen(){
177
 
178
- if ( isset($_REQUEST['action']) ) {
179
 
180
- $action = isset($_REQUEST['action']) ? sanitize_text_field ( $_REQUEST['action'] ) : '';
181
 
182
- $installer_settings = WP_Installer()->settings;
183
 
184
- //bulk mode
185
- if('update-selected' == $action) {
186
 
187
- global $plugins;
188
 
189
- if(isset($plugins) && is_array($plugins)) {
190
 
191
- foreach ($plugins as $k => $plugin) {
192
 
193
- $wp_plugin_slug = dirname($plugin);
194
 
195
- foreach ($installer_settings['repositories'] as $repository_id => $repository) {
196
 
197
- if( $this->is_win_paths_exception($repository_id) ){
198
 
199
- foreach ($repository['data']['packages'] as $package) {
200
 
201
- foreach ($package['products'] as $product) {
202
 
203
- foreach ($product['plugins'] as $plugin_slug) {
204
 
205
- $download = $installer_settings['repositories'][$repository_id]['data']['downloads']['plugins'][$plugin_slug];
206
 
207
- if ($download['slug'] == $wp_plugin_slug && empty($download['free-on-wporg']) ) {
208
 
209
- echo '<div class="updated error"><p>' . $this->win_paths_exception_message() .
210
- ' <strong>(' . $download['name'] . ')</strong>' . '</p></div>';
211
- unset($plugins[$k]);
212
 
213
- break(3);
214
 
215
- }
216
 
217
- }
218
 
219
- }
220
 
221
- }
222
 
223
 
224
- }
225
 
226
- }
227
 
228
- }
229
 
230
- }
231
 
232
- }
233
 
234
 
235
- if( 'upgrade-plugin' == $action || 'update-plugin' == $action ) {
236
 
237
- $plugin = isset($_REQUEST['plugin']) ? trim( sanitize_text_field ( $_REQUEST['plugin'] ) ) : '';
238
 
239
- $wp_plugin_slug = dirname($plugin);
240
 
241
- foreach($installer_settings['repositories'] as $repository_id => $repository){
242
 
243
- if( $this->is_win_paths_exception( $repository_id ) ) {
244
- foreach ($repository['data']['packages'] as $package) {
245
 
246
- foreach($package['products'] as $product) {
247
 
248
- foreach($product['plugins'] as $plugin_slug) {
249
- $download = $installer_settings['repositories'][$repository_id]['data']['downloads']['plugins'][$plugin_slug];
250
 
251
- //match by folder, will change to match by name and folder
252
- if ( $download['slug'] == $wp_plugin_slug && empty ($download['free-on-wporg'] ) ) {
253
 
254
- echo '<div class="updated error"><p>' . $this->win_paths_exception_message() . '</p></div>';
255
 
256
- echo '<div class="wrap">';
257
- echo '<h2>' . __('Update Plugin') . '</h2>';
258
- echo '<a href="' . admin_url('update-core.php') . '">' . __('Return to the updates page', 'installer') . '</a>';
259
- echo '</div>';
260
- require_once(ABSPATH . 'wp-admin/admin-footer.php');
261
- exit;
262
 
263
- }
264
 
265
- }
266
 
267
- }
268
 
269
- }
270
- }
271
 
272
- }
273
 
274
- }
275
- }
276
 
277
- }
278
 
279
 
280
  }
1
  <?php
2
 
3
+ class Installer_Dependencies {
4
 
5
+ private $uploading_allowed = null;
6
+ private $is_win_paths_exception = array();
7
 
8
 
9
+ function __construct() {
10
 
11
+ add_action( 'admin_init', array( $this, 'prevent_plugins_update_on_plugins_page' ), 100 );
12
 
13
 
14
+ global $pagenow;
15
+ if ( $pagenow == 'update.php' ) {
16
+ if ( isset( $_GET['action'] ) && $_GET['action'] == 'update-selected' ) {
17
+ add_action( 'admin_head', array(
18
+ $this,
19
+ 'prevent_plugins_update_on_updates_screen'
20
+ ) ); //iframe/bulk
21
+ } else {
22
+ add_action( 'all_admin_notices', array(
23
+ $this,
24
+ 'prevent_plugins_update_on_updates_screen'
25
+ ) ); //regular/singular
26
+ }
27
+ }
28
+ add_action( 'wp_ajax_update-plugin', array(
29
+ $this,
30
+ 'prevent_plugins_update_on_updates_screen'
31
+ ), 0 ); // high priority, before WP
32
 
33
+ }
 
 
 
 
 
 
 
 
34
 
35
+ public function is_win_paths_exception( $repository_id ) {
36
 
37
+ if ( ! isset( $this->is_win_paths_exception[ $repository_id ] ) ) {
38
 
39
+ $this->is_win_paths_exception[ $repository_id ] = false;
40
 
41
+ if ( strtoupper( substr( PHP_OS, 0, 3 ) ) === 'WIN' ) {
42
 
43
+ $windows_max_path_length = 256;
44
+ $longest_path['wpml'] = 109;
45
+ $longest_path['toolset'] = 99;
46
 
47
+ $margin = 15;
 
 
48
 
49
+ $upgrade_path_length = strlen( WP_CONTENT_DIR . '/upgrade' );
50
 
51
+ $installer_settings = WP_Installer()->settings;
 
 
52
 
53
  if ( isset($installer_settings['repositories'][$repository_id]['data']) && is_array( $installer_settings['repositories'][$repository_id]['data']['downloads']['plugins'] ) ) {
54
  $a_plugin = current( $installer_settings['repositories'][$repository_id]['data']['downloads']['plugins'] );
55
  $url = WP_Installer()->append_site_key_to_download_url( $a_plugin['url'], 'xxxxxx', $repository_id );
56
  $tmpfname = wp_tempnam( $url );
57
 
58
+ $tmpname_length = strlen( basename( $tmpfname ) ) - 4; // -.tmp
59
 
60
+ if ( $upgrade_path_length + $tmpname_length + $longest_path[ $repository_id ] + $margin > $windows_max_path_length ) {
61
 
62
+ $this->is_win_paths_exception[ $repository_id ] = true;
63
 
64
+ }
65
 
66
+ }
67
 
68
 
69
+ }
70
 
71
+ }
72
 
73
+ return $this->is_win_paths_exception[ $repository_id ];
74
 
75
+ }
76
 
77
+ public function is_uploading_allowed() {
78
 
79
+ if ( ! isset( $this->uploading_allowed ) ) {
80
+ require_once ABSPATH . 'wp-admin/includes/class-wp-upgrader.php';
81
+ require_once WP_Installer()->plugin_path() . '/includes/class-installer-upgrader-skins.php';
82
 
83
+ $upgrader_skins = new Installer_Upgrader_Skins(); //use our custom (mute) Skin
84
+ $upgrader = new Plugin_Upgrader( $upgrader_skins );
85
 
86
+ ob_start();
87
+ $res = $upgrader->fs_connect( array( WP_CONTENT_DIR, WP_PLUGIN_DIR ) );
88
+ ob_end_clean();
89
 
90
+ if ( ! $res || is_wp_error( $res ) ) {
91
+ $this->uploading_allowed = false;
92
+ } else {
93
+ $this->uploading_allowed = true;
94
+ }
95
+ }
96
 
97
+ return $this->uploading_allowed;
98
 
99
+ }
100
 
101
+ public function cant_download( $repository_id ) {
102
 
103
+ return ! $this->is_uploading_allowed() || $this->is_win_paths_exception( $repository_id );
104
 
105
+ }
106
 
107
+ public function win_paths_exception_message() {
108
+ return __( 'Downloading is not possible. WordPress cannot create required folders because of the
109
+ 256 characters limitation of the current Windows environment.', 'installer' );
110
+ }
111
 
112
+ public function prevent_plugins_update_on_plugins_page() {
113
 
114
+ $plugins = get_site_transient( 'update_plugins' );
115
+ if ( isset( $plugins->response ) && is_array( $plugins->response ) ) {
116
+ $plugins_with_updates = array_keys( $plugins->response );
117
+ }
118
 
119
+ if ( ! empty( $plugins_with_updates ) ) {
120
 
121
+ $plugins = get_plugins();
122
 
123
+ $installer_settings = WP_Installer()->settings;
124
+ if ( isset( $installer_settings['repositories'] ) ) {
125
+ foreach ( $installer_settings['repositories'] as $repository_id => $repository ) {
126
 
127
+ if ( $this->is_win_paths_exception( $repository_id ) ) {
128
 
129
+ $repositories_plugins = array();
130
+ foreach ( $repository['data']['packages'] as $package ) {
131
+ foreach ( $package['products'] as $product ) {
132
+ foreach ( $product['plugins'] as $plugin_slug ) {
133
+ $download = $installer_settings['repositories'][ $repository_id ]['data']['downloads']['plugins'][ $plugin_slug ];
134
+ if ( empty( $download['free-on-wporg'] ) ) {
135
+ $repositories_plugins[ $download['slug'] ] = $download['name'];
136
+ }
137
+ }
138
+ }
139
+ }
140
 
141
+ foreach ( $plugins as $plugin_id => $plugin ) {
142
 
143
+ if ( in_array( $plugin_id, $plugins_with_updates ) ) {
144
 
145
+ $wp_plugin_slug = dirname( $plugin_id );
146
+ if ( empty( $wp_plugin_slug ) ) {
147
+ $wp_plugin_slug = basename( $plugin_id, '.php' );
148
+ }
149
 
150
+ foreach ( $repositories_plugins as $slug => $name ) {
151
+ if ( $wp_plugin_slug == $slug || $name == $plugin['Name'] || $name == $plugin['Title'] ) { //match order: slug, name, title
152
 
153
+ remove_action( "after_plugin_row_$plugin_id", 'wp_plugin_update_row', 10, 2 );
154
+ add_action( "after_plugin_row_$plugin_id", array(
155
+ $this,
156
+ 'wp_plugin_update_row_win_exception',
157
+ ), 10, 2 );
158
 
159
+ }
160
+ }
161
 
162
+ }
163
 
164
+ }
165
 
166
+ }
167
 
168
 
169
+ }
170
+ }
171
 
172
+ }
173
 
174
+ }
175
 
176
+ public function wp_plugin_update_row_win_exception() {
177
+ $wp_list_table = _get_list_table( 'WP_Plugins_List_Table' );
178
+ echo '<tr class="plugin-update-tr">';
179
+ echo '<td class="plugin-update colspanchange" colspan="' . esc_attr( $wp_list_table->get_column_count() ) .
180
+ '"><div class="update-message">' . $this->win_paths_exception_message() . '</div></td>';
181
+ echo '</tr>';
182
+ }
183
 
184
+ public function prevent_plugins_update_on_updates_screen() {
185
 
186
+ if ( isset( $_REQUEST['action'] ) ) {
187
 
188
+ $action = isset( $_REQUEST['action'] ) ? sanitize_text_field( $_REQUEST['action'] ) : '';
189
 
190
+ $installer_settings = WP_Installer()->settings;
191
 
192
+ //bulk mode
193
+ if ( 'update-selected' == $action ) {
194
 
195
+ global $plugins;
196
 
197
+ if ( isset( $plugins ) && is_array( $plugins ) ) {
198
 
199
+ foreach ( $plugins as $k => $plugin ) {
200
 
201
+ $wp_plugin_slug = dirname( $plugin );
202
 
203
+ foreach ( $installer_settings['repositories'] as $repository_id => $repository ) {
204
 
205
+ if ( $this->is_win_paths_exception( $repository_id ) ) {
206
 
207
+ foreach ( $repository['data']['packages'] as $package ) {
208
 
209
+ foreach ( $package['products'] as $product ) {
210
 
211
+ foreach ( $product['plugins'] as $plugin_slug ) {
212
 
213
+ $download = $installer_settings['repositories'][ $repository_id ]['data']['downloads']['plugins'][ $plugin_slug ];
214
 
215
+ if ( $download['slug'] == $wp_plugin_slug && empty( $download['free-on-wporg'] ) ) {
216
 
217
+ echo '<div class="updated error"><p>' . $this->win_paths_exception_message() .
218
+ ' <strong>(' . $download['name'] . ')</strong>' . '</p></div>';
219
+ unset( $plugins[ $k ] );
220
 
221
+ break( 3 );
222
 
223
+ }
224
 
225
+ }
226
 
227
+ }
228
 
229
+ }
230
 
231
 
232
+ }
233
 
234
+ }
235
 
236
+ }
237
 
238
+ }
239
 
240
+ }
241
 
242
 
243
+ if ( 'upgrade-plugin' == $action || 'update-plugin' == $action ) {
244
 
245
+ $plugin = isset( $_REQUEST['plugin'] ) ? trim( sanitize_text_field( $_REQUEST['plugin'] ) ) : '';
246
 
247
+ $wp_plugin_slug = dirname( $plugin );
248
 
249
+ foreach ( $installer_settings['repositories'] as $repository_id => $repository ) {
250
 
251
+ if ( $this->is_win_paths_exception( $repository_id ) ) {
252
+ foreach ( $repository['data']['packages'] as $package ) {
253
 
254
+ foreach ( $package['products'] as $product ) {
255
 
256
+ foreach ( $product['plugins'] as $plugin_slug ) {
257
+ $download = $installer_settings['repositories'][ $repository_id ]['data']['downloads']['plugins'][ $plugin_slug ];
258
 
259
+ //match by folder, will change to match by name and folder
260
+ if ( $download['slug'] == $wp_plugin_slug && empty ( $download['free-on-wporg'] ) ) {
261
 
262
+ echo '<div class="updated error"><p>' . $this->win_paths_exception_message() . '</p></div>';
263
 
264
+ echo '<div class="wrap">';
265
+ echo '<h2>' . __( 'Update Plugin' ) . '</h2>';
266
+ echo '<a href="' . admin_url( 'update-core.php' ) . '">' . __( 'Return to the updates page', 'installer' ) . '</a>';
267
+ echo '</div>';
268
+ require_once( ABSPATH . 'wp-admin/admin-footer.php' );
269
+ exit;
270
 
271
+ }
272
 
273
+ }
274
 
275
+ }
276
 
277
+ }
278
+ }
279
 
280
+ }
281
 
282
+ }
283
+ }
284
 
285
+ }
286
 
287
 
288
  }
vendor/otgs/installer/includes/class-installer-upgrader-skins.php ADDED
@@ -0,0 +1,38 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Installer_Upgrader_Skins extends WP_Upgrader_Skin {
4
+
5
+ function __construct( $args = array() ) {
6
+ $defaults = array( 'url' => '', 'nonce' => '', 'title' => '', 'context' => false );
7
+ $this->options = wp_parse_args( $args, $defaults );
8
+ }
9
+
10
+ function header() {
11
+
12
+ }
13
+
14
+ function footer() {
15
+
16
+ }
17
+
18
+ function error( $error ) {
19
+ $this->installer_error = $error;
20
+ }
21
+
22
+ function add_strings() {
23
+
24
+ }
25
+
26
+ function feedback( $string ) {
27
+
28
+ }
29
+
30
+ function before() {
31
+
32
+ }
33
+
34
+ function after() {
35
+
36
+ }
37
+
38
+ }
vendor/otgs/installer/includes/class-translation-service-info.php ADDED
@@ -0,0 +1,40 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
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;
15
+
16
+ $save_settings = false;
17
+ if ( isset( $data->ts_info['preferred'] ) && empty( $ts_info['preferred'] ) ) {
18
+ WP_Installer()->settings['repositories'][ $repository_id ]['ts_info']['preferred'] = $data->ts_info['preferred'];
19
+ $save_settings = true;
20
+ }
21
+
22
+ if ( isset( $data->ts_info['referal'] ) && empty( $ts_info['referal'] ) ) {
23
+ WP_Installer()->settings['repositories'][ $repository_id ]['ts_info']['referal'] = $data->ts_info['referal'];
24
+ $save_settings = true;
25
+ }
26
+
27
+ if ( ! empty( $data->ts_info['client_id'] ) ) { // can be updated
28
+ WP_Installer()->settings['repositories'][ $repository_id ]['ts_info']['client_id'] = $data->ts_info['client_id'];
29
+ $save_settings = true;
30
+ }
31
+
32
+ if ( $save_settings ) {
33
+ WP_Installer()->save_settings();
34
+ }
35
+
36
+ }
37
+
38
+ }
39
+
40
+ new Translation_Service_Info();
vendor/otgs/installer/includes/class-wp-installer-api.php ADDED
@@ -0,0 +1,134 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class WP_Installer_API{
4
+
5
+ public static function get_product_installer_link($repository_id, $package_id = false){
6
+
7
+ $menu_url = WP_Installer()->menu_url();
8
+
9
+ $url = $menu_url . '#' . $repository_id;
10
+ if($package_id){
11
+ $url .= '/' . $package_id;
12
+ }
13
+
14
+ return $url;
15
+
16
+ }
17
+
18
+ public static function get_product_price($repository_id, $package_id, $product_id, $incl_discount = false){
19
+
20
+ $price = WP_Installer()->get_product_price($repository_id, $package_id, $product_id, $incl_discount);
21
+
22
+ return $price;
23
+ }
24
+
25
+ /**
26
+ * Retrieve the preferred translation service.
27
+ *
28
+ * @since 1.6.5
29
+ *
30
+ * @param string The repository id (e.g. wpml)
31
+ * @return string The translation service id
32
+ */
33
+ public static function get_preferred_ts($repository_id = 'wpml'){
34
+
35
+ if(isset(WP_Installer()->settings['repositories'][$repository_id]['ts_info']['preferred'])){
36
+ return WP_Installer()->settings['repositories'][$repository_id]['ts_info']['preferred'];
37
+ }
38
+
39
+ return false;
40
+
41
+ }
42
+
43
+ /**
44
+ * Set the preferred translation service.
45
+ *
46
+ * @since 1.6.5
47
+ *
48
+ * @param string The translation service id
49
+ * @param string The repository id (e.g. wpml)
50
+ */
51
+ public static function set_preferred_ts( $value, $repository_id = 'wpml' ){
52
+
53
+ if( isset( WP_Installer()->settings['repositories'][$repository_id]['ts_info']['preferred'] ) ){
54
+
55
+ WP_Installer()->settings['repositories'][$repository_id]['ts_info']['preferred'] = $value;
56
+
57
+ WP_Installer()->save_settings();
58
+
59
+ }
60
+
61
+ }
62
+
63
+ /**
64
+ * Retrieve the referring translation service (if any)
65
+ *
66
+ * @since 1.6.5
67
+ *
68
+ * @param string The repository id (e.g. wpml)
69
+ * @return string The translation service id or false
70
+ */
71
+ public static function get_ts_referal($repository_id = 'wpml'){
72
+
73
+ if(isset(WP_Installer()->settings['repositories'][$repository_id]['ts_info']['referal'])){
74
+ return WP_Installer()->settings['repositories'][$repository_id]['ts_info']['referal'];
75
+ }
76
+
77
+ return false;
78
+
79
+ }
80
+
81
+ /**
82
+ * Retrieve the translation services client id for a specific repository (if any)
83
+ *
84
+ * @since 1.7.9
85
+ *
86
+ * @param string The repository id (e.g. wpml)
87
+ * @return string The client id or false
88
+ */
89
+ public static function get_ts_client_id( $repository_id = 'wpml' ){
90
+
91
+ if(isset(WP_Installer()->settings['repositories'][$repository_id]['ts_info']['client_id'])){
92
+ return WP_Installer()->settings['repositories'][$repository_id]['ts_info']['client_id'];
93
+ }
94
+
95
+ return false;
96
+
97
+ }
98
+
99
+ /**
100
+ * Retrieve the site key corresponding to a repository.
101
+ * This is a wrapper of WP_Installer::get_site_key()
102
+ * @see WP_Installer::get_site_key()
103
+ *
104
+ * @since 1.7.9
105
+ *
106
+ * @param string The repository id (e.g. wpml)
107
+ * @return string The site key (or false)
108
+ */
109
+ public static function get_site_key( $repository_id = 'wpml' ){
110
+
111
+ return WP_Installer()->get_site_key( $repository_id );
112
+
113
+ }
114
+
115
+ /**
116
+ * Retrieve the ID of the last user who registered a repository.
117
+ *
118
+ * @since 1.7.16
119
+ *
120
+ * @param string The repository id (e.g. wpml)
121
+ * @return int The user id (or zero)
122
+ */
123
+ public static function get_registering_user_id( $repository_id = 'wpml' ){
124
+
125
+ $user_id = 0;
126
+ if( isset( WP_Installer()->settings['repositories'][$repository_id]['subscription']['registered_by'] ) ){
127
+ $user_id = WP_Installer()->settings['repositories'][$repository_id]['subscription']['registered_by'];
128
+ }
129
+
130
+ return $user_id;
131
+ }
132
+
133
+
134
+ }
vendor/otgs/installer/includes/class-wp-installer-channels.php ADDED
@@ -0,0 +1,291 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Class WP_Installer_Channels
5
+ * @since 1.8
6
+ */
7
+ class WP_Installer_Channels{
8
+
9
+ const CHANNEL_PRODUCTION = 1;
10
+ const CHANNEL_BETA = 2;
11
+ const CHANNEL_DEVELOPMENT = 3;
12
+
13
+ protected static $_instance = null;
14
+
15
+ function __construct() {
16
+ add_action( 'init', array( $this, 'init' ), 20 ); // after Installer
17
+ }
18
+
19
+ /**
20
+ * @return null|WP_Installer_Channels
21
+ */
22
+ public static function instance() {
23
+
24
+ if ( is_null( self::$_instance ) ) {
25
+ self::$_instance = new self();
26
+ }
27
+
28
+ return self::$_instance;
29
+ }
30
+
31
+ /**
32
+ * Get the channel literal id based on the numeric id
33
+ *
34
+ * @param int $int
35
+ *
36
+ * @return string
37
+ */
38
+ public static function channel_id( $int ) {
39
+ if ( self::CHANNEL_DEVELOPMENT === $int ) {
40
+ $channel = 'development';
41
+ } elseif ( self::CHANNEL_BETA === $int ) {
42
+ $channel = 'beta';
43
+ } else {
44
+ $channel = 'production';
45
+ }
46
+
47
+ return $channel;
48
+ }
49
+
50
+ /**
51
+ * Get the channel literal id based on the numeric id
52
+ *
53
+ * @param mixed $id
54
+ *
55
+ * @return string
56
+ */
57
+ public static function channel_name_by_id( $id ) {
58
+ if ( self::CHANNEL_DEVELOPMENT === $id || self::channel_id( self::CHANNEL_DEVELOPMENT ) === $id ) {
59
+ $channel = __( 'Development', 'installer' );
60
+ } elseif ( self::CHANNEL_BETA === $id || self::channel_id( self::CHANNEL_BETA ) === $id ) {
61
+ $channel = __( 'Beta', 'installer' );
62
+ } else {
63
+ $channel = __( 'Production', 'installer' );
64
+ }
65
+
66
+ return $channel;
67
+ }
68
+
69
+ /**
70
+ * Initialization
71
+ */
72
+ public function init(){
73
+ global $pagenow;
74
+
75
+ if ( defined( 'DOING_AJAX' ) ) {
76
+ add_action( 'wp_ajax_installer_set_channel', array( $this, 'set_channel' ) );
77
+ }
78
+
79
+ if ( $pagenow === 'plugin-install.php' && isset( $_GET['tab'] ) && $_GET['tab'] === 'commercial' ) {
80
+ wp_enqueue_script( 'installer-channels', WP_Installer()->res_url() . '/res/js/channels.js', array( 'jquery' ), WP_Installer()->version() );
81
+ }
82
+
83
+ }
84
+
85
+ /**
86
+ * Ajax handler for channel switching
87
+ */
88
+ public function set_channel(){
89
+ $repository_id = sanitize_text_field( $_POST['repository_id'] );
90
+ $channel = intval( $_POST['channel'] );
91
+
92
+ $response = array();
93
+
94
+ if( $_POST['nonce'] === wp_create_nonce( 'installer_set_channel:' . $repository_id ) ){
95
+
96
+ if( isset( WP_Installer()->settings['repositories'][$repository_id] ) ){
97
+ WP_Installer()->settings['repositories'][$repository_id]['channel'] = $channel;
98
+ WP_Installer()->settings['repositories'][$repository_id]['no-prompt'] = $_POST['noprompt'] === 'true';
99
+ WP_Installer()->save_settings();
100
+ }
101
+
102
+ WP_Installer()->refresh_repositories_data();
103
+
104
+ $response['status'] = 'OK';
105
+ }
106
+
107
+ echo json_encode( $response );
108
+ exit;
109
+ }
110
+
111
+ /**
112
+ * @param string $repository_id
113
+ *
114
+ * @return int
115
+ */
116
+ public function get_channel( $repository_id ){
117
+ $channel = 0;
118
+ if( isset( WP_Installer()->settings['repositories'][$repository_id]['channel'] ) ){
119
+ $channel = WP_Installer()->settings['repositories'][$repository_id]['channel'];
120
+ }
121
+ return $channel;
122
+ }
123
+
124
+ /**
125
+ * @param string $repository_id
126
+ * @param array $downloads
127
+ */
128
+ public function load_channel_selector( $repository_id, $downloads ) {
129
+
130
+ $available_channels = $this->get_available_channels( $repository_id );
131
+
132
+ if ( $available_channels ) {
133
+ $args = array(
134
+ 'can_switch' => $this->can_use_unstable_channels( $downloads ) || $this->get_channel( $repository_id ) > 1,
135
+ 'channels' => $available_channels,
136
+ 'repository_id' => $repository_id,
137
+ 'current_channel' => $this->get_channel( $repository_id ),
138
+ 'no_prompt' => !empty( WP_Installer()->settings['repositories'][ $repository_id ]['no-prompt'] ),
139
+ 'nonce' => wp_create_nonce( 'installer_set_channel:' . $repository_id )
140
+ );
141
+
142
+ extract( $args );
143
+ include WP_Installer()->plugin_path() . '/templates/channel-selector.php';
144
+ }
145
+ }
146
+
147
+ /**
148
+ * The beta and development channels can be used only when already using the most up to date versions
149
+ * @param array $downloads
150
+ *
151
+ * @return bool
152
+ */
153
+ public function can_use_unstable_channels( $downloads ){
154
+
155
+ $can = true;
156
+ foreach( $downloads as $download ){
157
+ $available_version = $download['version'];
158
+ $installed_version = WP_Installer()->plugin_is_installed( $download['name'], $download['slug'] );
159
+ if( $installed_version !== false && version_compare( $available_version, $installed_version, '>' ) ){
160
+ $can = false;
161
+ break;
162
+ }
163
+ }
164
+
165
+ return $can;
166
+ }
167
+
168
+ /**
169
+ * Get available updates channels. Only include channels with actual downloads available.
170
+ *
171
+ * @param string $repository_id
172
+ *
173
+ * @return array
174
+ */
175
+ public function get_available_channels( $repository_id ) {
176
+
177
+ $beta = false;
178
+ $dev = false;
179
+
180
+ $downloads = WP_Installer()->settings['repositories'][ $repository_id ]['data']['downloads'];
181
+ foreach ( $downloads as $type => $download_types ) {
182
+ foreach ( $download_types as $download ) {
183
+ $extra_channels = isset( $download['extra_channels'] ) ? array_keys( $download['extra_channels'] ) : array();
184
+ if ( ! $beta && in_array( self::channel_id( self::CHANNEL_BETA ), $extra_channels ) ) {
185
+ $beta = true;
186
+ }
187
+ if ( ! $dev && in_array( self::channel_id( self::CHANNEL_DEVELOPMENT ), $extra_channels ) ) {
188
+ $dev = true;
189
+ }
190
+ if ( $beta && $dev ) {
191
+ break;
192
+ }
193
+ }
194
+ }
195
+
196
+ $channels = array();
197
+ if ( $beta || $dev ) {
198
+ $channels[ self::CHANNEL_PRODUCTION ] = self::channel_name_by_id( self::CHANNEL_PRODUCTION );
199
+ if ( $beta ) {
200
+ $channels[ self::CHANNEL_BETA ] = self::channel_name_by_id( self::CHANNEL_BETA );
201
+ }
202
+ if ( $dev ) {
203
+ $channels[ self::CHANNEL_DEVELOPMENT ] = self::channel_name_by_id( self::CHANNEL_DEVELOPMENT );
204
+ }
205
+ }
206
+
207
+ return $channels;
208
+ }
209
+
210
+ /**
211
+ * @param string $repository_id
212
+ * @param array $downloads
213
+ *
214
+ * @return array
215
+ */
216
+ public function filter_downloads_by_channel( $repository_id, $downloads ) {
217
+
218
+ $current_channel = $this->get_channel( $repository_id );
219
+
220
+ foreach ( $downloads as $type => $type_downloads ) {
221
+ foreach ( $type_downloads as $slug => $download ) {
222
+
223
+ $override_download = false;
224
+ if ( $current_channel === self::CHANNEL_DEVELOPMENT ) {
225
+ if( ! empty( $download['channels']['development'] ) ){
226
+ $override_download = $download['channels']['development'];
227
+ $override_download['channel'] = self::channel_id( self::CHANNEL_DEVELOPMENT );
228
+ }elseif( ! empty( $download['channels']['beta'] ) ){
229
+ $override_download = $download['channels']['beta'];
230
+ $override_download['channel'] = self::channel_id( self::CHANNEL_BETA );
231
+ }
232
+ }elseif ( $current_channel === self::CHANNEL_BETA && ! empty( $download['channels']['beta'] ) ) {
233
+ $override_download = $download['channels']['beta'];
234
+ $override_download['channel'] = self::channel_id( self::CHANNEL_BETA );
235
+ }
236
+
237
+ if ( $override_download ) {
238
+ foreach ( $override_download as $key => $value ) {
239
+ $downloads[ $type ][ $slug ][ $key ] = $value;
240
+ }
241
+ } else {
242
+ $downloads[ $type ][ $slug ]['channel'] = self::channel_id( self::CHANNEL_PRODUCTION );
243
+ }
244
+ unset ( $downloads[ $type ][ $slug ]['channels'] );
245
+
246
+ $downloads[ $type ][ $slug ]['extra_channels'] = array();
247
+ if( isset( $download['channels'] ) ) {
248
+ foreach( $download['channels'] as $channel_id => $channel ){
249
+ $downloads[ $type ][ $slug ]['extra_channels'][$channel_id] = array(
250
+ 'version' => $channel['version']
251
+ );
252
+ }
253
+ }
254
+
255
+ }
256
+ }
257
+
258
+ return $downloads;
259
+ }
260
+
261
+ /**
262
+ * Get the source channel for the installed version when on the Beta or Development channel
263
+ * @param string $version
264
+ * @param string $repository_id
265
+ * @param string $download_id
266
+ * @param string $download_kind
267
+ *
268
+ * @return string
269
+ */
270
+ public function get_download_source_channel( $version, $repository_id, $download_id, $download_kind ) {
271
+
272
+ $version_channel = '';
273
+ $installer_settings = WP_Installer()->get_settings();
274
+ if ( isset( $installer_settings['repositories'][ $repository_id ] ) ) {
275
+ $repository_data = $installer_settings['repositories'][ $repository_id ]['data'];
276
+ if ( isset( $repository_data['downloads'][ $download_kind ][ $download_id ]['extra_channels'] ) ) {
277
+
278
+ foreach ( $repository_data['downloads'][ $download_kind ][ $download_id ]['extra_channels'] as $channel_id => $channel_data ) {
279
+ if ( $version === $channel_data['version'] ) {
280
+ $version_channel = self::channel_name_by_id( $channel_id );
281
+ break;
282
+ }
283
+
284
+ }
285
+ }
286
+
287
+ }
288
+
289
+ return $version_channel;
290
+ }
291
+ }
vendor/otgs/installer/includes/class-wp-installer.php ADDED
@@ -0,0 +1,2769 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ final class WP_Installer {
4
+ protected static $_instance = null;
5
+
6
+ public $settings = array();
7
+
8
+ private $repositories = array();
9
+
10
+ protected $api_debug = '';
11
+
12
+ private $config = array();
13
+
14
+ protected $_plugins_renew_warnings = array();
15
+
16
+ protected $_gz_on = false;
17
+
18
+ private $admin_messages = array();
19
+
20
+ private $_using_icl = false;
21
+ private $_wpml_version = false;
22
+
23
+ private $package_source = array();
24
+
25
+ const SITE_KEY_VALIDATION_SOURCE_OTHER = 0;
26
+ const SITE_KEY_VALIDATION_SOURCE_DOWNLOAD_SPECIFIC = 1;
27
+ const SITE_KEY_VALIDATION_SOURCE_DOWNLOAD_REPORT = 2;
28
+ const SITE_KEY_VALIDATION_SOURCE_REGISTRATION = 3;
29
+ const SITE_KEY_VALIDATION_SOURCE_REVALIDATION = 4;
30
+ const SITE_KEY_VALIDATION_SOURCE_UPDATES_CHECK = 5;
31
+
32
+ public $dependencies;
33
+
34
+ public static function instance() {
35
+
36
+ if ( is_null( self::$_instance ) ) {
37
+ self::$_instance = new self();
38
+ }
39
+
40
+ return self::$_instance;
41
+ }
42
+
43
+ public function __construct() {
44
+
45
+ if ( ! is_admin() || ! is_user_logged_in() ) {
46
+ return;
47
+ } //Only for admin
48
+
49
+ $this->_gz_on = function_exists( 'gzuncompress' ) && function_exists( 'gzcompress' );
50
+ $this->settings = $this->get_settings();
51
+
52
+ add_action( 'admin_notices', array( $this, 'show_site_key_nags' ) );
53
+
54
+ add_action( 'admin_notices', array( $this, 'show_admin_messages' ) );
55
+
56
+ add_action( 'admin_init', array( $this, 'load_embedded_plugins' ), 0 );
57
+
58
+ add_action( 'admin_menu', array( $this, 'menu_setup' ) );
59
+ add_action( 'network_admin_menu', array( $this, 'menu_setup' ) );
60
+
61
+ if ( defined( 'DOING_AJAX' ) && isset( $_POST['action'] ) && $_POST['action'] == 'installer_download_plugin' ) {
62
+ add_filter( 'site_transient_update_plugins', array( $this, 'plugins_upgrade_check' ) );
63
+ }
64
+ add_filter( 'plugins_api', array( $this, 'custom_plugins_api_call' ), 10, 3 );
65
+ add_filter( 'pre_set_site_transient_update_plugins', array( $this, 'plugins_upgrade_check' ) );
66
+
67
+ // register repositories
68
+ $this->load_repositories_list();
69
+
70
+ // default config
71
+ $this->config['plugins_install_tab'] = false;
72
+
73
+ add_action( 'init', array( $this, 'init' ) );
74
+
75
+ //add_filter('wp_installer_buy_url', array($this, 'append_parameters_to_buy_url'));
76
+
77
+ add_action( 'init', array( $this, 'load_locale' ) );
78
+
79
+ }
80
+
81
+ public function get_repositories() {
82
+
83
+ return $this->repositories;
84
+
85
+ }
86
+
87
+ public function set_config( $key, $value ) {
88
+
89
+ $this->config[ $key ] = $value;
90
+
91
+ }
92
+
93
+ public function init() {
94
+ global $pagenow;
95
+
96
+ if ( empty( $this->settings['last_repositories_update'] ) || time() - $this->settings['last_repositories_update'] > 86400
97
+ || ( isset( $_GET['force-check'] ) && $_GET['force-check'] == 1 )
98
+ ) {
99
+ $this->refresh_repositories_data();
100
+ }
101
+
102
+ $this->dependencies = new Installer_Dependencies;
103
+
104
+ if ( empty( $this->settings['_pre_1_0_clean_up'] ) ) {
105
+ $this->_pre_1_0_clean_up();
106
+ }
107
+
108
+ $this->settings = $this->_old_products_format_backwards_compatibility( $this->settings );
109
+
110
+ if ( ! function_exists( 'get_plugins' ) ) {
111
+ require_once ABSPATH . 'wp-admin/includes/plugin.php';
112
+ }
113
+
114
+ $this->_using_icl = function_exists( 'wpml_site_uses_icl' ) && wpml_site_uses_icl();
115
+ $this->_wpml_version = defined( 'ICL_SITEPRESS_VERSION' ) ? ICL_SITEPRESS_VERSION : '';
116
+
117
+ wp_enqueue_script( 'installer-admin', $this->res_url() . '/res/js/admin.js', array( 'jquery' ), $this->version() );
118
+ wp_enqueue_style( 'installer-admin', $this->res_url() . '/res/css/admin.css', array(), $this->version() );
119
+
120
+ $translation_array = array(
121
+ 'installing' => __( 'Installing %s', 'installer' ),
122
+ 'updating' => __( 'Updating %s', 'installer' ),
123
+ 'activating' => __( 'Activating %s', 'installer' )
124
+ );
125
+
126
+ wp_localize_script( 'installer-admin', 'installer_strings', $translation_array );
127
+
128
+ if ( $pagenow == 'plugins.php' ) {
129
+ add_action( 'admin_notices', array( $this, 'setup_plugins_page_notices' ) );
130
+ add_action( 'admin_notices', array( $this, 'setup_plugins_renew_warnings' ), 10 );
131
+ add_action( 'admin_notices', array( $this, 'queue_plugins_renew_warnings' ), 20 );
132
+
133
+ add_action( 'admin_init', array( $this, 'setup_plugins_action_links' ) );
134
+
135
+ }
136
+
137
+ if ( $this->is_repositories_page() ) {
138
+ add_action( 'admin_init', array( $this, 'validate_repository_subscription' ) );
139
+ }
140
+
141
+ if ( defined( 'DOING_AJAX' ) ) {
142
+ add_action( 'wp_ajax_save_site_key', array( $this, 'save_site_key' ) );
143
+ add_action( 'wp_ajax_remove_site_key', array( $this, 'remove_site_key_ajax' ) );
144
+ add_action( 'wp_ajax_update_site_key', array( $this, 'update_site_key' ) );
145
+
146
+ add_action( 'wp_ajax_installer_download_plugin', array( $this, 'download_plugin_ajax_handler' ) );
147
+ add_action( 'wp_ajax_installer_activate_plugin', array( $this, 'activate_plugin' ) );
148
+
149
+ add_action( 'wp_ajax_installer_dismiss_nag', array( $this, 'dismiss_nag' ) );
150
+ }
151
+
152
+ if ( $pagenow == 'update.php' ) {
153
+ if ( isset( $_GET['action'] ) && $_GET['action'] == 'update-selected' ) {
154
+ add_action( 'admin_head', array( $this, 'plugin_upgrade_custom_errors' ) ); //iframe/bulk
155
+ } else {
156
+ add_action( 'all_admin_notices', array( $this, 'plugin_upgrade_custom_errors' ) ); //regular/singular
157
+ }
158
+ }
159
+
160
+ // WP 4.2
161
+ if ( defined( 'DOING_AJAX' ) ) {
162
+ add_action( 'wp_ajax_update-plugin', array(
163
+ $this,
164
+ 'plugin_upgrade_custom_errors'
165
+ ), 0 ); // high priority, before WP
166
+ }
167
+
168
+ //Include theme support
169
+ include_once $this->plugin_path() . '/includes/class-installer-theme.php';
170
+
171
+ // Extra information about the source of Installer
172
+ $package_source_file = $this->plugin_path() . '/installer-source.json';
173
+ if ( file_exists( $package_source_file ) ) {
174
+ WP_Filesystem();
175
+ global $wp_filesystem;
176
+ $this->package_source = json_decode( $wp_filesystem->get_contents( $package_source_file ) );
177
+ }
178
+ }
179
+
180
+ protected function log( $message ) {
181
+ require_once ABSPATH . 'wp-admin/includes/file.php';
182
+ WP_Filesystem();
183
+ global $wp_filesystem;
184
+ if ( defined( 'WPML_INSTALLER_LOGGING' ) && WPML_INSTALLER_LOGGING ) {
185
+ $wp_filesystem->put_contents( $this->plugin_path() . '/installer.log', current_time( 'mysql' ) . "\t" . $message . "\n" );
186
+ }
187
+ }
188
+
189
+ public function register_admin_message( $text, $type = 'updated' ) {
190
+ $this->admin_messages[] = array( 'text' => $text, 'type' => $type );
191
+ }
192
+
193
+ public function show_admin_messages() {
194
+ if ( ! empty( $this->admin_messages ) ) {
195
+ $types = array( 'error', 'updated', 'notice' );
196
+ foreach ( $this->admin_messages as $message ) {
197
+ $class = in_array( $message['type'], $types ) ? $message['type'] : 'updated';
198
+ ?>
199
+ <div class="<?php echo $class ?>">
200
+ <p>
201
+ <?php echo $message['text'] ?>
202
+ </p>
203
+ </div>
204
+ <?php
205
+ }
206
+ }
207
+ }
208
+
209
+ public function load_locale() {
210
+ if ( function_exists( 'get_user_locale' ) ) {
211
+ $locale = get_user_locale();
212
+ } else {
213
+ $locale = get_locale();
214
+ }
215
+ $locale = apply_filters( 'plugin_locale', $locale, 'installer' );
216
+ $mo_file = $this->plugin_path() . '/locale/installer-' . $locale . '.mo';
217
+ if ( file_exists( $mo_file ) ) {
218
+ load_textdomain( 'installer', $mo_file );
219
+ }
220
+ }
221
+
222
+ public function load_embedded_plugins() {
223
+ if ( file_exists( $this->plugin_path() . '/embedded-plugins' ) ) {
224
+ include_once $this->plugin_path() . '/embedded-plugins/embedded-plugins.class.php';
225
+ $this->installer_embedded_plugins = new Installer_Embedded_Plugins();
226
+ }
227
+ }
228
+
229
+ public function menu_setup() {
230
+ global $pagenow;
231
+
232
+ if ( is_multisite() && ! is_network_admin() ) {
233
+ $this->menu_multisite_redirect();
234
+ add_options_page( __( 'Installer', 'installer' ), __( 'Installer', 'installer' ), 'manage_options', 'installer', array(
235
+ $this,
236
+ 'show_products'
237
+ ) );
238
+ } else {
239
+ if ( $this->config['plugins_install_tab'] && is_admin() && $pagenow == 'plugin-install.php' ) {
240
+ // Default GUI, under Plugins -> Install
241
+ add_filter( 'install_plugins_tabs', array( $this, 'add_install_plugins_tab' ) );
242
+ add_action( 'install_plugins_commercial', array( $this, 'show_products' ) );
243
+ }
244
+ }
245
+
246
+ }
247
+
248
+ public function menu_url() {
249
+ if ( is_multisite() ) {
250
+ if ( is_network_admin() ) {
251
+ $url = network_admin_url( 'plugin-install.php?tab=commercial' );
252
+ } else {
253
+ $url = admin_url( 'options-general.php?page=installer' );
254
+ }
255
+ } else {
256
+ $url = admin_url( 'plugin-install.php?tab=commercial' );
257
+ }
258
+
259
+ return $url;
260
+ }
261
+
262
+ private function menu_multisite_redirect() {
263
+ global $pagenow;
264
+
265
+ if ( $pagenow == 'plugin-install.php' && isset( $_GET['tab'] ) && $_GET['tab'] == 'commercial' ) {
266
+ wp_redirect( $this->menu_url() );
267
+ exit;
268
+ }
269
+
270
+ }
271
+
272
+ private function _pre_1_0_clean_up() {
273
+ global $wpdb;
274
+
275
+ if ( ! defined( 'WPRC_VERSION' ) ) {
276
+ $old_tables = array(
277
+ $wpdb->prefix . 'wprc_cached_requests',
278
+ $wpdb->prefix . 'wprc_extension_types',
279
+ $wpdb->prefix . 'wprc_extensions',
280
+ $wpdb->prefix . 'wprc_repositories',
281
+ $wpdb->prefix . 'wprc_repositories_relationships',
282
+ );
283
+
284
+ foreach ( $old_tables as $table ) {
285
+ $wpdb->query( sprintf( "DROP TABLE IF EXISTS %s", $table ) );
286
+ }
287
+
288
+ }
289
+
290
+ $this->settings['_pre_1_0_clean_up'] = true;
291
+ $this->save_settings();
292
+ }
293
+
294
+ public function setup_plugins_action_links() {
295
+
296
+ $plugins = get_plugins();
297
+
298
+ $repositories_plugins = array();
299
+
300
+ if ( ! empty( $this->settings['repositories'] ) ) {
301
+
302
+ foreach ( $this->settings['repositories'] as $repository_id => $repository ) {
303
+
304
+ foreach ( $repository['data']['packages'] as $package ) {
305
+
306
+ foreach ( $package['products'] as $product ) {
307
+
308
+ foreach ( $product['plugins'] as $plugin_slug ) {
309
+
310
+ $download = $this->settings['repositories'][ $repository_id ]['data']['downloads']['plugins'][ $plugin_slug ];
311
+
312
+ if ( ! isset( $repositories_plugins[ $repository_id ][ $download['slug'] ] ) ) {
313
+ $repositories_plugins[ $repository_id ][ $download['slug'] ] = array(
314
+ 'name' => $download['name'],
315
+ 'registered' => $this->plugin_is_registered( $repository_id, $download['slug'] ) ? 1 : 0
316
+ );
317
+ }
318
+
319
+ }
320
+
321
+ }
322
+
323
+ }
324
+
325
+ foreach ( $plugins as $plugin_id => $plugin ) {
326
+
327
+ $wp_plugin_slug = dirname( $plugin_id );
328
+ if ( empty( $wp_plugin_slug ) ) {
329
+ $wp_plugin_slug = basename( $plugin_id, '.php' );
330
+ }
331
+
332
+ foreach ( $repositories_plugins as $repository_id => $r_plugins ) {
333
+
334
+ foreach ( $r_plugins as $slug => $r_plugin ) {
335
+
336
+ if ( $wp_plugin_slug == $slug || $r_plugin['name'] == $plugin['Name'] || $r_plugin['name'] == $plugin['Title'] ) { //match order: slug, name, title
337
+
338
+ if ( $r_plugin['registered'] ) {
339
+ add_filter( 'plugin_action_links_' . $plugin_id, array(
340
+ $this,
341
+ 'plugins_action_links_registered'
342
+ ) );
343
+ } else {
344
+ add_filter( 'plugin_action_links_' . $plugin_id, array(
345
+ $this,
346
+ 'plugins_action_links_not_registered'
347
+ ) );
348
+ }
349
+
350
+ }
351
+
352
+ }
353
+
354
+ }
355
+
356
+
357
+ }
358
+
359
+ }
360
+ }
361
+
362
+ }
363
+
364
+ public function plugins_action_links_registered( $links ) {
365
+ $links[] = '<a href="' . $this->menu_url() . '">' . __( 'Registered', 'installer' ) . '</a>';
366
+
367
+ return $links;
368
+ }
369
+
370
+ public function plugins_action_links_not_registered( $links ) {
371
+ $links[] = '<a href="' . $this->menu_url() . '">' . __( 'Register', 'installer' ) . '</a>';
372
+
373
+ return $links;
374
+ }
375
+
376
+ public function plugin_is_registered( $repository_id, $slug ) {
377
+
378
+ $registered = false;
379
+
380
+ if ( $this->repository_has_valid_subscription( $repository_id ) ) {
381
+
382
+ $subscription_type = $this->get_subscription_type_for_repository( $repository_id );
383
+ $r_plugins = array();
384
+
385
+ foreach ( $this->settings['repositories'][ $repository_id ]['data']['packages'] as $package ) {
386
+
387
+ foreach ( $package['products'] as $product ) {
388
+
389
+ if ( $product['subscription_type'] == $subscription_type || $this->have_superior_subscription( $subscription_type, $product ) ) {
390
+
391
+ foreach ( $product['plugins'] as $plugin_slug ) {
392
+
393
+ $download = $this->settings['repositories'][ $repository_id ]['data']['downloads']['plugins'][ $plugin_slug ];
394
+
395
+ if ( ! isset( $rep_plugins[ $download['slug'] ] ) ) {
396
+ $r_plugins[ $download['slug'] ] = $download['slug'];
397
+ }
398
+
399
+ }
400
+
401
+ }
402
+
403
+ }
404
+
405
+ }
406
+
407
+ $registered = isset( $r_plugins[ $slug ] );
408
+
409
+ }
410
+
411
+
412
+ return $registered;
413
+
414
+ }
415
+
416
+ public function version() {
417
+ return WP_INSTALLER_VERSION;
418
+ }
419
+
420
+ public function plugin_path() {
421
+ return untrailingslashit( plugin_dir_path( dirname( __FILE__ ) ) );
422
+ }
423
+
424
+ public function plugin_url() {
425
+ if ( isset( $this->config['in_theme_folder'] ) && ! empty( $this->config['in_theme_folder'] ) ) {
426
+ $url = untrailingslashit( get_template_directory_uri() . '/' . $this->config['in_theme_folder'] );
427
+ } else {
428
+ $url = untrailingslashit( plugins_url( '/', dirname( __FILE__ ) ) );
429
+ }
430
+
431
+ return $url;
432
+ }
433
+
434
+ public function is_repositories_page() {
435
+ global $pagenow;
436
+
437
+ return $pagenow == 'plugin-install.php' && isset( $_GET['tab'] ) && $_GET['tab'] == 'commercial';
438
+ }
439
+
440
+ public function res_url() {
441
+ if ( isset( $this->config['in_theme_folder'] ) && ! empty( $this->config['in_theme_folder'] ) ) {
442
+ $url = untrailingslashit( get_template_directory_uri() . '/' . $this->config['in_theme_folder'] );
443
+ } else {
444
+ $url = $this->plugin_url();
445
+ }
446
+
447
+ return $url;
448
+ }
449
+
450
+ public function save_settings() {
451
+
452
+ $_settings = serialize( $this->settings );
453
+ if ( $this->_gz_on ) {
454
+ $_settings = gzcompress( $_settings );
455
+ }
456
+ $_settings = base64_encode( $_settings );
457
+
458
+ update_option( 'wp_installer_settings', $_settings );
459
+
460
+ if ( is_multisite() && is_main_site() && isset( $this->settings['repositories'] ) ) {
461
+ $network_settings = array();
462
+
463
+ foreach ( $this->settings['repositories'] as $rep_id => $repository ) {
464
+ if ( isset( $repository['subscription'] ) ) {
465
+ $network_settings[ $rep_id ] = $repository['subscription'];
466
+ }
467
+ }
468
+
469
+ update_site_option( 'wp_installer_network', $network_settings );
470
+
471
+
472
+ }
473
+
474
+ }
475
+
476
+ public function get_settings( $refresh = false ) {
477
+
478
+ if ( $refresh || empty( $this->settings ) ) {
479
+
480
+ $_settings = get_option( 'wp_installer_settings' );
481
+
482
+
483
+ if ( is_array( $_settings ) || empty( $_settings ) ) { //backward compatibility 1.1
484
+ $this->settings = $_settings;
485
+
486
+ } else {
487
+ $_settings = base64_decode( $_settings );
488
+ if ( $this->_gz_on ) {
489
+ $_settings = gzuncompress( $_settings );
490
+ }
491
+ $this->settings = unserialize( $_settings );
492
+ }
493
+
494
+ // Initialize
495
+ if ( empty( $this->settings ) ) {
496
+ $this->settings = array(
497
+ 'repositories' => array()
498
+ );
499
+ }
500
+
501
+ if ( is_multisite() ) {
502
+ $network_settings = maybe_unserialize( get_site_option( 'wp_installer_network' ) );
503
+ if ( $network_settings ) {
504
+ foreach ( $this->settings['repositories'] as $rep_id => $repository ) {
505
+ if ( isset( $network_settings[ $rep_id ] ) ) {
506
+ $this->settings['repositories'][ $rep_id ]['subscription'] = $network_settings[ $rep_id ];
507
+ }
508
+ }
509
+ }
510
+ }
511
+
512
+ $this->load_hardcoded_site_keys();
513
+
514
+ $this->_pre_1_8_backwards_compatibility( $this->settings );
515
+
516
+ $this->settings = $this->_old_products_format_backwards_compatibility( $this->settings );
517
+
518
+ }
519
+
520
+ return $this->settings;
521
+ }
522
+
523
+ private function load_hardcoded_site_keys() {
524
+
525
+ if ( ! empty( $this->settings['repositories'] ) ) {
526
+ foreach ( $this->settings['repositories'] as $repository_id => $repository ) {
527
+
528
+ if ( $site_key = self::get_repository_hardcoded_site_key( $repository_id ) ) {
529
+
530
+ $site_key_missing = empty( $this->settings['repositories'][ $repository_id ]['subscription']['data'] );
531
+ $site_key_changed = ! $site_key_missing &&
532
+ $this->settings['repositories'][ $repository_id ]['subscription']['key'] != $site_key;
533
+
534
+ if ( $site_key_missing || $site_key_changed ) {
535
+
536
+ if ( ! function_exists( 'get_plugins' ) ) {
537
+ require_once ABSPATH . 'wp-admin/includes/plugin.php';
538
+ }
539
+ $this->load_repositories_list();
540
+ $response = $this->save_site_key(
541
+ array(
542
+ 'repository_id' => $repository_id,
543
+ 'site_key' => $site_key,
544
+ 'return' => true,
545
+ 'nonce' => wp_create_nonce( 'save_site_key_' . $repository_id )
546
+ )
547
+ );
548
+
549
+ if ( ! empty( $response['error'] ) ) {
550
+ $this->remove_site_key( $repository_id );
551
+
552
+ $this->admin_messages[] = array(
553
+ 'type' => 'error',
554
+ 'text' => sprintf( __( 'You are using an invalid site key defined as the constant %s (most likely in wp-config.php).
555
+ Please remove it or use the correct value in order to be able to register correctly.', 'installer' ), 'OTGS_INSTALLER_SITE_KEY_' . strtoupper( $repository_id ) )
556
+ );
557
+
558
+ }
559
+
560
+ }
561
+
562
+ }
563
+
564
+ }
565
+ }
566
+
567
+ }
568
+
569
+ public static function get_repository_hardcoded_site_key( $repository_id ) {
570
+
571
+ $site_key = false;
572
+
573
+ $site_key_constant = 'OTGS_INSTALLER_SITE_KEY_' . strtoupper( $repository_id );
574
+ if ( defined( $site_key_constant ) ) {
575
+ $site_key = constant( $site_key_constant );
576
+ }
577
+
578
+ return $site_key;
579
+ }
580
+
581
+ //backward compatibility, add channel
582
+ private function _pre_1_8_backwards_compatibility( &$settings ) {
583
+ if ( empty( $settings['_pre_1_8_clean_up'] ) ) {
584
+ foreach ( $settings['repositories'] as $repository_id => $repository ) {
585
+ foreach ( $repository['data']['downloads']['plugins'] as $slug => $download ) {
586
+ if( !isset( $download['channel'] ) ){
587
+ $settings['repositories'][ $repository_id ]['data']['downloads']['plugins'][ $slug ]['channel'] = '';
588
+ }
589
+ }
590
+ }
591
+ $this->save_settings();
592
+ }
593
+ }
594
+
595
+ //backward compatibility - support old products list format (downloads under products instead of global downloads list)
596
+ private function _old_products_format_backwards_compatibility( $settings ) {
597
+
598
+ if ( version_compare( $this->version(), '1.8', '<' ) && ! empty( $settings['repositories'] ) && empty( $this->_old_products_format_backwards_compatibility ) ) {
599
+
600
+ foreach ( $settings['repositories'] as $repository_id => $repository ) {
601
+ $populate_downloads = false;
602
+ if ( isset( $repository['data'] ) ) {
603
+
604
+ foreach ( $repository['data']['packages'] as $package_id => $package ) {
605
+ foreach ( $package['products'] as $product_id => $product ) {
606
+ if ( ! isset( $product['plugins'] ) ) {
607
+ $populate_downloads = true;
608
+ foreach ( $product['downloads'] as $download_id => $download ) {
609
+ $settings['repositories'][ $repository_id ]['data']['packages'][ $package_id ]['products'][ $product_id ]['plugins'][] = $download['slug'];
610
+ }
611
+ }
612
+ }
613
+ }
614
+
615
+ if ( $populate_downloads ) {
616
+ // Add downloads branch
617
+ foreach ( $repository['data']['packages'] as $package_id => $package ) {
618
+ foreach ( $package['products'] as $product_id => $product ) {
619
+ foreach ( $product['downloads'] as $download_id => $download ) {
620
+ if ( ! isset( $settings['repositories'][ $repository_id ]['data']['downloads']['plugins'][ $download['slug'] ] ) ) {
621
+ $settings['repositories'][ $repository_id ]['data']['downloads']['plugins'][ $download['slug'] ] = $download;
622
+ }
623
+ $settings['repositories'][ $repository_id ]['data']['packages'][ $package_id ]['products'][ $product_id ]['plugins'][] = $download['slug'];
624
+ }
625
+ unset( $settings['repositories'][ $repository_id ]['data']['packages'][ $package_id ]['products'][ $product_id ]['downloads'] );
626
+ }
627
+ }
628
+ }
629
+ }
630
+ }
631
+
632
+ $this->_old_products_format_backwards_compatibility = true;
633
+ }
634
+
635
+ return $settings;
636
+ }
637
+
638
+ public function get_installer_site_url( $repository_id = false ) {
639
+ global $current_site;
640
+
641
+ $site_url = get_site_url();
642
+
643
+ if ( $repository_id && is_multisite() && isset( $this->settings['repositories'] ) ) {
644
+ $network_settings = maybe_unserialize( get_site_option( 'wp_installer_network' ) );
645
+
646
+ if ( isset( $network_settings[ $repository_id ] ) ) {
647
+ $site_url = get_site_url( $current_site->blog_id );
648
+ }
649
+
650
+ }
651
+
652
+ return $site_url;
653
+ }
654
+
655
+ public function show_site_key_nags() {
656
+ $screen = get_current_screen();
657
+
658
+ if ( $screen->base == 'settings_page_installer' || ( $screen->base == 'plugin-install' && isset( $_GET['tab'] ) && $_GET['tab'] == 'commercial' ) ) {
659
+ return;
660
+ }
661
+
662
+ if ( ! empty( $this->config['site_key_nags'] ) ) {
663
+
664
+ foreach ( $this->config['site_key_nags'] as $nag ) {
665
+
666
+ if ( ! $this->repository_has_subscription( $nag['repository_id'] ) ) {
667
+ $show = true;
668
+ if ( ! empty( $nag['condition_cb'] ) ) {
669
+ $show = call_user_func( $nag['condition_cb'] );
670
+ }
671
+
672
+ if ( empty( $this->settings['dismissed_nags'][ $nag['repository_id'] ] ) && $show ) {
673
+ echo '<div class="updated error otgs-is-dismissible"><p>';
674
+ printf( __( "To get automatic updates, you need to register %s for this site. %sRegister %s%s", 'sitepress' ),
675
+ $nag['product_name'], '<a class="button-primary" href="' . $this->menu_url() . '">', $nag['product_name'], '</a>' );
676
+
677
+ echo '</p>';
678
+ echo '<span class="installer-dismiss-nag notice-dismiss" data-repository="' . $nag['repository_id'] . '"><span class="screen-reader-text">' . __( 'Dismiss', 'sitepress' ) . '</span></span>';
679
+ echo '</div>';
680
+ }
681
+ }
682
+
683
+ }
684
+
685
+ }
686
+
687
+ }
688
+
689
+ public function dismiss_nag() {
690
+ $this->settings['dismissed_nags'][ $_POST['repository'] ] = 1;
691
+
692
+ $this->save_settings();
693
+
694
+ echo json_encode( array() );
695
+ exit;
696
+ }
697
+
698
+ public function add_install_plugins_tab( $tabs ) {
699
+
700
+ $tabs['commercial'] = __( 'Commercial', 'installer' );
701
+
702
+ return $tabs;
703
+ }
704
+
705
+ public function load_repositories_list() {
706
+ global $wp_installer_instances;
707
+
708
+ foreach ( $wp_installer_instances as $instance ) {
709
+
710
+ if ( file_exists( dirname( $instance['bootfile'] ) . '/repositories.xml' ) ) {
711
+ $config_file = dirname( $instance['bootfile'] ) . '/repositories.xml';
712
+
713
+ if ( file_exists( dirname( $instance['bootfile'] ) . '/repositories.sandbox.xml' ) ) {
714
+ $config_file = dirname( $instance['bootfile'] ) . '/repositories.sandbox.xml';
715
+ add_filter( 'https_ssl_verify', '__return_false' );
716
+ }
717
+
718
+ $repos = simplexml_load_file( $config_file );
719
+
720
+ if ( $repos ) {
721
+ foreach ( $repos as $repo ) {
722
+ $id = strval( $repo->id );
723
+
724
+ $data['api-url'] = strval( $repo->apiurl );
725
+ $data['products'] = strval( $repo->products );
726
+
727
+ // excludes rule;
728
+ if ( isset( $this->config['repositories_exclude'] ) && in_array( $id, $this->config['repositories_exclude'] ) ) {
729
+ continue;
730
+ }
731
+
732
+ // includes rule;
733
+ if ( isset( $this->config['repositories_include'] ) && ! in_array( $id, $this->config['repositories_include'] ) ) {
734
+ continue;
735
+ }
736
+
737
+ $this->repositories[ $id ] = $data;
738
+
739
+ }
740
+ }
741
+
742
+ }
743
+ }
744
+
745
+ }
746
+
747
+ public function filter_repositories_list() {
748
+
749
+ if ( ! empty( $this->settings['repositories'] ) ) {
750
+ foreach ( $this->settings['repositories'] as $id => $repo_data ) {
751
+
752
+ // excludes rule;
753
+ if ( isset( $this->config['repositories_exclude'] ) && in_array( $id, $this->config['repositories_exclude'] ) ) {
754
+ unset( $this->settings['repositories'][ $id ] );
755
+ }
756
+
757
+ // includes rule;
758
+ if ( isset( $this->config['repositories_include'] ) && ! in_array( $id, $this->config['repositories_include'] ) ) {
759
+ unset( $this->settings['repositories'][ $id ] );
760
+ }
761
+
762
+
763
+ }
764
+ }
765
+
766
+
767
+ }
768
+
769
+ public function refresh_repositories_data() {
770
+ static $checked = false;
771
+
772
+ if ( defined( 'OTGS_DISABLE_AUTO_UPDATES' ) && OTGS_DISABLE_AUTO_UPDATES && empty( $_GET['force-check'] ) || $checked ) {
773
+
774
+ if ( empty( $this->settings['repositories'] ) && $this->is_repositories_page() ) {
775
+
776
+ foreach ( $this->repositories as $id => $data ) {
777
+ $repository_names[] = $id;
778
+
779
+ }
780
+
781
+ $error = sprintf( __( "Installer cannot display the products information because the automatic updating for %s was explicitly disabled with the configuration below (usually in wp-config.php):", 'installer' ), strtoupper( join( ', ', $repository_names ) ) );
782
+ $error .= '<br /><br /><code>define("OTGS_DISABLE_AUTO_UPDATES", true);</code><br /><br />';
783
+ $error .= sprintf( __( "In order to see the products information, please run the %smanual updates check%s to initialize the products list or (temporarily) remove the above code.", 'installer' ), '<a href="' . admin_url( 'update-core.php' ) . '">', '</a>' );
784
+
785
+ $this->register_admin_message( $error, 'error' );
786
+
787
+
788
+ }
789
+
790
+ return;
791
+ }
792
+
793
+ $checked = true;
794
+
795
+ foreach ( $this->repositories as $id => $data ) {
796
+
797
+ $response = wp_remote_get( $data['products'] );
798
+
799
+ if ( is_wp_error( $response ) ) {
800
+ // http fallback
801
+ $data['products'] = preg_replace( "@^https://@", 'http://', $data['products'] );
802
+ $response = wp_remote_get( $data['products'] );
803
+ }
804
+
805
+ if ( is_wp_error( $response ) ) {
806
+
807
+ $error = sprintf( __( "Installer cannot contact our updates server to get information about the available products and check for new versions. If you are seeing this message for the first time, you can ignore it, as it may be a temporary communication problem. If the problem persists and your WordPress admin is slowing down, you can disable automated version checks. Add the following line to your wp-config.php file:", 'installer' ), strtoupper( $id ) );
808
+ $error .= '<br /><br /><code>define("OTGS_DISABLE_AUTO_UPDATES", true);</code>';
809
+
810
+ $this->register_admin_message( $error, 'error' );
811
+
812
+ continue;
813
+ }
814
+
815
+ if ( $response && isset( $response['response']['code'] ) && $response['response']['code'] == 200 ) {
816
+ $body = wp_remote_retrieve_body( $response );
817
+ if ( $body ) {
818
+ $products = json_decode( $body, true );
819
+
820
+ if ( is_array( $products ) ) {
821
+ $products['downloads'] = WP_Installer_Channels()->filter_downloads_by_channel( $id, $products['downloads'] );
822
+ $this->set_release_notes( $products['downloads'] );
823
+
824
+ $this->settings['repositories'][ $id ]['data'] = $products;
825
+ $this->_pre_1_8_backwards_compatibility( $this->settings );
826
+ }
827
+ }
828
+
829
+ }
830
+
831
+ $this->log( sprintf( "Checked for %s updates: %s", $id, $data['products'] ) );
832
+
833
+
834
+ }
835
+
836
+ // cleanup
837
+ if ( empty( $this->settings['repositories'] ) ) {
838
+ $this->settings['repositories'] = array();
839
+ }
840
+ foreach ( $this->settings['repositories'] as $id => $data ) {
841
+ if ( ! in_array( $id, array_keys( $this->repositories ) ) ) {
842
+ unset( $this->settings['repositories'][ $id ] );
843
+ }
844
+ }
845
+
846
+ $this->settings['last_repositories_update'] = time();
847
+
848
+ $this->save_settings();
849
+
850
+ }
851
+
852
+ /**
853
+ * Gets the release notes for the available version from the changelog
854
+ *
855
+ * @param array $all_downloads
856
+ */
857
+ private function set_release_notes( &$all_downloads ) {
858
+ foreach ( $all_downloads as $kind => $downloads ) {
859
+ foreach ( $downloads as $slug => $download ) {
860
+ $start = strpos( $download['changelog'], '<h4>' . $download['version'] . '</h4>' );
861
+ if ( $start !== false ) {
862
+ $start += strlen( $download['version'] ) + 9;
863
+ $end = strpos( $download['changelog'], '<h4>', 4 );
864
+ if ( $end ) {
865
+ $release_notes = substr( $download['changelog'], $start, $end - $start );
866
+ } else {
867
+ $release_notes = substr( $download['changelog'], $start );
868
+ }
869
+ }
870
+ $all_downloads[ $kind ][ $slug ]['release-notes'] = ! empty( $release_notes ) ? $release_notes : '';
871
+ }
872
+ }
873
+ }
874
+
875
+ public function show_products( $args = array() ) {
876
+
877
+ $screen = get_current_screen();
878
+
879
+ if ( $screen->base == 'settings_page_installer' ) { // settings page
880
+ echo '<div class="wrap">';
881
+ echo '<h2>' . __( 'Installer', 'installer' ) . '</h2>';
882
+ echo '<br />';
883
+ }
884
+
885
+ if ( ! is_array( $args ) ) {
886
+ $args = array();
887
+ }
888
+ if ( empty( $args['template'] ) ) {
889
+ $args['template'] = 'default';
890
+ }
891
+
892
+ $this->filter_repositories_list();
893
+
894
+ if ( ! empty( $this->settings['repositories'] ) ) {
895
+
896
+ $this->localize_strings();
897
+ $this->set_filtered_prices( $args );
898
+ $this->set_hierarchy_and_order();
899
+
900
+ foreach ( $this->settings['repositories'] as $repository_id => $repository ) {
901
+
902
+ if ( $args['template'] == 'compact' ) {
903
+
904
+ if ( isset( $args['repository'] ) && $args['repository'] == $repository_id ) {
905
+ include $this->plugin_path() . '/templates/products-compact.php';
906
+ }
907
+
908
+ } else {
909
+
910
+ include $this->plugin_path() . '/templates/repository-listing.php';
911
+
912
+ }
913
+
914
+ unset( $site_key, $subscription_type, $expired, $upgrade_options, $products_avaliable );
915
+
916
+ }
917
+
918
+ } else {
919
+
920
+ echo '<center>' . __( 'No repositories defined.', 'installer' ) . '</center>';
921
+
922
+ }
923
+
924
+ if ( $screen->base == 'settings_page_installer' ) { // settings page
925
+ echo '</div>';
926
+ }
927
+
928
+
929
+ }
930
+
931
+ public function get_product_price( $repository_id, $package_id, $product_id, $incl_discount = false ) {
932
+
933
+ $price = false;
934
+
935
+ foreach ( $this->settings['repositories'][ $repository_id ]['data']['packages'] as $package ) {
936
+
937
+ if ( $package['id'] == $package_id ) {
938
+ if ( isset( $package['products'][ $product_id ] ) ) {
939
+ if ( $incl_discount && isset( $package['products'][ $product_id ]['price_disc'] ) ) {
940
+ $price = $package['products'][ $product_id ]['price_disc'];
941
+ } elseif ( isset( $package['products'][ $product_id ]['price'] ) ) {
942
+ $price = $package['products'][ $product_id ]['price'];
943
+ }
944
+ }
945
+ break;
946
+ }
947
+ }
948
+
949
+ return $price;
950
+ }
951
+
952
+ private function _render_product_packages( $packages, $subscription_type, $expired, $upgrade_options, $repository_id ) {
953
+
954
+ $data = array();
955
+
956
+ foreach ( $packages as $package_id => $package ) {
957
+
958
+ $row = array( 'products' => array(), 'downloads' => array() );
959
+ foreach ( $package['products'] as $product ) {
960
+
961
+ // filter out free subscriptions from being displayed as buying options
962
+ if ( empty( $product['price'] ) && ( empty( $subscription_type ) || $expired ) ) {
963
+ continue;
964
+ }
965
+
966
+ //consider equivalent subscriptions
967
+ if ( empty( $product['subscription_type_equivalent'] ) ) {
968
+ $product['subscription_type_equivalent'] = '';
969
+ }
970
+
971
+ // buy base
972
+ if ( empty( $subscription_type ) || $expired ) {
973
+
974
+ $p['url'] = $this->append_parameters_to_buy_url( $product['url'], $repository_id );
975
+ if ( ! empty( $product['price_disc'] ) ) {
976
+ $p['label'] = $product['call2action'] . ' - ' . sprintf( '$%s %s$%d%s (USD)', $product['price_disc'], '&nbsp;&nbsp;<del>', $product['price'], '</del>' );
977
+ } else {
978
+ $p['label'] = $product['call2action'] . ' - ' . sprintf( '$%d (USD)', $product['price'] );
979
+ }
980
+ $row['products'][] = $p;
981
+
982
+ // renew
983
+ } elseif ( isset( $subscription_type ) && ( $product['subscription_type'] == $subscription_type || $product['subscription_type_equivalent'] == $subscription_type ) ) {
984
+
985
+ if ( $product['renewals'] ) {
986
+ foreach ( $product['renewals'] as $renewal ) {
987
+ $p['url'] = $this->append_parameters_to_buy_url( $renewal['url'], $repository_id );
988
+ $p['label'] = $renewal['call2action'] . ' - ' . sprintf( '$%d (USD)', $renewal['price'] );
989
+ }
990
+
991
+ $row['products'][] = $p;
992
+ }
993
+
994
+ }
995
+
996
+ // upgrades
997
+ if ( ! empty( $upgrade_options[ $product['subscription_type'] ] ) ) {
998
+
999
+ foreach ( $upgrade_options[ $product['subscription_type'] ] as $stype => $upgrade ) {
1000
+ if ( $stype != $subscription_type ) {
1001
+ continue;
1002
+ }
1003
+
1004
+ $p['url'] = $this->append_parameters_to_buy_url( $upgrade['url'], $repository_id );
1005
+ if ( ! empty( $upgrade['price_disc'] ) ) {
1006
+ $p['label'] = $upgrade['call2action'] . ' - ' . sprintf( '$%s %s$%d%s (USD)', $upgrade['price_disc'], '&nbsp;&nbsp;<del>', $upgrade['price'], '</del>' );
1007
+ } else {
1008
+ $p['label'] = $upgrade['call2action'] . ' - ' . sprintf( '$%d (USD)', $upgrade['price'] );
1009
+ }
1010
+ $row['products'][] = $p;
1011
+
1012
+ }
1013
+
1014
+ }
1015
+
1016
+ // downloads
1017
+ if ( isset( $subscription_type ) && ! $expired && ( $product['subscription_type'] == $subscription_type || $product['subscription_type_equivalent'] == $subscription_type ) ) {
1018
+
1019
+ foreach ( $product['plugins'] as $plugin_slug ) {
1020
+ $row['downloads'][ $plugin_slug ] = $this->settings['repositories'][ $repository_id ]['data']['downloads']['plugins'][ $plugin_slug ];
1021
+ }
1022
+
1023
+ }
1024
+
1025
+ //subpackages
1026
+ if ( ! empty( $package['sub-packages'] ) ) {
1027
+ $row['sub-packages'] = $package['sub-packages'];
1028
+ }
1029
+
1030
+ }
1031
+
1032
+ $row['id'] = $package['id'];
1033
+ $row['image_url'] = $package['image_url'];
1034
+ $row['name'] = $package['name'];
1035
+ $row['description'] = $package['description'];
1036
+
1037
+ if ( ! empty( $row['products'] ) || ! empty( $row['downloads'] ) || ! empty( $row['sub-packages'] ) ) {
1038
+ $data[] = $row;
1039
+ }
1040
+
1041
+
1042
+ }
1043
+
1044
+ return $data;
1045
+
1046
+ }
1047
+
1048
+ public function get_extra_url_parameters() {
1049
+
1050
+ $parameters = array();
1051
+
1052
+ if ( ! empty( $this->package_source ) ) {
1053
+ foreach ( $this->package_source as $key => $val ) {
1054
+ $parameters[ $key ] = $val;
1055
+ }
1056
+ }
1057
+
1058
+ $parameters['installer_version'] = WP_INSTALLER_VERSION;
1059
+ $parameters['theme'] = wp_get_theme()->get( 'Name' );
1060
+ $parameters['site_name'] = get_bloginfo( 'name' );
1061
+
1062
+ return $parameters;
1063
+ }
1064
+
1065
+ public function append_parameters_to_buy_url( $url, $repository_id, $args = array() ) {
1066
+
1067
+ $url = add_query_arg( array( 'icl_site_url' => $this->get_installer_site_url( $repository_id ) ), $url );
1068
+
1069
+ $affiliate_id = false;
1070
+ $affiliate_key = false;
1071
+
1072
+ // Add extra parameters for custom Installer packages
1073
+ if ( ! empty( $this->package_source ) ) {
1074
+ $extra = $this->get_extra_url_parameters();
1075
+
1076
+ if ( ! empty( $extra['repository'] ) && $extra['repository'] == $repository_id ) {
1077
+
1078
+ if ( ! empty( $extra['affiliate_key'] ) && ! empty( $extra['user_id'] ) ) {
1079
+ $this->config[ 'affiliate_id:' . $repository_id ] = $extra['user_id'];
1080
+ $this->config[ 'affiliate_key:' . $repository_id ] = $extra['affiliate_key'];
1081
+ unset( $extra['affiliate_key'], $extra['user_id'], $extra['repository'] ); // no need to include these ones
1082
+ }
1083
+
1084
+ $url = add_query_arg( $extra, $url );
1085
+ }
1086
+
1087
+ }
1088
+
1089
+ if ( isset( $this->config[ 'affiliate_id:' . $repository_id ] ) && isset( $this->config[ 'affiliate_key:' . $repository_id ] ) ) {
1090
+
1091
+ $affiliate_id = $this->config[ 'affiliate_id:' . $repository_id ];
1092
+ $affiliate_key = $this->config[ 'affiliate_key:' . $repository_id ];
1093
+
1094
+ } elseif ( isset( $args[ 'affiliate_id:' . $repository_id ] ) && isset( $args[ 'affiliate_key:' . $repository_id ] ) ) {
1095
+
1096
+ $affiliate_id = $args[ 'affiliate_id:' . $repository_id ];
1097
+ $affiliate_key = $args[ 'affiliate_key:' . $repository_id ];
1098
+
1099
+ } elseif ( defined( 'ICL_AFFILIATE_ID' ) && defined( 'ICL_AFFILIATE_KEY' ) ) { //support for 1 repo
1100
+
1101
+ $affiliate_id = ICL_AFFILIATE_ID;
1102
+ $affiliate_key = ICL_AFFILIATE_KEY;
1103
+
1104
+ } elseif ( isset( $this->config['affiliate_id'] ) && isset( $this->config['affiliate_key'] ) ) {
1105
+ // BACKWARDS COMPATIBILITY
1106
+ $affiliate_id = $this->config['affiliate_id'];
1107
+ $affiliate_key = $this->config['affiliate_key'];
1108
+ }
1109
+
1110
+ if ( $affiliate_id && $affiliate_key ) {
1111
+ $url = add_query_arg( array( 'aid' => $affiliate_id, 'affiliate_key' => $affiliate_key ), $url );
1112
+ }
1113
+
1114
+ if ( $repository_id == 'wpml' ) {
1115
+ $url = add_query_arg( array(
1116
+ 'using_icl' => $this->_using_icl,
1117
+ 'wpml_version' => $this->_wpml_version
1118
+ ), $url );
1119
+ }
1120
+
1121
+ $url = apply_filters( 'wp_installer_buy_url', $url );
1122
+
1123
+ $url = esc_url( $url );
1124
+
1125
+ return $url;
1126
+
1127
+ }
1128
+
1129
+ public function save_site_key( $args = array() ) {
1130
+
1131
+ $error = '';
1132
+
1133
+ if ( isset( $args['repository_id'] ) ) {
1134
+ $repository_id = $args['repository_id'];
1135
+ } elseif ( isset( $_POST['repository_id'] ) ) {
1136
+ $repository_id = sanitize_text_field( $_POST['repository_id'] );
1137
+ } else {
1138
+ $repository_id = false;
1139
+ }
1140
+
1141
+ if ( isset( $args['nonce'] ) ) {
1142
+ $nonce = $args['nonce'];
1143
+ } elseif ( isset( $_POST['nonce'] ) ) {
1144
+ $nonce = sanitize_text_field( $_POST['nonce'] );
1145
+ } else {
1146
+ $nonce = '';
1147
+ }
1148
+
1149
+ if ( isset( $args['site_key'] ) ) {
1150
+ $site_key = $args['site_key'];
1151
+ } else {
1152
+ $site_key = sanitize_text_field( $_POST[ 'site_key_' . $repository_id ] );
1153
+ }
1154
+ $site_key = preg_replace( "/[^A-Za-z0-9]/", '', $site_key );
1155
+
1156
+ if ( $repository_id && $nonce && wp_create_nonce( 'save_site_key_' . $repository_id ) == $nonce ) {
1157
+
1158
+ try {
1159
+ $subscription_data = $this->fetch_subscription_data( $repository_id, $site_key, self::SITE_KEY_VALIDATION_SOURCE_REGISTRATION );
1160
+
1161
+ if ( $subscription_data ) {
1162
+ $this->settings['repositories'][ $repository_id ]['subscription'] = array(
1163
+ 'key' => $site_key,
1164
+ 'data' => $subscription_data,
1165
+ 'registered_by' => get_current_user_id()
1166
+ );
1167
+ $this->save_settings();
1168
+ } else {
1169
+ $error = __( 'Invalid site key for the current site.', 'installer' )
1170
+ . '<br /><div class="installer-footnote">' . __( 'Please note that the site key is case sensitive.', 'installer' ) . '</div>';
1171
+ }
1172
+
1173
+ } catch ( Exception $e ) {
1174
+ $error = $e->getMessage();
1175
+ if ( preg_match( '#Could not resolve host: (.*)#', $error, $matches ) || preg_match( '#Couldn\'t resolve host \'(.*)\'#', $error, $matches ) ) {
1176
+ $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' ),
1177
+ '<strong><i>' . $this->get_generic_product_name( $repository_id ) . '</i></strong>',
1178
+ '<strong><i>' . $matches[1] . '</i></strong>'
1179
+ );
1180
+ }
1181
+ }
1182
+
1183
+ }
1184
+
1185
+ $return = array( 'error' => $error );
1186
+
1187
+ if ( $this->api_debug ) {
1188
+ $return['debug'] = $this->api_debug;
1189
+ }
1190
+
1191
+ if ( ! empty( $args['return'] ) ) {
1192
+ return $return;
1193
+ } else {
1194
+ echo json_encode( $return );
1195
+ exit;
1196
+ }
1197
+
1198
+ }
1199
+
1200
+ /**
1201
+ * Alias for WP_Installer::get_repository_site_key
1202
+ * @see WP_Installer::get_repository_site_key()
1203
+ *
1204
+ * @param string $repository_id
1205
+ *
1206
+ * @return string (site key) or bool
1207
+ */
1208
+ public function get_site_key( $repository_id ) {
1209
+ return WP_Installer::get_repository_site_key( $repository_id );
1210
+ }
1211
+
1212
+ public function remove_site_key( $repository_id ) {
1213
+ if ( isset( $this->settings['repositories'][ $repository_id ] ) ) {
1214
+ unset( $this->settings['repositories'][ $repository_id ]['subscription'] );
1215
+ $this->save_settings();
1216
+ $this->refresh_repositories_data();
1217
+ }
1218
+ }
1219
+
1220
+ public function remove_site_key_ajax() {
1221
+ if ( $_POST['nonce'] == wp_create_nonce( 'remove_site_key_' . $_POST['repository_id'] ) ) {
1222
+ $this->remove_site_key( $_POST['repository_id'] );
1223
+ }
1224
+ exit;
1225
+ }
1226
+
1227
+ public function validate_repository_subscription() {
1228
+ $repository_id = isset( $_GET['validate_repository'] ) ? sanitize_text_field( $_GET['validate_repository'] ) : false;
1229
+ if ( $repository_id ) {
1230
+
1231
+ $site_key = $this->get_site_key( $repository_id );
1232
+ if ( $site_key ) {
1233
+ $subscription_data = $this->fetch_subscription_data( $repository_id, $site_key, self::SITE_KEY_VALIDATION_SOURCE_REVALIDATION );
1234
+ if ( empty( $subscription_data ) ) {
1235
+ unset( $this->settings['repositories'][ $repository_id ]['subscription'] );
1236
+ delete_site_transient( 'update_plugins' );
1237
+ $this->save_settings();
1238
+ }
1239
+ }
1240
+
1241
+ wp_redirect( $this->menu_url() . '#repository-' . $repository_id );
1242
+ exit;
1243
+
1244
+ }
1245
+
1246
+ }
1247
+
1248
+ public function update_site_key() {
1249
+
1250
+ $error = '';
1251
+
1252
+ $repository_id = sanitize_text_field( $_POST['repository_id'] );
1253
+ if ( $_POST['nonce'] == wp_create_nonce( 'update_site_key_' . $repository_id ) ) {
1254
+
1255
+ $site_key = $this->get_site_key( $_POST['repository_id'] );
1256
+
1257
+ if ( $site_key ) {
1258
+ try {
1259
+ $subscription_data = $this->fetch_subscription_data( $repository_id, $site_key, self::SITE_KEY_VALIDATION_SOURCE_UPDATES_CHECK );
1260
+
1261
+ if ( $subscription_data ) {
1262
+ $this->settings['repositories'][ $repository_id ]['subscription'] = array(
1263
+ 'key' => $site_key,
1264
+ 'data' => $subscription_data,
1265
+ 'registered_by' => get_current_user_id()
1266
+ );
1267
+
1268
+ //also refresh products information
1269
+ $this->refresh_repositories_data();
1270
+
1271
+ $this->save_settings();
1272
+
1273
+ } else {
1274
+ unset( $this->settings['repositories'][ $repository_id ]['subscription'] );
1275
+ $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' );
1276
+ }
1277
+
1278
+
1279
+ } catch ( Exception $e ) {
1280
+ $error = $e->getMessage();
1281
+ if ( preg_match( '#Could not resolve host: (.*)#', $error, $matches ) || preg_match( '#Couldn\'t resolve host \'(.*)\'#', $error, $matches ) ) {
1282
+ $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' ),
1283
+ '<strong><i>' . $this->get_generic_product_name( $repository_id ) . '</i></strong>',
1284
+ '<strong><i>' . $matches[1] . '</i></strong>'
1285
+ );
1286
+ }
1287
+ }
1288
+
1289
+ }
1290
+
1291
+ }
1292
+
1293
+ echo json_encode( array( 'error' => $error ) );
1294
+
1295
+ exit;
1296
+ }
1297
+
1298
+ public function api_debug_log( $text ) {
1299
+
1300
+ if ( defined( 'WPML_DEBUG_INSTALLER' ) && WPML_DEBUG_INSTALLER ) {
1301
+
1302
+ if ( ! is_scalar( $text ) ) {
1303
+ $text = print_r( $text, 1 );
1304
+ }
1305
+
1306
+ $this->api_debug .= $text . "\n";
1307
+
1308
+ }
1309
+
1310
+ }
1311
+
1312
+ public function fetch_subscription_data( $repository_id, $site_key, $source = self::SITE_KEY_VALIDATION_SOURCE_OTHER ) {
1313
+
1314
+ $subscription_data = false;
1315
+
1316
+ $args['body'] = array(
1317
+ 'action' => 'site_key_validation',
1318
+ 'site_key' => $site_key,
1319
+ 'site_url' => $this->get_installer_site_url( $repository_id ),
1320
+ 'source' => $source
1321
+ );
1322
+
1323
+ if ( $repository_id == 'wpml' ) {
1324
+ $args['body']['using_icl'] = $this->_using_icl;
1325
+ $args['body']['wpml_version'] = $this->_wpml_version;
1326
+ }
1327
+
1328
+ $args['body']['installer_version'] = WP_INSTALLER_VERSION;
1329
+ $args['body']['theme'] = wp_get_theme()->get( 'Name' );
1330
+ $args['body']['site_name'] = get_bloginfo( 'name' );
1331
+
1332
+ $args['body']['versions'] = $this->get_local_product_versions( $repository_id );
1333
+
1334
+ $args['timeout'] = 45;
1335
+
1336
+ // Add extra parameters for custom Installer packages
1337
+ if ( ! empty( $this->package_source ) ) {
1338
+ $extra = $this->get_extra_url_parameters();
1339
+ if ( ! empty( $extra['repository'] ) && $extra['repository'] == $repository_id ) {
1340
+ unset( $extra['repository'] );
1341
+ foreach ( $extra as $key => $val ) {
1342
+ $args['body'][ $key ] = $val;
1343
+ }
1344
+ }
1345
+ }
1346
+
1347
+ $response = wp_remote_post( $this->repositories[ $repository_id ]['api-url'], $args );
1348
+
1349
+ $this->api_debug_log( "POST {$this->repositories[$repository_id]['api-url']}" );
1350
+ $this->api_debug_log( $args );
1351
+
1352
+ $this->log( "POST {$this->repositories[$repository_id]['api-url']} - fetch subscription data" );
1353
+
1354
+ if ( ! is_wp_error( $response ) ) {
1355
+ $datas = wp_remote_retrieve_body( $response );
1356
+
1357
+ if ( is_serialized( $datas ) ) {
1358
+ $data = unserialize( $datas );
1359
+ $this->api_debug_log( $data );
1360
+
1361
+ if ( ! empty( $data->subscription_data ) ) {
1362
+ $subscription_data = $data->subscription_data;
1363
+ }
1364
+
1365
+ do_action( 'installer_fetched_subscription_data', $data, $repository_id );
1366
+
1367
+ } else {
1368
+ $this->api_debug_log( $datas );
1369
+ }
1370
+
1371
+ } else {
1372
+
1373
+ $this->api_debug_log( $response );
1374
+ throw new Exception( $response->get_error_message() );
1375
+ }
1376
+
1377
+ return $subscription_data;
1378
+
1379
+ }
1380
+
1381
+ function get_local_product_versions( $repository_id ) {
1382
+
1383
+ $versions = array();
1384
+
1385
+ foreach ( $this->settings['repositories'][ $repository_id ]['data']['packages'] as $package_id => $package ) {
1386
+
1387
+ foreach ( $package['products'] as $product_id => $product ) {
1388
+
1389
+ foreach ( $product['plugins'] as $plugin_slug ) {
1390
+
1391
+ $download = $this->settings['repositories'][ $repository_id ]['data']['downloads']['plugins'][ $plugin_slug ];
1392
+
1393
+ if ( empty( $versions[ $download['slug'] ] ) ) {
1394
+ $v = $this->get_plugin_installed_version( $download['name'], $download['slug'] );
1395
+ if ( $v ) {
1396
+ $versions[ $download['slug'] ] = $v;
1397
+ }
1398
+ }
1399
+
1400
+ }
1401
+
1402
+ }
1403
+
1404
+ }
1405
+
1406
+ return $versions;
1407
+ }
1408
+
1409
+ public function get_repository_site_key( $repository_id ) {
1410
+ $site_key = false;
1411
+
1412
+ if ( ! empty( $this->settings['repositories'][ $repository_id ]['subscription']['key'] ) ) {
1413
+ $site_key = $this->settings['repositories'][ $repository_id ]['subscription']['key'];
1414
+ }
1415
+
1416
+ return $site_key;
1417
+ }
1418
+
1419
+ public function repository_has_valid_subscription( $repository_id ) {
1420
+
1421
+ $valid = false;
1422
+
1423
+ if ( ! empty( $this->settings['repositories'][ $repository_id ]['subscription'] ) ) {
1424
+
1425
+ $subscription = $this->settings['repositories'][ $repository_id ]['subscription']['data'];
1426
+ $valid = ( $subscription->status == 1 && ( strtotime( $subscription->expires ) > time() || empty( $subscription->expires ) ) ) || $subscription->status == 4;
1427
+
1428
+ }
1429
+
1430
+ return $valid;
1431
+
1432
+ }
1433
+
1434
+ public function repository_has_subscription( $repository_id ) {
1435
+ $key = false;
1436
+ if ( ! empty( $this->settings['repositories'][ $repository_id ]['subscription']['key'] ) ) {
1437
+ $key = $this->settings['repositories'][ $repository_id ]['subscription']['key'];
1438
+ }
1439
+
1440
+ return $key;
1441
+
1442
+ }
1443
+
1444
+ public function repository_has_expired_subscription( $repository_id ) {
1445
+
1446
+ return $this->repository_has_subscription( $repository_id ) && ! $this->repository_has_valid_subscription( $repository_id );
1447
+
1448
+ }
1449
+
1450
+ public function get_generic_product_name( $repository_id ) {
1451
+
1452
+ return $this->settings['repositories'][ $repository_id ]['data']['product-name'];
1453
+
1454
+ }
1455
+
1456
+ public function show_subscription_renew_warning( $repository_id, $subscription_id ) {
1457
+
1458
+ $show = false;
1459
+
1460
+ $data = $this->settings['repositories'][ $repository_id ]['data'];
1461
+ if ( ! empty( $data['subscriptions_meta'] ) ) {
1462
+ if ( isset( $data['subscriptions_meta']['expiration'] ) ) {
1463
+
1464
+ if ( ! empty( $data['subscriptions_meta']['expiration'][ $subscription_id ] ) ) {
1465
+
1466
+ $days = $data['subscriptions_meta']['expiration'][ $subscription_id ]['days_warning'];
1467
+ $message = $data['subscriptions_meta']['expiration'][ $subscription_id ]['warning_message'];
1468
+
1469
+ } else {
1470
+
1471
+ //defaults
1472
+ $days = 30;
1473
+ $message = __( 'You will have to renew your subscription in order to continue getting the updates and support.', 'installer' );
1474
+
1475
+ }
1476
+
1477
+ if ( ! empty( $this->settings['repositories'][ $repository_id ]['subscription'] ) ) {
1478
+ $subscription = $this->settings['repositories'][ $repository_id ]['subscription'];
1479
+
1480
+ if ( $subscription['data']->subscription_type == $subscription_id && ! empty( $subscription['data']->expires ) ) {
1481
+
1482
+ if ( strtotime( $subscription['data']->expires ) < strtotime( sprintf( "+%d day", $days ) ) ) {
1483
+
1484
+ $days_to_expiration = ceil( ( strtotime( $subscription['data']->expires ) - time() ) / 86400 );
1485
+
1486
+ echo '<div><p class="installer-warn-box">' .
1487
+ sprintf( _n( 'Your subscription expires in %d day.', 'Your subscription expires in %d days.', $days_to_expiration, 'installer' ), $days_to_expiration ) .
1488
+ '<br />' . $message .
1489
+ '</p></div>';
1490
+
1491
+ $show = true;
1492
+
1493
+ }
1494
+
1495
+ }
1496
+
1497
+ }
1498
+
1499
+
1500
+ }
1501
+ }
1502
+
1503
+
1504
+ return $show;
1505
+
1506
+ }
1507
+
1508
+ public function setup_plugins_renew_warnings() {
1509
+
1510
+ $plugins = get_plugins();
1511
+
1512
+ $subscriptions_with_warnings = array();
1513
+ foreach ( $this->settings['repositories'] as $repository_id => $repository ) {
1514
+
1515
+ if ( $this->repository_has_valid_subscription( $repository_id ) ) {
1516
+ $subscription_type = $this->settings['repositories'][ $repository_id ]['subscription']['data']->subscription_type;
1517
+ $expires = $this->settings['repositories'][ $repository_id ]['subscription']['data']->expires;
1518
+
1519
+ $never_expires = isset( $this->settings['repositories'][ $repository_id ]['subscription'] )
1520
+ && empty( $this->settings['repositories'][ $repository_id ]['subscription']['data']->expires )
1521
+ && (
1522
+ $this->settings['repositories'][ $repository_id ]['subscription']['data']->status == 4 ||
1523
+ $this->settings['repositories'][ $repository_id ]['subscription']['data']->status == 1
1524
+ );
1525
+
1526
+ if ( ! $never_expires ) {
1527
+ if ( isset( $this->settings['repositories'][ $repository_id ]['data']['subscriptions_meta']['expiration'][ $subscription_type ] ) ) {
1528
+
1529
+ $days_warning = $this->settings['repositories'][ $repository_id ]['data']['subscriptions_meta']['expiration'][ $subscription_type ]['days_warning'];
1530
+ $custom_message = $this->settings['repositories'][ $repository_id ]['data']['subscriptions_meta']['expiration'][ $subscription_type ]['warning_message'];
1531
+
1532
+ } else {
1533
+ //defaults
1534
+ $days_warning = 30;
1535
+ $custom_message = __( 'You will have to renew your subscription in order to continue getting the updates and support.', 'installer' );
1536
+ }
1537
+
1538
+ if ( strtotime( $expires ) < strtotime( sprintf( '+%d day', $days_warning ) ) ) {
1539
+
1540
+ $days_to_expiration = ceil( ( strtotime( $expires ) - time() ) / 86400 );
1541
+
1542
+ $message = sprintf( _n( 'Your subscription expires in %d day.', 'Your subscription expires in %d days.', $days_to_expiration, 'installer' ), $days_to_expiration );
1543
+ $subscriptions_with_warnings[ $subscription_type ] = $message . ' ' . $custom_message;
1544
+
1545
+ }
1546
+ }
1547
+
1548
+ }
1549
+
1550
+ }
1551
+
1552
+
1553
+ foreach ( $plugins as $plugin_id => $plugin ) {
1554
+
1555
+ $slug = dirname( $plugin_id );
1556
+ if ( empty( $slug ) ) {
1557
+ continue;
1558
+ }
1559
+
1560
+ foreach ( $this->settings['repositories'] as $repository_id => $repository ) {
1561
+
1562
+ if ( $this->repository_has_valid_subscription( $repository_id ) ) {
1563
+
1564
+ foreach ( $repository['data']['packages'] as $package ) {
1565
+
1566
+ foreach ( $package['products'] as $product ) {
1567
+
1568
+ foreach ( $product['plugins'] as $plugin_slug ) {
1569
+
1570
+ $download = $this->settings['repositories'][ $repository_id ]['data']['downloads']['plugins'][ $plugin_slug ];
1571
+
1572
+ if ( $download['slug'] == $slug || $download['name'] == $plugin['Name'] || $download['name'] == $plugin['Title'] ) { //match order: slug, name, title
1573
+
1574
+ if ( isset( $subscriptions_with_warnings[ $product['subscription_type'] ] ) ) {
1575
+
1576
+ $this->_plugins_renew_warnings[ $plugin_id ] = $subscriptions_with_warnings[ $product['subscription_type'] ];
1577
+
1578
+ }
1579
+
1580
+ }
1581
+
1582
+ }
1583
+
1584
+ }
1585
+
1586
+ }
1587
+
1588
+ }
1589
+
1590
+ }
1591
+
1592
+ }
1593
+
1594
+ }
1595
+
1596
+ public function queue_plugins_renew_warnings() {
1597
+
1598
+ if ( ! empty( $this->_plugins_renew_warnings ) ) {
1599
+
1600
+ foreach ( $this->_plugins_renew_warnings as $plugin_id => $message ) {
1601
+
1602
+ add_action( "after_plugin_row_" . $plugin_id, array( $this, 'plugins_renew_warning' ), 10, 3 );
1603
+ }
1604
+
1605
+ }
1606
+
1607
+ }
1608
+
1609
+ public function plugins_renew_warning( $plugin_file, $plugin_data, $status ) {
1610
+
1611
+ if ( empty( $this->_plugins_renew_warnings[ $plugin_file ] ) ) {
1612
+ return;
1613
+ }
1614
+
1615
+ $wp_list_table = _get_list_table( 'WP_Plugins_List_Table' );
1616
+ ?>
1617
+
1618
+ <tr class="plugin-update-tr">
1619
+ <td colspan="<?php echo $wp_list_table->get_column_count(); ?>" class="plugin-update colspanchange">
1620
+ <div class="update-message">
1621
+ <?php
1622
+ echo $this->_plugins_renew_warnings[ $plugin_file ] . ' ';
1623
+ printf( __( '%sRenew here%s.', 'installer' ),
1624
+ '<a href="' . $this->menu_url() . '">', '</a>' );
1625
+ ?>
1626
+ </div>
1627
+ </tr>
1628
+
1629
+ <?php
1630
+
1631
+ }
1632
+
1633
+ public function get_subscription_type_for_repository( $repository_id ) {
1634
+
1635
+ $subscription_type = false;
1636
+
1637
+ if ( ! empty( $this->settings['repositories'][ $repository_id ]['subscription'] ) ) {
1638
+ $subscription_type = $this->settings['repositories'][ $repository_id ]['subscription']['data']->subscription_type;
1639
+ }
1640
+
1641
+ return $subscription_type;
1642
+
1643
+ }
1644
+
1645
+ public function have_superior_subscription( $subscription_type, $product ) {
1646
+
1647
+ $have = false;
1648
+
1649
+ if ( is_array( $product['upgrades'] ) ) {
1650
+ foreach ( $product['upgrades'] as $u ) {
1651
+ if ( $u['subscription_type'] == $subscription_type ) {
1652
+ $have = true;
1653
+ break;
1654
+ }
1655
+ }
1656
+ }
1657
+
1658
+ return $have;
1659
+ }
1660
+
1661
+ public function is_product_available_for_download( $product_name, $repository_id ) {
1662
+
1663
+ $available = false;
1664
+
1665
+ $subscription_type = $this->get_subscription_type_for_repository( $repository_id );
1666
+ $expired = $this->repository_has_expired_subscription( $repository_id );
1667
+
1668
+ if ( $this->repository_has_subscription( $repository_id ) && ! $expired ) {
1669
+
1670
+ $this->set_hierarchy_and_order();
1671
+
1672
+ foreach ( $this->settings['repositories'][ $repository_id ]['data']['packages'] as $package_id => $package ) {
1673
+
1674
+ $has_top_package = false;
1675
+
1676
+ foreach ( $package['products'] as $product ) {
1677
+
1678
+ if ( $subscription_type == $product['subscription_type'] ) {
1679
+ $has_top_package = true;
1680
+ if ( $product['name'] == $product_name ) {
1681
+ return $available = true;
1682
+ }
1683
+ }
1684
+
1685
+ }
1686
+
1687
+ if ( ! empty( $package['sub-packages'] ) ) {
1688
+ foreach ( $package['sub-packages'] as $sub_package ) {
1689
+ foreach ( $sub_package['products'] as $product ) {
1690
+ if ( $product['name'] == $product_name && ( $subscription_type == $product['subscription_type'] || $has_top_package ) ) {
1691
+ return $available = true;
1692
+ }
1693
+ }
1694
+ }
1695
+ }
1696
+
1697
+ }
1698
+ }
1699
+
1700
+ return $available;
1701
+
1702
+ }
1703
+
1704
+ public function get_upgrade_options( $repository_id ) {
1705
+ $all_upgrades = array();
1706
+
1707
+
1708
+ //get all products: packages and subpackages
1709
+ $all_products = array();
1710
+ foreach ( $this->settings['repositories'][ $repository_id ]['data']['packages'] as $package ) {
1711
+ foreach ( $package['products'] as $product ) {
1712
+ $all_products[] = $product;
1713
+ }
1714
+ if ( ! empty( $package['sub-packages'] ) ) {
1715
+ foreach ( $package['sub-packages'] as $subpackage ) {
1716
+ foreach ( $subpackage['products'] as $product ) {
1717
+ $all_products[] = $product;
1718
+ }
1719
+
1720
+ }
1721
+
1722
+ }
1723
+
1724
+ }
1725
+
1726
+ foreach ( $all_products as $product ) {
1727
+ if ( $product['upgrades'] ) {
1728
+ foreach ( $product['upgrades'] as $upgrade ) {
1729
+ if ( $this->repository_has_valid_subscription( $repository_id ) || ( $this->repository_has_subscription( $repository_id ) && $upgrade['including_expired'] ) ) {
1730
+ $all_upgrades[ $upgrade['subscription_type'] ][ $product['subscription_type'] ] = $upgrade;
1731
+ }
1732
+ }
1733
+ }
1734
+ }
1735
+
1736
+ return $all_upgrades;
1737
+
1738
+ }
1739
+
1740
+ public function append_site_key_to_download_url( $url, $key, $repository_id ) {
1741
+
1742
+ $url_params['site_key'] = $key;
1743
+ $url_params['site_url'] = $this->get_installer_site_url( $repository_id );
1744
+
1745
+
1746
+ // Add extra parameters for custom Installer packages
1747
+ if ( ! empty( $this->package_source ) ) {
1748
+ $extra = $this->get_extra_url_parameters();
1749
+ if ( ! empty( $extra['repository'] ) && $extra['repository'] == $repository_id ) {
1750
+ unset( $extra['repository'] );
1751
+ foreach ( $extra as $key => $val ) {
1752
+ $url_params[ $key ] = $val;
1753
+ }
1754
+ }
1755
+ }
1756
+
1757
+ $url = add_query_arg( $url_params, $url );
1758
+
1759
+ if ( $repository_id == 'wpml' ) {
1760
+ $url = add_query_arg( array(
1761
+ 'using_icl' => $this->_using_icl,
1762
+ 'wpml_version' => $this->_wpml_version
1763
+ ), $url );
1764
+ }
1765
+
1766
+ return $url;
1767
+
1768
+ }
1769
+
1770
+ public function plugin_is_installed( $name, $slug, $version = null ) {
1771
+
1772
+ $is = false;
1773
+
1774
+ $plugins = get_plugins();
1775
+
1776
+ foreach ( $plugins as $plugin_id => $plugin ) {
1777
+
1778
+ $wp_plugin_slug = dirname( $plugin_id );
1779
+
1780
+ // Exception: embedded plugins
1781
+ if ( $wp_plugin_slug == $slug || $plugin['Name'] == $name || $plugin['Title'] == $name || ( $wp_plugin_slug == $slug . '-embedded' || $plugin['Name'] == $name . ' Embedded' ) ) {
1782
+ if ( $version ) {
1783
+ if ( version_compare( $plugin['Version'], $version, '>=' ) ) {
1784
+ $is = $plugin['Version'];
1785
+ }
1786
+ } else {
1787
+ $is = $plugin['Version'];
1788
+ }
1789
+
1790
+ break;
1791
+ }
1792
+
1793
+ }
1794
+
1795
+ //exception: Types name difference
1796
+ if ( ! $is && $name == 'Types' ) {
1797
+ return $this->plugin_is_installed( 'Types - Complete Solution for Custom Fields and Types', $slug, $version );
1798
+ }
1799
+
1800
+ return $is;
1801
+ }
1802
+
1803
+ public function plugin_is_embedded_version( $name, $slug ) {
1804
+ $is = false;
1805
+
1806
+ $plugins = get_plugins();
1807
+
1808
+ //false if teh full version is also installed
1809
+ $is_full_installed = false;
1810
+ foreach ( $plugins as $plugin_id => $plugin ) {
1811
+
1812
+ if ( ( $plugin['Name'] == $name && ! preg_match( "#-embedded$#", $slug ) ) ) {
1813
+ $is_full_installed = true;
1814
+ break;
1815
+ }
1816
+
1817
+ }
1818
+
1819
+ if ( $is_full_installed ) {
1820
+ return false;
1821
+ }
1822
+
1823
+ foreach ( $plugins as $plugin_id => $plugin ) {
1824
+
1825
+ // TBD
1826
+ $wp_plugin_slug = dirname( $plugin_id );
1827
+ if ( $wp_plugin_slug == $slug . '-embedded' && $plugin['Name'] == $name . ' Embedded' ) {
1828
+ $is = true;
1829
+ break;
1830
+ }
1831
+
1832
+ }
1833
+
1834
+ return $is;
1835
+
1836
+ }
1837
+
1838
+ //Alias for plugin_is_installed
1839
+ public function get_plugin_installed_version( $name, $slug ) {
1840
+
1841
+ return $this->plugin_is_installed( $name, $slug );
1842
+
1843
+ }
1844
+
1845
+ public function get_plugin_repository_version( $repository_id, $slug ) {
1846
+ $version = false;
1847
+
1848
+ if ( ! empty( $this->settings['repositories'][ $repository_id ]['data']['packages'] ) ) {
1849
+ foreach ( $this->settings['repositories'][ $repository_id ]['data']['packages'] as $package ) {
1850
+ foreach ( $package['products'] as $product ) {
1851
+
1852
+ foreach ( $product['plugins'] as $plugin_slug ) {
1853
+
1854
+ $download = $this->settings['repositories'][ $repository_id ]['data']['downloads']['plugins'][ $plugin_slug ];
1855
+
1856
+ if ( $download['slug'] == $slug ) {
1857
+ $version = $download['version'];
1858
+ break ( 3 );
1859
+ }
1860
+
1861
+ }
1862
+
1863
+ }
1864
+ }
1865
+ }
1866
+
1867
+ return $version;
1868
+ }
1869
+
1870
+ public function is_uploading_allowed() {
1871
+
1872
+ //_deprecated_function ( __FUNCTION__, '1.7.3', 'Installer_Dependencies::' . __FUNCTION__ );
1873
+ return $this->dependencies->is_uploading_allowed();
1874
+
1875
+ }
1876
+
1877
+ public function download_plugin_ajax_handler() {
1878
+
1879
+ require_once ABSPATH . 'wp-admin/includes/class-wp-upgrader.php';
1880
+ require_once $this->plugin_path() . '/includes/class-installer-upgrader-skins.php';
1881
+
1882
+ $data = json_decode( base64_decode( sanitize_text_field( $_POST['data'] ) ), true );
1883
+
1884
+ $ret = false;
1885
+ $plugin_id = false;
1886
+ $message = '';
1887
+
1888
+ //validate subscription
1889
+ $site_key = $this->get_repository_site_key( $data['repository_id'] );
1890
+ $subscription_data = $this->fetch_subscription_data( $data['repository_id'], $site_key, self::SITE_KEY_VALIDATION_SOURCE_DOWNLOAD_REPORT );
1891
+
1892
+ if ( $subscription_data && ! is_wp_error( $subscription_data ) && $this->repository_has_valid_subscription( $data['repository_id'] ) ) {
1893
+
1894
+ if ( $data['nonce'] == wp_create_nonce( 'install_plugin_' . $data['url'] ) ) {
1895
+
1896
+ $upgrader_skins = new Installer_Upgrader_Skins(); //use our custom (mute) Skin
1897
+ $upgrader = new Plugin_Upgrader( $upgrader_skins );
1898
+
1899
+ remove_action( 'upgrader_process_complete', array( 'Language_Pack_Upgrader', 'async_upgrade' ), 20 );
1900
+
1901
+ $plugins = get_plugins();
1902
+
1903
+ //upgrade or install?
1904
+ foreach ( $plugins as $id => $plugin ) {
1905
+ $wp_plugin_slug = dirname( $id );
1906
+ $is_embedded = $this->plugin_is_embedded_version( preg_replace( '/ Embedded$/', '', $plugin['Name'] ), preg_replace( '/-embedded$/', '', $wp_plugin_slug ) );
1907
+
1908
+ if ( $wp_plugin_slug == $data['slug'] || $is_embedded && preg_replace( '/-embedded$/', '', $wp_plugin_slug ) == $data['slug'] ) {
1909
+ $plugin_id = $id;
1910
+ break;
1911
+ }
1912
+ }
1913
+
1914
+ if ( $plugin_id && empty( $is_embedded ) ) { //upgrade
1915
+ $response['upgrade'] = 1;
1916
+
1917
+ $plugin_is_active = is_plugin_active( $plugin_id );
1918
+
1919
+ $ret = $upgrader->upgrade( $plugin_id );
1920
+
1921
+ if ( ! $ret && ! empty( $upgrader->skin->installer_error ) ) {
1922
+ if ( is_wp_error( $upgrader->skin->installer_error ) ) {
1923
+ $message = $upgrader->skin->installer_error->get_error_message() .
1924
+ ' (' . $upgrader->skin->installer_error->get_error_data() . ')';
1925
+ }
1926
+ $plugin_version = 0;
1927
+ }else{
1928
+ if ( $plugin_is_active ) {
1929
+ //prevent redirects
1930
+ add_filter( 'wp_redirect', '__return_false' );
1931
+ activate_plugin( $plugin_id );
1932
+ }
1933
+ $plugin_version = $this->get_plugin_repository_version( $data['repository_id'], $data['slug'] );
1934
+ }
1935
+
1936
+ } else { //install
1937
+
1938
+ if ( $is_embedded ) {
1939
+ delete_plugins( array( $plugin_id ) );
1940
+ }
1941
+
1942
+ $response['install'] = 1;
1943
+ $ret = $upgrader->install( $data['url'] );
1944
+ if ( ! $ret && ! empty( $upgrader->skin->installer_error ) ) {
1945
+ if ( is_wp_error( $upgrader->skin->installer_error ) ) {
1946
+ $message = $upgrader->skin->installer_error->get_error_message() .
1947
+ ' (' . $upgrader->skin->installer_error->get_error_data() . ')';
1948
+ }
1949
+ }
1950
+ }
1951
+
1952
+ $plugins = get_plugins(); //read again
1953
+
1954
+ if ( $ret ) {
1955
+ foreach ( $plugins as $id => $plugin ) {
1956
+ $wp_plugin_slug = dirname( $id );
1957
+ if ( $wp_plugin_slug == $data['slug'] ) {
1958
+ $plugin_version = $plugin['Version'];
1959
+ $plugin_id = $id;
1960
+ break;
1961
+ }
1962
+ }
1963
+
1964
+ }
1965
+
1966
+ if( WP_Installer_Channels()->get_channel( $data['repository_id'] ) !== WP_Installer_Channels::CHANNEL_PRODUCTION ){
1967
+ $download = $this->settings['repositories'][$data['repository_id']]['data']['downloads']['plugins'][$data['slug']];
1968
+ $non_stable = WP_Installer_Channels()->get_download_source_channel( $plugin_version, $data['repository_id'], $download['slug'], 'plugins' );
1969
+ }
1970
+
1971
+ }
1972
+
1973
+ } else { //subscription not valid
1974
+
1975
+ $ret = false;
1976
+ $message = __( 'Your subscription appears to no longer be valid. Please try to register again using a valid site key.', 'installer' );
1977
+ }
1978
+
1979
+ $response['version'] = isset( $plugin_version ) ? $plugin_version : 0;
1980
+ $response['non_stable']= isset( $non_stable ) ? $non_stable : '';
1981
+ $response['plugin_id'] = $plugin_id;
1982
+ $response['nonce'] = wp_create_nonce( 'activate_' . $plugin_id );
1983
+ $response['success'] = $ret;
1984
+ $response['message'] = $message;
1985
+
1986
+ echo json_encode( $response );
1987
+ exit;
1988
+
1989
+ }
1990
+
1991
+ public function download_plugin( $slug, $url ) {
1992
+
1993
+ require_once ABSPATH . 'wp-admin/includes/class-wp-upgrader.php';
1994
+ require_once $this->plugin_path() . '/includes/class-installer-upgrader-skins.php';
1995
+
1996
+ $upgrader_skins = new Installer_Upgrader_Skins(); //use our custom (mute) Skin
1997
+ $upgrader = new Plugin_Upgrader( $upgrader_skins );
1998
+
1999
+ remove_action( 'upgrader_process_complete', array( 'Language_Pack_Upgrader', 'async_upgrade' ), 20 );
2000
+
2001
+ $plugins = get_plugins();
2002
+
2003
+ $plugin_id = false;
2004
+
2005
+ //upgrade or install?
2006
+ foreach ( $plugins as $id => $plugin ) {
2007
+ $wp_plugin_slug = dirname( $id );
2008
+ if ( $wp_plugin_slug == $slug ) {
2009
+ $plugin_id = $id;
2010
+ break;
2011
+ }
2012
+ }
2013
+
2014
+ if ( $plugin_id ) { //upgrade
2015
+
2016
+ $plugin_is_active = is_plugin_active( $plugin_id );
2017
+
2018
+ $ret = $upgrader->upgrade( $plugin_id );
2019
+
2020
+ if ( $plugin_is_active ) {
2021
+ activate_plugin( $plugin_id );
2022
+ }
2023
+
2024
+ } else { //install
2025
+ $ret = $upgrader->install( $url );
2026
+ }
2027
+
2028
+ return $ret;
2029
+
2030
+ }
2031
+
2032
+ public function activate_plugin() {
2033
+
2034
+ $error = '';
2035
+
2036
+ $plugin_id = sanitize_text_field( $_POST['plugin_id'] );
2037
+ if ( isset( $_POST['nonce'] ) && $plugin_id && $_POST['nonce'] == wp_create_nonce( 'activate_' . $plugin_id ) ) {
2038
+
2039
+ // Deactivate any embedded version
2040
+ $plugin_slug = dirname( $plugin_id );
2041
+ $active_plugins = get_option( 'active_plugins' );
2042
+ foreach ( $active_plugins as $plugin ) {
2043
+ $wp_plugin_slug = dirname( $plugin );
2044
+ if ( $wp_plugin_slug == $plugin_slug . '-embedded' ) {
2045
+ deactivate_plugins( array( $plugin ) );
2046
+ break;
2047
+ }
2048
+ }
2049
+
2050
+ //prevent redirects
2051
+ add_filter( 'wp_redirect', '__return_false', 10000 );
2052
+
2053
+ $return = activate_plugin( $plugin_id );
2054
+
2055
+ if ( is_wp_error( $return ) ) {
2056
+ $error = $return->get_error_message();
2057
+ }
2058
+
2059
+ } else {
2060
+ $error = 'error';
2061
+ }
2062
+
2063
+ $ret = array( 'error' => $error );
2064
+
2065
+ echo json_encode( $ret );
2066
+ exit;
2067
+
2068
+ }
2069
+
2070
+ public function custom_plugins_api_call( $false, $action, $args ) {
2071
+
2072
+ if ( $action == 'plugin_information' ) {
2073
+
2074
+ $plugins = get_plugins();
2075
+ $plugin_names = array();
2076
+ foreach ( $plugins as $plugin_id => $plugin ) {
2077
+ // plugins by WP slug which (plugin folder) which can be different
2078
+ // will use this to compare by title
2079
+ $plugin_names[ dirname( $plugin_id ) ] = array(
2080
+ 'name' => $plugin['Name'],
2081
+ 'title' => $plugin['Title'],
2082
+ );
2083
+ }
2084
+
2085
+ $slug = $args->slug;
2086
+
2087
+ foreach ( $this->settings['repositories'] as $repository_id => $repository ) {
2088
+
2089
+ if ( ! $this->repository_has_valid_subscription( $repository_id ) ) {
2090
+ $site_key = false;
2091
+ } else {
2092
+ $site_key = $repository['subscription']['key'];
2093
+ }
2094
+
2095
+ foreach ( $repository['data']['packages'] as $package ) {
2096
+
2097
+ foreach ( $package['products'] as $product ) {
2098
+
2099
+ foreach ( $product['plugins'] as $plugin_slug ) {
2100
+
2101
+ $download = $this->settings['repositories'][ $repository_id ]['data']['downloads']['plugins'][ $plugin_slug ];
2102
+
2103
+ if ( $download['slug'] == $slug ||
2104
+ isset( $plugin_names[ $slug ] ) && (
2105
+ $plugin_names[ $slug ]['name'] == $download['name'] ||
2106
+ $plugin_names[ $slug ]['title'] == $download['name']
2107
+ )
2108
+ ) {
2109
+
2110
+ if ( ! empty( $download['free-on-wporg'] ) && $download['channel'] == WP_Installer_Channels::CHANNEL_PRODUCTION ) {
2111
+ return false; // use data from wordpress.org
2112
+ }
2113
+
2114
+ $res = new stdClass();
2115
+ $res->external = true;
2116
+
2117
+ $res->name = $download['name'];
2118
+ $res->slug = $slug;
2119
+ $res->version = $download['version'];
2120
+ $res->author = '';
2121
+ $res->author_profile = '';
2122
+ $res->last_updated = $download['date'];
2123
+
2124
+ if ( $site_key ) {
2125
+ $res->download_link = $this->append_site_key_to_download_url( $download['url'], $site_key, $repository_id );
2126
+ }
2127
+
2128
+ $res->homepage = $repository['data']['url'];
2129
+ $res->sections = array(
2130
+ 'Description' => $download['description'],
2131
+ 'Changelog' => $download['changelog']
2132
+ );
2133
+
2134
+ return $res;
2135
+
2136
+ }
2137
+
2138
+ }
2139
+
2140
+ }
2141
+
2142
+ }
2143
+
2144
+ }
2145
+
2146
+ }
2147
+
2148
+ return $false;
2149
+
2150
+ }
2151
+
2152
+ public function plugins_upgrade_check( $update_plugins ) {
2153
+
2154
+ if ( ! empty( $this->settings['repositories'] ) ) {
2155
+
2156
+ $plugins = get_plugins();
2157
+
2158
+ foreach ( $plugins as $plugin_id => $plugin ) {
2159
+
2160
+ $slug = dirname( $plugin_id );
2161
+ if ( empty( $slug ) ) {
2162
+ continue;
2163
+ }
2164
+
2165
+ $version = $plugin['Version'];
2166
+ $name = $plugin['Name'];
2167
+
2168
+ foreach ( $this->settings['repositories'] as $repository_id => $repository ) {
2169
+
2170
+
2171
+ if ( ! $this->repository_has_valid_subscription( $repository_id ) ) {
2172
+ $site_key = false;
2173
+ } else {
2174
+ $site_key = $repository['subscription']['key'];
2175
+ //$subscription_type = $this->get_subscription_type_for_repository($repository_id);
2176
+ }
2177
+
2178
+ foreach ( $repository['data']['packages'] as $package ) {
2179
+
2180
+ foreach ( $package['products'] as $product ) {
2181
+
2182
+ foreach ( $product['plugins'] as $plugin_slug ) {
2183
+
2184
+ $download = $this->settings['repositories'][ $repository_id ]['data']['downloads']['plugins'][ $plugin_slug ];
2185
+
2186
+ if ( ! empty( $download['free-on-wporg'] ) && $download['channel'] == WP_Installer_Channels::CHANNEL_PRODUCTION ) {
2187
+ continue;
2188
+ }
2189
+
2190
+ $needs_version_update = version_compare( $download['version'], $version, '>' ) ||
2191
+ ! empty( $_POST['reset_to_channel'] );
2192
+
2193
+ if (
2194
+ empty( $update_plugins->response[ $plugin_id ] ) &&
2195
+ ( $download['slug'] == $slug || $download['name'] == $name ) &&
2196
+ $needs_version_update
2197
+ ) {
2198
+
2199
+ $response = new stdClass();
2200
+ $response->id = 0;
2201
+ $response->slug = $slug;
2202
+ $response->plugin = $plugin_id;
2203
+ $response->new_version = $download['version'];
2204
+ $response->upgrade_notice = '';
2205
+ $response->url = $download['url'];
2206
+ if ( $site_key ) {
2207
+ $response->package = $this->append_site_key_to_download_url( $download['url'], $site_key, $repository_id );
2208
+ }
2209
+ $update_plugins->checked[ $plugin_id ] = $version;
2210
+ $update_plugins->response[ $plugin_id ] = $response;
2211
+
2212
+ }
2213
+
2214
+ }
2215
+
2216
+ }
2217
+
2218
+ }
2219
+
2220
+ }
2221
+
2222
+ }
2223
+
2224
+ }
2225
+
2226
+ return $update_plugins;
2227
+
2228
+ }
2229
+
2230
+ public function setup_plugins_page_notices() {
2231
+
2232
+ $plugins = get_plugins();
2233
+
2234
+ foreach ( $plugins as $plugin_id => $plugin ) {
2235
+
2236
+ $slug = dirname( $plugin_id );
2237
+ if ( empty( $slug ) ) {
2238
+ continue;
2239
+ }
2240
+
2241
+ $name = $plugin['Name'];
2242
+
2243
+ foreach ( $this->settings['repositories'] as $repository_id => $repository ) {
2244
+
2245
+ if ( ! $this->repository_has_valid_subscription( $repository_id ) ) {
2246
+ $site_key = false;
2247
+ } else {
2248
+ $site_key = $repository['subscription']['key'];
2249
+ }
2250
+
2251
+ foreach ( $repository['data']['packages'] as $package ) {
2252
+
2253
+ foreach ( $package['products'] as $product ) {
2254
+
2255
+ foreach ( $product['plugins'] as $plugin_slug ) {
2256
+
2257
+ $download = $this->settings['repositories'][ $repository_id ]['data']['downloads']['plugins'][ $plugin_slug ];
2258
+
2259
+ if ( ! empty( $download['free-on-wporg'] ) && $download['channel'] == WP_Installer_Channels::CHANNEL_PRODUCTION ) {
2260
+ continue;
2261
+ }
2262
+
2263
+ if ( $download['slug'] == $slug || $download['name'] == $name ) {
2264
+
2265
+ if ( ! $site_key || ! $this->plugin_is_registered( $repository_id, $download['slug'] ) ) {
2266
+ add_action( "after_plugin_row_" . $plugin_id, array(
2267
+ $this,
2268
+ 'show_purchase_notice_under_plugin'
2269
+ ), 10, 3 );
2270
+ }
2271
+
2272
+ }
2273
+
2274
+ }
2275
+
2276
+ }
2277
+
2278
+ }
2279
+
2280
+ }
2281
+
2282
+ }
2283
+
2284
+ }
2285
+
2286
+ public function show_purchase_notice_under_plugin( $plugin_file, $plugin_data, $status ) {
2287
+
2288
+ $wp_list_table = _get_list_table( 'WP_Plugins_List_Table' );
2289
+ $wp_version = preg_replace( '/-(.+)$/', '', $GLOBALS['wp_version'] );
2290
+
2291
+ if ( version_compare( $wp_version, '4.6', '>=' ) ) {
2292
+
2293
+ ?>
2294
+ <tr class="plugin-update-tr installer-plugin-update-tr">
2295
+ <td colspan="<?php echo $wp_list_table->get_column_count(); ?>" class="plugin-update colspanchange">
2296
+ <div class="notice inline notice-warning notice-alt">
2297
+ <p class="installer-q-icon">
2298
+ <?php printf( __( 'You must have a valid subscription in order to get upgrades or support for this plugin. %sPurchase a subscription or enter an existing site key%s.', 'installer' ),
2299
+ '<a href="' . $this->menu_url() . '">', '</a>' ); ?>
2300
+ </p>
2301
+ </div>
2302
+ </td>
2303
+ </tr>
2304
+ <?php
2305
+
2306
+ } else {
2307
+
2308
+ ?>
2309
+ <tr class="plugin-update-tr">
2310
+ <td colspan="<?php echo $wp_list_table->get_column_count(); ?>" class="plugin-update colspanchange">
2311
+ <div class="update-message installer-q-icon">
2312
+ <?php printf( __( 'You must have a valid subscription in order to get upgrades or support for this plugin. %sPurchase a subscription or enter an existing site key%s.', 'installer' ),
2313
+ '<a href="' . $this->menu_url() . '">', '</a>' ); ?>
2314
+ </div>
2315
+ </td>
2316
+ </tr>
2317
+ <?php
2318
+
2319
+ }
2320
+
2321
+ }
2322
+
2323
+ public function localize_strings() {
2324
+
2325
+ if ( ! empty( $this->settings['repositories'] ) ) {
2326
+ foreach ( $this->settings['repositories'] as $repository_id => $repository ) {
2327
+ //set name as call2action when don't have any
2328
+ //products
2329
+ foreach ( $repository['data']['packages'] as $package_id => $package ) {
2330
+ foreach ( $package['products'] as $product_id => $product ) {
2331
+ if ( empty( $product['call2action'] ) ) {
2332
+ $this->settings['repositories'][ $repository_id ]['data']['packages'][ $package_id ]['products'][ $product_id ]['call2action'] = $product['name'];
2333
+ }
2334
+
2335
+ foreach ( $product['upgrades'] as $idx => $upg ) {
2336
+ if ( empty( $upg['call2action'] ) ) {
2337
+ $this->settings['repositories'][ $repository_id ]['data']['packages'][ $package_id ]['products'][ $product_id ]['upgrades'][ $idx ]['call2action'] = $upg['name'];
2338
+ }
2339
+ }
2340
+
2341
+ foreach ( $product['renewals'] as $idx => $rnw ) {
2342
+ if ( empty( $rnw['call2action'] ) ) {
2343
+ $this->settings['repositories'][ $repository_id ]['data']['packages'][ $package_id ]['products'][ $product_id ]['renewals'][ $idx ]['call2action'] = $rnw['name'];
2344
+ }
2345
+
2346
+ }
2347
+
2348
+ }
2349
+ }
2350
+ }
2351
+ }
2352
+
2353
+ global $sitepress;
2354
+ if ( is_null( $sitepress ) ) {
2355
+ return;
2356
+ }
2357
+
2358
+ // default strings are always in English
2359
+ $user_admin_language = $sitepress->get_admin_language();
2360
+
2361
+ if ( $user_admin_language != 'en' ) {
2362
+ foreach ( $this->settings['repositories'] as $repository_id => $repository ) {
2363
+
2364
+ $localization = $repository['data']['localization'];
2365
+
2366
+ //packages
2367
+ foreach ( $repository['data']['packages'] as $package_id => $package ) {
2368
+
2369
+ if ( isset( $localization['packages'][ $package_id ]['name'][ $user_admin_language ] ) ) {
2370
+ $this->settings['repositories'][ $repository_id ]['data']['packages'][ $package_id ]['name'] = $localization['packages'][ $package_id ]['name'][ $user_admin_language ];
2371
+ }
2372
+ if ( isset( $localization['packages'][ $package_id ]['description'][ $user_admin_language ] ) ) {
2373
+ $this->settings['repositories'][ $repository_id ]['data']['packages'][ $package_id ]['description'] = $localization['packages'][ $package_id ]['description'][ $user_admin_language ];
2374
+ }
2375
+
2376
+ }
2377
+
2378
+ //products
2379
+ foreach ( $repository['data']['packages'] as $package_id => $package ) {
2380
+ foreach ( $package['products'] as $product_id => $product ) {
2381
+
2382
+ if ( isset( $localization['products'][ $product_id ]['name'][ $user_admin_language ] ) ) {
2383
+ $this->settings['repositories'][ $repository_id ]['data']['packages'][ $package_id ]['products'][ $product_id ]['name']
2384
+ = $localization['products'][ $product_id ]['name'][ $user_admin_language ];
2385
+ }
2386
+ if ( isset( $localization['products'][ $product_id ]['description'][ $user_admin_language ] ) ) {
2387
+ $this->settings['repositories'][ $repository_id ]['data']['packages'][ $package_id ]['products'][ $product_id ]['description']
2388
+ = $localization['products'][ $product_id ]['description'][ $user_admin_language ];
2389
+ }
2390
+ if ( isset( $localization['products'][ $product_id ]['call2action'][ $user_admin_language ] ) ) {
2391
+ $this->settings['repositories'][ $repository_id ]['data']['packages'][ $package_id ]['products'][ $product_id ]['name']
2392
+ = $localization['products'][ $product_id ]['call2action'][ $user_admin_language ];
2393
+ }
2394
+
2395
+
2396
+ }
2397
+ }
2398
+
2399
+ //subscription info
2400
+ if ( isset( $repository['data']['subscriptions_meta']['expiration'] ) ) {
2401
+ foreach ( $repository['data']['subscriptions_meta']['expiration'] as $subscription_id => $note ) {
2402
+ if ( isset( $localization['subscriptions-notes'][ $subscription_id ]['expiration-warning'][ $user_admin_language ] ) ) {
2403
+ $this->settings['repositories'][ $repository_id ]['data']['subscriptions_meta']['expiration'][ $subscription_id ]['warning_message']
2404
+ = $localization['subscriptions-notes'][ $subscription_id ]['expiration-warning'][ $user_admin_language ];
2405
+ }
2406
+ }
2407
+ }
2408
+
2409
+ }
2410
+ }
2411
+
2412
+ }
2413
+
2414
+ public function get_matching_cp( $repository, $args = array() ) {
2415
+ $match = false;
2416
+
2417
+
2418
+ $cp_name = $cp_author = false;
2419
+
2420
+ if ( isset( $this->config['src_name'] ) && isset( $this->config['src_author'] ) ) {
2421
+
2422
+ $cp_name = $this->config['src_name'];
2423
+ $cp_author = $this->config['src_author'];
2424
+
2425
+ } elseif ( isset( $args['src_name'] ) && isset( $args['src_author'] ) ) {
2426
+
2427
+ $cp_name = $args['src_name'];
2428
+ $cp_author = $args['src_author'];
2429
+
2430
+ }
2431
+
2432
+ if ( isset( $repository['data']['marketing_cp'] ) ) {
2433
+
2434
+ foreach ( $repository['data']['marketing_cp'] as $cp ) {
2435
+
2436
+ if ( ! empty( $cp['exp'] ) && time() > $cp['exp'] ) {
2437
+ continue;
2438
+ }
2439
+
2440
+ //Use theme_name for plugins too
2441
+ if ( ! empty( $cp['theme_name'] ) ) {
2442
+ if ( $cp['author_name'] == $cp_author && $cp['theme_name'] == $cp_name ) {
2443
+ $match = $cp;
2444
+ continue;
2445
+ }
2446
+ } else {
2447
+ if ( $cp['author_name'] == $cp_author ) {
2448
+ $match = $cp;
2449
+ continue;
2450
+ }
2451
+ }
2452
+
2453
+ }
2454
+
2455
+ }
2456
+
2457
+ return $match;
2458
+ }
2459
+
2460
+ public function set_filtered_prices( $args = array() ) {
2461
+
2462
+ foreach ( $this->settings['repositories'] as $repository_id => $repository ) {
2463
+
2464
+ $match = $this->get_matching_cp( $repository, $args );
2465
+
2466
+ if ( empty( $match ) ) {
2467
+ continue;
2468
+ }
2469
+
2470
+ foreach ( $repository['data']['packages'] as $package_id => $package ) {
2471
+
2472
+ foreach ( $package['products'] as $product_id => $product ) {
2473
+
2474
+ if ( $match['dtp'] == '%' ) {
2475
+ $fprice = round( $product['price'] * ( 1 - $match['amt'] / 100 ), 2 );
2476
+ $fprice = $fprice != round( $fprice ) ? sprintf( '%.2f', $fprice ) : round( $fprice, 0 );
2477
+ } elseif ( $match['dtp'] == '-' ) {
2478
+ $fprice = $product['price'] - $match['amt'];
2479
+ } else {
2480
+ $fprice = $product['price'];
2481
+ }
2482
+
2483
+ if ( $fprice ) {
2484
+ $this->settings['repositories'][ $repository_id ]['data']['packages'][ $package_id ]['products'][ $product_id ]['price_disc'] = $fprice;
2485
+
2486
+ $url_glue = false !== strpos( $this->settings['repositories'][ $repository_id ]['data']['packages'][ $package_id ]['products'][ $product_id ]['url'], '?' ) ? '&' : '?';
2487
+ $cpndata = base64_encode( json_encode( array(
2488
+ 'theme_author' => $match['author_name'],
2489
+ 'theme_name' => $match['theme_name'],
2490
+ 'vlc' => $match['vlc']
2491
+ ) ) );
2492
+ $this->settings['repositories'][ $repository_id ]['data']['packages'][ $package_id ]['products'][ $product_id ]['url'] .= $url_glue . 'cpn=' . $cpndata;
2493
+
2494
+ foreach ( $product['upgrades'] as $upgrade_id => $upgrade ) {
2495
+
2496
+ $fprice = false;
2497
+ if ( $match['dtp'] == '%' ) {
2498
+ $fprice = round( $upgrade['price'] * ( 1 - $match['amt'] / 100 ), 2 );
2499
+ $fprice = $fprice != round( $fprice ) ? sprintf( '%.2f', $fprice ) : round( $fprice, 0 );
2500
+ } elseif ( $match['dtp'] == '-' ) {
2501
+ $fprice = $upgrade['price'] - $match['amt'];
2502
+ }
2503
+ if ( $fprice ) {
2504
+ $this->settings['repositories'][ $repository_id ]['data']['packages'][ $package_id ]['products'][ $product_id ]['upgrades'][ $upgrade_id ]['price_disc'] = $fprice;
2505
+ $this->settings['repositories'][ $repository_id ]['data']['packages'][ $package_id ]['products'][ $product_id ]['upgrades'][ $upgrade_id ]['url'] .= $url_glue . 'cpn=' . $cpndata;
2506
+ }
2507
+
2508
+
2509
+ }
2510
+
2511
+ }
2512
+
2513
+ }
2514
+
2515
+ }
2516
+
2517
+ }
2518
+
2519
+ }
2520
+
2521
+ public function set_hierarchy_and_order() {
2522
+
2523
+ //2 levels
2524
+ if ( ! empty( $this->settings['repositories'] ) ) {
2525
+ foreach ( $this->settings['repositories'] as $repository_id => $repository ) {
2526
+
2527
+ if ( empty( $repository['data']['packages'] ) ) {
2528
+ continue;
2529
+ }
2530
+
2531
+ $all_packages = $repository['data']['packages'];
2532
+ $ordered_packages = array();
2533
+
2534
+ //backward compatibility - 'order'
2535
+ foreach ( $all_packages as $k => $v ) {
2536
+ if ( ! isset( $v['order'] ) ) {
2537
+ $all_packages[ $k ]['order'] = 0;
2538
+ }
2539
+ }
2540
+
2541
+ //select parents
2542
+ foreach ( $all_packages as $package_id => $package ) {
2543
+ if ( empty( $package['parent'] ) ) {
2544
+ $ordered_packages[ $package_id ] = $package;
2545
+ }
2546
+ }
2547
+
2548
+ //add sub-packages
2549
+ foreach ( $all_packages as $package_id => $package ) {
2550
+ if ( ! empty( $package['parent'] ) ) {
2551
+ if ( isset( $ordered_packages[ $package['parent'] ] ) ) {
2552
+ $ordered_packages[ $package['parent'] ]['sub-packages'][ $package_id ] = $package;
2553
+ }
2554
+ }
2555
+ }
2556
+
2557
+ // order parents
2558
+ usort( $ordered_packages, array( $this, '_order_packages_callback' ) );
2559
+ //order sub-packages
2560
+ foreach ( $ordered_packages as $package_id => $package ) {
2561
+ if ( ! empty( $package['sub-packages'] ) ) {
2562
+ usort( $ordered_packages[ $package_id ]['sub-packages'], create_function( '$a, $b', 'return $a[\'order\'] > $b[\'order\'];' ) );
2563
+ }
2564
+ }
2565
+
2566
+ $this->settings['repositories'][ $repository_id ]['data']['packages'] = $ordered_packages;
2567
+
2568
+
2569
+ }
2570
+ }
2571
+
2572
+
2573
+ }
2574
+
2575
+ public function _order_packages_callback( $a, $b ) {
2576
+ return $a['order'] > $b['order'];
2577
+ }
2578
+
2579
+ public function get_support_tag_by_name( $name, $repository ) {
2580
+
2581
+ if ( is_array( $this->settings['repositories'][ $repository ]['data']['support_tags'] ) ) {
2582
+ foreach ( $this->settings['repositories'][ $repository ]['data']['support_tags'] as $support_tag ) {
2583
+ if ( $support_tag['name'] == $name ) {
2584
+ return $support_tag['url'];
2585
+ }
2586
+ }
2587
+ }
2588
+
2589
+ return false;
2590
+ }
2591
+
2592
+ public function plugin_upgrade_custom_errors() {
2593
+
2594
+ if ( isset( $_REQUEST['action'] ) ) {
2595
+
2596
+ $action = isset( $_REQUEST['action'] ) ? sanitize_text_field( $_REQUEST['action'] ) : '';
2597
+
2598
+ //bulk mode
2599
+ if ( 'update-selected' == $action ) {
2600
+
2601
+ global $plugins;
2602
+
2603
+ if ( isset( $plugins ) && is_array( $plugins ) ) {
2604
+
2605
+ foreach ( $plugins as $k => $plugin ) {
2606
+ $plugin_repository = false;
2607
+
2608
+ $wp_plugin_slug = dirname( $plugin );
2609
+
2610
+ foreach ( $this->settings['repositories'] as $repository_id => $repository ) {
2611
+
2612
+ foreach ( $repository['data']['packages'] as $package ) {
2613
+
2614
+ foreach ( $package['products'] as $product ) {
2615
+
2616
+ foreach ( $product['plugins'] as $plugin_slug ) {
2617
+
2618
+ $download = $this->settings['repositories'][ $repository_id ]['data']['downloads']['plugins'][ $plugin_slug ];
2619
+
2620
+ if ( $download['slug'] == $wp_plugin_slug ) {
2621
+ $plugin_repository = $repository_id;
2622
+ $product_name = $repository['data']['product-name'];
2623
+ $plugin_name = $download['name'];
2624
+ $free_on_wporg = ! empty( $download['free-on-wporg'] ) && $download['channel'] == WP_Installer_Channels::CHANNEL_PRODUCTION;
2625
+ break;
2626
+ }
2627
+
2628
+ }
2629
+
2630
+ }
2631
+
2632
+ }
2633
+
2634
+ }
2635
+
2636
+ if ( $plugin_repository ) {
2637
+
2638
+ //validate subscription
2639
+ static $sub_cache = array();
2640
+
2641
+ if ( empty( $sub_cache[ $plugin_repository ] ) ) {
2642
+ $site_key = $this->get_repository_site_key( $plugin_repository );
2643
+ if ( $site_key ) {
2644
+ $subscription_data = $this->fetch_subscription_data( $plugin_repository, $site_key, self::SITE_KEY_VALIDATION_SOURCE_REVALIDATION );
2645
+ }
2646
+
2647
+ $sub_cache[ $plugin_repository ]['site_key'] = $site_key;
2648
+ $sub_cache[ $plugin_repository ]['subscription_data'] = isset( $subscription_data ) ? $subscription_data : false;
2649
+ } else {
2650
+
2651
+ $site_key = $sub_cache[ $plugin_repository ]['site_key'];
2652
+ $subscription_data = $sub_cache[ $plugin_repository ]['subscription_data'];
2653
+
2654
+ }
2655
+
2656
+ if ( ! $site_key && ! empty( $free_on_wporg ) ) { // allow the download from wp.org
2657
+ continue;
2658
+ }
2659
+
2660
+ if ( empty( $site_key ) || empty( $subscription_data ) ) {
2661
+
2662
+
2663
+ $error_message = sprintf( __( "%s cannot update because your site's registration is not valid. Please %sregister %s%s again for this site first.", 'installer' ),
2664
+ '<strong>' . $plugin_name . '</strong>', '<a target="_top" href="' . $this->menu_url() . '&validate_repository=' . $plugin_repository .
2665
+ '#repository-' . $plugin_repository . '">', $product_name, '</a>' );
2666
+
2667
+ echo '<div class="updated error"><p>' . $error_message . '</p></div>';
2668
+
2669
+ unset( $plugins[ $k ] );
2670
+
2671
+
2672
+ }
2673
+
2674
+ }
2675
+
2676
+ }
2677
+
2678
+ }
2679
+
2680
+ }
2681
+
2682
+
2683
+ if ( 'upgrade-plugin' == $action || 'update-plugin' == $action ) {
2684
+
2685
+ $plugin = isset( $_REQUEST['plugin'] ) ? trim( sanitize_text_field( $_REQUEST['plugin'] ) ) : '';
2686
+
2687
+ $wp_plugin_slug = dirname( $plugin );
2688
+
2689
+ $plugin_repository = false;
2690
+
2691
+ foreach ( $this->settings['repositories'] as $repository_id => $repository ) {
2692
+
2693
+ foreach ( $repository['data']['packages'] as $package ) {
2694
+
2695
+ foreach ( $package['products'] as $product ) {
2696
+
2697
+ foreach ( $product['plugins'] as $plugin_slug ) {
2698
+ $download = $this->settings['repositories'][ $repository_id ]['data']['downloads']['plugins'][ $plugin_slug ];
2699
+
2700
+ //match by folder, will change to match by name and folder
2701
+ if ( $download['slug'] == $wp_plugin_slug ) {
2702
+ $plugin_repository = $repository_id;
2703
+ $product_name = $repository['data']['product-name'];
2704
+ $plugin_name = $download['name'];
2705
+ $free_on_wporg = ! empty( $download['free-on-wporg'] ) && $download['channel'] == WP_Installer_Channels::CHANNEL_PRODUCTION;
2706
+ break;
2707
+ }
2708
+
2709
+ }
2710
+
2711
+ }
2712
+
2713
+ }
2714
+
2715
+ }
2716
+
2717
+ if ( $plugin_repository ) {
2718
+
2719
+ //validate subscription
2720
+ $site_key = $this->get_repository_site_key( $plugin_repository );
2721
+ if ( $site_key ) {
2722
+ $subscription_data = $this->fetch_subscription_data( $plugin_repository, $site_key, self::SITE_KEY_VALIDATION_SOURCE_REVALIDATION );
2723
+ }
2724
+
2725
+ if ( ( empty( $site_key ) || empty( $subscription_data ) ) && empty( $free_on_wporg ) ) {
2726
+
2727
+ $error_message = sprintf( __( "%s cannot update because your site's registration is not valid. Please %sregister %s%s again for this site first.", 'installer' ),
2728
+ '<strong>' . $plugin_name . '</strong>', '<a href="' . $this->menu_url() . '&validate_repository=' . $plugin_repository .
2729
+ '#repository-' . $plugin_repository . '">', $product_name, '</a>' );
2730
+
2731
+ if ( defined( 'DOING_AJAX' ) ) { //WP 4.2
2732
+
2733
+ $status = array(
2734
+ 'update' => 'plugin',
2735
+ 'plugin' => $plugin,
2736
+ 'slug' => sanitize_key( $_POST['slug'] ),
2737
+ 'oldVersion' => '',
2738
+ 'newVersion' => '',
2739
+ );
2740
+
2741
+ $status['errorCode'] = 'wp_installer_invalid_subscription';
2742
+ $status['error'] = $error_message;
2743
+
2744
+ wp_send_json_error( $status );
2745
+
2746
+ } else { // WP 4.1.1
2747
+ echo '<div class="updated error"><p>' . $error_message . '</p></div>';
2748
+
2749
+
2750
+ echo '<div class="wrap">';
2751
+ echo '<h2>' . __( 'Update Plugin', 'installer' ) . '</h2>';
2752
+ echo '<a href="' . admin_url( 'plugins.php' ) . '">' . __( 'Return to the plugins page', 'installer' ) . '</a>';
2753
+ echo '</div>';
2754
+ require_once( ABSPATH . 'wp-admin/admin-footer.php' );
2755
+ exit;
2756
+
2757
+ }
2758
+
2759
+ }
2760
+
2761
+
2762
+ }
2763
+
2764
+ }
2765
+ }
2766
+
2767
+ }
2768
+
2769
+ }
vendor/otgs/installer/includes/functions-core.php ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ function WP_Installer(){
4
+ return WP_Installer::instance();
5
+ }
6
+
7
+ function WP_Installer_Channels(){
8
+ return WP_Installer_Channels::instance();
9
+ }
vendor/otgs/installer/includes/functions-templates.php ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
1
+ <?php
2
+
3
+ // Ext function
4
+ function WP_Installer_Show_Products($args = array()){
5
+ WP_Installer()->show_products($args);
6
+ }
vendor/otgs/installer/installer.php CHANGED
@@ -1,22 +1,18 @@
1
- <?php
2
- define('WP_INSTALLER_VERSION', '1.7.17');
3
-
4
- include_once dirname(__FILE__) . '/includes/installer.class.php';
5
 
6
- function WP_Installer() {
7
- return WP_Installer::instance();
8
- }
9
 
 
 
 
 
 
 
10
 
 
11
  WP_Installer();
 
12
 
13
- include_once WP_Installer()->plugin_path() . '/includes/installer-api.php';
14
- include_once WP_Installer()->plugin_path() . '/includes/translation-service-info.class.php';
15
- include_once WP_Installer()->plugin_path() . '/includes/class-installer-dependencies.php';
16
 
17
- // Ext function
18
- function WP_Installer_Show_Products($args = array()){
19
-
20
- WP_Installer()->show_products($args);
21
-
22
- }
1
+ <?php
2
+ define( 'WP_INSTALLER_VERSION', '1.8' );
 
 
3
 
4
+ include_once dirname( __FILE__ ) . '/includes/functions-core.php';
5
+ include_once dirname( __FILE__ ) . '/includes/class-wp-installer.php';
 
6
 
7
+ include_once WP_Installer()->plugin_path() . '/includes/class-wp-installer-api.php';
8
+ include_once WP_Installer()->plugin_path() . '/includes/class-translation-service-info.php';
9
+ include_once WP_Installer()->plugin_path() . '/includes/class-installer-dependencies.php';
10
+ include_once WP_Installer()->plugin_path() . '/includes/class-wp-installer-channels.php';
11
+
12
+ include_once WP_Installer()->plugin_path() . '/includes/functions-templates.php';
13
 
14
+ // Initialization
15
  WP_Installer();
16
+ WP_Installer_Channels();
17
 
 
 
 
18
 
 
 
 
 
 
 
vendor/otgs/installer/loader.php CHANGED
@@ -19,7 +19,7 @@ $wp_installer_instance = dirname(__FILE__) . '/installer.php';
19
  global $wp_installer_instances;
20
  $wp_installer_instances[$wp_installer_instance] = array(
21
  'bootfile' => $wp_installer_instance,
22
- 'version' => '1.7.17'
23
  );
24
 
25
 
19
  global $wp_installer_instances;
20
  $wp_installer_instances[$wp_installer_instance] = array(
21
  'bootfile' => $wp_installer_instance,
22
+ 'version' => '1.8'
23
  );
24
 
25
 
vendor/otgs/installer/res/css/admin.css CHANGED
@@ -11,6 +11,16 @@
11
  .installer-status-updating{color: #FF9900; }
12
  .installer-status-updated{color: #003300; font-weight: bold; }
13
 
 
 
 
 
 
 
 
 
 
 
14
  .installer-status-activating{color: #996666 }
15
  .installer-status-activated{color: #333366; font-weight: bold; }
16
 
@@ -63,8 +73,12 @@
63
  font-style: italic;
64
  }
65
 
 
 
 
 
66
  .installer-warn-box{
67
- -webkit-border-radius: 5px;-moz-border-radius: 5px;border-radius: 5px;border:1px solid #962722;background-color:#F5C8C6;
68
  color: #333;
69
  padding: 5px;
70
  }
@@ -189,6 +203,60 @@
189
  padding-left:24px;
190
  }
191
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
192
  .otgs-is-dismissible {
193
  position: relative;
194
  padding-right: 38px;
@@ -198,4 +266,24 @@
198
  }
199
  .otgs-is-dismissible p [class*="button-"] {
200
  margin: -5px 5px;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
201
  }
11
  .installer-status-updating{color: #FF9900; }
12
  .installer-status-updated{color: #003300; font-weight: bold; }
13
 
14
+ .installer-status-installed .error-details:before,
15
+ .installer-status-updated .error-details:before{
16
+ content: "\f534";
17
+ font: 200 16px/1 dashicons;
18
+ vertical-align: text-bottom;
19
+ margin-left: 5px;
20
+ color: red;
21
+ cursor: help;
22
+ }
23
+
24
  .installer-status-activating{color: #996666 }
25
  .installer-status-activated{color: #333366; font-weight: bold; }
26
 
73
  font-style: italic;
74
  }
75
 
76
+ .installer-warn-text{
77
+ color: #FF6400;
78
+ }
79
+
80
  .installer-warn-box{
81
+ -webkit-border-radius: 5px;-moz-border-radius: 5px;border-radius: 5px;border:1px solid #FF6400;background-color:#df8a48;
82
  color: #333;
83
  padding: 5px;
84
  }
203
  padding-left:24px;
204
  }
205
 
206
+ .installer-release-notes{
207
+ display: none;
208
+ }
209
+
210
+ .handle.extended:after{
211
+ content: "▾";
212
+ font-size: 24px;
213
+ vertical-align:bottom;
214
+ }
215
+ .installer-table-wrap a.handle:active,
216
+ .installer-table-wrap a.handle:focus{
217
+ outline:0;
218
+ border:none;
219
+ -moz-outline-style: none;
220
+ -webkit-box-shadow: none;
221
+ box-shadow: none;
222
+ }
223
+
224
+ .installer-release-notes .arrow_box {
225
+ position: relative;
226
+ background: #eee;
227
+ border: 1px solid #ccc;
228
+ }
229
+ .installer-release-notes .arrow_box:after, .installer-release-notes .arrow_box:before {
230
+ bottom: 100%;
231
+ left: 50%;
232
+ border: solid transparent;
233
+ content: " ";
234
+ height: 0;
235
+ width: 0;
236
+ position: absolute;
237
+ pointer-events: none;
238
+ }
239
+
240
+ .installer-release-notes .arrow_box:after {
241
+ border-color: rgba(238, 238, 238, 0);
242
+ border-bottom-color: #eee;
243
+ border-width: 16px;
244
+ margin-left: -16px;
245
+ }
246
+ .installer-release-notes .arrow_box:before {
247
+ border-color: rgba(204, 204, 204, 0);
248
+ border-bottom-color: #ccc;
249
+ border-width: 17px;
250
+ margin-left: -17px;
251
+ }
252
+
253
+ .installer-release-notes .arrow_box div{
254
+ margin-top:5px;
255
+ padding: 10px;
256
+ overflow-y: auto;
257
+ max-height: 400px;
258
+ }
259
+
260
  .otgs-is-dismissible {
261
  position: relative;
262
  padding-right: 38px;
266
  }
267
  .otgs-is-dismissible p [class*="button-"] {
268
  margin: -5px 5px;
269
+ }
270
+
271
+ .otgsi_downloads_form{
272
+ margin-top: 15px;
273
+ }
274
+
275
+ .spinner-with-text{
276
+ padding-left: 25px;
277
+ float:none;
278
+ width: auto;
279
+ }
280
+ .installer-channel-update-ok{
281
+ padding-left: 10px;
282
+ display: none;
283
+ color: #006600;
284
+ }
285
+ .installer-channel-update-fail{
286
+ padding-left: 10px;
287
+ display: none;
288
+ color: #962722;
289
  }
vendor/otgs/installer/res/js/admin.js CHANGED
@@ -1,5 +1,9 @@
 
 
1
  var otgs_wp_installer = {
2
-
 
 
3
  init: function(){
4
 
5
  jQuery('.otgs_wp_installer_table').on('click', '.enter_site_key_js', otgs_wp_installer.show_site_key_form);
@@ -38,6 +42,7 @@
38
  jQuery( '.plugin-install-tab-commercial .search-plugins' ).remove();
39
  }
40
 
 
41
  },
42
 
43
  getQueryParameters : function(str) {
@@ -258,9 +263,14 @@
258
  }
259
 
260
 
261
- data = {action: 'installer_download_plugin', data: elem.val(), activate: activate}
 
 
 
 
 
262
 
263
- jQuery.ajax({
264
  url: ajaxurl,
265
  type: 'POST',
266
  dataType: 'json',
@@ -270,22 +280,35 @@
270
 
271
  if(!ret.success){
272
  installed.addClass('installer-status-error');
273
- installed.html(installed.data('fail'));
 
 
 
274
 
275
  if(ret.message){
276
- installed.closest('.otgs_wp_installer_table').find('.installer-error-box').html('<p>' + ret.message + '</p>').show();
 
 
 
277
  }else{
278
- installed.closest('.otgs_wp_installer_table').find('.installer-error-box').html('<p>' + downloads_form.find('.installer-revalidate-message').html() + '</p>').show();
 
 
 
279
  }
280
 
281
-
282
  }
283
 
284
  installed.show();
285
  spinner.fadeOut();
286
 
287
  if(ret.version){
288
- this_tr.find('.installer_version_installed').html('<span class="installer-green-text">' + ret.version + '</span>');
 
 
 
 
289
  }
290
 
291
  if(ret.success && activate){
@@ -315,6 +338,8 @@
315
  otgs_wp_installer.hide_download_progress_status(downloads_form);
316
  downloads_form.find('div.installer-status-success').show();
317
  action_button.removeAttr('disabled');
 
 
318
  }
319
  }
320
  });
@@ -326,6 +351,9 @@
326
  otgs_wp_installer.hide_download_progress_status(downloads_form);
327
  downloads_form.find('div.installer-status-success').show();
328
  action_button.removeAttr('disabled');
 
 
 
329
  }
330
  }
331
  }
@@ -336,8 +364,7 @@
336
 
337
  return false;
338
  },
339
-
340
-
341
  show_download_progress_status: function(downloads_form, text){
342
 
343
  downloads_form.find('.installer-download-progress-status').html(text).fadeIn();
@@ -412,8 +439,21 @@
412
 
413
  }
414
 
415
- }
 
 
 
 
 
 
 
 
 
 
416
 
 
 
 
417
 
418
  }
419
 
1
+
2
+
3
  var otgs_wp_installer = {
4
+
5
+ plugins_update_XHR :{},
6
+
7
  init: function(){
8
 
9
  jQuery('.otgs_wp_installer_table').on('click', '.enter_site_key_js', otgs_wp_installer.show_site_key_form);
42
  jQuery( '.plugin-install-tab-commercial .search-plugins' ).remove();
43
  }
44
 
45
+ jQuery('.installer-table-wrap').on('click', '.js-release-notes', otgs_wp_installer.toggle_release_notes);
46
  },
47
 
48
  getQueryParameters : function(str) {
263
  }
264
 
265
 
266
+ data = {
267
+ action: 'installer_download_plugin',
268
+ data: elem.val(),
269
+ activate: activate,
270
+ reset_to_channel: downloads_form.find('input[name="reset-to-channel"]').val()
271
+ }
272
 
273
+ otgs_wp_installer.plugins_update_XHR = jQuery.ajax({
274
  url: ajaxurl,
275
  type: 'POST',
276
  dataType: 'json',
280
 
281
  if(!ret.success){
282
  installed.addClass('installer-status-error');
283
+ installed.html(
284
+ installed.data('fail') +
285
+ '<a class="error-details" href="#" title="' + ret.message + '"></a>'
286
+ );
287
 
288
  if(ret.message){
289
+ installed.closest('.otgs_wp_installer_table')
290
+ .find('.installer-error-box')
291
+ .html('<p>' + ret.message + '</p>')
292
+ .show();
293
  }else{
294
+ installed.closest('.otgs_wp_installer_table')
295
+ .find('.installer-error-box')
296
+ .html('<p>' + downloads_form.find('.installer-revalidate-message').html() + '</p>')
297
+ .show();
298
  }
299
 
300
+ downloads_form.trigger('installer-update-fail');
301
  }
302
 
303
  installed.show();
304
  spinner.fadeOut();
305
 
306
  if(ret.version){
307
+ var updated_version = '<span class="installer-green-text">' + ret.version + '</span>';
308
+ if( ret.non_stable ){
309
+ updated_version += ' (' + ret.non_stable + ')';
310
+ }
311
+ this_tr.find('.installer_version_installed').html(updated_version);
312
  }
313
 
314
  if(ret.success && activate){
338
  otgs_wp_installer.hide_download_progress_status(downloads_form);
339
  downloads_form.find('div.installer-status-success').show();
340
  action_button.removeAttr('disabled');
341
+
342
+ downloads_form.trigger('installer-update-complete');
343
  }
344
  }
345
  });
351
  otgs_wp_installer.hide_download_progress_status(downloads_form);
352
  downloads_form.find('div.installer-status-success').show();
353
  action_button.removeAttr('disabled');
354
+
355
+ downloads_form.trigger('installer-update-complete');
356
+
357
  }
358
  }
359
  }
364
 
365
  return false;
366
  },
367
+
 
368
  show_download_progress_status: function(downloads_form, text){
369
 
370
  downloads_form.find('.installer-download-progress-status').html(text).fadeIn();
439
 
440
  }
441
 
442
+ },
443
+
444
+ toggle_release_notes: function(){
445
+ var handle = jQuery(this);
446
+ var tr = handle.closest('tr');
447
+ if( tr.next('.installer-release-notes').is(':visible') ){
448
+ handle.removeClass('extended');
449
+ }else{
450
+ handle.addClass('extended');
451
+ }
452
+ tr.next('.installer-release-notes').fadeToggle();
453
 
454
+ return false;
455
+ }
456
+
457
 
458
  }
459
 
vendor/otgs/installer/res/js/channels.js ADDED
@@ -0,0 +1,261 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ (function($){
2
+
3
+ var updateErrors = [];
4
+ var channelUpdateInProgress = false;
5
+
6
+ function channelSelectorInit(){
7
+
8
+ $('.otgs_wp_installer_table')
9
+ .on('focus', '.installer-channel-selector', saveCurrentValue)
10
+ .on('change', '.installer-channel-selector', maybeShowPrompt);
11
+
12
+ $('.otgs_wp_installer_table')
13
+ .on('click', '.installer-channel-retry', retryChannelSwitch)
14
+
15
+ $('.installer-switch-confirmation')
16
+ .on('click', '.js-cancel', cancelSwitch)
17
+ .on('click', '.js-proceed', changeChannel);
18
+
19
+ $('.otgsi_downloads_form').on('installer-update-complete', maybeShowWarn);
20
+ $('.otgsi_downloads_form').on('installer-update-complete', hideUpdateProgress);
21
+
22
+ $('.otgsi_downloads_form').on('installer-update-complete', showConfirmationMessage);
23
+
24
+ $('.otgsi_downloads_form').on('installer-update-fail', logUpdateError);
25
+
26
+ }
27
+
28
+ function saveCurrentValue(){
29
+ $(this).data('previous-value', $(this).val());
30
+ }
31
+
32
+ function maybeShowPrompt(){
33
+ var selectorContainer = $(this).closest('.installer-channel-selector-wrap');
34
+ var prompt = selectorContainer.find('.installer-switch-confirmation:hidden');
35
+
36
+ if(prompt.length){
37
+ prompt.show();
38
+ selectorContainer.find('select').prop('disabled', true);
39
+ var warnText = selectorContainer.find('.installer-warn-text');
40
+ warnText.hide();
41
+ }else{
42
+ changeChannel(selectorContainer);
43
+ }
44
+
45
+ }
46
+
47
+ function changeChannel(selectorContainer){
48
+
49
+ if(selectorContainer.type == 'click'){
50
+ var selectorContainer = $(this).closest('.installer-channel-selector-wrap');
51
+ }
52
+
53
+ var select = selectorContainer.find('select');
54
+ select.prop('disabled', true);
55
+
56
+ hideConfirmationMessage(select);
57
+ showUpdateProgress(select);
58
+
59
+ selectorContainer.find('.installer-switch-confirmation').hide();
60
+
61
+ var data = {
62
+ action: 'installer_set_channel',
63
+ repository_id: select.data('repository-id'),
64
+ channel: select.val(),
65
+ nonce: select.parent().find('.nonce').val(),
66
+ noprompt: selectorContainer.find('.js-remember').length ?
67
+ selectorContainer.find('.js-remember').attr('checked') == 'checked' : 0
68
+ }
69
+
70
+ resetUpdateErrors();
71
+ otgs_wp_installer.reset_errors();
72
+ channelUpdateInProgress = true;
73
+
74
+ // save selection
75
+ jQuery.ajax({
76
+ url: ajaxurl,
77
+ type: 'POST',
78
+ dataType: 'json',
79
+ data: data,
80
+ success: function (ret) {
81
+ if( ret.status == 'OK'){
82
+ var tableSelector = '#installer_repo_' + select.data('repository-id') + ' .installer-table-wrap';
83
+ $(tableSelector).load( location.href + ' ' + tableSelector + ' table.widefat', function(){
84
+
85
+ var upgradesCount = $(tableSelector).find('tr .installer-red-text').length
86
+ || select.val() == 1 && $(tableSelector).find('td.installer_version_installed .unstable').length;
87
+ if( upgradesCount > 0){
88
+ automaticUpgrade(tableSelector);
89
+ }else{
90
+ $('#installer_repo_' + select.data('repository-id') + ' .otgsi_downloads_form')
91
+ .trigger('installer-update-complete');
92
+ }
93
+
94
+ select.prop('disabled', false);
95
+ } );
96
+ }
97
+
98
+ }
99
+
100
+ });
101
+
102
+ }
103
+
104
+ function retryChannelSwitch(){
105
+ var selectorContainer = $(this).closest('.installer-channel-selector-wrap');
106
+ changeChannel(selectorContainer);
107
+ return false;
108
+ }
109
+
110
+ function cancelSwitch(){
111
+ $(this).closest('.installer-switch-confirmation').hide();
112
+ var select = $(this).closest('.installer-switch-confirmation').prev().find('.installer-channel-selector');
113
+ var previousValue = select.data('previous-value');
114
+
115
+ select.val(previousValue).prop('disabled', false);
116
+
117
+ if( select.val() > 1){
118
+ var selectorContainer = $(this).closest('.installer-channel-selector-wrap');
119
+ var warnText = selectorContainer.find('.installer-warn-text');
120
+ warnText.show();
121
+ }
122
+
123
+ }
124
+
125
+ function automaticUpgrade(downloadsTable){
126
+ $(downloadsTable + ' tr').each(
127
+ function () {
128
+ var needsUpgrade = $(this).find(
129
+ 'td.installer_version_installed .installer-red-text, ' +
130
+ 'td.installer_version_installed .unstable'
131
+ ).length > 0;
132
+ if (needsUpgrade) {
133
+ $(this).find('td :checkbox').prop('disabled', false).prop('checked', true);
134
+ }
135
+ }
136
+ );
137
+
138
+ $(downloadsTable)
139
+ .closest('form')
140
+ .append('<input type="hidden" name="reset-to-channel" value="1">')
141
+ .submit();
142
+
143
+ }
144
+
145
+ function maybeShowWarn(){
146
+
147
+ var select = $(this)
148
+ .closest('.otgs_wp_installer_table')
149
+ .find('.installer-channel-selector')
150
+
151
+ if(select.val() > 1 && !hasUpdateErrors()){
152
+
153
+ var warnText = select
154
+ .closest('.installer-channel-selector-wrap')
155
+ .find('.installer-warn-text');
156
+ warnText.show();
157
+
158
+ }
159
+
160
+
161
+ }
162
+
163
+ function showUpdateProgress(select){
164
+
165
+ var spinner = select
166
+ .closest('.installer-channel-selector-wrap')
167
+ .find('.spinner-with-text');
168
+
169
+ spinner.addClass('is-active').show();
170
+
171
+ }
172
+
173
+ function hideUpdateProgress(){
174
+
175
+ var spinner = $(this)
176
+ .closest('.otgs_wp_installer_table')
177
+ .find('.installer-channel-selector-wrap')
178
+ .find('.spinner-with-text');
179
+
180
+ spinner.removeClass('is-active').hide();
181
+
182
+ }
183
+
184
+ function showConfirmationMessage(){
185
+
186
+ if( ! channelUpdateInProgress ) return false;
187
+
188
+ var selectWrap = $(this)
189
+ .closest('.otgs_wp_installer_table')
190
+ .find('.installer-channel-selector-wrap');
191
+
192
+ var select = $(this)
193
+ .closest('.otgs_wp_installer_table')
194
+ .find('.installer-channel-selector');
195
+
196
+ var channelName = select.find('option:selected').text();
197
+
198
+ if( hasUpdateErrors() ) {
199
+
200
+ var message = selectWrap.find('.installer-channel-update-fail');
201
+ // suppress default errors
202
+ $(this).closest('.otgs_wp_installer_table').find('.installer-error-box').hide();
203
+
204
+ var channelType = select.val() == 1 ? 'stable' : 'unstable';
205
+ message.html(message.data('text-' + channelType).replace(/%CHANNEL%/, channelName));
206
+
207
+ }else{
208
+
209
+ var message = selectWrap.find('.installer-channel-update-ok');
210
+ message.html(message.data('text').replace(/%CHANNEL%/, channelName));
211
+ }
212
+
213
+ message.show();
214
+
215
+ channelUpdateInProgress = false;
216
+ }
217
+
218
+ function hideConfirmationMessage(select){
219
+
220
+ var selectWrap = select.closest('.installer-channel-selector-wrap');
221
+ if( hasUpdateErrors() ){
222
+ var message = selectWrap.find('.installer-channel-update-fail');
223
+ }else{
224
+ var message = selectWrap.find('.installer-channel-update-ok');
225
+ }
226
+
227
+ message.hide();
228
+ }
229
+
230
+ /*
231
+ function showFailureMessage(download_form){
232
+ var message = download_form
233
+ .closest('.otgs_wp_installer_table')
234
+ .find('.installer-channel-selector-wrap')
235
+ .find('.installer-channel-update-fail');
236
+
237
+ var channelName = $(this)
238
+ .closest('.otgs_wp_installer_table')
239
+ .find('.installer-channel-selector option:selected')
240
+ .text();
241
+
242
+ message.html( message.data('text').replace(/%CHANNEL%/, channelName) );
243
+ message.show();
244
+ }
245
+ */
246
+
247
+ function logUpdateError(){
248
+ updateErrors.push(1);
249
+ }
250
+
251
+ function resetUpdateErrors(){
252
+ updateErrors = [];
253
+ }
254
+
255
+ function hasUpdateErrors() {
256
+ return updateErrors.length;
257
+ }
258
+
259
+ $(document).ready( channelSelectorInit );
260
+
261
+ })(jQuery)
vendor/otgs/installer/templates/channel-selector.php ADDED
@@ -0,0 +1,68 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <div class="installer-channel-selector-wrap">
2
+ <label>
3
+ <?php esc_html_e('Updates channel:', 'installer'); ?>
4
+ <select class="installer-channel-selector" data-repository-id="<?php echo $repository_id ?>"<?php if( !$can_switch ): ?> disabled<?php endif ?>>
5
+ <?php foreach( $channels as $channel_id => $channel_name ): ?>
6
+ <option value="<?php echo $channel_id ?>" <?php
7
+ if( $channel_id == $current_channel ): ?>selected="selected"<?php
8
+ endif; ?>><?php echo $channel_name ?></option>
9
+ <?php endforeach ?>
10
+ </select>
11
+ <span class="installer-status-note" <?php if( $can_switch ): ?>style="display:none" <?php endif; ?>>
12
+ <?php _e("To select different update channels (beta, development) you must update your existing products to their most recent stable versions.", 'installer') ?>
13
+ </span>
14
+ <span class="spinner spinner-with-text">
15
+ <?php _e( "Updating the plugins on your site. Please don't close this page or navigate away.", 'installer' ); ?>
16
+ </span>
17
+ <span class="installer-channel-update-ok" data-text="<?php
18
+ esc_attr_e( sprintf("Update completed. You are now using the %s channel of %s.",
19
+ '%CHANNEL%', WP_Installer()->get_generic_product_name( $repository_id ) ) ) ?>">
20
+ </span>
21
+ <span class="installer-channel-update-fail" data-text-unstable="<?php
22
+ $support_url = $repository_id ==='toolset' ? 'https://wp-types.com/forums/forum/support-2/' : 'https://wpml.org/forums/forum/english-support/';
23
+ $download_url = $repository_id ==='toolset' ? 'https://wp-types.com/account/downloads/' : 'https://wpml.org/account/downloads/';
24
+ echo esc_attr( sprintf(
25
+ __( "Something went wrong and we could not install all updates from the %s channel. Click here to %stry again%s. If the errors persist, please switch back to the Production channel and contact the %s%s support%s.", 'installer' ),
26
+ '%CHANNEL%',
27
+ '<a href="#" class="installer-channel-retry"><strong>',
28
+ '</strong></a>',
29
+ '<a href="' . $support_url . '">', WP_Installer()->get_generic_product_name( $repository_id ), '</a>'
30
+ ) );
31
+ ?>" data-text-stable="<?php
32
+ echo esc_attr( sprintf(
33
+ esc_attr__( "There was a problem switching to the %s channel. You can %sretry%s. If the problem continues, please %sdownload %s%s and install again manually", 'installer' ),
34
+ '%CHANNEL%',
35
+ '<a href="#" class="installer-channel-retry"><strong>',
36
+ '</strong></a>',
37
+ '<a href="' . $download_url . '">', WP_Installer()->get_generic_product_name( $repository_id ), '</a>'
38
+ ) );
39
+ ?>">
40
+ </span>
41
+ <input type="hidden" class="nonce" value="<?php echo $nonce ?>" />
42
+ </label>
43
+
44
+ <?php if( !$no_prompt ): ?>
45
+ <div class="installer-warn-box installer-switch-confirmation" style="margin-top: 10px; display: none">
46
+ <p class="alignright">
47
+ <button class="button-secondary js-cancel"><?php _e("Cancel", 'installer') ?></button>
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; ?>
59
+
60
+ <div class="installer-warn-text" <?php if( WP_Installer_Channels()->get_channel( $repository_id ) <= 1 ): ?>style="display:none" <?php endif; ?>>
61
+ <?php printf(
62
+ __("You are using a potentially less stable channel for %s. If you didn't enable this on purpose, you should switch to the 'Production' channel.", 'installer'),
63
+ WP_Installer()->get_generic_product_name( $repository_id )
64
+ );
65
+ ?>
66
+ </div>
67
+
68
+ </div>
vendor/otgs/installer/templates/downloads-list.php CHANGED
@@ -1,16 +1,16 @@
1
- <br clear="all" /><br />
2
- <strong><?php _e('Downloads:', 'installer') ?></strong>
3
-
4
  <form method="post" class="otgsi_downloads_form">
5
-
6
- <table class="widefat">
 
7
  <thead>
8
  <tr>
9
  <th>&nbsp;</th>
10
  <th><?php _e('Plugin', 'installer') ?></th>
11
- <th><?php _e('Current version', 'installer') ?></th>
 
12
  <th><?php _e('Released', 'installer') ?></th>
13
- <th><?php _e('Installed version', 'installer') ?></th>
14
  <th>&nbsp;</th>
15
  <th>&nbsp;</th>
16
  <th>&nbsp;</th>
@@ -18,7 +18,7 @@
18
  </thead>
19
  <tbody>
20
  <?php
21
- foreach($package['downloads'] as $download): ?>
22
  <tr>
23
  <td>
24
  <label>
@@ -33,19 +33,34 @@
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']) && !$this->plugin_is_embedded_version($download['name'], $download['slug']) || WP_Installer()->dependencies->cant_download($repository_id) ): ?>disabled="disabled"<?php endif; ?> />&nbsp;
37
-
 
38
  </label>
39
  </td>
40
  <td class="installer_plugin_name"><?php echo $download['name'] ?></td>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
41
  <td><?php echo $download['version'] ?></td>
42
  <td><?php echo date_i18n('F j, Y', strtotime($download['date'])) ?></td>
43
- <td class="installer_version_installed">
44
- <?php if($v = $this->plugin_is_installed($download['name'], $download['slug'])): $class = version_compare($v, $download['version'], '>=') ? 'installer-green-text' : 'installer-red-text'; ?>
45
- <span class="<?php echo $class ?>"><?php echo $v; ?></span>
46
- <?php if($this->plugin_is_embedded_version($download['name'], $download['slug'])): ?>&nbsp;<?php _e('(embedded)', 'installer'); ?><?php endif; ?>
47
  <?php endif; ?>
48
- </td>
49
  <td>
50
  <span class="installer-status-installing"><?php _e('installing...', 'installer') ?></span>
51
  <span class="installer-status-updating"><?php _e('updating...', 'installer') ?></span>
@@ -58,10 +73,19 @@
58
  </td>
59
  <td class="for_spinner_js"><span class="spinner"></span></td>
60
  </tr>
 
 
 
 
 
 
 
 
 
61
  <?php endforeach; ?>
62
  </tbody>
63
  </table>
64
-
65
  <br />
66
 
67
  <div class="installer-error-box">
1
+
 
 
2
  <form method="post" class="otgsi_downloads_form">
3
+
4
+ <div class="installer-table-wrap">
5
+ <table class="widefat">
6
  <thead>
7
  <tr>
8
  <th>&nbsp;</th>
9
  <th><?php _e('Plugin', 'installer') ?></th>
10
+ <th><?php _e('Installed', 'installer') ?></th>
11
+ <th><?php _e('Current', 'installer') ?></th>
12
  <th><?php _e('Released', 'installer') ?></th>
13
+ <th>&nbsp;</th>
14
  <th>&nbsp;</th>
15
  <th>&nbsp;</th>
16
  <th>&nbsp;</th>
18
  </thead>
19
  <tbody>
20
  <?php
21
+ foreach($package['downloads'] as $download_id => $download): ?>
22
  <tr>
23
  <td>
24
  <label>
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;
39
  </label>
40
  </td>
41
  <td class="installer_plugin_name"><?php echo $download['name'] ?></td>
42
+ <td class="installer_version_installed">
43
+ <?php if ( $v = $this->plugin_is_installed( $download['name'], $download['slug'] ) ): ?>
44
+ <?php
45
+ $class = version_compare( $v, $download['version'], '>=' ) ? 'installer-green-text' : 'installer-red-text';
46
+ $class .= version_compare( $v, $download['version'], '>' ) ? ' unstable' : '';
47
+ ?>
48
+ <span class="<?php echo $class ?>"><?php echo $v; ?></span>
49
+ <?php if ( $this->plugin_is_embedded_version( $download['name'], $download['slug'] ) ): ?>&nbsp;<?php _e( '(embedded)', 'installer' ); ?><?php endif; ?>
50
+ <?php if(
51
+ WP_Installer_Channels()->get_channel( $repository_id ) !== WP_Installer_Channels::CHANNEL_PRODUCTION &&
52
+ $non_stable = WP_Installer_Channels()->get_download_source_channel( $v, $repository_id, $download_id, 'plugins')
53
+ ) : ?>
54
+ (<?php echo $non_stable ?>)
55
+ <?php endif; ?>
56
+ <?php endif; ?>
57
+ </td>
58
  <td><?php echo $download['version'] ?></td>
59
  <td><?php echo date_i18n('F j, Y', strtotime($download['date'])) ?></td>
60
+ <td>
61
+ <?php if ( !empty( $download['release-notes'] ) ): ?>
62
+ <a class="js-release-notes handle" href="#">Release notes</a></td>
 
63
  <?php endif; ?>
 
64
  <td>
65
  <span class="installer-status-installing"><?php _e('installing...', 'installer') ?></span>
66
  <span class="installer-status-updating"><?php _e('updating...', 'installer') ?></span>
73
  </td>
74
  <td class="for_spinner_js"><span class="spinner"></span></td>
75
  </tr>
76
+ <?php if ( !empty( $download['release-notes'] ) ): ?>
77
+ <tr class="installer-release-notes">
78
+ <td colspan="9">
79
+ <div class="arrow_box">
80
+ <div><?php echo force_balance_tags( $download['release-notes'] ) ?></div>
81
+ </div>
82
+ </td>
83
+ </tr>
84
+ <?php endif; ?>
85
  <?php endforeach; ?>
86
  </tbody>
87
  </table>
88
+ </div>
89
  <br />
90
 
91
  <div class="installer-error-box">
vendor/otgs/installer/templates/repository-listing.php CHANGED
@@ -137,9 +137,12 @@
137
  <?php endforeach; ?>
138
  <?php endif; ?>
139
 
140
- <?php if($package['downloads']): ?>
141
- <?php include $this->plugin_path() . '/templates/downloads-list.php'; ?>
142
- <?php endif; ?>
 
 
 
143
 
144
  <?php if(!empty($package['sub-packages'])): ?>
145
 
137
  <?php endforeach; ?>
138
  <?php endif; ?>
139
 
140
+ <?php
141
+ if ( $package['downloads'] ) {
142
+ WP_Installer_Channels()->load_channel_selector( $repository_id, $package['downloads'] );
143
+ include $this->plugin_path() . '/templates/downloads-list.php';
144
+ }
145
+ ?>
146
 
147
  <?php if(!empty($package['sub-packages'])): ?>
148
 
vendor/twig/twig/CHANGELOG CHANGED
@@ -1,6 +1,36 @@
1
- * 1.33.1 (2017-XX-XX)
2
 
3
- * n/a
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4
 
5
  * 1.33.0 (2017-03-22)
6
 
1
+ * 1.34.4 (2017-XX-XX)
2
 
3
+ * fixed deprecation when using Twig_Profiler_Dumper_Html
4
+
5
+ * 1.34.3 (2017-06-07)
6
+
7
+ * fixed namespaces introduction
8
+
9
+ * 1.34.2 (2017-06-05)
10
+
11
+ * fixed namespaces introduction
12
+
13
+ * 1.34.1 (2017-06-05)
14
+
15
+ * fixed namespaces introduction
16
+
17
+ * 1.34.0 (2017-06-05)
18
+
19
+ * added support for PHPUnit 6 when testing extensions
20
+ * fixed PHP 7.2 compatibility
21
+ * fixed template name generation in Twig_Environment::createTemplate()
22
+ * removed final tag on Twig_TokenParser_Include
23
+ * added namespaced aliases for all (non-deprecated) classes and interfaces
24
+ * dropped HHVM support
25
+ * dropped PHP 5.2 support
26
+
27
+ * 1.33.2 (2017-04-20)
28
+
29
+ * fixed edge case in the method cache for Twig attributes
30
+
31
+ * 1.33.1 (2017-04-18)
32
+
33
+ * fixed the empty() test
34
 
35
  * 1.33.0 (2017-03-22)
36
 
vendor/twig/twig/ext/twig/php_twig.h CHANGED
@@ -15,7 +15,7 @@
15
  #ifndef PHP_TWIG_H
16
  #define PHP_TWIG_H
17
 
18
- #define PHP_TWIG_VERSION "1.33.1-DEV"
19
 
20
  #include "php.h"
21
 
15
  #ifndef PHP_TWIG_H
16
  #define PHP_TWIG_H
17
 
18
+ #define PHP_TWIG_VERSION "1.34.4-DEV"
19
 
20
  #include "php.h"
21
 
vendor/twig/twig/lib/Twig/BaseNodeVisitor.php CHANGED
@@ -48,3 +48,7 @@ abstract class Twig_BaseNodeVisitor implements Twig_NodeVisitorInterface
48
  */
49
  abstract protected function doLeaveNode(Twig_Node $node, Twig_Environment $env);
50
  }
 
 
 
 
48
  */
49
  abstract protected function doLeaveNode(Twig_Node $node, Twig_Environment $env);
50
  }
51
+
52
+ class_alias('Twig_BaseNodeVisitor', 'Twig\NodeVisitor\AbstractNodeVisitor', false);
53
+ class_exists('Twig_Environment');
54
+ class_exists('Twig_Node');
vendor/twig/twig/lib/Twig/Cache/Filesystem.php CHANGED
@@ -89,3 +89,5 @@ class Twig_Cache_Filesystem implements Twig_CacheInterface
89
  return (int) @filemtime($key);
90
  }
91
  }
 
 
89
  return (int) @filemtime($key);
90
  }
91
  }
92
+
93
+ class_alias('Twig_Cache_Filesystem', 'Twig\Cache\FilesystemCache', false);
vendor/twig/twig/lib/Twig/Cache/Null.php CHANGED
@@ -36,3 +36,5 @@ class Twig_Cache_Null implements Twig_CacheInterface
36
  return 0;
37
  }
38
  }
 
 
36
  return 0;
37
  }
38
  }
39
+
40
+ class_alias('Twig_Cache_Null', 'Twig\Cache\NullCache', false);
vendor/twig/twig/lib/Twig/CacheInterface.php CHANGED
@@ -54,3 +54,5 @@ interface Twig_CacheInterface
54
  */
55
  public function getTimestamp($key);
56
  }
 
 
54
  */
55
  public function getTimestamp($key);
56
  }
57
+
58
+ class_alias('Twig_CacheInterface', 'Twig\Cache\CacheInterface', false);
vendor/twig/twig/lib/Twig/Compiler.php CHANGED
@@ -279,3 +279,6 @@ class Twig_Compiler implements Twig_CompilerInterface
279
  return sprintf('__internal_%s', hash('sha256', uniqid(mt_rand(), true), false));
280
  }
281
  }
 
 
 
279
  return sprintf('__internal_%s', hash('sha256', uniqid(mt_rand(), true), false));
280
  }
281
  }
282
+
283
+ class_alias('Twig_Compiler', 'Twig\Compiler', false);
284
+ class_exists('Twig_Node');
vendor/twig/twig/lib/Twig/ContainerRuntimeLoader.php CHANGED
@@ -35,3 +35,5 @@ class Twig_ContainerRuntimeLoader implements Twig_RuntimeLoaderInterface
35
  }
36
  }
37
  }
 
 
35
  }
36
  }
37
  }
38
+
39
+ class_alias('Twig_ContainerRuntimeLoader', 'Twig\RuntimeLoader\ContainerRuntimeLoader', false);
vendor/twig/twig/lib/Twig/Environment.php CHANGED
@@ -16,11 +16,11 @@
16
  */
17
  class Twig_Environment
18
  {
19
- const VERSION = '1.33.1';
20
- const VERSION_ID = 13301;
21
  const MAJOR_VERSION = 1;
22
- const MINOR_VERSION = 33;
23
- const RELEASE_VERSION = 1;
24
  const EXTRA_VERSION = 'DEV';
25
 
26
  protected $charset;
@@ -489,7 +489,7 @@ class Twig_Environment
489
  */
490
  public function createTemplate($template)
491
  {
492
- $name = sprintf('__string_template__%s', hash('sha256', uniqid(mt_rand(), true), false));
493
 
494
  $loader = new Twig_Loader_Chain(array(
495
  new Twig_Loader_Array(array($name => $template)),
@@ -758,7 +758,7 @@ class Twig_Environment
758
 
759
  public function setLoader(Twig_LoaderInterface $loader)
760
  {
761
- if (!$loader instanceof Twig_SourceContextLoaderInterface && 0 !== strpos(get_class($loader), 'Mock_Twig_LoaderInterface')) {
762
  @trigger_error(sprintf('Twig loader "%s" should implement Twig_SourceContextLoaderInterface since version 1.27.', get_class($loader)), E_USER_DEPRECATED);
763
  }
764
 
@@ -831,6 +831,12 @@ class Twig_Environment
831
  public function hasExtension($class)
832
  {
833
  $class = ltrim($class, '\\');
 
 
 
 
 
 
834
  if (isset($this->extensions[$class])) {
835
  if ($class !== get_class($this->extensions[$class])) {
836
  @trigger_error(sprintf('Referencing the "%s" extension by its name (defined by getName()) is deprecated since 1.26 and will be removed in Twig 2.0. Use the Fully Qualified Extension Class Name instead.', $class), E_USER_DEPRECATED);
@@ -860,6 +866,11 @@ class Twig_Environment
860
  public function getExtension($class)
861
  {
862
  $class = ltrim($class, '\\');
 
 
 
 
 
863
 
864
  if (isset($this->extensions[$class])) {
865
  if ($class !== get_class($this->extensions[$class])) {
@@ -938,6 +949,12 @@ class Twig_Environment
938
  }
939
 
940
  $class = ltrim($name, '\\');
 
 
 
 
 
 
941
  if (isset($this->extensions[$class])) {
942
  if ($class !== get_class($this->extensions[$class])) {
943
  @trigger_error(sprintf('Referencing the "%s" extension by its name (defined by getName()) is deprecated since 1.26 and will be removed in Twig 2.0. Use the Fully Qualified Extension Class Name instead.', $class), E_USER_DEPRECATED);
@@ -1559,3 +1576,5 @@ class Twig_Environment
1559
  $this->optionsHash = implode(':', $hashParts);
1560
  }
1561
  }
 
 
16
  */
17
  class Twig_Environment
18
  {
19
+ const VERSION = '1.34.4-DEV';
20
+ const VERSION_ID = 13404;
21
  const MAJOR_VERSION = 1;
22
+ const MINOR_VERSION = 34;
23
+ const RELEASE_VERSION = 4;
24
  const EXTRA_VERSION = 'DEV';
25
 
26
  protected $charset;
489
  */
490
  public function createTemplate($template)
491
  {
492
+ $name = sprintf('__string_template__%s', hash('sha256', $template, false));
493
 
494
  $loader = new Twig_Loader_Chain(array(
495
  new Twig_Loader_Array(array($name => $template)),
758
 
759
  public function setLoader(Twig_LoaderInterface $loader)
760
  {
761
+ if (!$loader instanceof Twig_SourceContextLoaderInterface && 0 !== strpos(get_class($loader), 'Mock_')) {
762
  @trigger_error(sprintf('Twig loader "%s" should implement Twig_SourceContextLoaderInterface since version 1.27.', get_class($loader)), E_USER_DEPRECATED);
763
  }
764
 
831
  public function hasExtension($class)
832
  {
833
  $class = ltrim($class, '\\');
834
+ if (!isset($this->extensionsByClass[$class]) && class_exists($class, false)) {
835
+ // For BC/FC with namespaced aliases
836
+ $class = new ReflectionClass($class);
837
+ $class = $class->name;
838
+ }
839
+
840
  if (isset($this->extensions[$class])) {
841
  if ($class !== get_class($this->extensions[$class])) {
842
  @trigger_error(sprintf('Referencing the "%s" extension by its name (defined by getName()) is deprecated since 1.26 and will be removed in Twig 2.0. Use the Fully Qualified Extension Class Name instead.', $class), E_USER_DEPRECATED);
866
  public function getExtension($class)
867
  {
868
  $class = ltrim($class, '\\');
869
+ if (!isset($this->extensionsByClass[$class]) && class_exists($class, false)) {
870
+ // For BC/FC with namespaced aliases
871
+ $class = new ReflectionClass($class);
872
+ $class = $class->name;
873
+ }
874
 
875
  if (isset($this->extensions[$class])) {
876
  if ($class !== get_class($this->extensions[$class])) {
949
  }
950
 
951
  $class = ltrim($name, '\\');
952
+ if (!isset($this->extensionsByClass[$class]) && class_exists($class, false)) {
953
+ // For BC/FC with namespaced aliases
954
+ $class = new ReflectionClass($class);
955
+ $class = $class->name;
956
+ }
957
+
958
  if (isset($this->extensions[$class])) {
959
  if ($class !== get_class($this->extensions[$class])) {
960
  @trigger_error(sprintf('Referencing the "%s" extension by its name (defined by getName()) is deprecated since 1.26 and will be removed in Twig 2.0. Use the Fully Qualified Extension Class Name instead.', $class), E_USER_DEPRECATED);
1576
  $this->optionsHash = implode(':', $hashParts);
1577
  }
1578
  }
1579
+
1580
+ class_alias('Twig_Environment', 'Twig\Environment', false);
vendor/twig/twig/lib/Twig/Error.php CHANGED
@@ -332,11 +332,6 @@ class Twig_Error extends Exception
332
  $r = new ReflectionObject($template);
333
  $file = $r->getFileName();
334
 
335
- // hhvm has a bug where eval'ed files comes out as the current directory
336
- if (is_dir($file)) {
337
- $file = '';
338
- }
339
-
340
  $exceptions = array($e = $this);
341
  while (($e instanceof self || method_exists($e, 'getPrevious')) && $e = $e->getPrevious()) {
342
  $exceptions[] = $e;
@@ -363,3 +358,6 @@ class Twig_Error extends Exception
363
  }
364
  }
365
  }
 
 
 
332
  $r = new ReflectionObject($template);
333
  $file = $r->getFileName();
334
 
 
 
 
 
 
335
  $exceptions = array($e = $this);
336
  while (($e instanceof self || method_exists($e, 'getPrevious')) && $e = $e->getPrevious()) {
337
  $exceptions[] = $e;
358
  }
359
  }
360
  }
361
+
362
+ class_alias('Twig_Error', 'Twig\Error\Error', false);
363
+ class_exists('Twig_Source');
vendor/twig/twig/lib/Twig/Error/Loader.php CHANGED
@@ -36,3 +36,5 @@ class Twig_Error_Loader extends Twig_Error
36
  $this->setTemplateLine(false);
37
  }
38
  }
 
 
36
  $this->setTemplateLine(false);
37
  }
38
  }
39
+
40
+ class_alias('Twig_Error_Loader', 'Twig\Error\LoaderError', false);
vendor/twig/twig/lib/Twig/Error/Runtime.php CHANGED
@@ -18,3 +18,5 @@
18
  class Twig_Error_Runtime extends Twig_Error
19
  {
20
  }
 
 
18
  class Twig_Error_Runtime extends Twig_Error
19
  {
20
  }
21
+
22
+ class_alias('Twig_Error_Runtime', 'Twig\Error\RuntimeError', false);
vendor/twig/twig/lib/Twig/Error/Syntax.php CHANGED
@@ -51,3 +51,5 @@ class Twig_Error_Syntax extends Twig_Error
51
  return array_keys($alternatives);
52
  }
53
  }
 
 
51
  return array_keys($alternatives);
52
  }
53
  }
54
+
55
+ class_alias('Twig_Error_Syntax', 'Twig\Error\SyntaxError', false);
vendor/twig/twig/lib/Twig/ExistsLoaderInterface.php CHANGED
@@ -27,3 +27,5 @@ interface Twig_ExistsLoaderInterface
27
  */
28
  public function exists($name);
29
  }
 
 
27
  */
28
  public function exists($name);
29
  }
30
+
31
+ class_alias('Twig_ExistsLoaderInterface', 'Twig\Loader\ExistsLoaderInterface', false);
vendor/twig/twig/lib/Twig/ExpressionParser.php CHANGED
@@ -737,3 +737,5 @@ class Twig_ExpressionParser
737
  return true;
738
  }
739
  }
 
 
737
  return true;
738
  }
739
  }
740
+
741
+ class_alias('Twig_ExpressionParser', 'Twig\ExpressionParser', false);
vendor/twig/twig/lib/Twig/Extension.php CHANGED
@@ -8,6 +8,7 @@
8
  * For the full copyright and license information, please view the LICENSE
9
  * file that was distributed with this source code.
10
  */
 
11
  abstract class Twig_Extension implements Twig_ExtensionInterface
12
  {
13
  /**
@@ -63,3 +64,6 @@ abstract class Twig_Extension implements Twig_ExtensionInterface
63
  return get_class($this);
64
  }
65
  }
 
 
 
8
  * For the full copyright and license information, please view the LICENSE
9
  * file that was distributed with this source code.
10
  */
11
+
12
  abstract class Twig_Extension implements Twig_ExtensionInterface
13
  {
14
  /**
64
  return get_class($this);
65
  }
66
  }
67
+
68
+ class_alias('Twig_Extension', 'Twig\Extension\AbstractExtension', false);
69
+ class_exists('Twig_Environment');
vendor/twig/twig/lib/Twig/Extension/Core.php CHANGED
@@ -1,8 +1,7 @@
1
  <?php
2
 
3
  if (!defined('ENT_SUBSTITUTE')) {
4
- // use 0 as hhvm does not support several flags yet
5
- define('ENT_SUBSTITUTE', 0);
6
  }
7
 
8
  /*
@@ -1006,30 +1005,22 @@ function twig_escape_filter(Twig_Environment $env, $string, $strategy = 'html',
1006
  // Using a static variable to avoid initializing the array
1007
  // each time the function is called. Moving the declaration on the
1008
  // top of the function slow downs other escaping strategies.
1009
- static $htmlspecialcharsCharsets;
1010
-
1011
- if (null === $htmlspecialcharsCharsets) {
1012
- if (defined('HHVM_VERSION')) {
1013
- $htmlspecialcharsCharsets = array('utf-8' => true, 'UTF-8' => true);
1014
- } else {
1015
- $htmlspecialcharsCharsets = array(
1016
- 'ISO-8859-1' => true, 'ISO8859-1' => true,
1017
- 'ISO-8859-15' => true, 'ISO8859-15' => true,
1018
- 'utf-8' => true, 'UTF-8' => true,
1019
- 'CP866' => true, 'IBM866' => true, '866' => true,
1020
- 'CP1251' => true, 'WINDOWS-1251' => true, 'WIN-1251' => true,
1021
- '1251' => true,
1022
- 'CP1252' => true, 'WINDOWS-1252' => true, '1252' => true,
1023
- 'KOI8-R' => true, 'KOI8-RU' => true, 'KOI8R' => true,
1024
- 'BIG5' => true, '950' => true,
1025
- 'GB2312' => true, '936' => true,
1026
- 'BIG5-HKSCS' => true,
1027
- 'SHIFT_JIS' => true, 'SJIS' => true, '932' => true,
1028
- 'EUC-JP' => true, 'EUCJP' => true,
1029
- 'ISO8859-5' => true, 'ISO-8859-5' => true, 'MACROMAN' => true,
1030
- );
1031
- }
1032
- }
1033
 
1034
  if (isset($htmlspecialcharsCharsets[$charset])) {
1035
  return htmlspecialchars($string, ENT_QUOTES | ENT_SUBSTITUTE, $charset);
@@ -1264,6 +1255,10 @@ if (function_exists('mb_get_info')) {
1264
  */
1265
  function twig_length_filter(Twig_Environment $env, $thing)
1266
  {
 
 
 
 
1267
  if (is_scalar($thing)) {
1268
  return mb_strlen($thing, $env->getCharset());
1269
  }
@@ -1272,7 +1267,11 @@ if (function_exists('mb_get_info')) {
1272
  return mb_strlen((string) $thing, $env->getCharset());
1273
  }
1274
 
1275
- return count($thing);
 
 
 
 
1276
  }
1277
 
1278
  /**
@@ -1355,6 +1354,10 @@ else {
1355
  */
1356
  function twig_length_filter(Twig_Environment $env, $thing)
1357
  {
 
 
 
 
1358
  if (is_scalar($thing)) {
1359
  return strlen($thing);
1360
  }
@@ -1363,7 +1366,11 @@ else {
1363
  return strlen((string) $thing);
1364
  }
1365
 
1366
- return count($thing);
 
 
 
 
1367
  }
1368
 
1369
  /**
@@ -1601,3 +1608,5 @@ function twig_array_batch($items, $size, $fill = null)
1601
 
1602
  return $result;
1603
  }
 
 
1
  <?php
2
 
3
  if (!defined('ENT_SUBSTITUTE')) {
4
+ define('ENT_SUBSTITUTE', 8);
 
5
  }
6
 
7
  /*
1005
  // Using a static variable to avoid initializing the array
1006
  // each time the function is called. Moving the declaration on the
1007
  // top of the function slow downs other escaping strategies.
1008
+ static $htmlspecialcharsCharsets = array(
1009
+ 'ISO-8859-1' => true, 'ISO8859-1' => true,
1010
+ 'ISO-8859-15' => true, 'ISO8859-15' => true,
1011
+ 'utf-8' => true, 'UTF-8' => true,
1012
+ 'CP866' => true, 'IBM866' => true, '866' => true,
1013
+ 'CP1251' => true, 'WINDOWS-1251' => true, 'WIN-1251' => true,
1014
+ '1251' => true,
1015
+ 'CP1252' => true, 'WINDOWS-1252' => true, '1252' => true,
1016
+ 'KOI8-R' => true, 'KOI8-RU' => true, 'KOI8R' => true,
1017
+ 'BIG5' => true, '950' => true,
1018
+ 'GB2312' => true, '936' => true,
1019
+ 'BIG5-HKSCS' => true,
1020
+ 'SHIFT_JIS' => true, 'SJIS' => true, '932' => true,
1021
+ 'EUC-JP' => true, 'EUCJP' => true,
1022
+ 'ISO8859-5' => true, 'ISO-8859-5' => true, 'MACROMAN' => true,
1023
+ );
 
 
 
 
 
 
 
 
1024
 
1025
  if (isset($htmlspecialcharsCharsets[$charset])) {
1026
  return htmlspecialchars($string, ENT_QUOTES | ENT_SUBSTITUTE, $charset);
1255
  */
1256
  function twig_length_filter(Twig_Environment $env, $thing)
1257
  {
1258
+ if (null === $thing) {
1259
+ return 0;
1260
+ }
1261
+
1262
  if (is_scalar($thing)) {
1263
  return mb_strlen($thing, $env->getCharset());
1264
  }
1267
  return mb_strlen((string) $thing, $env->getCharset());
1268
  }
1269
 
1270
+ if ($thing instanceof \Countable || is_array($thing)) {
1271
+ return count($thing);
1272
+ }
1273
+
1274
+ return 1;
1275
  }
1276
 
1277
  /**
1354
  */
1355
  function twig_length_filter(Twig_Environment $env, $thing)
1356
  {
1357
+ if (null === $thing) {
1358
+ return 0;
1359
+ }
1360
+
1361
  if (is_scalar($thing)) {
1362
  return strlen($thing);
1363
  }
1366
  return strlen((string) $thing);
1367
  }
1368
 
1369
+ if ($thing instanceof \Countable || is_array($thing)) {
1370
+ return count($thing);
1371
+ }
1372
+
1373
+ return 1;
1374
  }
1375
 
1376
  /**
1608
 
1609
  return $result;
1610
  }
1611
+
1612
+ class_alias('Twig_Extension_Core', 'Twig\Extension\CoreExtension', false);
vendor/twig/twig/lib/Twig/Extension/Debug.php CHANGED
@@ -23,7 +23,7 @@ class Twig_Extension_Debug extends Twig_Extension
23
  // false means that it was not set (and the default is on) or it explicitly enabled
24
  // xdebug.overload_var_dump produces HTML only when html_errors is also enabled
25
  && (false === ini_get('html_errors') || ini_get('html_errors'))
26
- || 'cli' === php_sapi_name()
27
  ;
28
 
29
  return array(
@@ -63,3 +63,5 @@ function twig_var_dump(Twig_Environment $env, $context)
63
 
64
  return ob_get_clean();
65
  }
 
 
23
  // false means that it was not set (and the default is on) or it explicitly enabled
24
  // xdebug.overload_var_dump produces HTML only when html_errors is also enabled
25
  && (false === ini_get('html_errors') || ini_get('html_errors'))
26
+ || 'cli' === PHP_SAPI
27
  ;
28
 
29
  return array(
63
 
64
  return ob_get_clean();
65
  }
66
+
67
+ class_alias('Twig_Extension_Debug', 'Twig\Extension\DebugExtension', false);
vendor/twig/twig/lib/Twig/Extension/Escaper.php CHANGED
@@ -108,3 +108,5 @@ function twig_raw_filter($string)
108
  {
109
  return $string;
110
  }
 
 
108
  {
109
  return $string;
110
  }
111
+
112
+ class_alias('Twig_Extension_Escaper', 'Twig\Extension\EscaperExtension', false);
vendor/twig/twig/lib/Twig/Extension/GlobalsInterface.php CHANGED
@@ -20,3 +20,5 @@
20
  interface Twig_Extension_GlobalsInterface
21
  {
22
  }
 
 
20
  interface Twig_Extension_GlobalsInterface
21
  {
22
  }
23
+
24
+ class_alias('Twig_Extension_GlobalsInterface', 'Twig\Extension\GlobalsInterface', false);
vendor/twig/twig/lib/Twig/Extension/InitRuntimeInterface.php CHANGED
@@ -20,3 +20,5 @@
20
  interface Twig_Extension_InitRuntimeInterface
21
  {
22
  }
 
 
20
  interface Twig_Extension_InitRuntimeInterface
21
  {
22
  }
23
+
24
+ class_alias('Twig_Extension_InitRuntimeInterface', 'Twig\Extension\InitRuntimeInterface', false);
vendor/twig/twig/lib/Twig/Extension/Optimizer.php CHANGED
@@ -31,3 +31,5 @@ class Twig_Extension_Optimizer extends Twig_Extension
31
  return 'optimizer';
32
  }
33
  }
 
 
31
  return 'optimizer';
32
  }
33
  }
34
+
35
+ class_alias('Twig_Extension_Optimizer', 'Twig\Extension\OptimizerExtension', false);
vendor/twig/twig/lib/Twig/Extension/Profiler.php CHANGED
@@ -44,3 +44,6 @@ class Twig_Extension_Profiler extends Twig_Extension
44
  return 'profiler';
45
  }
46
  }
 
 
 
44
  return 'profiler';
45
  }
46
  }
47
+
48
+ class_alias('Twig_Extension_Profiler', 'Twig\Extension\ProfilerExtension', false);
49
+ class_exists('Twig_Profiler_Profile');
vendor/twig/twig/lib/Twig/Extension/Sandbox.php CHANGED
@@ -99,3 +99,5 @@ class Twig_Extension_Sandbox extends Twig_Extension
99
  return 'sandbox';
100
  }
101
  }
 
 
99
  return 'sandbox';
100
  }
101
  }
102
+
103
+ class_alias('Twig_Extension_Sandbox', 'Twig\Extension\SandboxExtension', false);
vendor/twig/twig/lib/Twig/Extension/Staging.php CHANGED
@@ -108,3 +108,5 @@ class Twig_Extension_Staging extends Twig_Extension
108
  return 'staging';
109
  }
110
  }
 
 
108
  return 'staging';
109
  }
110
  }
111
+
112
+ class_alias('Twig_Extension_Staging', 'Twig\Extension\StagingExtension', false);
vendor/twig/twig/lib/Twig/Extension/StringLoader.php CHANGED
@@ -43,3 +43,5 @@ function twig_template_from_string(Twig_Environment $env, $template)
43
  {
44
  return $env->createTemplate((string) $template);
45
  }
 
 
43
  {
44
  return $env->createTemplate((string) $template);
45
  }
46
+
47
+ class_alias('Twig_Extension_StringLoader', 'Twig\Extension\StringLoaderExtension', false);
vendor/twig/twig/lib/Twig/ExtensionInterface.php CHANGED
@@ -85,3 +85,6 @@ interface Twig_ExtensionInterface
85
  */
86
  public function getName();
87
  }
 
 
 
85
  */
86
  public function getName();
87
  }
88
+
89
+ class_alias('Twig_ExtensionInterface', 'Twig\Extension\ExtensionInterface', false);
90
+ class_exists('Twig_Environment');
vendor/twig/twig/lib/Twig/FactoryRuntimeLoader.php CHANGED
@@ -35,3 +35,5 @@ class Twig_FactoryRuntimeLoader implements Twig_RuntimeLoaderInterface
35
  }
36
  }
37
  }
 
 
35
  }
36
  }
37
  }
38
+
39
+ class_alias('Twig_FactoryRuntimeLoader', 'Twig\RuntimeLoader\FactoryRuntimeLoader', false);
vendor/twig/twig/lib/Twig/FileExtensionEscapingStrategy.php CHANGED
@@ -56,3 +56,5 @@ class Twig_FileExtensionEscapingStrategy
56
  }
57
  }
58
  }
 
 
56
  }
57
  }
58
  }
59
+
60
+ class_alias('Twig_FileExtensionEscapingStrategy', 'Twig\FileExtensionEscapingStrategy', false);
vendor/twig/twig/lib/Twig/Lexer.php CHANGED
@@ -420,3 +420,5 @@ class Twig_Lexer implements Twig_LexerInterface
420
  $this->state = array_pop($this->states);
421
  }
422
  }
 
 
420
  $this->state = array_pop($this->states);
421
  }
422
  }
423
+
424
+ class_alias('Twig_Lexer', 'Twig\Lexer', false);
vendor/twig/twig/lib/Twig/Loader/Array.php CHANGED
@@ -93,3 +93,5 @@ class Twig_Loader_Array implements Twig_LoaderInterface, Twig_ExistsLoaderInterf
93
  return true;
94
  }
95
  }
 
 
93
  return true;
94
  }
95
  }
96
+
97
+ class_alias('Twig_Loader_Array', 'Twig\Loader\ArrayLoader', false);
vendor/twig/twig/lib/Twig/Loader/Chain.php CHANGED
@@ -147,3 +147,5 @@ class Twig_Loader_Chain implements Twig_LoaderInterface, Twig_ExistsLoaderInterf
147
  throw new Twig_Error_Loader(sprintf('Template "%s" is not defined%s.', $name, $exceptions ? ' ('.implode(', ', $exceptions).')' : ''));
148
  }
149
  }
 
 
147
  throw new Twig_Error_Loader(sprintf('Template "%s" is not defined%s.', $name, $exceptions ? ' ('.implode(', ', $exceptions).')' : ''));
148
  }
149
  }
150
+
151
+ class_alias('Twig_Loader_Chain', 'Twig\Loader\ChainLoader', false);
vendor/twig/twig/lib/Twig/Loader/Filesystem.php CHANGED
@@ -286,3 +286,5 @@ class Twig_Loader_Filesystem implements Twig_LoaderInterface, Twig_ExistsLoaderI
286
  ;
287
  }
288
  }
 
 
286
  ;
287
  }
288
  }
289
+
290
+ class_alias('Twig_Loader_Filesystem', 'Twig\Loader\FilesystemLoader', false);
vendor/twig/twig/lib/Twig/LoaderInterface.php CHANGED
@@ -53,3 +53,5 @@ interface Twig_LoaderInterface
53
  */
54
  public function isFresh($name, $time);
55
  }
 
 
53
  */
54
  public function isFresh($name, $time);
55
  }
56
+
57
+ class_alias('Twig_LoaderInterface', 'Twig\Loader\LoaderInterface', false);
vendor/twig/twig/lib/Twig/Markup.php CHANGED
@@ -35,3 +35,5 @@ class Twig_Markup implements Countable
35
  return function_exists('mb_get_info') ? mb_strlen($this->content, $this->charset) : strlen($this->content);
36
  }
37
  }
 
 
35
  return function_exists('mb_get_info') ? mb_strlen($this->content, $this->charset) : strlen($this->content);
36
  }
37
  }
38
+
39
+ class_alias('Twig_Markup', 'Twig\Markup', false);
vendor/twig/twig/lib/Twig/Node.php CHANGED
@@ -251,3 +251,6 @@ class Twig_Node implements Twig_NodeInterface
251
  return $this->name;
252
  }
253
  }
 
 
 
251
  return $this->name;
252
  }
253
  }
254
+
255
+ class_alias('Twig_Node', 'Twig\Node\Node', false);
256
+ class_exists('Twig_Compiler');
vendor/twig/twig/lib/Twig/Node/AutoEscape.php CHANGED
@@ -32,3 +32,5 @@ class Twig_Node_AutoEscape extends Twig_Node
32
  $compiler->subcompile($this->getNode('body'));
33
  }
34
  }
 
 
32
  $compiler->subcompile($this->getNode('body'));
33
  }
34
  }
35
+
36
+ class_alias('Twig_Node_AutoEscape', 'Twig\Node\AutoEscapeNode', false);
vendor/twig/twig/lib/Twig/Node/Block.php CHANGED
@@ -37,3 +37,5 @@ class Twig_Node_Block extends Twig_Node
37
  ;
38
  }
39
  }
 
 
37
  ;
38
  }
39
  }
40
+
41
+ class_alias('Twig_Node_Block', 'Twig\Node\BlockNode', false);
vendor/twig/twig/lib/Twig/Node/BlockReference.php CHANGED
@@ -30,3 +30,5 @@ class Twig_Node_BlockReference extends Twig_Node implements Twig_NodeOutputInter
30
  ;
31
  }
32
  }
 
 
30
  ;
31
  }
32
  }
33
+
34
+ class_alias('Twig_Node_BlockReference', 'Twig\Node\BlockReferenceNode', false);
vendor/twig/twig/lib/Twig/Node/Body.php CHANGED
@@ -17,3 +17,5 @@
17
  class Twig_Node_Body extends Twig_Node
18
  {
19
  }
 
 
17
  class Twig_Node_Body extends Twig_Node
18
  {
19
  }
20
+
21
+ class_alias('Twig_Node_Body', 'Twig\Node\BodyNode', false);
vendor/twig/twig/lib/Twig/Node/CheckSecurity.php CHANGED
@@ -76,3 +76,5 @@ class Twig_Node_CheckSecurity extends Twig_Node
76
  ;
77
  }
78
  }
 
 
76
  ;
77
  }
78
  }
79
+
80
+ class_alias('Twig_Node_CheckSecurity', 'Twig\Node\CheckSecurityNode', false);
vendor/twig/twig/lib/Twig/Node/Do.php CHANGED
@@ -31,3 +31,5 @@ class Twig_Node_Do extends Twig_Node
31
  ;
32
  }
33
  }
 
 
31
  ;
32
  }
33
  }
34
+
35
+ class_alias('Twig_Node_Do', 'Twig\Node\DoNode', false);
vendor/twig/twig/lib/Twig/Node/Embed.php CHANGED
@@ -42,3 +42,5 @@ class Twig_Node_Embed extends Twig_Node_Include
42
  ;
43
  }
44
  }
 
 
42
  ;
43
  }
44
  }
45
+
46
+ class_alias('Twig_Node_Embed', 'Twig\Node\EmbedNode', false);
vendor/twig/twig/lib/Twig/Node/Expression.php CHANGED
@@ -18,3 +18,5 @@
18
  abstract class Twig_Node_Expression extends Twig_Node
19
  {
20
  }
 
 
18
  abstract class Twig_Node_Expression extends Twig_Node
19
  {
20
  }
21
+
22
+ class_alias('Twig_Node_Expression', 'Twig\Node\Expression\AbstractExpression', false);
vendor/twig/twig/lib/Twig/Node/Expression/Array.php CHANGED
@@ -79,3 +79,5 @@ class Twig_Node_Expression_Array extends Twig_Node_Expression
79
  $compiler->raw(')');
80
  }
81
  }
 
 
79
  $compiler->raw(')');
80
  }
81
  }
82
+
83
+ class_alias('Twig_Node_Expression_Array', 'Twig\Node\Expression\ArrayExpression', false);
vendor/twig/twig/lib/Twig/Node/Expression/AssignName.php CHANGED
@@ -21,3 +21,5 @@ class Twig_Node_Expression_AssignName extends Twig_Node_Expression_Name
21
  ;
22
  }
23
  }
 
 
21
  ;
22
  }
23
  }
24
+
25
+ class_alias('Twig_Node_Expression_AssignName', 'Twig\Node\Expression\AssignNameExpression', false);
vendor/twig/twig/lib/Twig/Node/Expression/Binary.php CHANGED
@@ -33,3 +33,5 @@ abstract class Twig_Node_Expression_Binary extends Twig_Node_Expression
33
 
34
  abstract public function operator(Twig_Compiler $compiler);
35
  }
 
 
33
 
34
  abstract public function operator(Twig_Compiler $compiler);
35
  }
36
+
37
+ class_alias('Twig_Node_Expression_Binary', 'Twig\Node\Expression\Binary\AbstractBinary', false);
vendor/twig/twig/lib/Twig/Node/Expression/Binary/Add.php CHANGED
@@ -16,3 +16,5 @@ class Twig_Node_Expression_Binary_Add extends Twig_Node_Expression_Binary
16
  return $compiler->raw('+');
17
  }
18
  }
 
 
16
  return $compiler->raw('+');
17
  }
18
  }
19
+
20
+ class_alias('Twig_Node_Expression_Binary_Add', 'Twig\Node\Expression\Binary\AddBinary', false);
vendor/twig/twig/lib/Twig/Node/Expression/Binary/And.php CHANGED
@@ -16,3 +16,5 @@ class Twig_Node_Expression_Binary_And extends Twig_Node_Expression_Binary
16
  return $compiler->raw('&&');
17
  }
18
  }
 
 
16
  return $compiler->raw('&&');
17
  }
18
  }
19
+
20
+ class_alias('Twig_Node_Expression_Binary_And', 'Twig\Node\Expression\Binary\AndBinary', false);
vendor/twig/twig/lib/Twig/Node/Expression/Binary/BitwiseAnd.php CHANGED
@@ -16,3 +16,5 @@ class Twig_Node_Expression_Binary_BitwiseAnd extends Twig_Node_Expression_Binary
16
  return $compiler->raw('&');
17
  }
18
  }
 
 
16
  return $compiler->raw('&');
17
  }
18
  }
19
+
20
+ class_alias('Twig_Node_Expression_Binary_BitwiseAnd', 'Twig\Node\Expression\Binary\BitwiseAndBinary', false);
vendor/twig/twig/lib/Twig/Node/Expression/Binary/BitwiseOr.php CHANGED
@@ -16,3 +16,5 @@ class Twig_Node_Expression_Binary_BitwiseOr extends Twig_Node_Expression_Binary
16
  return $compiler->raw('|');
17
  }
18
  }
 
 
16
  return $compiler->raw('|');
17
  }
18
  }
19
+
20
+ class_alias('Twig_Node_Expression_Binary_BitwiseOr', 'Twig\Node\Expression\Binary\BitwiseOrBinary', false);
vendor/twig/twig/lib/Twig/Node/Expression/Binary/BitwiseXor.php CHANGED
@@ -16,3 +16,5 @@ class Twig_Node_Expression_Binary_BitwiseXor extends Twig_Node_Expression_Binary
16
  return $compiler->raw('^');
17
  }
18
  }
 
 
16
  return $compiler->raw('^');
17
  }
18
  }
19
+
20
+ class_alias('Twig_Node_Expression_Binary_BitwiseXor', 'Twig\Node\Expression\Binary\BitwiseXorBinary', false);
vendor/twig/twig/lib/Twig/Node/Expression/Binary/Concat.php CHANGED
@@ -16,3 +16,5 @@ class Twig_Node_Expression_Binary_Concat extends Twig_Node_Expression_Binary
16
  return $compiler->raw('.');
17
  }
18
  }
 
 
16
  return $compiler->raw('.');
17
  }
18
  }
19
+
20
+ class_alias('Twig_Node_Expression_Binary_Concat', 'Twig\Node\Expression\Binary\ConcatBinary', false);
vendor/twig/twig/lib/Twig/Node/Expression/Binary/Div.php CHANGED
@@ -16,3 +16,5 @@ class Twig_Node_Expression_Binary_Div extends Twig_Node_Expression_Binary
16
  return $compiler->raw('/');
17
  }
18
  }
 
 
16
  return $compiler->raw('/');
17
  }
18
  }
19
+
20
+ class_alias('Twig_Node_Expression_Binary_Div', 'Twig\Node\Expression\Binary\DivBinary', false);
vendor/twig/twig/lib/Twig/Node/Expression/Binary/EndsWith.php CHANGED
@@ -28,3 +28,5 @@ class Twig_Node_Expression_Binary_EndsWith extends Twig_Node_Expression_Binary
28
  return $compiler->raw('');
29
  }
30
  }
 
 
28
  return $compiler->raw('');
29
  }
30
  }
31
+
32
+ class_alias('Twig_Node_Expression_Binary_EndsWith', 'Twig\Node\Expression\Binary\EndsWithBinary', false);
vendor/twig/twig/lib/Twig/Node/Expression/Binary/Equal.php CHANGED
@@ -15,3 +15,5 @@ class Twig_Node_Expression_Binary_Equal extends Twig_Node_Expression_Binary
15
  return $compiler->raw('==');
16
  }
17
  }
 
 
15
  return $compiler->raw('==');
16
  }
17
  }
18
+
19
+ class_alias('Twig_Node_Expression_Binary_Equal', 'Twig\Node\Expression\Binary\EqualBinary', false);
vendor/twig/twig/lib/Twig/Node/Expression/Binary/FloorDiv.php CHANGED
@@ -22,3 +22,5 @@ class Twig_Node_Expression_Binary_FloorDiv extends Twig_Node_Expression_Binary
22
  return $compiler->raw('/');
23
  }
24
  }
 
 
22
  return $compiler->raw('/');
23
  }
24
  }
25
+
26
+ class_alias('Twig_Node_Expression_Binary_FloorDiv', 'Twig\Node\Expression\Binary\FloorDivBinary', false);
vendor/twig/twig/lib/Twig/Node/Expression/Binary/Greater.php CHANGED
@@ -15,3 +15,5 @@ class Twig_Node_Expression_Binary_Greater extends Twig_Node_Expression_Binary
15
  return $compiler->raw('>');
16
  }
17
  }
 
 
15
  return $compiler->raw('>');
16
  }
17
  }
18
+
19
+ class_alias('Twig_Node_Expression_Binary_Greater', 'Twig\Node\Expression\Binary\GreaterBinary', false);
vendor/twig/twig/lib/Twig/Node/Expression/Binary/GreaterEqual.php CHANGED
@@ -15,3 +15,5 @@ class Twig_Node_Expression_Binary_GreaterEqual extends Twig_Node_Expression_Bina
15
  return $compiler->raw('>=');
16
  }
17
  }
 
 
15
  return $compiler->raw('>=');
16
  }
17
  }
18
+
19
+ class_alias('Twig_Node_Expression_Binary_GreaterEqual', 'Twig\Node\Expression\Binary\GreaterEqualBinary', false);
vendor/twig/twig/lib/Twig/Node/Expression/Binary/In.php CHANGED
@@ -26,3 +26,5 @@ class Twig_Node_Expression_Binary_In extends Twig_Node_Expression_Binary
26
  return $compiler->raw('in');
27
  }
28
  }
 
 
26
  return $compiler->raw('in');
27
  }
28
  }
29
+
30
+ class_alias('Twig_Node_Expression_Binary_In', 'Twig\Node\Expression\Binary\InBinary', false);
vendor/twig/twig/lib/Twig/Node/Expression/Binary/Less.php CHANGED
@@ -15,3 +15,5 @@ class Twig_Node_Expression_Binary_Less extends Twig_Node_Expression_Binary
15
  return $compiler->raw('<');
16
  }
17
  }
 
 
15
  return $compiler->raw('<');
16
  }
17
  }
18
+
19
+ class_alias('Twig_Node_Expression_Binary_Less', 'Twig\Node\Expression\Binary\LessBinary', false);
vendor/twig/twig/lib/Twig/Node/Expression/Binary/LessEqual.php CHANGED
@@ -15,3 +15,5 @@ class Twig_Node_Expression_Binary_LessEqual extends Twig_Node_Expression_Binary
15
  return $compiler->raw('<=');
16
  }
17
  }
 
 
15
  return $compiler->raw('<=');
16
  }
17
  }
18
+
19
+ class_alias('Twig_Node_Expression_Binary_LessEqual', 'Twig\Node\Expression\Binary\LessEqualBinary', false);
vendor/twig/twig/lib/Twig/Node/Expression/Binary/Matches.php CHANGED
@@ -26,3 +26,5 @@ class Twig_Node_Expression_Binary_Matches extends Twig_Node_Expression_Binary
26
  return $compiler->raw('');
27
  }
28
  }
 
 
26
  return $compiler->raw('');
27
  }
28
  }
29
+
30
+ class_alias('Twig_Node_Expression_Binary_Matches', 'Twig\Node\Expression\Binary\MatchesBinary', false);
vendor/twig/twig/lib/Twig/Node/Expression/Binary/Mod.php CHANGED
@@ -16,3 +16,5 @@ class Twig_Node_Expression_Binary_Mod extends Twig_Node_Expression_Binary
16
  return $compiler->raw('%');
17
  }
18
  }
 
 
16
  return $compiler->raw('%');
17
  }
18
  }
19
+
20
+ class_alias('Twig_Node_Expression_Binary_Mod', 'Twig\Node\Expression\Binary\ModBinary', false);
vendor/twig/twig/lib/Twig/Node/Expression/Binary/Mul.php CHANGED
@@ -16,3 +16,5 @@ class Twig_Node_Expression_Binary_Mul extends Twig_Node_Expression_Binary
16
  return $compiler->raw('*');
17
  }
18
  }
 
 
16
  return $compiler->raw('*');
17
  }
18
  }
19
+
20
+ class_alias('Twig_Node_Expression_Binary_Mul', 'Twig\Node\Expression\Binary\MulBinary', false);
vendor/twig/twig/lib/Twig/Node/Expression/Binary/NotEqual.php CHANGED
@@ -15,3 +15,5 @@ class Twig_Node_Expression_Binary_NotEqual extends Twig_Node_Expression_Binary
15
  return $compiler->raw('!=');
16
  }
17
  }
 
 
15
  return $compiler->raw('!=');
16
  }
17
  }
18
+
19
+ class_alias('Twig_Node_Expression_Binary_NotEqual', 'Twig\Node\Expression\Binary\NotEqualBinary', false);
vendor/twig/twig/lib/Twig/Node/Expression/Binary/NotIn.php CHANGED
@@ -26,3 +26,5 @@ class Twig_Node_Expression_Binary_NotIn extends Twig_Node_Expression_Binary
26
  return $compiler->raw('not in');
27
  }
28
  }
 
 
26
  return $compiler->raw('not in');
27
  }
28
  }
29
+
30
+ class_alias('Twig_Node_Expression_Binary_NotIn', 'Twig\Node\Expression\Binary\NotInBinary', false);
vendor/twig/twig/lib/Twig/Node/Expression/Binary/Or.php CHANGED
@@ -16,3 +16,5 @@ class Twig_Node_Expression_Binary_Or extends Twig_Node_Expression_Binary
16
  return $compiler->raw('||');
17
  }
18
  }
 
 
16
  return $compiler->raw('||');
17
  }
18
  }
19
+
20
+ class_alias('Twig_Node_Expression_Binary_Or', 'Twig\Node\Expression\Binary\OrBinary', false);
vendor/twig/twig/lib/Twig/Node/Expression/Binary/Power.php CHANGED
@@ -30,3 +30,5 @@ class Twig_Node_Expression_Binary_Power extends Twig_Node_Expression_Binary
30
  return $compiler->raw('**');
31
  }
32
  }
 
 
30
  return $compiler->raw('**');
31
  }
32
  }
33
+
34
+ class_alias('Twig_Node_Expression_Binary_Power', 'Twig\Node\Expression\Binary\PowerBinary', false);
vendor/twig/twig/lib/Twig/Node/Expression/Binary/Range.php CHANGED
@@ -26,3 +26,5 @@ class Twig_Node_Expression_Binary_Range extends Twig_Node_Expression_Binary
26
  return $compiler->raw('..');
27
  }
28
  }
 
 
26
  return $compiler->raw('..');
27
  }
28
  }
29
+
30
+ class_alias('Twig_Node_Expression_Binary_Range', 'Twig\Node\Expression\Binary\RangeBinary', false);
vendor/twig/twig/lib/Twig/Node/Expression/Binary/StartsWith.php CHANGED
@@ -28,3 +28,5 @@ class Twig_Node_Expression_Binary_StartsWith extends Twig_Node_Expression_Binary
28
  return $compiler->raw('');
29
  }
30
  }
 
 
28
  return $compiler->raw('');
29
  }
30
  }
31
+
32
+ class_alias('Twig_Node_Expression_Binary_StartsWith', 'Twig\Node\Expression\Binary\StartsWithBinary', false);
vendor/twig/twig/lib/Twig/Node/Expression/Binary/Sub.php CHANGED
@@ -16,3 +16,5 @@ class Twig_Node_Expression_Binary_Sub extends Twig_Node_Expression_Binary
16
  return $compiler->raw('-');
17
  }
18
  }
 
 
16
  return $compiler->raw('-');
17
  }
18
  }
19
+
20
+ class_alias('Twig_Node_Expression_Binary_Sub', 'Twig\Node\Expression\Binary\SubBinary', false);
vendor/twig/twig/lib/Twig/Node/Expression/BlockReference.php CHANGED
@@ -89,3 +89,5 @@ class Twig_Node_Expression_BlockReference extends Twig_Node_Expression
89
  return $compiler->raw(')');
90
  }
91
  }
 
 
89
  return $compiler->raw(')');
90
  }
91
  }
92
+
93
+ class_alias('Twig_Node_Expression_BlockReference', 'Twig\Node\Expression\BlockReferenceExpression', false);
vendor/twig/twig/lib/Twig/Node/Expression/Call.php CHANGED
@@ -287,3 +287,5 @@ abstract class Twig_Node_Expression_Call extends Twig_Node_Expression
287
  return $this->reflector = array($r, $callable);
288
  }
289
  }
 
 
287
  return $this->reflector = array($r, $callable);
288
  }
289
  }
290
+
291
+ class_alias('Twig_Node_Expression_Call', 'Twig\Node\Expression\CallExpression', false);
vendor/twig/twig/lib/Twig/Node/Expression/Conditional.php CHANGED
@@ -29,3 +29,5 @@ class Twig_Node_Expression_Conditional extends Twig_Node_Expression
29
  ;
30
  }
31
  }
 
 
29
  ;
30
  }
31
  }
32
+
33
+ class_alias('Twig_Node_Expression_Conditional', 'Twig\Node\Expression\ConditionalExpression', false);
vendor/twig/twig/lib/Twig/Node/Expression/Constant.php CHANGED
@@ -21,3 +21,5 @@ class Twig_Node_Expression_Constant extends Twig_Node_Expression
21
  $compiler->repr($this->getAttribute('value'));
22
  }
23
  }
 
 
21
  $compiler->repr($this->getAttribute('value'));
22
  }
23
  }
24
+
25
+ class_alias('Twig_Node_Expression_Constant', 'Twig\Node\Expression\ConstantExpression', false);
vendor/twig/twig/lib/Twig/Node/Expression/Filter.php CHANGED
@@ -37,3 +37,5 @@ class Twig_Node_Expression_Filter extends Twig_Node_Expression_Call
37
  $this->compileCallable($compiler);
38
  }
39
  }
 
 
37
  $this->compileCallable($compiler);
38
  }
39
  }
40
+
41
+ class_alias('Twig_Node_Expression_Filter', 'Twig\Node\Expression\FilterExpression', false);
vendor/twig/twig/lib/Twig/Node/Expression/Filter/Default.php CHANGED
@@ -41,3 +41,5 @@ class Twig_Node_Expression_Filter_Default extends Twig_Node_Expression_Filter
41
  $compiler->subcompile($this->getNode('node'));
42
  }
43
  }
 
 
41
  $compiler->subcompile($this->getNode('node'));
42
  }
43
  }
44
+
45
+ class_alias('Twig_Node_Expression_Filter_Default', 'Twig\Node\Expression\Filter\DefaultFilter', false);
vendor/twig/twig/lib/Twig/Node/Expression/Function.php CHANGED
@@ -41,3 +41,5 @@ class Twig_Node_Expression_Function extends Twig_Node_Expression_Call
41
  $this->compileCallable($compiler);
42
  }
43
  }
 
 
41
  $this->compileCallable($compiler);
42
  }
43
  }
44
+
45
+ class_alias('Twig_Node_Expression_Function', 'Twig\Node\Expression\FunctionExpression', false);
vendor/twig/twig/lib/Twig/Node/Expression/GetAttr.php CHANGED
@@ -70,3 +70,5 @@ class Twig_Node_Expression_GetAttr extends Twig_Node_Expression
70
  $compiler->raw(')');
71
  }
72
  }
 
 
70
  $compiler->raw(')');
71
  }
72
  }
73
+
74
+ class_alias('Twig_Node_Expression_GetAttr', 'Twig\Node\Expression\GetAttrExpression', false);
vendor/twig/twig/lib/Twig/Node/Expression/MethodCall.php CHANGED
@@ -39,3 +39,5 @@ class Twig_Node_Expression_MethodCall extends Twig_Node_Expression
39
  $compiler->raw(')');
40
  }
41
  }
 
 
39
  $compiler->raw(')');
40
  }
41
  }
42
+
43
+ class_alias('Twig_Node_Expression_MethodCall', 'Twig\Node\Expression\MethodCallExpression', false);
vendor/twig/twig/lib/Twig/Node/Expression/Name.php CHANGED
@@ -98,3 +98,5 @@ class Twig_Node_Expression_Name extends Twig_Node_Expression
98
  return !$this->isSpecial() && !$this->getAttribute('is_defined_test');
99
  }
100
  }
 
 
98
  return !$this->isSpecial() && !$this->getAttribute('is_defined_test');
99
  }
100
  }
101
+
102
+ class_alias('Twig_Node_Expression_Name', 'Twig\Node\Expression\NameExpression', false);
vendor/twig/twig/lib/Twig/Node/Expression/NullCoalesce.php CHANGED
@@ -44,3 +44,5 @@ class Twig_Node_Expression_NullCoalesce extends Twig_Node_Expression_Conditional
44
  }
45
  }
46
  }
 
 
44
  }
45
  }
46
  }
47
+
48
+ class_alias('Twig_Node_Expression_NullCoalesce', 'Twig\Node\Expression\NullCoalesceExpression', false);
vendor/twig/twig/lib/Twig/Node/Expression/Parent.php CHANGED
@@ -40,3 +40,5 @@ class Twig_Node_Expression_Parent extends Twig_Node_Expression
40
  }
41
  }
42
  }
 
 
40
  }
41
  }
42
  }
43
+
44
+ class_alias('Twig_Node_Expression_Parent', 'Twig\Node\Expression\ParentExpression', false);
vendor/twig/twig/lib/Twig/Node/Expression/TempName.php CHANGED
@@ -24,3 +24,5 @@ class Twig_Node_Expression_TempName extends Twig_Node_Expression
24
  ;
25
  }
26
  }
 
 
24
  ;
25
  }
26
  }
27
+
28
+ class_alias('Twig_Node_Expression_TempName', 'Twig\Node\Expression\TempNameExpression', false);
vendor/twig/twig/lib/Twig/Node/Expression/Test.php CHANGED
@@ -38,3 +38,5 @@ class Twig_Node_Expression_Test extends Twig_Node_Expression_Call
38
  $this->compileCallable($compiler);
39
  }
40
  }
 
 
38
  $this->compileCallable($compiler);
39
  }
40
  }
41
+
42
+ class_alias('Twig_Node_Expression_Test', 'Twig\Node\Expression\TestExpression', false);
vendor/twig/twig/lib/Twig/Node/Expression/Test/Constant.php CHANGED
@@ -44,3 +44,5 @@ class Twig_Node_Expression_Test_Constant extends Twig_Node_Expression_Test
44
  ;
45
  }
46
  }
 
 
44
  ;
45
  }
46
  }
47
+
48
+ class_alias('Twig_Node_Expression_Test_Constant', 'Twig\Node\Expression\Test\ConstantTest', false);
vendor/twig/twig/lib/Twig/Node/Expression/Test/Defined.php CHANGED
@@ -57,3 +57,5 @@ class Twig_Node_Expression_Test_Defined extends Twig_Node_Expression_Test
57
  $compiler->subcompile($this->getNode('node'));
58
  }
59
  }
 
 
57
  $compiler->subcompile($this->getNode('node'));
58
  }
59
  }
60
+
61
+ class_alias('Twig_Node_Expression_Test_Defined', 'Twig\Node\Expression\Test\DefinedTest', false);
vendor/twig/twig/lib/Twig/Node/Expression/Test/Divisibleby.php CHANGED
@@ -31,3 +31,5 @@ class Twig_Node_Expression_Test_Divisibleby extends Twig_Node_Expression_Test
31
  ;
32
  }
33
  }
 
 
31
  ;
32
  }
33
  }
34
+
35
+ class_alias('Twig_Node_Expression_Test_Divisibleby', 'Twig\Node\Expression\Test\DivisiblebyTest', false);
vendor/twig/twig/lib/Twig/Node/Expression/Test/Even.php CHANGED
@@ -30,3 +30,5 @@ class Twig_Node_Expression_Test_Even extends Twig_Node_Expression_Test
30
  ;
31
  }
32
  }
 
 
30
  ;
31
  }
32
  }
33
+
34
+ class_alias('Twig_Node_Expression_Test_Even', 'Twig\Node\Expression\Test\EvenTest', false);
vendor/twig/twig/lib/Twig/Node/Expression/Test/Null.php CHANGED
@@ -29,3 +29,5 @@ class Twig_Node_Expression_Test_Null extends Twig_Node_Expression_Test
29
  ;
30
  }
31
  }
 
 
29
  ;
30
  }
31
  }
32
+
33
+ class_alias('Twig_Node_Expression_Test_Null', 'Twig\Node\Expression\Test\NullTest', false);
vendor/twig/twig/lib/Twig/Node/Expression/Test/Odd.php CHANGED
@@ -30,3 +30,5 @@ class Twig_Node_Expression_Test_Odd extends Twig_Node_Expression_Test
30
  ;
31
  }
32
  }
 
 
30
  ;
31
  }
32
  }
33
+
34
+ class_alias('Twig_Node_Expression_Test_Odd', 'Twig\Node\Expression\Test\OddTest', false);
vendor/twig/twig/lib/Twig/Node/Expression/Test/Sameas.php CHANGED
@@ -27,3 +27,5 @@ class Twig_Node_Expression_Test_Sameas extends Twig_Node_Expression_Test
27
  ;
28
  }
29
  }
 
 
27
  ;
28
  }
29
  }
30
+
31
+ class_alias('Twig_Node_Expression_Test_Sameas', 'Twig\Node\Expression\Test\SameasTest', false);
vendor/twig/twig/lib/Twig/Node/Expression/Unary.php CHANGED
@@ -25,3 +25,5 @@ abstract class Twig_Node_Expression_Unary extends Twig_Node_Expression
25
 
26
  abstract public function operator(Twig_Compiler $compiler);
27
  }
 
 
25
 
26
  abstract public function operator(Twig_Compiler $compiler);
27
  }
28
+
29
+ class_alias('Twig_Node_Expression_Unary', 'Twig\Node\Expression\Unary\AbstractUnary', false);
vendor/twig/twig/lib/Twig/Node/Expression/Unary/Neg.php CHANGED
@@ -16,3 +16,5 @@ class Twig_Node_Expression_Unary_Neg extends Twig_Node_Expression_Unary
16
  $compiler->raw('-');
17
  }
18
  }
 
 
16
  $compiler->raw('-');
17
  }
18
  }
19
+
20
+ class_alias('Twig_Node_Expression_Unary_Neg', 'Twig\Node\Expression\Unary\NegUnary', false);
vendor/twig/twig/lib/Twig/Node/Expression/Unary/Not.php CHANGED
@@ -16,3 +16,5 @@ class Twig_Node_Expression_Unary_Not extends Twig_Node_Expression_Unary
16
  $compiler->raw('!');
17
  }
18
  }
 
 
16
  $compiler->raw('!');
17
  }
18
  }
19
+
20
+ class_alias('Twig_Node_Expression_Unary_Not', 'Twig\Node\Expression\Unary\NotUnary', false);
vendor/twig/twig/lib/Twig/Node/Expression/Unary/Pos.php CHANGED
@@ -16,3 +16,5 @@ class Twig_Node_Expression_Unary_Pos extends Twig_Node_Expression_Unary
16
  $compiler->raw('+');
17
  }
18
  }
 
 
16
  $compiler->raw('+');
17
  }
18
  }
19
+
20
+ class_alias('Twig_Node_Expression_Unary_Pos', 'Twig\Node\Expression\Unary\PosUnary', false);
vendor/twig/twig/lib/Twig/Node/Flush.php CHANGED
@@ -29,3 +29,5 @@ class Twig_Node_Flush extends Twig_Node
29
  ;
30
  }
31
  }
 
 
29
  ;
30
  }
31
  }
32
+
33
+ class_alias('Twig_Node_Flush', 'Twig\Node\FlushNode', false);
vendor/twig/twig/lib/Twig/Node/For.php CHANGED
@@ -109,3 +109,5 @@ class Twig_Node_For extends Twig_Node
109
  $compiler->write("\$context = array_intersect_key(\$context, \$_parent) + \$_parent;\n");
110
  }
111
  }
 
 
109
  $compiler->write("\$context = array_intersect_key(\$context, \$_parent) + \$_parent;\n");
110
  }
111
  }
112
+
113
+ class_alias('Twig_Node_For', 'Twig\Node\ForNode', false);
vendor/twig/twig/lib/Twig/Node/ForLoop.php CHANGED
@@ -48,3 +48,5 @@ class Twig_Node_ForLoop extends Twig_Node
48
  }
49
  }
50
  }
 
 
48
  }
49
  }
50
  }
51
+
52
+ class_alias('Twig_Node_ForLoop', 'Twig\Node\ForLoopNode', false);
vendor/twig/twig/lib/Twig/Node/If.php CHANGED
@@ -64,3 +64,5 @@ class Twig_Node_If extends Twig_Node
64
  ->write("}\n");
65
  }
66
  }
 
 
64
  ->write("}\n");
65
  }
66
  }
67
+
68
+ class_alias('Twig_Node_If', 'Twig\Node\IfNode', false);
vendor/twig/twig/lib/Twig/Node/Import.php CHANGED
@@ -47,3 +47,5 @@ class Twig_Node_Import extends Twig_Node
47
  $compiler->raw(";\n");
48
  }
49
  }
 
 
47
  $compiler->raw(";\n");
48
  }
49
  }
50
+
51
+ class_alias('Twig_Node_Import', 'Twig\Node\ImportNode', false);
vendor/twig/twig/lib/Twig/Node/Include.php CHANGED
@@ -86,3 +86,5 @@ class Twig_Node_Include extends Twig_Node implements Twig_NodeOutputInterface
86
  }
87
  }
88
  }
 
 
86
  }
87
  }
88
  }
89
+
90
+ class_alias('Twig_Node_Include', 'Twig\Node\IncludeNode', false);
vendor/twig/twig/lib/Twig/Node/Macro.php CHANGED
@@ -121,3 +121,5 @@ class Twig_Node_Macro extends Twig_Node
121
  ;
122
  }
123
  }
 
 
121
  ;
122
  }
123
  }
124
+
125
+ class_alias('Twig_Node_Macro', 'Twig\Node\MacroNode', false);
vendor/twig/twig/lib/Twig/Node/Module.php CHANGED
@@ -457,3 +457,5 @@ class Twig_Node_Module extends Twig_Node
457
  }
458
  }
459
  }
 
 
457
  }
458
  }
459
  }
460
+
461
+ class_alias('Twig_Node_Module', 'Twig\Node\ModuleNode', false);
vendor/twig/twig/lib/Twig/Node/Print.php CHANGED
@@ -32,3 +32,5 @@ class Twig_Node_Print extends Twig_Node implements Twig_NodeOutputInterface
32
  ;
33
  }
34
  }
 
 
32
  ;
33
  }
34
  }
35
+
36
+ class_alias('Twig_Node_Print', 'Twig\Node\PrintNode', false);
vendor/twig/twig/lib/Twig/Node/Sandbox.php CHANGED
@@ -40,3 +40,5 @@ class Twig_Node_Sandbox extends Twig_Node
40
  ;
41
  }
42
  }
 
 
40
  ;
41
  }
42
  }
43
+
44
+ class_alias('Twig_Node_Sandbox', 'Twig\Node\SandboxNode', false);
vendor/twig/twig/lib/Twig/Node/SandboxedPrint.php CHANGED
@@ -47,3 +47,5 @@ class Twig_Node_SandboxedPrint extends Twig_Node_Print
47
  return $node;
48
  }
49
  }
 
 
47
  return $node;
48
  }
49
  }
50
+
51
+ class_alias('Twig_Node_SandboxedPrint', 'Twig\Node\SandboxedPrintNode', false);
vendor/twig/twig/lib/Twig/Node/Set.php CHANGED
@@ -94,3 +94,5 @@ class Twig_Node_Set extends Twig_Node implements Twig_NodeCaptureInterface
94
  $compiler->raw(";\n");
95
  }
96
  }
 
 
94
  $compiler->raw(";\n");
95
  }
96
  }
97
+
98
+ class_alias('Twig_Node_Set', 'Twig\Node\SetNode', false);
vendor/twig/twig/lib/Twig/Node/SetTemp.php CHANGED
@@ -9,6 +9,9 @@
9
  * file that was distributed with this source code.
10
  */
11
 
 
 
 
12
  class Twig_Node_SetTemp extends Twig_Node
13
  {
14
  public function __construct($name, $lineno)
@@ -33,3 +36,5 @@ class Twig_Node_SetTemp extends Twig_Node
33
  ;
34
  }
35
  }
 
 
9
  * file that was distributed with this source code.
10
  */
11
 
12
+ /**
13
+ * @internal
14
+ */
15
  class Twig_Node_SetTemp extends Twig_Node
16
  {
17
  public function __construct($name, $lineno)
36
  ;
37
  }
38
  }
39
+
40
+ class_alias('Twig_Node_SetTemp', 'Twig\Node\SetTempNode', false);
vendor/twig/twig/lib/Twig/Node/Spaceless.php CHANGED
@@ -33,3 +33,5 @@ class Twig_Node_Spaceless extends Twig_Node
33
  ;
34
  }
35
  }
 
 
33
  ;
34
  }
35
  }
36
+
37
+ class_alias('Twig_Node_Spaceless', 'Twig\Node\SpacelessNode', false);
vendor/twig/twig/lib/Twig/Node/Text.php CHANGED
@@ -32,3 +32,5 @@ class Twig_Node_Text extends Twig_Node implements Twig_NodeOutputInterface
32
  ;
33
  }
34
  }
 
 
32
  ;
33
  }
34
  }
35
+
36
+ class_alias('Twig_Node_Text', 'Twig\Node\TextNode', false);
vendor/twig/twig/lib/Twig/Node/With.php CHANGED
@@ -60,3 +60,5 @@ class Twig_Node_With extends Twig_Node
60
  ;
61
  }
62
  }
 
 
60
  ;
61
  }
62
  }
63
+
64
+ class_alias('Twig_Node_With', 'Twig\Node\WithNode', false);
vendor/twig/twig/lib/Twig/NodeCaptureInterface.php CHANGED
@@ -17,3 +17,5 @@
17
  interface Twig_NodeCaptureInterface
18
  {
19
  }
 
 
17
  interface Twig_NodeCaptureInterface
18
  {
19
  }
20
+
21
+ class_alias('Twig_NodeCaptureInterface', 'Twig\Node\NodeCaptureInterface', false);
vendor/twig/twig/lib/Twig/NodeOutputInterface.php CHANGED
@@ -17,3 +17,5 @@
17
  interface Twig_NodeOutputInterface
18
  {
19
  }
 
 
17
  interface Twig_NodeOutputInterface
18
  {
19
  }
20
+
21
+ class_alias('Twig_NodeOutputInterface', 'Twig\Node\NodeOutputInterface', false);
vendor/twig/twig/lib/Twig/NodeTraverser.php CHANGED
@@ -80,3 +80,5 @@ class Twig_NodeTraverser
80
  return $visitor->leaveNode($node, $this->env);
81
  }
82
  }
 
 
80
  return $visitor->leaveNode($node, $this->env);
81
  }
82
  }
83
+
84
+ class_alias('Twig_NodeTraverser', 'Twig\NodeTraverser', false);
vendor/twig/twig/lib/Twig/NodeVisitor/Escaper.php CHANGED
@@ -150,3 +150,5 @@ class Twig_NodeVisitor_Escaper extends Twig_BaseNodeVisitor
150
  return 0;
151
  }
152
  }
 
 
150
  return 0;
151
  }
152
  }
153
+
154
+ class_alias('Twig_NodeVisitor_Escaper', 'Twig\NodeVisitor\EscaperNodeVisitor', false);
vendor/twig/twig/lib/Twig/NodeVisitor/Optimizer.php CHANGED
@@ -249,3 +249,5 @@ class Twig_NodeVisitor_Optimizer extends Twig_BaseNodeVisitor
249
  return 255;
250
  }
251
  }
 
 
249
  return 255;
250
  }
251
  }
252
+
253
+ class_alias('Twig_NodeVisitor_Optimizer', 'Twig\NodeVisitor\OptimizerNodeVisitor', false);
vendor/twig/twig/lib/Twig/NodeVisitor/SafeAnalysis.php CHANGED
@@ -146,3 +146,5 @@ class Twig_NodeVisitor_SafeAnalysis extends Twig_BaseNodeVisitor
146
  return 0;
147
  }
148
  }
 
 
146
  return 0;
147
  }
148
  }
149
+
150
+ class_alias('Twig_NodeVisitor_SafeAnalysis', 'Twig\NodeVisitor\SafeAnalysisNodeVisitor', false);
vendor/twig/twig/lib/Twig/NodeVisitor/Sandbox.php CHANGED
@@ -73,3 +73,5 @@ class Twig_NodeVisitor_Sandbox extends Twig_BaseNodeVisitor
73
  return 0;
74
  }
75
  }
 
 
73
  return 0;
74
  }
75
  }
76
+
77
+ class_alias('Twig_NodeVisitor_Sandbox', 'Twig\NodeVisitor\SandboxNodeVisitor', false);
vendor/twig/twig/lib/Twig/NodeVisitorInterface.php CHANGED
@@ -39,3 +39,7 @@ interface Twig_NodeVisitorInterface
39
  */
40
  public function getPriority();
41
  }
 
 
 
 
39
  */
40
  public function getPriority();
41
  }
42
+
43
+ class_alias('Twig_NodeVisitorInterface', 'Twig\NodeVisitor\NodeVisitorInterface', false);
44
+ class_exists('Twig_Environment');
45
+ class_exists('Twig_Node');
vendor/twig/twig/lib/Twig/Parser.php CHANGED
@@ -404,3 +404,7 @@ class Twig_Parser implements Twig_ParserInterface
404
  return $node;
405
  }
406
  }
 
 
 
 
404
  return $node;
405
  }
406
  }
407
+
408
+ class_alias('Twig_Parser', 'Twig\Parser', false);
409
+ class_exists('Twig_Node');
410
+ class_exists('Twig_TokenStream');
vendor/twig/twig/lib/Twig/Profiler/Dumper/Base.php ADDED
@@ -0,0 +1,62 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of Twig.
5
+ *
6
+ * (c) Fabien Potencier
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ /**
13
+ * @author Fabien Potencier <fabien@symfony.com>
14
+ */
15
+ abstract class Twig_Profiler_Dumper_Base
16
+ {
17
+ private $root;
18
+
19
+ public function dump(Twig_Profiler_Profile $profile)
20
+ {
21
+ return $this->dumpProfile($profile);
22
+ }
23
+
24
+ abstract protected function formatTemplate(Twig_Profiler_Profile $profile, $prefix);
25
+
26
+ abstract protected function formatNonTemplate(Twig_Profiler_Profile $profile, $prefix);
27
+
28
+ abstract protected function formatTime(Twig_Profiler_Profile $profile, $percent);
29
+
30
+ private function dumpProfile(Twig_Profiler_Profile $profile, $prefix = '', $sibling = false)
31
+ {
32
+ if ($profile->isRoot()) {
33
+ $this->root = $profile->getDuration();
34
+ $start = $profile->getName();
35
+ } else {
36
+ if ($profile->isTemplate()) {
37
+ $start = $this->formatTemplate($profile, $prefix);
38
+ } else {
39
+ $start = $this->formatNonTemplate($profile, $prefix);
40
+ }
41
+ $prefix .= $sibling ? '│ ' : ' ';
42
+ }
43
+
44
+ $percent = $this->root ? $profile->getDuration() / $this->root * 100 : 0;
45
+
46
+ if ($profile->getDuration() * 1000 < 1) {
47
+ $str = $start."\n";
48
+ } else {
49
+ $str = sprintf("%s %s\n", $start, $this->formatTime($profile, $percent));
50
+ }
51
+
52
+ $nCount = count($profile->getProfiles());
53
+ foreach ($profile as $i => $p) {
54
+ $str .= $this->dumpProfile($p, $prefix, $i + 1 !== $nCount);
55
+ }
56
+
57
+ return $str;
58
+ }
59
+ }
60
+
61
+ class_alias('Twig_Profiler_Dumper_Base', 'Twig\Profiler\Dumper\BaseDumper', false);
62
+ class_exists('Twig_Profiler_Profile');
vendor/twig/twig/lib/Twig/Profiler/Dumper/Blackfire.php CHANGED
@@ -68,3 +68,5 @@ EOF;
68
  }
69
  }
70
  }
 
 
68
  }
69
  }
70
  }
71
+
72
+ class_alias('Twig_Profiler_Dumper_Blackfire', 'Twig\Profiler\Dumper\BlackfireDumper', false);
vendor/twig/twig/lib/Twig/Profiler/Dumper/Html.php CHANGED
@@ -14,7 +14,7 @@
14
  *
15
  * @final
16
  */
17
- class Twig_Profiler_Dumper_Html extends Twig_Profiler_Dumper_Text
18
  {
19
  private static $colors = array(
20
  'block' => '#dfd',
@@ -43,3 +43,5 @@ class Twig_Profiler_Dumper_Html extends Twig_Profiler_Dumper_Text
43
  return sprintf('<span style="color: %s">%.2fms/%.0f%%</span>', $percent > 20 ? self::$colors['big'] : 'auto', $profile->getDuration() * 1000, $percent);
44
  }
45
  }
 
 
14
  *
15
  * @final
16
  */
17
+ class Twig_Profiler_Dumper_Html extends Twig_Profiler_Dumper_Base
18
  {
19
  private static $colors = array(
20
  'block' => '#dfd',
43
  return sprintf('<span style="color: %s">%.2fms/%.0f%%</span>', $percent > 20 ? self::$colors['big'] : 'auto', $profile->getDuration() * 1000, $percent);
44
  }
45
  }
46
+
47
+ class_alias('Twig_Profiler_Dumper_Html', 'Twig\Profiler\Dumper\HtmlDumper', false);
vendor/twig/twig/lib/Twig/Profiler/Dumper/Text.php CHANGED
@@ -14,15 +14,8 @@
14
  *
15
  * @final
16
  */
17
- class Twig_Profiler_Dumper_Text
18
  {
19
- private $root;
20
-
21
- public function dump(Twig_Profiler_Profile $profile)
22
- {
23
- return $this->dumpProfile($profile);
24
- }
25
-
26
  protected function formatTemplate(Twig_Profiler_Profile $profile, $prefix)
27
  {
28
  return sprintf('%s└ %s', $prefix, $profile->getTemplate());
@@ -37,34 +30,6 @@ class Twig_Profiler_Dumper_Text
37
  {
38
  return sprintf('%.2fms/%.0f%%', $profile->getDuration() * 1000, $percent);
39
  }
40
-
41
- private function dumpProfile(Twig_Profiler_Profile $profile, $prefix = '', $sibling = false)
42
- {
43
- if ($profile->isRoot()) {
44
- $this->root = $profile->getDuration();
45
- $start = $profile->getName();
46
- } else {
47
- if ($profile->isTemplate()) {
48
- $start = $this->formatTemplate($profile, $prefix);
49
- } else {
50
- $start = $this->formatNonTemplate($profile, $prefix);
51
- }
52
- $prefix .= $sibling ? '│ ' : ' ';
53
- }
54
-
55
- $percent = $this->root ? $profile->getDuration() / $this->root * 100 : 0;
56
-
57
- if ($profile->getDuration() * 1000 < 1) {
58
- $str = $start."\n";
59
- } else {
60
- $str = sprintf("%s %s\n", $start, $this->formatTime($profile, $percent));
61
- }
62
-
63
- $nCount = count($profile->getProfiles());
64
- foreach ($profile as $i => $p) {
65
- $str .= $this->dumpProfile($p, $prefix, $i + 1 !== $nCount);
66
- }
67
-
68
- return $str;
69
- }
70
  }
 
 
14
  *
15
  * @final
16
  */
17
+ class Twig_Profiler_Dumper_Text extends Twig_Profiler_Dumper_Base
18
  {
 
 
 
 
 
 
 
19
  protected function formatTemplate(Twig_Profiler_Profile $profile, $prefix)
20
  {
21
  return sprintf('%s└ %s', $prefix, $profile->getTemplate());
30
  {
31
  return sprintf('%.2fms/%.0f%%', $profile->getDuration() * 1000, $percent);
32
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
33
  }
34
+
35
+ class_alias('Twig_Profiler_Dumper_Text', 'Twig\Profiler\Dumper\TextDumper', false);
vendor/twig/twig/lib/Twig/Profiler/Node/EnterProfile.php CHANGED
@@ -35,3 +35,5 @@ class Twig_Profiler_Node_EnterProfile extends Twig_Node
35
  ;
36
  }
37
  }
 
 
35
  ;
36
  }
37
  }
38
+
39
+ class_alias('Twig_Profiler_Node_EnterProfile', 'Twig\Profiler\Node\EnterProfileNode', false);
vendor/twig/twig/lib/Twig/Profiler/Node/LeaveProfile.php CHANGED
@@ -29,3 +29,5 @@ class Twig_Profiler_Node_LeaveProfile extends Twig_Node
29
  ;
30
  }
31
  }
 
 
29
  ;
30
  }
31
  }
32
+
33
+ class_alias('Twig_Profiler_Node_LeaveProfile', 'Twig\Profiler\Node\LeaveProfileNode', false);
vendor/twig/twig/lib/Twig/Profiler/NodeVisitor/Profiler.php CHANGED
@@ -63,3 +63,5 @@ class Twig_Profiler_NodeVisitor_Profiler extends Twig_BaseNodeVisitor
63
  return 0;
64
  }
65
  }
 
 
63
  return 0;
64
  }
65
  }
66
+
67
+ class_alias('Twig_Profiler_NodeVisitor_Profiler', 'Twig\Profiler\NodeVisitor\ProfilerNodeVisitor', false);
vendor/twig/twig/lib/Twig/Profiler/Profile.php CHANGED
@@ -160,3 +160,5 @@ class Twig_Profiler_Profile implements IteratorAggregate, Serializable
160
  list($this->template, $this->name, $this->type, $this->starts, $this->ends, $this->profiles) = unserialize($data);
161
  }
162
  }
 
 
160
  list($this->template, $this->name, $this->type, $this->starts, $this->ends, $this->profiles) = unserialize($data);
161
  }
162
  }
163
+
164
+ class_alias('Twig_Profiler_Profile', 'Twig\Profiler\Profile', false);
vendor/twig/twig/lib/Twig/RuntimeLoaderInterface.php CHANGED
@@ -25,3 +25,5 @@ interface Twig_RuntimeLoaderInterface
25
  */
26
  public function load($class);
27
  }
 
 
25
  */
26
  public function load($class);
27
  }
28
+
29
+ class_alias('Twig_RuntimeLoaderInterface', 'Twig\RuntimeLoader\RuntimeLoaderInterface', false);
vendor/twig/twig/lib/Twig/Sandbox/SecurityError.php CHANGED
@@ -17,3 +17,5 @@
17
  class Twig_Sandbox_SecurityError extends Twig_Error
18
  {
19
  }
 
 
17
  class Twig_Sandbox_SecurityError extends Twig_Error
18
  {
19
  }
20
+
21
+ class_alias('Twig_Sandbox_SecurityError', 'Twig\Sandbox\SecurityError', false);
vendor/twig/twig/lib/Twig/Sandbox/SecurityNotAllowedFilterError.php CHANGED
@@ -29,3 +29,5 @@ class Twig_Sandbox_SecurityNotAllowedFilterError extends Twig_Sandbox_SecurityEr
29
  return $this->filterName;
30
  }
31
  }
 
 
29
  return $this->filterName;
30
  }
31
  }
32
+
33
+ class_alias('Twig_Sandbox_SecurityNotAllowedFilterError', 'Twig\Sandbox\SecurityNotAllowedFilterError', false);
vendor/twig/twig/lib/Twig/Sandbox/SecurityNotAllowedFunctionError.php CHANGED
@@ -29,3 +29,5 @@ class Twig_Sandbox_SecurityNotAllowedFunctionError extends Twig_Sandbox_Security
29
  return $this->functionName;
30
  }
31
  }
 
 
29
  return $this->functionName;
30
  }
31
  }
32
+
33
+ class_alias('Twig_Sandbox_SecurityNotAllowedFunctionError', 'Twig\Sandbox\SecurityNotAllowedFunctionError', false);
vendor/twig/twig/lib/Twig/Sandbox/SecurityNotAllowedMethodError.php CHANGED
@@ -36,3 +36,5 @@ class Twig_Sandbox_SecurityNotAllowedMethodError extends Twig_Sandbox_SecurityEr
36
  return $this->methodName;
37
  }
38
  }
 
 
36
  return $this->methodName;
37
  }
38
  }
39
+
40
+ class_alias('Twig_Sandbox_SecurityNotAllowedMethodError', 'Twig\Sandbox\SecurityNotAllowedMethodError', false);
vendor/twig/twig/lib/Twig/Sandbox/SecurityNotAllowedPropertyError.php CHANGED
@@ -36,3 +36,5 @@ class Twig_Sandbox_SecurityNotAllowedPropertyError extends Twig_Sandbox_Security
36
  return $this->propertyName;
37
  }
38
  }
 
 
36
  return $this->propertyName;
37
  }
38
  }
39
+
40
+ class_alias('Twig_Sandbox_SecurityNotAllowedPropertyError', 'Twig\Sandbox\SecurityNotAllowedPropertyError', false);
vendor/twig/twig/lib/Twig/Sandbox/SecurityNotAllowedTagError.php CHANGED
@@ -29,3 +29,5 @@ class Twig_Sandbox_SecurityNotAllowedTagError extends Twig_Sandbox_SecurityError
29
  return $this->tagName;
30
  }
31
  }
 
 
29
  return $this->tagName;
30
  }
31
  }
32
+
33
+ class_alias('Twig_Sandbox_SecurityNotAllowedTagError', 'Twig\Sandbox\SecurityNotAllowedTagError', false);
vendor/twig/twig/lib/Twig/Sandbox/SecurityPolicy.php CHANGED
@@ -121,3 +121,5 @@ class Twig_Sandbox_SecurityPolicy implements Twig_Sandbox_SecurityPolicyInterfac
121
  }
122
  }
123
  }
 
 
121
  }
122
  }
123
  }
124
+
125
+ class_alias('Twig_Sandbox_SecurityPolicy', 'Twig\Sandbox\SecurityPolicy', false);
vendor/twig/twig/lib/Twig/Sandbox/SecurityPolicyInterface.php CHANGED
@@ -22,3 +22,5 @@ interface Twig_Sandbox_SecurityPolicyInterface
22
 
23
  public function checkPropertyAllowed($obj, $method);
24
  }
 
 
22
 
23
  public function checkPropertyAllowed($obj, $method);
24
  }
25
+
26
+ class_alias('Twig_Sandbox_SecurityPolicyInterface', 'Twig\Sandbox\SecurityPolicyInterface', false);
vendor/twig/twig/lib/Twig/SimpleFilter.php CHANGED
@@ -117,3 +117,5 @@ class Twig_SimpleFilter
117
  return $this->options['alternative'];
118
  }
119
  }
 
 
117
  return $this->options['alternative'];
118
  }
119
  }
120
+
121
+ class_alias('Twig_SimpleFilter', 'Twig\TwigFilter', false);
vendor/twig/twig/lib/Twig/SimpleFunction.php CHANGED
@@ -107,3 +107,5 @@ class Twig_SimpleFunction
107
  return $this->options['alternative'];
108
  }
109
  }
 
 
107
  return $this->options['alternative'];
108
  }
109
  }
110
+
111
+ class_alias('Twig_SimpleFunction', 'Twig\TwigFunction', false);
vendor/twig/twig/lib/Twig/SimpleTest.php CHANGED
@@ -69,3 +69,5 @@ class Twig_SimpleTest
69
  return $this->options['alternative'];
70
  }
71
  }
 
 
69
  return $this->options['alternative'];
70
  }
71
  }
72
+
73
+ class_alias('Twig_SimpleTest', 'Twig\TwigTest', false);
vendor/twig/twig/lib/Twig/Source.php CHANGED
@@ -49,3 +49,5 @@ class Twig_Source
49
  return $this->path;
50
  }
51
  }
 
 
49
  return $this->path;
50
  }
51
  }
52
+
53
+ class_alias('Twig_Source', 'Twig\Source', false);
vendor/twig/twig/lib/Twig/SourceContextLoaderInterface.php CHANGED
@@ -29,3 +29,5 @@ interface Twig_SourceContextLoaderInterface
29
  */
30
  public function getSourceContext($name);
31
  }
 
 
29
  */
30
  public function getSourceContext($name);
31
  }
32
+
33
+ class_alias('Twig_SourceContextLoaderInterface', 'Twig\Loader\SourceContextLoaderInterface', false);
vendor/twig/twig/lib/Twig/Template.php CHANGED
@@ -627,11 +627,14 @@ abstract class Twig_Template implements Twig_TemplateInterface
627
  continue;
628
  }
629
 
630
- if (!isset($cache[$name])) {
631
- $cache[$name] = $method;
632
- }
633
- if (!isset($cache[$lcName])) {
634
- $cache[$lcName] = $method;
 
 
 
635
  }
636
  }
637
  self::$cache[$class] = $cache;
@@ -699,3 +702,5 @@ abstract class Twig_Template implements Twig_TemplateInterface
699
  return $ret;
700
  }
701
  }
 
 
627
  continue;
628
  }
629
 
630
+ // skip get() and is() methods (in which case, $name is empty)
631
+ if ($name) {
632
+ if (!isset($cache[$name])) {
633
+ $cache[$name] = $method;
634
+ }
635
+ if (!isset($cache[$lcName])) {
636
+ $cache[$lcName] = $method;
637
+ }
638
  }
639
  }
640
  self::$cache[$class] = $cache;
702
  return $ret;
703
  }
704
  }
705
+
706
+ class_alias('Twig_Template', 'Twig\Template', false);
vendor/twig/twig/lib/Twig/TemplateWrapper.php CHANGED
@@ -129,3 +129,5 @@ final class Twig_TemplateWrapper
129
  return $this->template->getSourceContext();
130
  }
131
  }
 
 
129
  return $this->template->getSourceContext();
130
  }
131
  }
132
+
133
+ class_alias('Twig_TemplateWrapper', 'Twig\TemplateWrapper', false);
vendor/twig/twig/lib/Twig/Test/IntegrationTestCase.php CHANGED
@@ -9,19 +9,29 @@
9
  * file that was distributed with this source code.
10
  */
11
 
 
 
12
  /**
13
  * Integration test helper.
14
  *
15
  * @author Fabien Potencier <fabien@symfony.com>
16
  * @author Karma Dordrak <drak@zikula.org>
17
  */
18
- abstract class Twig_Test_IntegrationTestCase extends PHPUnit_Framework_TestCase
19
  {
20
  /**
21
  * @return string
22
  */
23
  abstract protected function getFixturesDir();
24
 
 
 
 
 
 
 
 
 
25
  /**
26
  * @return Twig_ExtensionInterface[]
27
  */
@@ -141,6 +151,10 @@ abstract class Twig_Test_IntegrationTestCase extends PHPUnit_Framework_TestCase
141
  ), $match[2] ? eval($match[2].';') : array());
142
  $twig = new Twig_Environment($loader, $config);
143
  $twig->addGlobal('global', 'global');
 
 
 
 
144
  foreach ($this->getExtensions() as $extension) {
145
  $twig->addExtension($extension);
146
  }
@@ -196,7 +210,8 @@ abstract class Twig_Test_IntegrationTestCase extends PHPUnit_Framework_TestCase
196
 
197
  if (false !== $exception) {
198
  list($class) = explode(':', $exception);
199
- $this->assertThat(null, new PHPUnit_Framework_Constraint_Exception($class));
 
200
  }
201
 
202
  $expected = trim($match[3], "\n ");
@@ -230,3 +245,5 @@ abstract class Twig_Test_IntegrationTestCase extends PHPUnit_Framework_TestCase
230
  return $templates;
231
  }
232
  }
 
 
9
  * file that was distributed with this source code.
10
  */
11
 
12
+ use PHPUnit\Framework\TestCase;
13
+
14
  /**
15
  * Integration test helper.
16
  *
17
  * @author Fabien Potencier <fabien@symfony.com>
18
  * @author Karma Dordrak <drak@zikula.org>
19
  */
20
+ abstract class Twig_Test_IntegrationTestCase extends TestCase
21
  {
22
  /**
23
  * @return string
24
  */
25
  abstract protected function getFixturesDir();
26
 
27
+ /**
28
+ * @return Twig_RuntimeLoaderInterface[]
29
+ */
30
+ protected function getRuntimeLoaders()
31
+ {
32
+ return array();
33
+ }
34
+
35
  /**
36
  * @return Twig_ExtensionInterface[]
37
  */
151
  ), $match[2] ? eval($match[2].';') : array());
152
  $twig = new Twig_Environment($loader, $config);
153
  $twig->addGlobal('global', 'global');
154
+ foreach ($this->getRuntimeLoaders() as $runtimeLoader) {
155
+ $twig->addRuntimeLoader($runtimeLoader);
156
+ }
157
+
158
  foreach ($this->getExtensions() as $extension) {
159
  $twig->addExtension($extension);
160
  }
210
 
211
  if (false !== $exception) {
212
  list($class) = explode(':', $exception);
213
+ $constraintClass = class_exists('PHPUnit\Framework\Constraint\Exception') ? 'PHPUnit\Framework\Constraint\Exception' : 'PHPUnit_Framework_Constraint_Exception';
214
+ $this->assertThat(null, new $constraintClass($class));
215
  }
216
 
217
  $expected = trim($match[3], "\n ");
245
  return $templates;
246
  }
247
  }
248
+
249
+ class_alias('Twig_Test_IntegrationTestCase', 'Twig\Test\IntegrationTestCase', false);
vendor/twig/twig/lib/Twig/Test/NodeTestCase.php CHANGED
@@ -8,7 +8,10 @@
8
  * For the full copyright and license information, please view the LICENSE
9
  * file that was distributed with this source code.
10
  */
11
- abstract class Twig_Test_NodeTestCase extends PHPUnit_Framework_TestCase
 
 
 
12
  {
13
  abstract public function getTests();
14
 
@@ -66,3 +69,7 @@ abstract class Twig_Test_NodeTestCase extends PHPUnit_Framework_TestCase
66
  return '$this->getAttribute(';
67
  }
68
  }
 
 
 
 
8
  * For the full copyright and license information, please view the LICENSE
9
  * file that was distributed with this source code.
10
  */
11
+
12
+ use PHPUnit\Framework\TestCase;
13
+
14
+ abstract class Twig_Test_NodeTestCase extends TestCase
15
  {
16
  abstract public function getTests();
17
 
69
  return '$this->getAttribute(';
70
  }
71
  }
72
+
73
+ class_alias('Twig_Test_NodeTestCase', 'Twig\Test\NodeTestCase', false);
74
+ class_exists('Twig_Environment');
75
+ class_exists('Twig_Node');
vendor/twig/twig/lib/Twig/Token.php CHANGED
@@ -203,3 +203,5 @@ class Twig_Token
203
  }
204
  }
205
  }
 
 
203
  }
204
  }
205
  }
206
+
207
+ class_alias('Twig_Token', 'Twig\Token', false);
vendor/twig/twig/lib/Twig/TokenParser.php CHANGED
@@ -29,3 +29,5 @@ abstract class Twig_TokenParser implements Twig_TokenParserInterface
29
  $this->parser = $parser;
30
  }
31
  }
 
 
29
  $this->parser = $parser;
30
  }
31
  }
32
+
33
+ class_alias('Twig_TokenParser', 'Twig\TokenParser\AbstractTokenParser', false);
vendor/twig/twig/lib/Twig/TokenParser/AutoEscape.php CHANGED
@@ -79,3 +79,5 @@ class Twig_TokenParser_AutoEscape extends Twig_TokenParser
79
  return 'autoescape';
80
  }
81
  }
 
 
79
  return 'autoescape';
80
  }
81
  }
82
+
83
+ class_alias('Twig_TokenParser_AutoEscape', 'Twig\TokenParser\AutoEscapeTokenParser', false);
vendor/twig/twig/lib/Twig/TokenParser/Block.php CHANGED
@@ -69,3 +69,5 @@ class Twig_TokenParser_Block extends Twig_TokenParser
69
  return 'block';
70
  }
71
  }
 
 
69
  return 'block';
70
  }
71
  }
72
+
73
+ class_alias('Twig_TokenParser_Block', 'Twig\TokenParser\BlockTokenParser', false);
vendor/twig/twig/lib/Twig/TokenParser/Do.php CHANGED
@@ -30,3 +30,5 @@ class Twig_TokenParser_Do extends Twig_TokenParser
30
  return 'do';
31
  }
32
  }
 
 
30
  return 'do';
31
  }
32
  }
33
+
34
+ class_alias('Twig_TokenParser_Do', 'Twig\TokenParser\DoTokenParser', false);
vendor/twig/twig/lib/Twig/TokenParser/Embed.php CHANGED
@@ -63,3 +63,5 @@ class Twig_TokenParser_Embed extends Twig_TokenParser_Include
63
  return 'embed';
64
  }
65
  }
 
 
63
  return 'embed';
64
  }
65
  }
66
+
67
+ class_alias('Twig_TokenParser_Embed', 'Twig\TokenParser\EmbedTokenParser', false);
vendor/twig/twig/lib/Twig/TokenParser/Extends.php CHANGED
@@ -42,3 +42,5 @@ class Twig_TokenParser_Extends extends Twig_TokenParser
42
  return 'extends';
43
  }
44
  }
 
 
42
  return 'extends';
43
  }
44
  }
45
+
46
+ class_alias('Twig_TokenParser_Extends', 'Twig\TokenParser\ExtendsTokenParser', false);
vendor/twig/twig/lib/Twig/TokenParser/Filter.php CHANGED
@@ -49,3 +49,5 @@ class Twig_TokenParser_Filter extends Twig_TokenParser
49
  return 'filter';
50
  }
51
  }
 
 
49
  return 'filter';
50
  }
51
  }
52
+
53
+ class_alias('Twig_TokenParser_Filter', 'Twig\TokenParser\FilterTokenParser', false);
vendor/twig/twig/lib/Twig/TokenParser/Flush.php CHANGED
@@ -30,3 +30,5 @@ class Twig_TokenParser_Flush extends Twig_TokenParser
30
  return 'flush';
31
  }
32
  }
 
 
30
  return 'flush';
31
  }
32
  }
33
+
34
+ class_alias('Twig_TokenParser_Flush', 'Twig\TokenParser\FlushTokenParser', false);
vendor/twig/twig/lib/Twig/TokenParser/For.php CHANGED
@@ -123,3 +123,5 @@ class Twig_TokenParser_For extends Twig_TokenParser
123
  return 'for';
124
  }
125
  }
 
 
123
  return 'for';
124
  }
125
  }
126
+
127
+ class_alias('Twig_TokenParser_For', 'Twig\TokenParser\ForTokenParser', false);
vendor/twig/twig/lib/Twig/TokenParser/From.php CHANGED
@@ -62,3 +62,5 @@ class Twig_TokenParser_From extends Twig_TokenParser
62
  return 'from';
63
  }
64
  }
 
 
62
  return 'from';
63
  }
64
  }
65
+
66
+ class_alias('Twig_TokenParser_From', 'Twig\TokenParser\FromTokenParser', false);
vendor/twig/twig/lib/Twig/TokenParser/If.php CHANGED
@@ -82,3 +82,5 @@ class Twig_TokenParser_If extends Twig_TokenParser
82
  return 'if';
83
  }
84
  }
 
 
82
  return 'if';
83
  }
84
  }
85
+
86
+ class_alias('Twig_TokenParser_If', 'Twig\TokenParser\IfTokenParser', false);
vendor/twig/twig/lib/Twig/TokenParser/Import.php CHANGED
@@ -37,3 +37,5 @@ class Twig_TokenParser_Import extends Twig_TokenParser
37
  return 'import';
38
  }
39
  }
 
 
37
  return 'import';
38
  }
39
  }
40
+
41
+ class_alias('Twig_TokenParser_Import', 'Twig\TokenParser\ImportTokenParser', false);
vendor/twig/twig/lib/Twig/TokenParser/Include.php CHANGED
@@ -18,8 +18,6 @@
18
  * Body
19
  * {% include 'footer.html' %}
20
  * </pre>
21
- *
22
- * @final
23
  */
24
  class Twig_TokenParser_Include extends Twig_TokenParser
25
  {
@@ -63,3 +61,5 @@ class Twig_TokenParser_Include extends Twig_TokenParser
63
  return 'include';
64
  }
65
  }
 
 
18
  * Body
19
  * {% include 'footer.html' %}
20
  * </pre>
 
 
21
  */
22
  class Twig_TokenParser_Include extends Twig_TokenParser
23
  {
61
  return 'include';
62
  }
63
  }
64
+
65
+ class_alias('Twig_TokenParser_Include', 'Twig\TokenParser\IncludeTokenParser', false);
vendor/twig/twig/lib/Twig/TokenParser/Macro.php CHANGED
@@ -56,3 +56,5 @@ class Twig_TokenParser_Macro extends Twig_TokenParser
56
  return 'macro';
57
  }
58
  }
 
 
56
  return 'macro';
57
  }
58
  }
59
+
60
+ class_alias('Twig_TokenParser_Macro', 'Twig\TokenParser\MacroTokenParser', false);
vendor/twig/twig/lib/Twig/TokenParser/Sandbox.php CHANGED
@@ -57,3 +57,5 @@ class Twig_TokenParser_Sandbox extends Twig_TokenParser
57
  return 'sandbox';
58
  }
59
  }
 
 
57
  return 'sandbox';
58
  }
59
  }
60
+
61
+ class_alias('Twig_TokenParser_Sandbox', 'Twig\TokenParser\SandboxTokenParser', false);
vendor/twig/twig/lib/Twig/TokenParser/Set.php CHANGED
@@ -71,3 +71,5 @@ class Twig_TokenParser_Set extends Twig_TokenParser
71
  return 'set';
72
  }
73
  }
 
 
71
  return 'set';
72
  }
73
  }
74
+
75
+ class_alias('Twig_TokenParser_Set', 'Twig\TokenParser\SetTokenParser', false);
vendor/twig/twig/lib/Twig/TokenParser/Spaceless.php CHANGED
@@ -47,3 +47,5 @@ class Twig_TokenParser_Spaceless extends Twig_TokenParser
47
  return 'spaceless';
48
  }
49
  }
 
 
47
  return 'spaceless';
48
  }
49
  }
50
+
51
+ class_alias('Twig_TokenParser_Spaceless', 'Twig\TokenParser\SpacelessTokenParser', false);
vendor/twig/twig/lib/Twig/TokenParser/Use.php CHANGED
@@ -64,3 +64,5 @@ class Twig_TokenParser_Use extends Twig_TokenParser
64
  return 'use';
65
  }
66
  }
 
 
64
  return 'use';
65
  }
66
  }
67
+
68
+ class_alias('Twig_TokenParser_Use', 'Twig\TokenParser\UseTokenParser', false);
vendor/twig/twig/lib/Twig/TokenParser/With.php CHANGED
@@ -48,3 +48,5 @@ class Twig_TokenParser_With extends Twig_TokenParser
48
  return 'with';
49
  }
50
  }
 
 
48
  return 'with';
49
  }
50
  }
51
+
52
+ class_alias('Twig_TokenParser_With', 'Twig\TokenParser\WithTokenParser', false);
vendor/twig/twig/lib/Twig/TokenParserInterface.php CHANGED
@@ -37,3 +37,7 @@ interface Twig_TokenParserInterface
37
  */
38
  public function getTag();
39
  }
 
 
 
 
37
  */
38
  public function getTag();
39
  }
40
+
41
+ class_alias('Twig_TokenParserInterface', 'Twig\TokenParser\TokenParserInterface', false);
42
+ class_exists('Twig_Parser');
43
+ class_exists('Twig_Token');
vendor/twig/twig/lib/Twig/TokenStream.php CHANGED
@@ -192,3 +192,5 @@ class Twig_TokenStream
192
  return $this->source;
193
  }
194
  }
 
 
192
  return $this->source;
193
  }
194
  }
195
+
196
+ class_alias('Twig_TokenStream', 'Twig\TokenStream', false);
vendor/twig/twig/lib/Twig/Util/DeprecationCollector.php CHANGED
@@ -82,3 +82,5 @@ class Twig_Util_DeprecationCollector
82
  }
83
  }
84
  }
 
 
82
  }
83
  }
84
  }
85
+
86
+ class_alias('Twig_Util_DeprecationCollector', 'Twig\Util\DeprecationCollector', false);
vendor/twig/twig/lib/Twig/Util/TemplateDirIterator.php CHANGED
@@ -24,3 +24,5 @@ class Twig_Util_TemplateDirIterator extends IteratorIterator
24
  return (string) parent::key();
25
  }
26
  }
 
 
24
  return (string) parent::key();
25
  }
26
  }
27
+
28
+ class_alias('Twig_Util_TemplateDirIterator', 'Twig\Util\TemplateDirIterator', false);
wpml-woocommerce.php CHANGED
@@ -6,14 +6,16 @@
6
  Author: OnTheGoSystems
7
  Author URI: http://www.onthegosystems.com/
8
  Text Domain: woocommerce-multilingual
9
- Version: 4.1.4
 
 
10
  */
11
 
12
  if ( defined( 'WCML_VERSION' ) ) {
13
  return;
14
  }
15
 
16
- define( 'WCML_VERSION', '4.1.4' );
17
  define( 'WCML_PLUGIN_PATH', dirname( __FILE__ ) );
18
  define( 'WCML_PLUGIN_FOLDER', basename( WCML_PLUGIN_PATH ) );
19
  define( 'WCML_LOCALE_PATH', WCML_PLUGIN_PATH . '/locale' );
@@ -29,8 +31,10 @@ include WCML_PLUGIN_PATH . '/inc/wcml-switch-lang-request.php';
29
  include WCML_PLUGIN_PATH . '/inc/wcml-cart-switch-lang-functions.php';
30
 
31
  if ( defined( 'ICL_SITEPRESS_VERSION' ) && ! ICL_PLUGIN_INACTIVE && class_exists( 'SitePress' ) ) {
 
32
  //detecting language switching
33
- $wcml_switch_lang_request = new WCML_Switch_Lang_Request( new WPML_Cookie(), new WPML_WP_API() );
 
34
 
35
  //cart related language switching functions
36
  $wcml_cart_switch_lang_functions = new WCML_Cart_Switch_Lang_Functions();
6
  Author: OnTheGoSystems
7
  Author URI: http://www.onthegosystems.com/
8
  Text Domain: woocommerce-multilingual
9
+ Requires at least: 3.9
10
+ Tested up to: 4.8
11
+ Version: 4.2.0
12
  */
13
 
14
  if ( defined( 'WCML_VERSION' ) ) {
15
  return;
16
  }
17
 
18
+ define( 'WCML_VERSION', '4.2.0' );
19
  define( 'WCML_PLUGIN_PATH', dirname( __FILE__ ) );
20
  define( 'WCML_PLUGIN_FOLDER', basename( WCML_PLUGIN_PATH ) );
21
  define( 'WCML_LOCALE_PATH', WCML_PLUGIN_PATH . '/locale' );
31
  include WCML_PLUGIN_PATH . '/inc/wcml-cart-switch-lang-functions.php';
32
 
33
  if ( defined( 'ICL_SITEPRESS_VERSION' ) && ! ICL_PLUGIN_INACTIVE && class_exists( 'SitePress' ) ) {
34
+ global $sitepress;
35
  //detecting language switching
36
+ $wcml_switch_lang_request = new WCML_Switch_Lang_Request( new WPML_Cookie(), new WPML_WP_API(), $sitepress );
37
+ $wcml_switch_lang_request->add_hooks();
38
 
39
  //cart related language switching functions
40
  $wcml_cart_switch_lang_functions = new WCML_Cart_Switch_Lang_Functions();