WooCommerce Multilingual – run WooCommerce with WPML - Version 4.7.0

Version Description

Download this release

Release Info

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

Code changes from version 4.6.7 to 4.7.0

Files changed (465) hide show
  1. changelog/4.6.3.md +4 -2
  2. changelog/4.7.0.md +43 -0
  3. classes/RewriteRules/Hooks.php +33 -0
  4. classes/class-woocommerce-wpml.php +3 -3
  5. classes/media/Wrapper/Factory.php +29 -0
  6. classes/media/Wrapper/IMedia.php +58 -0
  7. classes/media/Wrapper/NonTranslatable.php +62 -0
  8. classes/media/Wrapper/Translatable.php +185 -0
  9. classes/order-property-filter/class-wcml-payment-method-filter.php +10 -1
  10. classes/product/class-wcml-product-data-store-cpt.php +14 -0
  11. classes/shortcodes/class-wcml-wc-shortcode-product-category.php +25 -22
  12. classes/templates/php/model.php +114 -0
  13. compatibility/class-wcml-bookings.php +123 -44
  14. compatibility/class-wcml-checkout-addons.php +50 -9
  15. compatibility/class-wcml-composite-products.php +25 -4
  16. compatibility/class-wcml-order-status-manager.php +88 -0
  17. compatibility/class-wcml-product-addons.php +30 -23
  18. compatibility/class-wcml-tab-manager.php +0 -6
  19. compatibility/class-wcml-variation-swatches-and-photos.php +1 -1
  20. compatibility/class-wcml-woobe.php +74 -0
  21. inc/class-wcml-ajax-setup.php +0 -8
  22. inc/class-wcml-attributes.php +55 -22
  23. inc/class-wcml-cart.php +0 -1
  24. inc/class-wcml-compatibility.php +86 -55
  25. inc/class-wcml-dependencies.php +3 -18
  26. inc/class-wcml-emails.php +441 -415
  27. inc/class-wcml-locale.php +0 -17
  28. inc/class-wcml-media.php +0 -170
  29. inc/class-wcml-orders.php +332 -312
  30. inc/class-wcml-resources.php +1 -1
  31. inc/class-wcml-troubleshooting.php +52 -10
  32. inc/class-wcml-upgrade.php +21 -0
  33. inc/class-wcml-wc-gateways.php +81 -37
  34. inc/class-wcml-wc-shipping.php +19 -0
  35. inc/currencies/class-wcml-multi-currency-prices.php +32 -2
  36. inc/template-classes/class-wcml-plugins-wrap.php +68 -62
  37. inc/template-classes/class-wcml-products-ui.php +2 -1
  38. inc/template-classes/class-wcml-settings-ui.php +11 -11
  39. inc/template-classes/class-wcml-templates-factory.php +7 -7
  40. inc/template-classes/class-wcml-troubleshooting-ui.php +3 -1
  41. inc/template-classes/currency-switcher/class-wcml-currency-switcher-template.php +1 -1
  42. inc/template-classes/multi-currency/class-wcml-custom-currency-options.php +1 -1
  43. inc/template-classes/multi-currency/class-wcml-multi-currency-ui.php +1 -1
  44. inc/template-classes/setup/class-wcml-setup-header.php +1 -1
  45. inc/template-classes/status/class-wcml-status-config-warnings-ui.php +1 -1
  46. inc/template-classes/status/class-wcml-status-store-pages-ui.php +1 -1
  47. inc/template-classes/store-urls/class-wcml-store-urls-translation-statuses-ui.php +1 -1
  48. inc/translation-editor/class-wcml-synchronize-product-data.php +66 -24
  49. inc/translation-editor/class-wcml-synchronize-variations-data.php +2 -0
  50. inc/wcml-core-functions.php +13 -0
  51. inc/wcml-switch-lang-request.php +2 -2
  52. lib/twig/lib/Twig/Autoloader.php +0 -49
  53. lib/twig/lib/Twig/BaseNodeVisitor.php +0 -11
  54. lib/twig/lib/Twig/Cache/Filesystem.php +0 -11
  55. lib/twig/lib/Twig/Cache/Null.php +0 -11
  56. lib/twig/lib/Twig/CacheInterface.php +0 -11
  57. lib/twig/lib/Twig/Compiler.php +0 -11
  58. lib/twig/lib/Twig/CompilerInterface.php +0 -34
  59. lib/twig/lib/Twig/ContainerRuntimeLoader.php +0 -11
  60. lib/twig/lib/Twig/Environment.php +0 -11
  61. lib/twig/lib/Twig/Error.php +0 -11
  62. lib/twig/lib/Twig/Error/Loader.php +0 -11
  63. lib/twig/lib/Twig/Error/Runtime.php +0 -11
  64. lib/twig/lib/Twig/Error/Syntax.php +0 -11
  65. lib/twig/lib/Twig/ExistsLoaderInterface.php +0 -11
  66. lib/twig/lib/Twig/ExpressionParser.php +0 -11
  67. lib/twig/lib/Twig/Extension.php +0 -11
  68. lib/twig/lib/Twig/Extension/Core.php +0 -11
  69. lib/twig/lib/Twig/Extension/Debug.php +0 -11
  70. lib/twig/lib/Twig/Extension/Escaper.php +0 -11
  71. lib/twig/lib/Twig/Extension/GlobalsInterface.php +0 -11
  72. lib/twig/lib/Twig/Extension/InitRuntimeInterface.php +0 -11
  73. lib/twig/lib/Twig/Extension/Optimizer.php +0 -11
  74. lib/twig/lib/Twig/Extension/Profiler.php +0 -11
  75. lib/twig/lib/Twig/Extension/Sandbox.php +0 -11
  76. lib/twig/lib/Twig/Extension/Staging.php +0 -11
  77. lib/twig/lib/Twig/Extension/StringLoader.php +0 -11
  78. lib/twig/lib/Twig/ExtensionInterface.php +0 -11
  79. lib/twig/lib/Twig/FactoryRuntimeLoader.php +0 -11
  80. lib/twig/lib/Twig/FileExtensionEscapingStrategy.php +0 -11
  81. lib/twig/lib/Twig/Filter.php +0 -69
  82. lib/twig/lib/Twig/Filter/Function.php +0 -36
  83. lib/twig/lib/Twig/Filter/Method.php +0 -39
  84. lib/twig/lib/Twig/Filter/Node.php +0 -38
  85. lib/twig/lib/Twig/FilterCallableInterface.php +0 -25
  86. lib/twig/lib/Twig/FilterInterface.php +0 -38
  87. lib/twig/lib/Twig/Function.php +0 -62
  88. lib/twig/lib/Twig/Function/Function.php +0 -37
  89. lib/twig/lib/Twig/Function/Method.php +0 -40
  90. lib/twig/lib/Twig/Function/Node.php +0 -38
  91. lib/twig/lib/Twig/FunctionCallableInterface.php +0 -25
  92. lib/twig/lib/Twig/FunctionInterface.php +0 -37
  93. lib/twig/lib/Twig/Lexer.php +0 -11
  94. lib/twig/lib/Twig/LexerInterface.php +0 -36
  95. lib/twig/lib/Twig/Loader/Array.php +0 -11
  96. lib/twig/lib/Twig/Loader/Chain.php +0 -11
  97. lib/twig/lib/Twig/Loader/Filesystem.php +0 -11
  98. lib/twig/lib/Twig/Loader/String.php +0 -57
  99. lib/twig/lib/Twig/LoaderInterface.php +0 -11
  100. lib/twig/lib/Twig/Markup.php +0 -11
  101. lib/twig/lib/Twig/Node.php +0 -11
  102. lib/twig/lib/Twig/Node/AutoEscape.php +0 -11
  103. lib/twig/lib/Twig/Node/Block.php +0 -11
  104. lib/twig/lib/Twig/Node/BlockReference.php +0 -11
  105. lib/twig/lib/Twig/Node/Body.php +0 -11
  106. lib/twig/lib/Twig/Node/CheckSecurity.php +0 -11
  107. lib/twig/lib/Twig/Node/Deprecated.php +0 -11
  108. lib/twig/lib/Twig/Node/Do.php +0 -11
  109. lib/twig/lib/Twig/Node/Embed.php +0 -11
  110. lib/twig/lib/Twig/Node/Expression.php +0 -11
  111. lib/twig/lib/Twig/Node/Expression/Array.php +0 -11
  112. lib/twig/lib/Twig/Node/Expression/AssignName.php +0 -11
  113. lib/twig/lib/Twig/Node/Expression/Binary.php +0 -11
  114. lib/twig/lib/Twig/Node/Expression/Binary/Add.php +0 -11
  115. lib/twig/lib/Twig/Node/Expression/Binary/And.php +0 -11
  116. lib/twig/lib/Twig/Node/Expression/Binary/BitwiseAnd.php +0 -11
  117. lib/twig/lib/Twig/Node/Expression/Binary/BitwiseOr.php +0 -11
  118. lib/twig/lib/Twig/Node/Expression/Binary/BitwiseXor.php +0 -11
  119. lib/twig/lib/Twig/Node/Expression/Binary/Concat.php +0 -11
  120. lib/twig/lib/Twig/Node/Expression/Binary/Div.php +0 -11
  121. lib/twig/lib/Twig/Node/Expression/Binary/EndsWith.php +0 -11
  122. lib/twig/lib/Twig/Node/Expression/Binary/Equal.php +0 -11
  123. lib/twig/lib/Twig/Node/Expression/Binary/FloorDiv.php +0 -11
  124. lib/twig/lib/Twig/Node/Expression/Binary/Greater.php +0 -11
  125. lib/twig/lib/Twig/Node/Expression/Binary/GreaterEqual.php +0 -11
  126. lib/twig/lib/Twig/Node/Expression/Binary/In.php +0 -11
  127. lib/twig/lib/Twig/Node/Expression/Binary/Less.php +0 -11
  128. lib/twig/lib/Twig/Node/Expression/Binary/LessEqual.php +0 -11
  129. lib/twig/lib/Twig/Node/Expression/Binary/Matches.php +0 -11
  130. lib/twig/lib/Twig/Node/Expression/Binary/Mod.php +0 -11
  131. lib/twig/lib/Twig/Node/Expression/Binary/Mul.php +0 -11
  132. lib/twig/lib/Twig/Node/Expression/Binary/NotEqual.php +0 -11
  133. lib/twig/lib/Twig/Node/Expression/Binary/NotIn.php +0 -11
  134. lib/twig/lib/Twig/Node/Expression/Binary/Or.php +0 -11
  135. lib/twig/lib/Twig/Node/Expression/Binary/Power.php +0 -11
  136. lib/twig/lib/Twig/Node/Expression/Binary/Range.php +0 -11
  137. lib/twig/lib/Twig/Node/Expression/Binary/StartsWith.php +0 -11
  138. lib/twig/lib/Twig/Node/Expression/Binary/Sub.php +0 -11
  139. lib/twig/lib/Twig/Node/Expression/BlockReference.php +0 -11
  140. lib/twig/lib/Twig/Node/Expression/Call.php +0 -11
  141. lib/twig/lib/Twig/Node/Expression/Conditional.php +0 -11
  142. lib/twig/lib/Twig/Node/Expression/Constant.php +0 -11
  143. lib/twig/lib/Twig/Node/Expression/ExtensionReference.php +0 -33
  144. lib/twig/lib/Twig/Node/Expression/Filter.php +0 -11
  145. lib/twig/lib/Twig/Node/Expression/Filter/Default.php +0 -11
  146. lib/twig/lib/Twig/Node/Expression/Function.php +0 -11
  147. lib/twig/lib/Twig/Node/Expression/GetAttr.php +0 -11
  148. lib/twig/lib/Twig/Node/Expression/MethodCall.php +0 -11
  149. lib/twig/lib/Twig/Node/Expression/Name.php +0 -11
  150. lib/twig/lib/Twig/Node/Expression/NullCoalesce.php +0 -11
  151. lib/twig/lib/Twig/Node/Expression/Parent.php +0 -11
  152. lib/twig/lib/Twig/Node/Expression/TempName.php +0 -11
  153. lib/twig/lib/Twig/Node/Expression/Test.php +0 -11
  154. lib/twig/lib/Twig/Node/Expression/Test/Constant.php +0 -11
  155. lib/twig/lib/Twig/Node/Expression/Test/Defined.php +0 -11
  156. lib/twig/lib/Twig/Node/Expression/Test/Divisibleby.php +0 -11
  157. lib/twig/lib/Twig/Node/Expression/Test/Even.php +0 -11
  158. lib/twig/lib/Twig/Node/Expression/Test/Null.php +0 -11
  159. lib/twig/lib/Twig/Node/Expression/Test/Odd.php +0 -11
  160. lib/twig/lib/Twig/Node/Expression/Test/Sameas.php +0 -11
  161. lib/twig/lib/Twig/Node/Expression/Unary.php +0 -11
  162. lib/twig/lib/Twig/Node/Expression/Unary/Neg.php +0 -11
  163. lib/twig/lib/Twig/Node/Expression/Unary/Not.php +0 -11
  164. lib/twig/lib/Twig/Node/Expression/Unary/Pos.php +0 -11
  165. lib/twig/lib/Twig/Node/Flush.php +0 -11
  166. lib/twig/lib/Twig/Node/For.php +0 -11
  167. lib/twig/lib/Twig/Node/ForLoop.php +0 -11
  168. lib/twig/lib/Twig/Node/If.php +0 -11
  169. lib/twig/lib/Twig/Node/Import.php +0 -11
  170. lib/twig/lib/Twig/Node/Include.php +0 -11
  171. lib/twig/lib/Twig/Node/Macro.php +0 -11
  172. lib/twig/lib/Twig/Node/Module.php +0 -11
  173. lib/twig/lib/Twig/Node/Print.php +0 -11
  174. lib/twig/lib/Twig/Node/Sandbox.php +0 -11
  175. lib/twig/lib/Twig/Node/SandboxedPrint.php +0 -11
  176. lib/twig/lib/Twig/Node/Set.php +0 -11
  177. lib/twig/lib/Twig/Node/SetTemp.php +0 -11
  178. lib/twig/lib/Twig/Node/Spaceless.php +0 -11
  179. lib/twig/lib/Twig/Node/Text.php +0 -11
  180. lib/twig/lib/Twig/Node/With.php +0 -11
  181. lib/twig/lib/Twig/NodeCaptureInterface.php +0 -11
  182. lib/twig/lib/Twig/NodeInterface.php +0 -32
  183. lib/twig/lib/Twig/NodeOutputInterface.php +0 -11
  184. lib/twig/lib/Twig/NodeTraverser.php +0 -11
  185. lib/twig/lib/Twig/NodeVisitor/Escaper.php +0 -11
  186. lib/twig/lib/Twig/NodeVisitor/Optimizer.php +0 -11
  187. lib/twig/lib/Twig/NodeVisitor/SafeAnalysis.php +0 -11
  188. lib/twig/lib/Twig/NodeVisitor/Sandbox.php +0 -11
  189. lib/twig/lib/Twig/NodeVisitorInterface.php +0 -11
  190. lib/twig/lib/Twig/Parser.php +0 -11
  191. lib/twig/lib/Twig/ParserInterface.php +0 -33
  192. lib/twig/lib/Twig/Profiler/Dumper/Base.php +0 -11
  193. lib/twig/lib/Twig/Profiler/Dumper/Blackfire.php +0 -11
  194. lib/twig/lib/Twig/Profiler/Dumper/Html.php +0 -11
  195. lib/twig/lib/Twig/Profiler/Dumper/Text.php +0 -11
  196. lib/twig/lib/Twig/Profiler/Node/EnterProfile.php +0 -11
  197. lib/twig/lib/Twig/Profiler/Node/LeaveProfile.php +0 -11
  198. lib/twig/lib/Twig/Profiler/NodeVisitor/Profiler.php +0 -11
  199. lib/twig/lib/Twig/Profiler/Profile.php +0 -11
  200. lib/twig/lib/Twig/RuntimeLoaderInterface.php +0 -11
  201. lib/twig/lib/Twig/Sandbox/SecurityError.php +0 -11
  202. lib/twig/lib/Twig/Sandbox/SecurityNotAllowedFilterError.php +0 -11
  203. lib/twig/lib/Twig/Sandbox/SecurityNotAllowedFunctionError.php +0 -11
  204. lib/twig/lib/Twig/Sandbox/SecurityNotAllowedMethodError.php +0 -11
  205. lib/twig/lib/Twig/Sandbox/SecurityNotAllowedPropertyError.php +0 -11
  206. lib/twig/lib/Twig/Sandbox/SecurityNotAllowedTagError.php +0 -11
  207. lib/twig/lib/Twig/Sandbox/SecurityPolicy.php +0 -11
  208. lib/twig/lib/Twig/Sandbox/SecurityPolicyInterface.php +0 -11
  209. lib/twig/lib/Twig/SimpleFilter.php +0 -11
  210. lib/twig/lib/Twig/SimpleFunction.php +0 -11
  211. lib/twig/lib/Twig/SimpleTest.php +0 -11
  212. lib/twig/lib/Twig/Source.php +0 -11
  213. lib/twig/lib/Twig/SourceContextLoaderInterface.php +0 -11
  214. lib/twig/lib/Twig/Template.php +0 -11
  215. lib/twig/lib/Twig/TemplateInterface.php +0 -47
  216. lib/twig/lib/Twig/TemplateWrapper.php +0 -11
  217. lib/twig/lib/Twig/Test.php +0 -33
  218. lib/twig/lib/Twig/Test/Function.php +0 -34
  219. lib/twig/lib/Twig/Test/IntegrationTestCase.php +0 -11
  220. lib/twig/lib/Twig/Test/Method.php +0 -37
  221. lib/twig/lib/Twig/Test/Node.php +0 -36
  222. lib/twig/lib/Twig/Test/NodeTestCase.php +0 -11
  223. lib/twig/lib/Twig/TestCallableInterface.php +0 -23
  224. lib/twig/lib/Twig/TestInterface.php +0 -28
  225. lib/twig/lib/Twig/Token.php +0 -11
  226. lib/twig/lib/Twig/TokenParser.php +0 -11
  227. lib/twig/lib/Twig/TokenParser/AutoEscape.php +0 -11
  228. lib/twig/lib/Twig/TokenParser/Block.php +0 -11
  229. lib/twig/lib/Twig/TokenParser/Deprecated.php +0 -11
  230. lib/twig/lib/Twig/TokenParser/Do.php +0 -11
  231. lib/twig/lib/Twig/TokenParser/Embed.php +0 -11
  232. lib/twig/lib/Twig/TokenParser/Extends.php +0 -11
  233. lib/twig/lib/Twig/TokenParser/Filter.php +0 -11
  234. lib/twig/lib/Twig/TokenParser/Flush.php +0 -11
  235. lib/twig/lib/Twig/TokenParser/For.php +0 -11
  236. lib/twig/lib/Twig/TokenParser/From.php +0 -11
  237. lib/twig/lib/Twig/TokenParser/If.php +0 -11
  238. lib/twig/lib/Twig/TokenParser/Import.php +0 -11
  239. lib/twig/lib/Twig/TokenParser/Include.php +0 -11
  240. lib/twig/lib/Twig/TokenParser/Macro.php +0 -11
  241. lib/twig/lib/Twig/TokenParser/Sandbox.php +0 -11
  242. lib/twig/lib/Twig/TokenParser/Set.php +0 -11
  243. lib/twig/lib/Twig/TokenParser/Spaceless.php +0 -11
  244. lib/twig/lib/Twig/TokenParser/Use.php +0 -11
  245. lib/twig/lib/Twig/TokenParser/With.php +0 -11
  246. lib/twig/lib/Twig/TokenParserBroker.php +0 -112
  247. lib/twig/lib/Twig/TokenParserBrokerInterface.php +0 -44
  248. lib/twig/lib/Twig/TokenParserInterface.php +0 -11
  249. lib/twig/lib/Twig/TokenStream.php +0 -11
  250. lib/twig/lib/Twig/Util/DeprecationCollector.php +0 -11
  251. lib/twig/lib/Twig/Util/TemplateDirIterator.php +0 -11
  252. lib/twig/src/Cache/CacheInterface.php +0 -55
  253. lib/twig/src/Cache/FilesystemCache.php +0 -79
  254. lib/twig/src/Cache/NullCache.php +0 -37
  255. lib/twig/src/Compiler.php +0 -247
  256. lib/twig/src/Environment.php +0 -1407
  257. lib/twig/src/Error/Error.php +0 -280
  258. lib/twig/src/Error/LoaderError.php +0 -21
  259. lib/twig/src/Error/RuntimeError.php +0 -22
  260. lib/twig/src/Error/SyntaxError.php +0 -52
  261. lib/twig/src/ExpressionParser.php +0 -684
  262. lib/twig/src/Extension/AbstractExtension.php +0 -61
  263. lib/twig/src/Extension/CoreExtension.php +0 -1390
  264. lib/twig/src/Extension/DebugExtension.php +0 -56
  265. lib/twig/src/Extension/EscaperExtension.php +0 -101
  266. lib/twig/src/Extension/ExtensionInterface.php +0 -89
  267. lib/twig/src/Extension/GlobalsInterface.php +0 -24
  268. lib/twig/src/Extension/InitRuntimeInterface.php +0 -24
  269. lib/twig/src/Extension/OptimizerExtension.php +0 -33
  270. lib/twig/src/Extension/ProfilerExtension.php +0 -44
  271. lib/twig/src/Extension/RuntimeExtensionInterface.php +0 -18
  272. lib/twig/src/Extension/SandboxExtension.php +0 -91
  273. lib/twig/src/Extension/StagingExtension.php +0 -97
  274. lib/twig/src/Extension/StringLoaderExtension.php +0 -46
  275. lib/twig/src/FileExtensionEscapingStrategy.php +0 -55
  276. lib/twig/src/Lexer.php +0 -392
  277. lib/twig/src/Loader/ArrayLoader.php +0 -87
  278. lib/twig/src/Loader/ChainLoader.php +0 -137
  279. lib/twig/src/Loader/ExistsLoaderInterface.php +0 -31
  280. lib/twig/src/Loader/FilesystemLoader.php +0 -261
  281. lib/twig/src/Loader/LoaderInterface.php +0 -56
  282. lib/twig/src/Loader/SourceContextLoaderInterface.php +0 -35
  283. lib/twig/src/Markup.php +0 -36
  284. lib/twig/src/Node/AutoEscapeNode.php +0 -36
  285. lib/twig/src/Node/BlockNode.php +0 -32
  286. lib/twig/src/Node/BlockReferenceNode.php +0 -31
  287. lib/twig/src/Node/BodyNode.php +0 -21
  288. lib/twig/src/Node/CheckSecurityNode.php +0 -44
  289. lib/twig/src/Node/CheckToStringNode.php +0 -35
  290. lib/twig/src/Node/DeprecatedNode.php +0 -40
  291. lib/twig/src/Node/DoNode.php +0 -31
  292. lib/twig/src/Node/EmbedNode.php +0 -37
  293. lib/twig/src/Node/Expression/AbstractExpression.php +0 -23
  294. lib/twig/src/Node/Expression/ArrayExpression.php +0 -67
  295. lib/twig/src/Node/Expression/ArrowFunctionExpression.php +0 -41
  296. lib/twig/src/Node/Expression/AssignNameExpression.php +0 -22
  297. lib/twig/src/Node/Expression/Binary/AbstractBinary.php +0 -30
  298. lib/twig/src/Node/Expression/Binary/AddBinary.php +0 -22
  299. lib/twig/src/Node/Expression/Binary/AndBinary.php +0 -22
  300. lib/twig/src/Node/Expression/Binary/BitwiseAndBinary.php +0 -22
  301. lib/twig/src/Node/Expression/Binary/BitwiseOrBinary.php +0 -22
  302. lib/twig/src/Node/Expression/Binary/BitwiseXorBinary.php +0 -22
  303. lib/twig/src/Node/Expression/Binary/ConcatBinary.php +0 -22
  304. lib/twig/src/Node/Expression/Binary/DivBinary.php +0 -22
  305. lib/twig/src/Node/Expression/Binary/EndsWithBinary.php +0 -27
  306. lib/twig/src/Node/Expression/Binary/EqualBinary.php +0 -21
  307. lib/twig/src/Node/Expression/Binary/FloorDivBinary.php +0 -27
  308. lib/twig/src/Node/Expression/Binary/GreaterBinary.php +0 -21
  309. lib/twig/src/Node/Expression/Binary/GreaterEqualBinary.php +0 -21
  310. lib/twig/src/Node/Expression/Binary/InBinary.php +0 -25
  311. lib/twig/src/Node/Expression/Binary/LessBinary.php +0 -21
  312. lib/twig/src/Node/Expression/Binary/LessEqualBinary.php +0 -21
  313. lib/twig/src/Node/Expression/Binary/MatchesBinary.php +0 -25
  314. lib/twig/src/Node/Expression/Binary/ModBinary.php +0 -22
  315. lib/twig/src/Node/Expression/Binary/MulBinary.php +0 -22
  316. lib/twig/src/Node/Expression/Binary/NotEqualBinary.php +0 -21
  317. lib/twig/src/Node/Expression/Binary/NotInBinary.php +0 -25
  318. lib/twig/src/Node/Expression/Binary/OrBinary.php +0 -22
  319. lib/twig/src/Node/Expression/Binary/PowerBinary.php +0 -28
  320. lib/twig/src/Node/Expression/Binary/RangeBinary.php +0 -25
  321. lib/twig/src/Node/Expression/Binary/StartsWithBinary.php +0 -27
  322. lib/twig/src/Node/Expression/Binary/SubBinary.php +0 -22
  323. lib/twig/src/Node/Expression/BlockReferenceExpression.php +0 -71
  324. lib/twig/src/Node/Expression/CallExpression.php +0 -256
  325. lib/twig/src/Node/Expression/ConditionalExpression.php +0 -26
  326. lib/twig/src/Node/Expression/ConstantExpression.php +0 -26
  327. lib/twig/src/Node/Expression/Filter/DefaultFilter.php +0 -47
  328. lib/twig/src/Node/Expression/FilterExpression.php +0 -41
  329. lib/twig/src/Node/Expression/FunctionExpression.php +0 -44
  330. lib/twig/src/Node/Expression/GetAttrExpression.php +0 -65
  331. lib/twig/src/Node/Expression/InlinePrint.php +0 -28
  332. lib/twig/src/Node/Expression/MethodCallExpression.php +0 -37
  333. lib/twig/src/Node/Expression/NameExpression.php +0 -73
  334. lib/twig/src/Node/Expression/NullCoalesceExpression.php +0 -43
  335. lib/twig/src/Node/Expression/ParentExpression.php +0 -35
  336. lib/twig/src/Node/Expression/TempNameExpression.php +0 -25
  337. lib/twig/src/Node/Expression/Test/ConstantTest.php +0 -35
  338. lib/twig/src/Node/Expression/Test/DefinedTest.php +0 -64
  339. lib/twig/src/Node/Expression/Test/DivisiblebyTest.php +0 -29
  340. lib/twig/src/Node/Expression/Test/EvenTest.php +0 -29
  341. lib/twig/src/Node/Expression/Test/NullTest.php +0 -29
  342. lib/twig/src/Node/Expression/Test/OddTest.php +0 -29
  343. lib/twig/src/Node/Expression/Test/SameasTest.php +0 -27
  344. lib/twig/src/Node/Expression/TestExpression.php +0 -44
  345. lib/twig/src/Node/Expression/Unary/AbstractUnary.php +0 -30
  346. lib/twig/src/Node/Expression/Unary/NegUnary.php +0 -22
  347. lib/twig/src/Node/Expression/Unary/NotUnary.php +0 -22
  348. lib/twig/src/Node/Expression/Unary/PosUnary.php +0 -22
  349. lib/twig/src/Node/FlushNode.php +0 -30
  350. lib/twig/src/Node/ForLoopNode.php +0 -38
  351. lib/twig/src/Node/ForNode.php +0 -63
  352. lib/twig/src/Node/IfNode.php +0 -47
  353. lib/twig/src/Node/ImportNode.php +0 -38
  354. lib/twig/src/Node/IncludeNode.php +0 -65
  355. lib/twig/src/Node/MacroNode.php +0 -69
  356. lib/twig/src/Node/ModuleNode.php +0 -237
  357. lib/twig/src/Node/Node.php +0 -228
  358. lib/twig/src/Node/NodeCaptureInterface.php +0 -21
  359. lib/twig/src/Node/NodeOutputInterface.php +0 -21
  360. lib/twig/src/Node/PrintNode.php +0 -32
  361. lib/twig/src/Node/SandboxNode.php +0 -30
  362. lib/twig/src/Node/SandboxedPrintNode.php +0 -54
  363. lib/twig/src/Node/SetNode.php +0 -87
  364. lib/twig/src/Node/SetTempNode.php +0 -29
  365. lib/twig/src/Node/SpacelessNode.php +0 -38
  366. lib/twig/src/Node/TextNode.php +0 -31
  367. lib/twig/src/Node/WithNode.php +0 -48
  368. lib/twig/src/NodeTraverser.php +0 -77
  369. lib/twig/src/NodeVisitor/AbstractNodeVisitor.php +0 -51
  370. lib/twig/src/NodeVisitor/EscaperNodeVisitor.php +0 -172
  371. lib/twig/src/NodeVisitor/NodeVisitorInterface.php +0 -44
  372. lib/twig/src/NodeVisitor/OptimizerNodeVisitor.php +0 -206
  373. lib/twig/src/NodeVisitor/SafeAnalysisNodeVisitor.php +0 -143
  374. lib/twig/src/NodeVisitor/SandboxNodeVisitor.php +0 -118
  375. lib/twig/src/Parser.php +0 -358
  376. lib/twig/src/Profiler/Dumper/BaseDumper.php +0 -53
  377. lib/twig/src/Profiler/Dumper/BlackfireDumper.php +0 -63
  378. lib/twig/src/Profiler/Dumper/HtmlDumper.php +0 -39
  379. lib/twig/src/Profiler/Dumper/TextDumper.php +0 -34
  380. lib/twig/src/Profiler/Node/EnterProfileNode.php +0 -31
  381. lib/twig/src/Profiler/Node/LeaveProfileNode.php +0 -31
  382. lib/twig/src/Profiler/NodeVisitor/ProfilerNodeVisitor.php +0 -63
  383. lib/twig/src/Profiler/Profile.php +0 -154
  384. lib/twig/src/RuntimeLoader/ContainerRuntimeLoader.php +0 -36
  385. lib/twig/src/RuntimeLoader/FactoryRuntimeLoader.php +0 -36
  386. lib/twig/src/RuntimeLoader/RuntimeLoaderInterface.php +0 -29
  387. lib/twig/src/Sandbox/SecurityError.php +0 -22
  388. lib/twig/src/Sandbox/SecurityNotAllowedFilterError.php +0 -31
  389. lib/twig/src/Sandbox/SecurityNotAllowedFunctionError.php +0 -31
  390. lib/twig/src/Sandbox/SecurityNotAllowedMethodError.php +0 -37
  391. lib/twig/src/Sandbox/SecurityNotAllowedPropertyError.php +0 -37
  392. lib/twig/src/Sandbox/SecurityNotAllowedTagError.php +0 -31
  393. lib/twig/src/Sandbox/SecurityPolicy.php +0 -110
  394. lib/twig/src/Sandbox/SecurityPolicyInterface.php +0 -24
  395. lib/twig/src/Source.php +0 -49
  396. lib/twig/src/Template.php +0 -639
  397. lib/twig/src/TemplateWrapper.php +0 -148
  398. lib/twig/src/Test/IntegrationTestCase.php +0 -213
  399. lib/twig/src/Test/NodeTestCase.php +0 -65
  400. lib/twig/src/Token.php +0 -198
  401. lib/twig/src/TokenParser/AbstractTokenParser.php +0 -30
  402. lib/twig/src/TokenParser/ApplyTokenParser.php +0 -47
  403. lib/twig/src/TokenParser/AutoEscapeTokenParser.php +0 -75
  404. lib/twig/src/TokenParser/BlockTokenParser.php +0 -69
  405. lib/twig/src/TokenParser/DeprecatedTokenParser.php +0 -38
  406. lib/twig/src/TokenParser/DoTokenParser.php +0 -33
  407. lib/twig/src/TokenParser/EmbedTokenParser.php +0 -55
  408. lib/twig/src/TokenParser/ExtendsTokenParser.php +0 -46
  409. lib/twig/src/TokenParser/FilterTokenParser.php +0 -50
  410. lib/twig/src/TokenParser/FlushTokenParser.php +0 -34
  411. lib/twig/src/TokenParser/ForTokenParser.php +0 -118
  412. lib/twig/src/TokenParser/FromTokenParser.php +0 -59
  413. lib/twig/src/TokenParser/IfTokenParser.php +0 -79
  414. lib/twig/src/TokenParser/ImportTokenParser.php +0 -39
  415. lib/twig/src/TokenParser/IncludeTokenParser.php +0 -55
  416. lib/twig/src/TokenParser/MacroTokenParser.php +0 -58
  417. lib/twig/src/TokenParser/SandboxTokenParser.php +0 -59
  418. lib/twig/src/TokenParser/SetTokenParser.php +0 -62
  419. lib/twig/src/TokenParser/SpacelessTokenParser.php +0 -46
  420. lib/twig/src/TokenParser/TokenParserInterface.php +0 -45
  421. lib/twig/src/TokenParser/UseTokenParser.php +0 -63
  422. lib/twig/src/TokenParser/WithTokenParser.php +0 -47
  423. lib/twig/src/TokenStream.php +0 -170
  424. lib/twig/src/TwigFilter.php +0 -97
  425. lib/twig/src/TwigFunction.php +0 -90
  426. lib/twig/src/TwigTest.php +0 -69
  427. lib/twig/src/Util/DeprecationCollector.php +0 -75
  428. lib/twig/src/Util/TemplateDirIterator.php +0 -27
  429. locale/woocommerce-multilingual-ar.mo +0 -0
  430. locale/woocommerce-multilingual-de_DE.mo +0 -0
  431. locale/woocommerce-multilingual-el.mo +0 -0
  432. locale/woocommerce-multilingual-es_ES.mo +0 -0
  433. locale/woocommerce-multilingual-fr_FR.mo +0 -0
  434. locale/woocommerce-multilingual-he_IL.mo +0 -0
  435. locale/woocommerce-multilingual-it_IT.mo +0 -0
  436. locale/woocommerce-multilingual-ja.mo +0 -0
  437. locale/woocommerce-multilingual-ko_KR.mo +0 -0
  438. locale/woocommerce-multilingual-nl_NL.mo +0 -0
  439. locale/woocommerce-multilingual-pl_PL.mo +0 -0
  440. locale/woocommerce-multilingual-pt_BR.mo +0 -0
  441. locale/woocommerce-multilingual-pt_PT.mo +0 -0
  442. locale/woocommerce-multilingual-ru_RU.mo +0 -0
  443. locale/woocommerce-multilingual-sv_SE.mo +0 -0
  444. locale/woocommerce-multilingual-uk.mo +0 -0
  445. locale/woocommerce-multilingual-vi.mo +0 -0
  446. locale/woocommerce-multilingual-zh_CN.mo +0 -0
  447. locale/woocommerce-multilingual-zh_TW.mo +0 -0
  448. readme.txt +8 -474
  449. res/css/admin.css +1 -1
  450. res/js/scripts.js +18 -0
  451. res/js/scripts.min.js +1 -1
  452. res/js/troubleshooting.js +29 -0
  453. res/js/troubleshooting.min.js +1 -1
  454. templates/php/plugins-wrap.php +127 -0
  455. templates/plugins-wrap.twig +0 -99
  456. templates/products-list/products.twig +7 -1
  457. templates/troubleshooting.twig +12 -2
  458. vendor/autoload.php +1 -1
  459. vendor/autoload_52.php +0 -7
  460. vendor/composer/ClassLoader52.php +0 -271
  461. vendor/composer/autoload_classmap.php +9 -378
  462. vendor/composer/autoload_namespaces.php +0 -1
  463. vendor/composer/autoload_real.php +7 -7
  464. vendor/composer/autoload_real_52.php +0 -46
  465. vendor/composer/autoload_static.php +1 -72
changelog/4.6.3.md CHANGED
@@ -7,8 +7,10 @@
7
  * [wcml-2785] Fixed performance issues while translating Product via WPML Translation Editor with a lot of variations
8
  * [wcml-2765] Fixed overridden discounted item price when manually creating/editing order from the admin
9
  * [wcml-2758] Fixed customer email language when changing order from "On Hold" to "Processing"
10
- * [wcml-2753] Fixed product gallery being synchronized even if WPML media duplication option is disabled
11
  * [wcml-2736] Fixed custom "Sing-up Fee" price for variation Subscription not saved
12
  * [wcml-2688] Fixed variation not available in second language in some cases when original language is German or Danish
13
  * [wcml-2637] Fix mixed endpoint contexts/domains and their translations/language
14
- * [wcml-2567] Fixed inability to add reviews after bought product
 
 
 
7
  * [wcml-2785] Fixed performance issues while translating Product via WPML Translation Editor with a lot of variations
8
  * [wcml-2765] Fixed overridden discounted item price when manually creating/editing order from the admin
9
  * [wcml-2758] Fixed customer email language when changing order from "On Hold" to "Processing"
 
10
  * [wcml-2736] Fixed custom "Sing-up Fee" price for variation Subscription not saved
11
  * [wcml-2688] Fixed variation not available in second language in some cases when original language is German or Danish
12
  * [wcml-2637] Fix mixed endpoint contexts/domains and their translations/language
13
+ * [wcml-2567] Fixed inability to add reviews after bought product
14
+
15
+ # Compatibility
16
+ * [wcml-2753] Fixed product gallery being synchronized even if WPML media duplication option is disabled
changelog/4.7.0.md ADDED
@@ -0,0 +1,43 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Features
2
+ * [wcml-2836] Replaced some Twig templates with pure PHP templates as the first step towards the removal of Twig dependencies.
3
+ * [wcml-2740] Added compatibility class for WooCommerce order status Manager plugin
4
+
5
+ # Fixes
6
+ * [wcml-2965] Fixed PHP Notice for WC Variations Swatches And Photos compatibility.
7
+ * [wcml-2963] WooCommerce Bookings compatibility : Fixed notice when trying to cancel booking.
8
+ * [wcml-2954] Fixed a JavaScript error on the Store URLs tab.
9
+ * [wcml-2947] Fixed an issue where the "Fix translated variations relationships" troubleshooting option was removing translated variations.
10
+ * [wcml-2944] Fixed an issue where the strings for the default payment methods were not properly translated on the Checkout page.
11
+ * [wcml-2941] Fixed an issue where product names were not translated in the admin emails.
12
+ * [wcml-2931] Fixed an issue with the WooCommerce Subscriptions availability in the secondary language after purchasing the subscription in the original language.
13
+ * [wcml-2929] Fixed an issue with the cache flush during language switching.
14
+ * [wcml-2928] Fixed in the original ticket.
15
+ * [wcml-2923] Fixed an issue where the gateway strings would always register in English instead of the site's default language.
16
+ * [wcml-2914] Fixed an issue with the price filter widget not showing results in a secondary language.
17
+ * [wcml-2864] Fixed an issue where customers would not receive notifications in the correct language.
18
+ * [wcml-2838] Fixed an issue where the shipping classes in secondary languages were not calculated during checkout.
19
+ * [wcml-2827] Fixed error while sending WooCoomerce Bookings email for bookings which didn't have orders assigned.
20
+ * [wcml-2798] added comp. class to cover price update when products are edited with WOOBE plugin
21
+ * [wcml-2792] Updated compatibility class for WC Checkout Addons
22
+
23
+ # Compatibility
24
+ * [wcml-2938] Fixed an issue where the total price on the Composite product page was not rounded.
25
+ * [wcml-2937] Fixed an issue causing wrong rewrite rules after saving the settings and visiting a page in a language other than the default.
26
+ * [wcml-2936] Fixed an issue with incorrect price converting for the Product add-ons.
27
+ * [wcml-2922] Fixed an issue with the currency reverting to the default one during checkout.
28
+ * [wcml-2921] Fixed removed meta from original product not synchronized to translation.
29
+ * [wcml-2918] Fixed an issue where the BACS gateway instructions were not translated when re-sending the customer notification email from the admin.
30
+ * [wcml-2896] Fixed an issue with missing language information for attribute terms that happened after changing the attribute slug.
31
+ * [wcml-2878] Removed the Twig Composer dependency as it now relies on Twig from the WPML core plugin.
32
+ * [wcml-2854] Fixed an issue where the Products shortcode was not working in the secondary language.
33
+ * [wcml-2612] Fixed the images that were wrongly inserted in the translation job when attachments are not translatable.
34
+
35
+ # Performances
36
+ * [wcml-2970] Significantly improved the site performance on when updating the page, post, or a WooCommerce product page in the admin.
37
+ * [wcml-2917] Added the "wp_" prefix to all cookies so that hosting and caching layers can properly handle them.
38
+
39
+ # Usability
40
+ * [wcml-1365] Display larger images when hovering thumbnails in the WooCommerce Multilingual Products admin page.
41
+
42
+ # API
43
+ * [wcml-2953] Added the "wcml_new_order_admin_email_language" filter to allow setting the language of emails sent to admins for new or updated orders.
classes/RewriteRules/Hooks.php ADDED
@@ -0,0 +1,33 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace WCML\RewriteRules;
4
+
5
+ class Hooks implements \IWPML_Backend_Action, \IWPML_Frontend_Action, \IWPML_DIC_Action {
6
+
7
+ /** @var \SitePress $sitepress */
8
+ private $sitepress;
9
+
10
+ public function __construct( \SitePress $sitepress ) {
11
+ $this->sitepress = $sitepress;
12
+ }
13
+
14
+ public function add_hooks() {
15
+ add_filter( 'option_woocommerce_queue_flush_rewrite_rules', [ $this, 'preventFlushInNonDefaultLang' ] );
16
+ }
17
+
18
+ /**
19
+ * @param string $value
20
+ *
21
+ * @return string
22
+ */
23
+ public function preventFlushInNonDefaultLang( $value ) {
24
+ if (
25
+ 'yes' === $value
26
+ && $this->sitepress->get_current_language() !== $this->sitepress->get_default_language()
27
+ ) {
28
+ return 'no';
29
+ }
30
+
31
+ return $value;
32
+ }
33
+ }
classes/class-woocommerce-wpml.php CHANGED
@@ -39,7 +39,7 @@ class woocommerce_wpml {
39
  public $coupons;
40
  /** @var WCML_Locale */
41
  public $locale;
42
- /** @var WCML_Media */
43
  public $media;
44
  /** @var WCML_Downloadable_Products */
45
  public $downloadable;
@@ -160,7 +160,7 @@ class woocommerce_wpml {
160
 
161
  new WCML_Upgrade();
162
 
163
- $this->compatibility = new WCML_Compatibility( $sitepress, $this, $wpdb, new WPML_Element_Translation_Package() );
164
 
165
  $actions_that_need_mc = array(
166
  'save-mc-options',
@@ -240,7 +240,7 @@ class woocommerce_wpml {
240
  $this->coupons = new WCML_Coupons( $this, $sitepress );
241
  $this->coupons->add_hooks();
242
  $this->locale = new WCML_Locale( $this, $sitepress );
243
- $this->media = new WCML_Media( $this, $sitepress, $wpdb );
244
  $this->media->add_hooks();
245
  $this->downloadable = new WCML_Downloadable_Products( $this, $sitepress );
246
  $this->downloadable->add_hooks();
39
  public $coupons;
40
  /** @var WCML_Locale */
41
  public $locale;
42
+ /** @var WCML\Media\Wrapper\IMedia */
43
  public $media;
44
  /** @var WCML_Downloadable_Products */
45
  public $downloadable;
160
 
161
  new WCML_Upgrade();
162
 
163
+ $this->compatibility = new WCML_Compatibility( $sitepress, $this, $wpdb, new WPML_Element_Translation_Package(), $wpml_post_translations );
164
 
165
  $actions_that_need_mc = array(
166
  'save-mc-options',
240
  $this->coupons = new WCML_Coupons( $this, $sitepress );
241
  $this->coupons->add_hooks();
242
  $this->locale = new WCML_Locale( $this, $sitepress );
243
+ $this->media = WCML\Media\Wrapper\Factory::create( $this );
244
  $this->media->add_hooks();
245
  $this->downloadable = new WCML_Downloadable_Products( $this, $sitepress );
246
  $this->downloadable->add_hooks();
classes/media/Wrapper/Factory.php ADDED
@@ -0,0 +1,29 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace WCML\Media\Wrapper;
4
+
5
+ use WCML\Media\Wrapper\Translatable;
6
+ use woocommerce_wpml;
7
+ use WPML_Element_Sync_Settings_Factory;
8
+
9
+ class Factory {
10
+
11
+ /**
12
+ * @return IMedia
13
+ */
14
+ public static function create( woocommerce_wpml $woocommerce_wpml ) {
15
+ /**
16
+ * @var \SitePress $sitepress
17
+ * @var \wpdb $wpdb
18
+ */
19
+ global $sitepress, $wpdb;
20
+
21
+ $settingsFactory = new WPML_Element_Sync_Settings_Factory();
22
+
23
+ if ( $settingsFactory->create( 'post' )->is_sync( 'attachment' ) ) {
24
+ return new Translatable( $woocommerce_wpml, $sitepress, $wpdb );
25
+ }
26
+
27
+ return new NonTranslatable();
28
+ }
29
+ }
classes/media/Wrapper/IMedia.php ADDED
@@ -0,0 +1,58 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace WCML\Media\Wrapper;
4
+
5
+ interface IMedia {
6
+
7
+ public function add_hooks();
8
+
9
+ /**
10
+ * This method will return only translatable image IDs
11
+ *
12
+ * @param int $product_id
13
+ *
14
+ * @return array
15
+ */
16
+ public function product_images_ids( $product_id );
17
+
18
+ /**
19
+ * @param int $orig_post_id
20
+ * @param int $trnsl_post_id
21
+ * @param string $lang
22
+ */
23
+ public function sync_thumbnail_id( $orig_post_id, $trnsl_post_id, $lang );
24
+
25
+ /**
26
+ * @param int $variation_id
27
+ * @param int $translated_variation_id
28
+ * @param string $lang
29
+ */
30
+ public function sync_variation_thumbnail_id( $variation_id, $translated_variation_id, $lang );
31
+
32
+ /**
33
+ * @param int $product_id
34
+ */
35
+ public function sync_product_gallery( $product_id );
36
+
37
+ /**
38
+ * @param int $attachment_id
39
+ * @param int $parent_id
40
+ * @param string $target_lang
41
+ *
42
+ * @return int
43
+ */
44
+ public function create_base_media_translation( $attachment_id, $parent_id, $target_lang );
45
+
46
+ /**
47
+ * @param int $att_id
48
+ * @param int $dup_att_id
49
+ */
50
+ public function sync_product_gallery_duplicate_attachment( $att_id, $dup_att_id );
51
+
52
+ /**
53
+ * @param int $product_id
54
+ *
55
+ * @return bool
56
+ */
57
+ public function is_media_duplication_enabled( $product_id );
58
+ }
classes/media/Wrapper/NonTranslatable.php ADDED
@@ -0,0 +1,62 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace WCML\Media\Wrapper;
4
+
5
+ class NonTranslatable implements IMedia {
6
+
7
+ public function add_hooks() {}
8
+
9
+ /**
10
+ * @param int $product_id
11
+ *
12
+ * @return array
13
+ */
14
+ public function product_images_ids( $product_id ) {
15
+ return [];
16
+ }
17
+
18
+ /**
19
+ * @param int $orig_post_id
20
+ * @param int $trnsl_post_id
21
+ * @param string $lang
22
+ */
23
+ public function sync_thumbnail_id( $orig_post_id, $trnsl_post_id, $lang ) {}
24
+
25
+ /**
26
+ * @param int $variation_id
27
+ * @param int $translated_variation_id
28
+ * @param string $lang
29
+ */
30
+ public function sync_variation_thumbnail_id( $variation_id, $translated_variation_id, $lang ) {}
31
+
32
+ /**
33
+ * @param int $product_id
34
+ */
35
+ public function sync_product_gallery( $product_id ) {}
36
+
37
+ /**
38
+ * @param int $attachment_id
39
+ * @param int $parent_id
40
+ * @param string $target_lang
41
+ *
42
+ * @return int
43
+ */
44
+ public function create_base_media_translation( $attachment_id, $parent_id, $target_lang ) {
45
+ return 0;
46
+ }
47
+
48
+ /**
49
+ * @param int $att_id
50
+ * @param int $dup_att_id
51
+ */
52
+ public function sync_product_gallery_duplicate_attachment( $att_id, $dup_att_id ) {}
53
+
54
+ /**
55
+ * @param int $product_id
56
+ *
57
+ * @return bool
58
+ */
59
+ public function is_media_duplication_enabled( $product_id ) {
60
+ return false;
61
+ }
62
+ }
classes/media/Wrapper/Translatable.php ADDED
@@ -0,0 +1,185 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace WCML\Media\Wrapper;
4
+
5
+ use SitePress;
6
+ use woocommerce_wpml;
7
+ use wpdb;
8
+ use WPML_Media_Attachments_Duplication_Factory;
9
+
10
+ class Translatable implements IMedia {
11
+
12
+ /** @var woocommerce_wpml */
13
+ private $woocommerce_wpml;
14
+ /** @var SitePress */
15
+ private $sitepress;
16
+ /** @var wpdb */
17
+ private $wpdb;
18
+
19
+ public $settings = [];
20
+
21
+ private $products_being_synced = [];
22
+
23
+ public function __construct( $woocommerce_wpml, $sitepress, $wpdb ) {
24
+ $this->woocommerce_wpml = $woocommerce_wpml;
25
+ $this->sitepress = $sitepress;
26
+ $this->wpdb = $wpdb;
27
+ }
28
+
29
+ public function add_hooks() {
30
+ //when save new attachment duplicate product gallery
31
+ add_action( 'wpml_media_create_duplicate_attachment', [ $this, 'sync_product_gallery_duplicate_attachment' ], 11, 2 );
32
+ }
33
+
34
+ public function product_images_ids( $product_id ) {
35
+ $product_images_ids = [];
36
+
37
+ //thumbnail image
38
+ $tmb = get_post_meta( $product_id, '_thumbnail_id', true );
39
+ if ( $tmb ) {
40
+ $product_images_ids[] = $tmb;
41
+ }
42
+
43
+ //product gallery
44
+ $product_gallery = get_post_meta( $product_id, '_product_image_gallery', true );
45
+ if ( $product_gallery ) {
46
+ $product_gallery = explode( ',', $product_gallery );
47
+ foreach ( $product_gallery as $img ) {
48
+ if ( ! in_array( $img, $product_images_ids ) ) {
49
+ $product_images_ids[] = $img;
50
+ }
51
+ }
52
+ }
53
+
54
+ foreach ( wp_get_post_terms( $product_id, 'product_type', [ "fields" => "names" ] ) as $type ) {
55
+ $product_type = $type;
56
+ }
57
+
58
+ if ( isset( $product_type ) && $product_type == 'variable' ) {
59
+ $get_post_variations_image = $this->wpdb->get_col( $this->wpdb->prepare( "SELECT pm.meta_value FROM {$this->wpdb->posts} AS p
60
+ LEFT JOIN {$this->wpdb->postmeta} AS pm ON p.ID = pm.post_id
61
+ WHERE pm.meta_key='_thumbnail_id'
62
+ AND p.post_status IN ('publish','private')
63
+ AND p.post_type = 'product_variation'
64
+ AND p.post_parent = %d
65
+ ORDER BY ID",
66
+ $product_id ) );
67
+ foreach ( $get_post_variations_image as $variation_image ) {
68
+ if ( $variation_image && ! in_array( $variation_image, $product_images_ids ) ) {
69
+ $product_images_ids[] = $variation_image;
70
+ }
71
+ }
72
+ }
73
+
74
+ foreach ( $product_images_ids as $key => $image ) {
75
+ if ( ! get_post_status( $image ) ) {
76
+ unset( $product_images_ids[ $key ] );
77
+ }
78
+ }
79
+
80
+ return $product_images_ids;
81
+ }
82
+
83
+ public function sync_thumbnail_id( $orig_post_id, $trnsl_post_id, $lang ) {
84
+ if ( method_exists( 'WPML_Media_Attachments_Duplication', 'sync_post_thumbnail' ) ) {
85
+ $factory = new WPML_Media_Attachments_Duplication_Factory();
86
+ $media_duplicate = $factory->create();
87
+ if ( $media_duplicate ) {
88
+ $media_duplicate->sync_post_thumbnail( $orig_post_id );
89
+ }
90
+ }
91
+ }
92
+
93
+ public function sync_variation_thumbnail_id( $variation_id, $translated_variation_id, $lang ) {
94
+ $thumbnail_id = get_post_meta( $variation_id, '_thumbnail_id', true );
95
+ $translated_thumbnail = apply_filters( 'translate_object_id', $thumbnail_id, 'attachment', false, $lang );
96
+
97
+ if ( is_null( $translated_thumbnail ) && $thumbnail_id ) {
98
+ $factory = new WPML_Media_Attachments_Duplication_Factory();
99
+ $media_duplicate = $factory->create();
100
+ $translated_thumbnail = $media_duplicate->create_duplicate_attachment( $thumbnail_id,
101
+ wp_get_post_parent_id( $thumbnail_id ),
102
+ $lang );
103
+ }
104
+ if ( $translated_thumbnail ) {
105
+ update_post_meta( $translated_variation_id, '_thumbnail_id', $translated_thumbnail );
106
+ update_post_meta( $variation_id, '_wpml_media_duplicate', 1 );
107
+ update_post_meta( $variation_id, '_wpml_media_featured', 1 );
108
+ }
109
+ }
110
+
111
+ public function sync_product_gallery( $product_id ) {
112
+
113
+ if ( $this->is_media_duplication_enabled( $product_id ) ) {
114
+ $product_gallery = get_post_meta( $product_id, '_product_image_gallery', true );
115
+ $gallery_ids = explode( ',', $product_gallery );
116
+
117
+ $trid = $this->sitepress->get_element_trid( $product_id, 'post_product' );
118
+ $translations = $this->sitepress->get_element_translations( $trid, 'post_product', true );
119
+ foreach ( $translations as $translation ) {
120
+ $duplicated_ids = '';
121
+ if ( ! $translation->original ) {
122
+ foreach ( $gallery_ids as $image_id ) {
123
+ if ( get_post( $image_id ) ) {
124
+ $duplicated_id = apply_filters( 'translate_object_id',
125
+ $image_id,
126
+ 'attachment',
127
+ false,
128
+ $translation->language_code );
129
+ if ( is_null( $duplicated_id ) && $image_id ) {
130
+ $duplicated_id = $this->create_base_media_translation( $image_id,
131
+ $translation->element_id,
132
+ $translation->language_code );
133
+ }
134
+ $duplicated_ids .= $duplicated_id . ',';
135
+ }
136
+ }
137
+ $duplicated_ids = substr( $duplicated_ids, 0, strlen( $duplicated_ids ) - 1 );
138
+ update_post_meta( $translation->element_id, '_product_image_gallery', $duplicated_ids );
139
+ }
140
+ }
141
+ }
142
+ }
143
+
144
+ public function create_base_media_translation( $attachment_id, $parent_id, $target_lang ) {
145
+
146
+ $factory = new WPML_Media_Attachments_Duplication_Factory();
147
+ $media_duplicate = $factory->create();
148
+ $duplicated_id = $media_duplicate->create_duplicate_attachment( $attachment_id, $parent_id, $target_lang );
149
+
150
+ return $duplicated_id;
151
+ }
152
+
153
+ public function sync_product_gallery_duplicate_attachment( $att_id, $dup_att_id ) {
154
+ $product_id = wp_get_post_parent_id( $att_id );
155
+ $post_type = get_post_type( $product_id );
156
+ if ( $post_type != 'product' || array_key_exists( $product_id, $this->products_being_synced ) ) {
157
+ return;
158
+ }
159
+ $this->products_being_synced[ $product_id ] = 1;
160
+ $this->sync_product_gallery( $product_id );
161
+ unset( $this->products_being_synced[ $product_id ] );
162
+ }
163
+
164
+ public function is_media_duplication_enabled( $product_id ) {
165
+
166
+ $setting_value = get_post_meta( $product_id,
167
+ $this->sitepress->get_wp_api()
168
+ ->constant( 'WPML_Admin_Post_Actions::DUPLICATE_MEDIA_META_KEY' ),
169
+ true );
170
+
171
+ if ( '' === $setting_value ) {
172
+ // fallback to global setting
173
+ $media_options = get_option( '_wpml_media', [] );
174
+
175
+ $global_setting_key = $this->sitepress->get_wp_api()
176
+ ->constant( 'WPML_Admin_Post_Actions::DUPLICATE_MEDIA_GLOBAL_KEY' );
177
+ if ( isset( $media_options['new_content_settings'][ $global_setting_key ] ) ) {
178
+ $setting_value = $media_options['new_content_settings'][ $global_setting_key ];
179
+ }
180
+ }
181
+
182
+ return (bool) $setting_value;
183
+ }
184
+
185
+ }
classes/order-property-filter/class-wcml-payment-method-filter.php CHANGED
@@ -12,6 +12,7 @@ class WCML_Payment_Method_Filter {
12
  }
13
 
14
  public function payment_method_string( $title, $object_id, $meta_key ) {
 
15
  if ( '_payment_method_title' === $meta_key && !empty( $title ) && $object_id && 'shop_order' === $this->get_post_type( $object_id ) ) {
16
  $payment_gateway = $this->get_payment_gateway( $object_id );
17
 
@@ -23,7 +24,15 @@ class WCML_Payment_Method_Filter {
23
  }
24
 
25
  if( $payment_gateway ){
26
- $title = icl_translate( 'woocommerce', $payment_gateway->id . '_gateway_title', $payment_gateway->title );
 
 
 
 
 
 
 
 
27
  }
28
  }
29
 
12
  }
13
 
14
  public function payment_method_string( $title, $object_id, $meta_key ) {
15
+
16
  if ( '_payment_method_title' === $meta_key && !empty( $title ) && $object_id && 'shop_order' === $this->get_post_type( $object_id ) ) {
17
  $payment_gateway = $this->get_payment_gateway( $object_id );
18
 
24
  }
25
 
26
  if( $payment_gateway ){
27
+ $title = icl_translate( 'admin_texts_woocommerce_gateways', $payment_gateway->id . '_gateway_title', $payment_gateway->title );
28
+
29
+ if( $title === $payment_gateway->title ){
30
+ $title = __( $payment_gateway->title, 'woocommerce' );
31
+
32
+ if ( 'cheque' === $payment_gateway->id && $title === $payment_gateway->title ) {
33
+ $translated_string = _x( $payment_gateway->title, 'Check payment method', 'woocommerce' );
34
+ }
35
+ }
36
  }
37
  }
38
 
classes/product/class-wcml-product-data-store-cpt.php ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Class WCML_Product_Data_Store_CPT
4
+ */
5
+ class WCML_Product_Data_Store_CPT extends WC_Product_Data_Store_CPT{
6
+
7
+ /**
8
+ * @param int $product_id
9
+ */
10
+ public function update_lookup_table_data( $product_id ){
11
+ $this->update_lookup_table( $product_id, 'wc_product_meta_lookup' );
12
+ }
13
+
14
+ }
classes/shortcodes/class-wcml-wc-shortcode-product-category.php CHANGED
@@ -38,33 +38,36 @@ class WCML_WC_Shortcode_Product_Category {
38
  if ( isset( $args['product_cat'] ) ) {
39
  $args = $this->translate_categories_using_simple_tax_query( $args );
40
  } elseif ( ! empty( $atts['category'] ) && isset( $args['tax_query'] ) ) {
 
 
 
41
 
42
- // Get translated category slugs, we need to remove WPML filter.
43
- $filter_exists = remove_filter( 'terms_clauses', array( $this->sitepress, 'terms_clauses' ), 10 );
44
- $slugs = array_filter( explode(',', $atts['category'] ), 'trim' ) ;
45
- $categories = get_terms( array( 'slug' => $slugs, 'taxonomy' => 'product_cat' ) );
46
 
47
- if ( $filter_exists ) {
48
- add_filter( 'terms_clauses', array( $this->sitepress, 'terms_clauses' ), 10, 3 );
49
- }
50
 
51
- // Replace slugs in query arguments.
52
- $terms = wp_list_pluck( $categories, 'slug' );
53
-
54
- foreach ( $args['tax_query'] as $i => $tax_query ) {
55
- $args['tax_query'][ $i ] = array();
56
- if ( ! is_int( key( $tax_query ) ) ) {
57
- $tax_query = array( $tax_query );
58
- }
59
- foreach ( $tax_query as $j => $condition ) {
60
- if ( 'product_cat' === $condition['taxonomy'] ) {
61
- $condition['terms'] = $terms;
62
- }
63
- $args['tax_query'][ $i ][] = $condition;
64
- }
 
 
65
  }
 
66
  }
67
-
68
  }
69
 
70
  return $args;
38
  if ( isset( $args['product_cat'] ) ) {
39
  $args = $this->translate_categories_using_simple_tax_query( $args );
40
  } elseif ( ! empty( $atts['category'] ) && isset( $args['tax_query'] ) ) {
41
+ $categories = wpml_collect( explode(',', $atts['category'] ) )
42
+ ->filter( 'trim' )
43
+ ->map( function ( $category ) { return get_term( $category, 'product_cat' ); } );
44
 
45
+ $args = $this->replace_category_in_query_arguments( $args, $categories );
46
+ }
47
+ }
 
48
 
49
+ return $args;
50
+ }
 
51
 
52
+ /**
53
+ * @param array $args
54
+ * @param array $terms
55
+ *
56
+ * @return array
57
+ */
58
+ private function replace_category_in_query_arguments( $args, $terms ){
59
+
60
+ foreach ( $args['tax_query'] as $i => $tax_query ) {
61
+ $args['tax_query'][ $i ] = array();
62
+ if ( ! is_int( key( $tax_query ) ) ) {
63
+ $tax_query = array( $tax_query );
64
+ }
65
+ foreach ( $tax_query as $j => $condition ) {
66
+ if ( 'product_cat' === $condition['taxonomy'] ) {
67
+ $condition['terms'] = wp_list_pluck( $terms, $condition['field'] );
68
  }
69
+ $args['tax_query'][ $i ][] = $condition;
70
  }
 
71
  }
72
 
73
  return $args;
classes/templates/php/model.php ADDED
@@ -0,0 +1,114 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * @author OnTheGo Systems
4
+ * @package WPML\Templates
5
+ */
6
+
7
+ namespace WPML\Templates\PHP;
8
+
9
+ class Model {
10
+ /**
11
+ * @var \WPML\Templates\PHP\Model[]|mixed[]
12
+ */
13
+ private $attributes = [];
14
+
15
+ /**
16
+ * Model constructor.
17
+ *
18
+ * @param array $data
19
+ */
20
+ public function __construct( $data = [] ) {
21
+ foreach ( $data as $key => $value ) {
22
+ $this->__set( $key, $value );
23
+ }
24
+ }
25
+
26
+ /**
27
+ * If a property does not exist, the method will create it as an "empty" instance of `Model`
28
+ * so that children properties can be called without throwing errors.
29
+ *
30
+ * @param string $name
31
+ *
32
+ * @return mixed|null
33
+ * @see \WPML\Templates\PHP\Model::__toString
34
+ */
35
+ public function __get( $name ) {
36
+ if ( ! array_key_exists( $name, $this->attributes ) ) {
37
+ $this->attributes[ $name ] = new Model();
38
+ }
39
+
40
+ return $this->attributes[ $name ];
41
+ }
42
+
43
+ /**
44
+ * It ensures that $value is always either an array or a primitive type.
45
+ *
46
+ * @param string $name
47
+ * @param mixed $value
48
+ */
49
+ public function __set( $name, $value ) {
50
+ if ( is_object( $value ) ) {
51
+ $value = get_object_vars( $value );
52
+ }
53
+ if ( is_array( $value ) ) {
54
+ $is_assoc = is_array( $value ) && count( array_filter( array_keys( $value ), 'is_string' ) ) > 0;
55
+ if($is_assoc) {
56
+ $value = new Model( $value );
57
+ }
58
+ }
59
+ $this->attributes[ $name ] = $value;
60
+ }
61
+
62
+ /**
63
+ * @param string $name
64
+ *
65
+ * @return bool
66
+ */
67
+ public function hasValue( $name ) {
68
+ return ! $this->isNull( $name ) && ! $this->isEmpty( $name );
69
+ }
70
+
71
+ /**
72
+ * @param string $name
73
+ *
74
+ * @return bool
75
+ */
76
+ public function isNull( $name ) {
77
+ return $this->__get( $name ) === null;
78
+ }
79
+
80
+ /**
81
+ * @param string $name
82
+ *
83
+ * @return bool
84
+ */
85
+ public function isEmpty( $name ) {
86
+ return $this->__get( $name ) === '' || ( ( $this->__get( $name ) instanceof Model ) && ! $this->__get( $name )->getAttributes() );
87
+ }
88
+
89
+ /**
90
+ * @return mixed[]|\WPML\Templates\PHP\Model[]
91
+ */
92
+ public function getAttributes() {
93
+ return $this->attributes;
94
+ }
95
+
96
+ /**
97
+ * This logic allows using the model in a template even when referring to properties which do no exist.
98
+ *
99
+ * Example:
100
+ * `<h1><?php echo esc_html( $model->non_existing_property->title ); ?></h1>` Will output an empty string instead of throwing an error
101
+ *
102
+ * @return string
103
+ */
104
+ public function __toString() {
105
+ if ( count( $this->attributes ) === 0 ) {
106
+ return '';
107
+ }
108
+ if ( count( $this->attributes ) === 1 ) {
109
+ return array_values( $this->attributes )[0];
110
+ }
111
+
112
+ return wp_json_encode( $this->attributes );
113
+ }
114
+ }
compatibility/class-wcml-bookings.php CHANGED
@@ -46,7 +46,17 @@ class WCML_Bookings {
46
  $this->tp = $tp;
47
  }
48
 
 
 
 
49
  public function add_hooks(){
 
 
 
 
 
 
 
50
  add_action( 'woocommerce_bookings_after_booking_base_cost', array(
51
  $this,
52
  'wcml_price_field_after_booking_base_cost'
@@ -227,6 +237,47 @@ class WCML_Bookings {
227
 
228
  }
229
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
230
  public function save_booking_action_handler( $booking_id ) {
231
 
232
  $this->maybe_set_booking_language( $booking_id );
@@ -2450,70 +2501,82 @@ class WCML_Bookings {
2450
  }
2451
 
2452
  public function translate_booking_confirmed_email_texts( $booking_id ){
2453
-
2454
- if( class_exists( 'WC_Email_Booking_Confirmed' ) && isset( $this->woocommerce->mailer()->emails[ 'WC_Email_Booking_Confirmed' ] ) ){
2455
- $booking = get_wc_booking( $booking_id );
2456
- if( $booking->get_order() ){
2457
- $this->translate_email_strings( 'WC_Email_Booking_Confirmed', 'woocommerce_booking_confirmed_settings', $booking->get_order()->get_id() );
2458
- }
2459
  }
2460
-
2461
  }
2462
 
2463
  public function translate_booking_cancelled_email_texts( $booking_id ){
2464
-
2465
- if( class_exists( 'WC_Email_Booking_Cancelled' ) && isset( $this->woocommerce->mailer()->emails[ 'WC_Email_Booking_Cancelled' ] ) ){
2466
- $booking = get_wc_booking( $booking_id );
2467
- $this->translate_email_strings( 'WC_Email_Booking_Cancelled', 'woocommerce_booking_cancelled_settings', $booking->get_order()->get_id() );
2468
  }
2469
-
2470
  }
2471
 
2472
  public function translate_booking_reminder_email_texts( $booking_id ){
2473
-
2474
- if( class_exists( 'WC_Email_Booking_Reminder' ) && isset( $this->woocommerce->mailer()->emails[ 'WC_Email_Booking_Reminder' ] ) ){
2475
- $booking = get_wc_booking( $booking_id );
2476
- $this->translate_email_strings( 'WC_Email_Booking_Reminder', 'woocommerce_booking_reminder_settings', $booking->get_order()->get_id() );
2477
  }
2478
-
2479
  }
2480
 
2481
  public function translate_new_booking_email_texts( $booking_id ){
2482
-
2483
- if( class_exists( 'WC_Email_New_Booking' ) && isset( $this->woocommerce->mailer()->emails[ 'WC_Email_New_Booking' ] ) ){
2484
- $user = get_user_by('email', $this->woocommerce->mailer()->emails['WC_Email_New_Booking']->recipient );
2485
- if($user){
2486
- $user_lang = $this->sitepress->get_user_admin_language($user->ID, true );
2487
- }else{
2488
- $booking = get_wc_booking( $booking_id );
2489
- $user_lang = get_post_meta( $booking->get_order()->get_id(), 'wpml_language', true );
2490
- }
2491
- $this->translate_email_strings( 'WC_Email_New_Booking', 'woocommerce_new_booking_settings', false, $user_lang );
2492
  $this->woocommerce->mailer()->emails['WC_Email_New_Booking']->heading_confirmation = $this->woocommerce_wpml->emails->wcml_get_translated_email_string( 'admin_texts_woocommerce_new_booking_settings', '[woocommerce_new_booking_settings]heading_confirmation', $user_lang );
2493
  $this->woocommerce->mailer()->emails['WC_Email_New_Booking']->subject_confirmation = $this->woocommerce_wpml->emails->wcml_get_translated_email_string( 'admin_texts_woocommerce_new_booking_settings', '[woocommerce_new_booking_settings]subject_confirmation', $user_lang );
2494
  }
2495
  }
2496
 
2497
  public function translate_booking_cancelled_admin_email_texts( $booking_id ){
2498
-
2499
- if( class_exists( 'WC_Email_Admin_Booking_Cancelled' ) && isset( $this->woocommerce->mailer()->emails[ 'WC_Email_Admin_Booking_Cancelled' ] ) ){
2500
- $user = get_user_by('email', $this->woocommerce->mailer()->emails['WC_Email_Admin_Booking_Cancelled']->recipient );
2501
- if($user){
2502
- $user_lang = $this->sitepress->get_user_admin_language($user->ID, true );
2503
- }else{
2504
- $booking = get_wc_booking( $booking_id );
2505
- $user_lang = get_post_meta( $booking->get_order()->get_id(), 'wpml_language', true );
2506
- }
2507
- $this->translate_email_strings( 'WC_Email_Admin_Booking_Cancelled', 'woocommerce_admin_booking_cancelled_settings', false, $user_lang );
2508
  }
 
2509
 
 
 
 
 
 
 
 
2510
  }
2511
 
2512
- public function booking_email_language( $current_language ){
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2513
 
2514
- if( isset( $_POST[ 'post_type' ] ) && 'wc_booking' === $_POST[ 'post_type' ] ){
2515
- $order_language = get_post_meta( $_POST[ '_booking_order_id' ], 'wpml_language', true );
2516
- if( $order_language ){
2517
  $current_language = $order_language;
2518
  }
2519
  }
@@ -2521,10 +2584,26 @@ class WCML_Bookings {
2521
  return $current_language;
2522
  }
2523
 
2524
- private function translate_email_strings( $email_class, $setting_slug, $order_id = false, $user_lang = null ){
 
 
 
 
 
 
2525
 
2526
- $this->woocommerce->mailer()->emails[$email_class]->heading = $this->woocommerce_wpml->emails->wcml_get_translated_email_string( 'admin_texts_'.$setting_slug, '['.$setting_slug.']heading', $order_id, $user_lang );
2527
- $this->woocommerce->mailer()->emails[$email_class]->subject = $this->woocommerce_wpml->emails->wcml_get_translated_email_string( 'admin_texts_'.$setting_slug, '['.$setting_slug.']subject', $order_id, $user_lang );
 
 
 
 
 
 
 
 
 
 
2528
  }
2529
 
2530
  public function maybe_set_booking_language( $booking_id ) {
46
  $this->tp = $tp;
47
  }
48
 
49
+ /**
50
+ * Adds hooks.
51
+ */
52
  public function add_hooks(){
53
+
54
+ // Translate emails.
55
+ add_filter( 'get_post_metadata', array( $this, 'get_order_language' ), 10, 4 );
56
+ add_filter( 'woocommerce_booking_reminder_notification', array( $this, 'translate_notification' ), 9 );
57
+ add_filter( 'woocommerce_booking_confirmed_notification', array( $this, 'translate_notification' ), 9 );
58
+ add_filter( 'woocommerce_booking_cancelled_notification', array( $this, 'translate_notification' ), 9 );
59
+
60
  add_action( 'woocommerce_bookings_after_booking_base_cost', array(
61
  $this,
62
  'wcml_price_field_after_booking_base_cost'
237
 
238
  }
239
 
240
+ /**
241
+ * When sending a booking notification to the customer get the language from the order.
242
+ *
243
+ * @param string $check Dummy argument.
244
+ * @param integer $object_id The Post ID to query.
245
+ * @param string $meta_key The meta key to query.
246
+ * @param bool $single Wether we want a single value or an array.
247
+ * @return string
248
+ */
249
+ public function get_order_language( $check, $object_id, $meta_key, $single ) {
250
+
251
+ if ( 'wpml_language' === $meta_key && 'wc_booking' === get_post_type( $object_id ) ) {
252
+ // Get the order_item_id which might be in the original booking.
253
+ $order_item_id = get_post_meta( $object_id, '_booking_order_item_id', true );
254
+ if ( empty( $order_item_id ) ) {
255
+ $original_booking_id = get_post_meta( $object_id, '_booking_duplicate_of', true );
256
+ $order_item_id = get_post_meta( $original_booking_id, '_booking_order_item_id', true );
257
+ }
258
+
259
+ // From here we can grab the order_id and return its language.
260
+ $order_id = $this->wpdb->get_var( $this->wpdb->prepare(
261
+ "SELECT order_id FROM {$this->wpdb->prefix}woocommerce_order_items WHERE order_item_id = %d",
262
+ $order_item_id
263
+ ) ); // WPCS: unprepared SQL OK.
264
+ remove_filter( 'get_post_metadata', array( $this, 'get_order_language' ), 10 );
265
+ $check = get_post_meta( $order_id, 'wpml_language', $single );
266
+ add_filter( 'get_post_metadata', array( $this, 'get_order_language' ), 10, 4 );
267
+ }
268
+
269
+ return $check;
270
+ }
271
+
272
+ /**
273
+ * Translate strings of notifications.
274
+ *
275
+ * @param integer $order_id Order ID.
276
+ */
277
+ public function translate_notification( $order_id ) {
278
+ $this->woocommerce_wpml->emails->refresh_email_lang( $order_id );
279
+ }
280
+
281
  public function save_booking_action_handler( $booking_id ) {
282
 
283
  $this->maybe_set_booking_language( $booking_id );
2501
  }
2502
 
2503
  public function translate_booking_confirmed_email_texts( $booking_id ){
2504
+ if( $this->email_class_exists( 'WC_Email_Booking_Confirmed' ) ){
2505
+ $this->translate_email_strings( 'WC_Email_Booking_Confirmed', 'woocommerce_booking_confirmed_settings', $booking_id );
 
 
 
 
2506
  }
 
2507
  }
2508
 
2509
  public function translate_booking_cancelled_email_texts( $booking_id ){
2510
+ if( $this->email_class_exists( 'WC_Email_Booking_Cancelled' ) ){
2511
+ $this->translate_email_strings( 'WC_Email_Booking_Cancelled', 'woocommerce_booking_cancelled_settings', $booking_id );
 
 
2512
  }
 
2513
  }
2514
 
2515
  public function translate_booking_reminder_email_texts( $booking_id ){
2516
+ if( $this->email_class_exists( 'WC_Email_Booking_Reminder' ) ){
2517
+ $this->translate_email_strings( 'WC_Email_Booking_Reminder', 'woocommerce_booking_reminder_settings', $booking_id );
 
 
2518
  }
 
2519
  }
2520
 
2521
  public function translate_new_booking_email_texts( $booking_id ){
2522
+ if( $this->email_class_exists( 'WC_Email_New_Booking' ) ){
2523
+ $user_lang = $this->get_admin_user_email_language( 'WC_Email_New_Booking' );
2524
+ $this->translate_email_strings( 'WC_Email_New_Booking', 'woocommerce_new_booking_settings', $booking_id, $user_lang );
 
 
 
 
 
 
 
2525
  $this->woocommerce->mailer()->emails['WC_Email_New_Booking']->heading_confirmation = $this->woocommerce_wpml->emails->wcml_get_translated_email_string( 'admin_texts_woocommerce_new_booking_settings', '[woocommerce_new_booking_settings]heading_confirmation', $user_lang );
2526
  $this->woocommerce->mailer()->emails['WC_Email_New_Booking']->subject_confirmation = $this->woocommerce_wpml->emails->wcml_get_translated_email_string( 'admin_texts_woocommerce_new_booking_settings', '[woocommerce_new_booking_settings]subject_confirmation', $user_lang );
2527
  }
2528
  }
2529
 
2530
  public function translate_booking_cancelled_admin_email_texts( $booking_id ){
2531
+ if( $this->email_class_exists( 'WC_Email_Admin_Booking_Cancelled' ) ){
2532
+ $this->translate_email_strings( 'WC_Email_Admin_Booking_Cancelled', 'woocommerce_admin_booking_cancelled_settings', $booking_id, $this->get_admin_user_email_language( 'WC_Email_Admin_Booking_Cancelled' ) );
 
 
 
 
 
 
 
 
2533
  }
2534
+ }
2535
 
2536
+ /**
2537
+ * @param string $email_class
2538
+ *
2539
+ * @return bool
2540
+ */
2541
+ private function email_class_exists( $email_class ) {
2542
+ return class_exists( $email_class ) && isset( $this->woocommerce->mailer()->emails[ $email_class ] );
2543
  }
2544
 
2545
+ /**
2546
+ * @param string $email_class
2547
+ *
2548
+ * @return bool|mixed|null|string
2549
+ */
2550
+ private function get_admin_user_email_language( $email_class ){
2551
+
2552
+ $user = get_user_by('email', $this->woocommerce->mailer()->emails[$email_class]->recipient );
2553
+ if ( $user ) {
2554
+ return $this->sitepress->get_user_admin_language( $user->ID, true );
2555
+ }
2556
+
2557
+ return null;
2558
+ }
2559
+
2560
+ /**
2561
+ * @param $booking_id
2562
+ *
2563
+ * @return bool|WC_Order
2564
+ */
2565
+ private function get_booking_order( $booking_id ){
2566
+ return get_wc_booking( $booking_id )->get_order();
2567
+ }
2568
+
2569
+
2570
+ /**
2571
+ * @param string $current_language
2572
+ *
2573
+ * @return string
2574
+ */
2575
+ public function booking_email_language( $current_language ) {
2576
 
2577
+ if ( isset( $_POST['post_type'] ) && 'wc_booking' === $_POST['post_type'] && isset( $_POST['_booking_order_id'] ) ) {
2578
+ $order_language = get_post_meta( $_POST['_booking_order_id'], 'wpml_language', true );
2579
+ if ( $order_language ) {
2580
  $current_language = $order_language;
2581
  }
2582
  }
2584
  return $current_language;
2585
  }
2586
 
2587
+ /**
2588
+ * @param string $email_class
2589
+ * @param string $setting_slug
2590
+ * @param int $booking_id
2591
+ * @param string|null $user_lang
2592
+ */
2593
+ private function translate_email_strings( $email_class, $setting_slug, $booking_id, $user_lang = null ){
2594
 
2595
+ $order_id = false;
2596
+ if ( !$user_lang ){
2597
+ $booking_order = $this->get_booking_order( $booking_id );
2598
+ if( $booking_order ){
2599
+ $order_id = $booking_order->get_id();
2600
+ }
2601
+ }
2602
+
2603
+ if( $order_id || $user_lang ){
2604
+ $this->woocommerce->mailer()->emails[$email_class]->heading = $this->woocommerce_wpml->emails->wcml_get_translated_email_string( 'admin_texts_'.$setting_slug, '['.$setting_slug.']heading', $order_id, $user_lang );
2605
+ $this->woocommerce->mailer()->emails[$email_class]->subject = $this->woocommerce_wpml->emails->wcml_get_translated_email_string( 'admin_texts_'.$setting_slug, '['.$setting_slug.']subject', $order_id, $user_lang );
2606
+ }
2607
  }
2608
 
2609
  public function maybe_set_booking_language( $booking_id ) {
compatibility/class-wcml-checkout-addons.php CHANGED
@@ -1,20 +1,61 @@
1
  <?php
2
  /**
3
- * Description of wc_checkout_addons
4
  *
5
  * @author konrad
6
  */
7
  class WCML_Checkout_Addons {
8
- public function __construct() {
9
- add_filter( 'wc_checkout_add_ons_options', array( $this, 'wc_checkout_add_ons_options_wpml_multi_currency_support' ) );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
10
  }
11
-
12
- public function wc_checkout_add_ons_options_wpml_multi_currency_support( $options ) {
13
 
14
- foreach ( $options as $i => $option ) {
15
- $options[ $i ]['cost'] = apply_filters( 'wcml_raw_price_amount', $options[ $i ]['cost'] );
 
 
 
16
  }
 
 
17
 
18
- return $options;
19
- }
 
20
  }
1
  <?php
2
  /**
3
+ * Compatibility class for wc_checkout_addons plugin.
4
  *
5
  * @author konrad
6
  */
7
  class WCML_Checkout_Addons {
8
+
9
+ public function add_hooks() {
10
+ add_filter( 'option_wc_checkout_add_ons', array( $this, 'option_wc_checkout_add_ons' ), 10, 2 );
11
+ }
12
+
13
+ public function option_wc_checkout_add_ons( $option_value, $option_name = null ) {
14
+ if ( is_array( $option_value ) ) {
15
+ foreach ( $option_value as $addon_id => $addon_conf ) {
16
+ $addon_conf = $this->handle_option_part( $addon_id, $addon_conf );
17
+ if ( isset( $addon_conf['options'] ) ) {
18
+ foreach ( $addon_conf['options'] as $index => $fields ) {
19
+ $addon_conf['options'][ $index ] = $this->handle_option_part( $index, $fields );
20
+ }
21
+ }
22
+ $option_value[ $addon_id ] = $addon_conf;
23
+ }
24
+ }
25
+
26
+ return $option_value;
27
+ }
28
+
29
+ private function handle_option_part( $index, $conf ) {
30
+ $conf = $this->register_or_translate( 'label', $conf, $index );
31
+ $conf = $this->register_or_translate( 'description', $conf, $index );
32
+ $conf = $this->adjust_price( $conf );
33
+ return $conf;
34
+ }
35
+
36
+ private function register_or_translate( $element, $conf, $index ) {
37
+ if ( isset( $conf[ $element ] ) ) {
38
+ $string = $conf[ $element ];
39
+ $key = $index . '_' . $element . '_' . md5( $string );
40
+ if ( $this->is_default_language() ) {
41
+ do_action( 'wpml_register_single_string', 'wc_checkout_addons', $key, $string );
42
+ } else {
43
+ $conf[ $element ] = apply_filters( 'wpml_translate_single_string', $string, 'wc_checkout_addons', $key );
44
+ }
45
+ }
46
+ return $conf;
47
  }
 
 
48
 
49
+ private function adjust_price( $conf ) {
50
+ if ( isset( $conf['adjustment'], $conf['adjustment_type'] )
51
+ && $conf['adjustment_type'] === 'fixed'
52
+ && ! $this->is_default_language() ) {
53
+ $conf['adjustment'] = apply_filters( 'wcml_raw_price_amount', $conf['adjustment'] );
54
  }
55
+ return $conf;
56
+ }
57
 
58
+ private function is_default_language() {
59
+ return apply_filters( 'wpml_current_language', null ) === apply_filters( 'wpml_default_language', null );
60
+ }
61
  }
compatibility/class-wcml-composite-products.php CHANGED
@@ -3,6 +3,8 @@
3
 
4
  class WCML_Composite_Products extends WCML_Compatibility_Helper{
5
 
 
 
6
  /**
7
  * @var SitePress
8
  */
@@ -34,8 +36,6 @@ class WCML_Composite_Products extends WCML_Compatibility_Helper{
34
  add_filter( 'wcml_cart_contents', array($this, 'wpml_composites_compat'), 11, 4 );
35
  add_filter( 'woocommerce_composite_component_options_query_args', array($this, 'wpml_composites_transients_cache_per_language'), 10, 3 );
36
  add_action( 'wcml_before_sync_product', array( $this, 'sync_composite_data_across_translations'), 10, 2 );
37
- add_filter( 'raw_woocommerce_price', array( $this, 'apply_rounding_rules' ) );
38
-
39
 
40
  if( is_admin() ){
41
 
@@ -57,10 +57,27 @@ class WCML_Composite_Products extends WCML_Compatibility_Helper{
57
  add_filter( 'wcml_do_not_display_custom_fields_for_product', array( $this, 'replace_tm_editor_custom_fields_with_own_sections' ) );
58
  }else{
59
  add_filter( 'get_post_metadata', array( $this, 'filter_composite_product_cost' ), 10, 4 );
 
60
  }
61
 
62
  }
63
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
64
  function woocommerce_composite_component_default_option($selected_value, $component_id, $object) {
65
 
66
  if( !empty( $selected_value ) )
@@ -568,8 +585,12 @@ class WCML_Composite_Products extends WCML_Compatibility_Helper{
568
  }
569
 
570
  public function apply_rounding_rules( $price ) {
571
- if ( wcml_is_multi_currency_on() ) {
572
- $price = $this->woocommerce_wpml->multi_currency->prices->apply_rounding_rules( $price );
 
 
 
 
573
  }
574
 
575
  return $price;
3
 
4
  class WCML_Composite_Products extends WCML_Compatibility_Helper{
5
 
6
+ const PRICE_FILTERS_PRIORITY_AFTER_COMPOSITE = 99;
7
+
8
  /**
9
  * @var SitePress
10
  */
36
  add_filter( 'wcml_cart_contents', array($this, 'wpml_composites_compat'), 11, 4 );
37
  add_filter( 'woocommerce_composite_component_options_query_args', array($this, 'wpml_composites_transients_cache_per_language'), 10, 3 );
38
  add_action( 'wcml_before_sync_product', array( $this, 'sync_composite_data_across_translations'), 10, 2 );
 
 
39
 
40
  if( is_admin() ){
41
 
57
  add_filter( 'wcml_do_not_display_custom_fields_for_product', array( $this, 'replace_tm_editor_custom_fields_with_own_sections' ) );
58
  }else{
59
  add_filter( 'get_post_metadata', array( $this, 'filter_composite_product_cost' ), 10, 4 );
60
+ $this->add_price_rounding_filters();
61
  }
62
 
63
  }
64
 
65
+ public function add_price_rounding_filters(){
66
+
67
+ $filters = array(
68
+ 'woocommerce_product_get_price',
69
+ 'woocommerce_product_get_sale_price',
70
+ 'woocommerce_product_get_regular_price',
71
+ 'woocommerce_product_variation_get_price',
72
+ 'woocommerce_product_variation_get_sale_price',
73
+ 'woocommerce_product_variation_get_regular_price'
74
+ );
75
+
76
+ foreach( $filters as $filter ){
77
+ add_filter( $filter, array( $this, 'apply_rounding_rules' ), self::PRICE_FILTERS_PRIORITY_AFTER_COMPOSITE );
78
+ }
79
+ }
80
+
81
  function woocommerce_composite_component_default_option($selected_value, $component_id, $object) {
82
 
83
  if( !empty( $selected_value ) )
585
  }
586
 
587
  public function apply_rounding_rules( $price ) {
588
+
589
+ if ( is_composite_product() && wcml_is_multi_currency_on() ) {
590
+ $current_currency = $this->woocommerce_wpml->multi_currency->get_client_currency();
591
+ if( $current_currency !== wcml_get_woocommerce_currency_option() ) {
592
+ $price = $this->woocommerce_wpml->multi_currency->prices->apply_rounding_rules( $price, $current_currency );
593
+ }
594
  }
595
 
596
  return $price;
compatibility/class-wcml-order-status-manager.php ADDED
@@ -0,0 +1,88 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Class WCML_Order_Status_Manager
4
+ * compatibility class for WC Order Status Manager plugin.
5
+ */
6
+ class WCML_Order_Status_Manager {
7
+ /**
8
+ * WordPress query object.
9
+ *
10
+ * @var WP_Query
11
+ */
12
+ private $wp_query;
13
+
14
+ /**
15
+ * WCML_Order_Status_Manager constructor.
16
+ *
17
+ * @param WP_Query $wp_query WordPress query object.
18
+ */
19
+ public function __construct( WP_Query $wp_query ) {
20
+ $this->wp_query = $wp_query;
21
+ }
22
+
23
+ /**
24
+ * Adds WordPress hooks.
25
+ */
26
+ public function add_hooks() {
27
+ add_action( 'pre_get_posts', array( $this, 'pre_get_posts' ), 10, 1 );
28
+ }
29
+
30
+ /**
31
+ * Adds post__not_in to the query arguments.
32
+ *
33
+ * @param null $q the parsed query.
34
+ */
35
+ public function pre_get_posts( $q = null ) {
36
+ if ( isset( $q->query['post_type'] )
37
+ && 'wc_order_status' === $q->query['post_type']
38
+ && doing_filter( 'woocommerce_register_shop_order_post_statuses' )
39
+ ) {
40
+ $q->set( 'post__not_in', $this->prepare_post_not_in( $q, $this->get_statuses() ) );
41
+ }
42
+ }
43
+
44
+ /**
45
+ * Queries for all statuses in wp_posts table.
46
+ */
47
+ private function get_statuses() {
48
+ remove_action( 'pre_get_posts', array( $this, 'pre_get_posts' ), 10 );
49
+ $this->wp_query->query(
50
+ array(
51
+ 'post_type' => 'wc_order_status',
52
+ 'posts_per_page' => -1,
53
+ 'suppress_filters' => false,
54
+
55
+ )
56
+ );
57
+ add_action( 'pre_get_posts', array( $this, 'pre_get_posts' ), 10, 1 );
58
+ return $this->wp_query->posts;
59
+ }
60
+
61
+ /**
62
+ * Filters out elements not in the current language from query results.
63
+ *
64
+ * @param WP_Query $q The WordPress query.
65
+ * @param void $statuses Posts with post type wc_order_status
66
+ *
67
+ * @return array The post__not_in array.
68
+ */
69
+ private function prepare_post_not_in( $q, $statuses ) {
70
+ $post__not_in = array();
71
+
72
+ if ( $statuses ) {
73
+ $current_language = apply_filters( 'wpml_current_language', null );
74
+
75
+ foreach( $statuses as $status ) {
76
+ $post_language_details = apply_filters( 'wpml_post_language_details', '', $status->ID );
77
+ if ( isset( $post_language_details['language_code'] ) ) {
78
+ if ( $post_language_details['language_code'] !== $current_language ) {
79
+ $post__not_in[] = $status->ID;
80
+ }
81
+ }
82
+ }
83
+ }
84
+
85
+ $post__not_in_query = isset( $q->query_vars['post__not_in'] ) ? $q->query_vars['post__not_in'] : array();
86
+ return array_merge( $post__not_in_query, $post__not_in );
87
+ }
88
+ }
compatibility/class-wcml-product-addons.php CHANGED
@@ -171,33 +171,13 @@ class WCML_Product_Addons {
171
 
172
  if ( $this->is_multi_currency_on() ) {
173
 
174
- $client_currency = $this->woocommerce_wpml->multi_currency->get_client_currency();
175
- $is_custom_prices_on = $this->is_product_custom_prices_on( $post_id );
176
-
177
  foreach ( $addons as $add_id => $addon ) {
178
-
179
  if ( isset( $addon['price'] ) && $addon['price'] ) {
180
- if (
181
- $is_custom_prices_on &&
182
- isset( $addon[ 'price_' . $client_currency ] ) &&
183
- $addon[ 'price_' . $client_currency ]
184
- ) {
185
- $addons[ $add_id ]['price'] = $addon[ 'price_' . $client_currency ];
186
- } else {
187
- $addons[ $add_id ]['price'] = apply_filters( 'wcml_raw_price_amount', $addon['price'] );
188
- }
189
  }
190
 
191
  foreach ( $addon['options'] as $key => $option ) {
192
- if (
193
- $is_custom_prices_on &&
194
- isset( $option[ 'price_' . $client_currency ] ) &&
195
- $option[ 'price_' . $client_currency ]
196
- ) {
197
- $addons[ $add_id ]['options'][ $key ]['price'] = $option[ 'price_' . $client_currency ];
198
- } else {
199
- $addons[ $add_id ]['options'][ $key ]['price'] = apply_filters( 'wcml_raw_price_amount', $option['price'] );
200
- }
201
  }
202
  }
203
  }
@@ -205,6 +185,33 @@ class WCML_Product_Addons {
205
  return $addons;
206
  }
207
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
208
  /**
209
  * @param $product_terms
210
  *
@@ -401,7 +408,7 @@ class WCML_Product_Addons {
401
  }
402
 
403
  public function load_dialog_resources(){
404
- wp_enqueue_script( 'wcml-dialogs', WCML_PLUGIN_URL . '/res/js/dialogs' . WCML_JS_MIN . '.js', array('jquery-ui-dialog'), WCML_VERSION );
405
  }
406
 
407
  /**
171
 
172
  if ( $this->is_multi_currency_on() ) {
173
 
 
 
 
174
  foreach ( $addons as $add_id => $addon ) {
 
175
  if ( isset( $addon['price'] ) && $addon['price'] ) {
176
+ $addons[ $add_id ]['price'] = $this->converted_addon_price( $addon, $post_id );
 
 
 
 
 
 
 
 
177
  }
178
 
179
  foreach ( $addon['options'] as $key => $option ) {
180
+ $addons[ $add_id ]['options'][ $key ]['price'] = $this->converted_addon_price( $option, $post_id );
 
 
 
 
 
 
 
 
181
  }
182
  }
183
  }
185
  return $addons;
186
  }
187
 
188
+ /**
189
+ * @param array $addon
190
+ * @param int $post_id
191
+ *
192
+ * @return string
193
+ */
194
+ private function converted_addon_price( $addon, $post_id ){
195
+
196
+ $client_currency = $this->woocommerce_wpml->multi_currency->get_client_currency();
197
+ $is_custom_prices_on = $this->is_product_custom_prices_on( $post_id );
198
+ $field = 'price_' . $this->woocommerce_wpml->multi_currency->get_client_currency();
199
+
200
+ if (
201
+ $is_custom_prices_on &&
202
+ isset( $addon[ $field ] ) &&
203
+ $addon[ $field ]
204
+ ) {
205
+ return $addon[ $field ];
206
+ }
207
+
208
+ if( wpml_collect( [ 'flat_fee', 'quantity_based' ] )->contains( $addon['price_type'] ) ) {
209
+ return apply_filters( 'wcml_raw_price_amount', $addon['price'] );
210
+ }
211
+
212
+ return $addon['price'];
213
+ }
214
+
215
  /**
216
  * @param $product_terms
217
  *
408
  }
409
 
410
  public function load_dialog_resources(){
411
+ wp_enqueue_script( 'wcml-dialogs', WCML_PLUGIN_URL . '/res/js/dialogs' . WCML_JS_MIN . '.js', array( 'jquery-ui-dialog', 'underscore' ), WCML_VERSION );
412
  }
413
 
414
  /**
compatibility/class-wcml-tab-manager.php CHANGED
@@ -203,9 +203,7 @@ class WCML_Tab_Manager {
203
  * @param $lang
204
  */
205
  function refresh_text_domain( $lang ) {
206
- unload_textdomain( 'woocommerce' );
207
  $this->sitepress->switch_lang( $lang );
208
- $this->woocommerce->load_plugin_textdomain();
209
  }
210
 
211
  /**
@@ -403,9 +401,7 @@ class WCML_Tab_Manager {
403
  $current_language = $this->sitepress->get_current_language();
404
  foreach ( $orig_prod_tabs as $key => $prod_tab ) {
405
  if ( 'core' === $prod_tab['type'] ) {
406
- unload_textdomain( 'woocommerce' );
407
  $this->sitepress->switch_lang( $lang );
408
- $this->woocommerce->load_plugin_textdomain();
409
  $title = __( $prod_tab['title'], 'woocommerce' );
410
  if ( $prod_tab['title'] !== $title ) {
411
  $data[ 'coretab_' . $prod_tab['id'] . '_title' ]['translation'] = $title;
@@ -420,9 +416,7 @@ class WCML_Tab_Manager {
420
  }
421
  }
422
 
423
- unload_textdomain( 'woocommerce' );
424
  $this->sitepress->switch_lang( $current_language );
425
- $this->woocommerce->load_plugin_textdomain();
426
  }
427
  }
428
  }
203
  * @param $lang
204
  */
205
  function refresh_text_domain( $lang ) {
 
206
  $this->sitepress->switch_lang( $lang );
 
207
  }
208
 
209
  /**
401
  $current_language = $this->sitepress->get_current_language();
402
  foreach ( $orig_prod_tabs as $key => $prod_tab ) {
403
  if ( 'core' === $prod_tab['type'] ) {
 
404
  $this->sitepress->switch_lang( $lang );
 
405
  $title = __( $prod_tab['title'], 'woocommerce' );
406
  if ( $prod_tab['title'] !== $title ) {
407
  $data[ 'coretab_' . $prod_tab['id'] . '_title' ]['translation'] = $title;
416
  }
417
  }
418
 
 
419
  $this->sitepress->switch_lang( $current_language );
 
420
  }
421
  }
422
  }
compatibility/class-wcml-variation-swatches-and-photos.php CHANGED
@@ -60,7 +60,7 @@ class WCML_Variation_Swatches_And_Photos {
60
 
61
  $translated_product_term = get_term( $translated_product_term_id, $original_product_term->taxonomy );
62
 
63
- if ( is_object( $translated_product_term ) ) {
64
 
65
  $translated_product_term_slug_md5 = md5( $translated_product_term->slug );
66
 
60
 
61
  $translated_product_term = get_term( $translated_product_term_id, $original_product_term->taxonomy );
62
 
63
+ if ( isset( $translated_product_term->slug ) ) {
64
 
65
  $translated_product_term_slug_md5 = md5( $translated_product_term->slug );
66
 
compatibility/class-wcml-woobe.php ADDED
@@ -0,0 +1,74 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class WCML_Woobe {
4
+
5
+ /**
6
+ * @var SitePress
7
+ */
8
+ private $sitepress;
9
+
10
+ /**
11
+ * @var WPML_Post_Translation
12
+ */
13
+ private $post_translations;
14
+
15
+
16
+ /**
17
+ * WCML_Woobe constructor.
18
+ *
19
+ * @param SitePress $sitepress
20
+ * @param WPML_Post_Translation $post_translations
21
+ */
22
+ function __construct( SitePress $sitepress, WPML_Post_Translation $post_translations ) {
23
+ $this->sitepress = $sitepress;
24
+ $this->post_translations = $post_translations;
25
+ }
26
+
27
+ public function add_hooks() {
28
+ add_action( 'woobe_after_update_page_field', array( $this, 'replace_price_in_translations' ), 10, 5 );
29
+ }
30
+
31
+ /**
32
+ * Replaces product price for translation of given product.
33
+ *
34
+ * @param int|null $product_id Product ID
35
+ * @param WC_Product|null $product Product object
36
+ * @param string|null $field_key Key of processed custom field
37
+ * @param mixed|null $value Value of processed custom field
38
+ * @param string|null $field_type Type of processed custom field
39
+ */
40
+ public function replace_price_in_translations( $product_id = null, $product = null, $field_key = null, $value = null, $field_type = null ) {
41
+ if ( $this->is_price_updated( $product_id, $field_key, $value )
42
+ && $this->is_field_set_to_copy( $field_key )
43
+ ) {
44
+ $translations = $this->post_translations->get_element_translations( $product_id, false, true );
45
+ if ( ! empty( $translations ) ) {
46
+ foreach ( $translations as $translation ) {
47
+ update_post_meta( $translation, '_' . $field_key, $value );
48
+ update_post_meta( $translation, '_price', $value );
49
+ }
50
+ }
51
+ }
52
+ }
53
+
54
+ /**
55
+ * Check if filter runs during the bulk price update
56
+ *
57
+ * @param $product_id Product ID
58
+ * @param $field_key Key of processed custom field
59
+ * @param $value Value of processed custom field
60
+ *
61
+ * @return bool
62
+ */
63
+ private function is_price_updated( $product_id, $field_key, $value ) {
64
+ return is_numeric( $product_id )
65
+ && 'regular_price' === $field_key
66
+ && is_numeric( $value );
67
+ }
68
+
69
+ private function is_field_set_to_copy( $field_key ) {
70
+ $settings = $this->sitepress->get_settings();
71
+ $field_translation_setting = isset( $settings['translation-management']['custom_fields_translation']['_' . $field_key] ) ? $settings['translation-management']['custom_fields_translation']['_' . $field_key] : null;
72
+ return $field_translation_setting === $this->sitepress->get_wp_api()->constant( 'WPML_COPY_CUSTOM_FIELD' );
73
+ }
74
+ }
inc/class-wcml-ajax-setup.php CHANGED
@@ -30,17 +30,9 @@ class WCML_Ajax_Setup{
30
  }
31
 
32
  add_filter( 'woocommerce_get_script_data', array( $this, 'add_language_parameter_to_ajax_url' ) );
33
- add_action( 'woocommerce_checkout_order_review', array( $this, 'filter_woocommerce_order_review' ), 9 );
34
  add_action( 'woocommerce_checkout_order_review', array( $this, 'add_hidden_language_field' ) );
35
- add_action( 'woocommerce_checkout_update_order_review', array( $this, 'filter_woocommerce_order_review' ), 9 );
36
 
37
  }
38
-
39
- function filter_woocommerce_order_review(){
40
- global $woocommerce;
41
- unload_textdomain('woocommerce');
42
- $woocommerce->load_plugin_textdomain();
43
- }
44
 
45
  function add_hidden_language_field() {
46
  do_action( 'wpml_add_language_form_field' );
30
  }
31
 
32
  add_filter( 'woocommerce_get_script_data', array( $this, 'add_language_parameter_to_ajax_url' ) );
 
33
  add_action( 'woocommerce_checkout_order_review', array( $this, 'add_hidden_language_field' ) );
 
34
 
35
  }
 
 
 
 
 
 
36
 
37
  function add_hidden_language_field() {
38
  do_action( 'wpml_add_language_form_field' );
inc/class-wcml-attributes.php CHANGED
@@ -2,6 +2,8 @@
2
 
3
  class WCML_Attributes{
4
 
 
 
5
  /** @var woocommerce_wpml */
6
  private $woocommerce_wpml;
7
  /** @var Sitepress */
@@ -34,7 +36,6 @@ class WCML_Attributes{
34
 
35
  add_action( 'init', array( $this, 'init' ) );
36
 
37
- add_action( 'woocommerce_attribute_added', array( $this, 'set_attribute_readonly_config' ), 100, 2 );
38
  add_filter( 'wpml_translation_job_post_meta_value_translated', array($this, 'filter_product_attributes_for_translation'), 10, 2 );
39
  add_filter( 'woocommerce_dropdown_variation_attribute_options_args', array($this, 'filter_dropdown_variation_attribute_options_args') );
40
 
@@ -61,20 +62,19 @@ class WCML_Attributes{
61
  add_action( 'update_post_meta', array( $this, 'set_translation_status_as_needs_update' ), 10, 3 );
62
  }
63
 
64
- public function init(){
65
-
66
- $is_attr_page = apply_filters( 'wcml_is_attributes_page', isset( $_GET[ 'page' ] ) && $_GET[ 'page' ] == 'product_attributes' && isset( $_GET[ 'post_type' ] ) && $_GET[ 'post_type' ] == 'product' );
67
-
68
- if( $is_attr_page ){
69
 
70
- add_action( 'admin_init', array( $this, 'not_translatable_html' ) );
 
 
71
 
72
- if( isset( $_POST[ 'save_attribute' ] ) && isset( $_GET[ 'edit' ] ) ){
73
- $this->set_attribute_readonly_config( $_GET[ 'edit' ], $_POST );
74
- }
75
- }
 
76
 
77
- }
78
 
79
  public function not_translatable_html(){
80
  $attr_id = isset( $_GET[ 'edit' ] ) ? absint( $_GET[ 'edit' ] ) : false;
@@ -90,19 +90,52 @@ class WCML_Attributes{
90
 
91
  }
92
 
93
- public function set_attribute_readonly_config( $id, $attribute ){
 
 
 
 
 
94
 
95
- $is_translatable = isset( $_POST[ 'wcml-is-translatable-attr' ] ) ? 1 : 0;
96
- $attribute_name = wc_attribute_taxonomy_name( $attribute['attribute_name'] );
97
- if( $is_translatable === 0 ){
98
- //delete all translated attributes terms if "Translatable?" option un-checked
99
- $this->delete_translated_attribute_terms( $attribute_name );
100
- $this->set_variations_to_use_original_attributes( $attribute_name );
101
- $this->set_original_attributes_for_products( $attribute_name );
102
- }
103
- $this->set_attribute_config_in_settings( $attribute_name, $is_translatable );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
104
  }
105
 
 
 
 
 
 
 
 
 
 
 
 
 
106
  public function set_attribute_config_in_settings( $attribute_name, $is_translatable ){
107
  $this->set_attribute_config_in_wcml_settings( $attribute_name, $is_translatable );
108
  $this->set_attribute_config_in_wpml_settings( $attribute_name, $is_translatable );
2
 
3
  class WCML_Attributes{
4
 
5
+ const PRIORITY_AFTER_WC_INIT = 100;
6
+
7
  /** @var woocommerce_wpml */
8
  private $woocommerce_wpml;
9
  /** @var Sitepress */
36
 
37
  add_action( 'init', array( $this, 'init' ) );
38
 
 
39
  add_filter( 'wpml_translation_job_post_meta_value_translated', array($this, 'filter_product_attributes_for_translation'), 10, 2 );
40
  add_filter( 'woocommerce_dropdown_variation_attribute_options_args', array($this, 'filter_dropdown_variation_attribute_options_args') );
41
 
62
  add_action( 'update_post_meta', array( $this, 'set_translation_status_as_needs_update' ), 10, 3 );
63
  }
64
 
65
+ public function init() {
 
 
 
 
66
 
67
+ $is_attr_page = isset( $_GET['page'], $_GET['post_type'] )
68
+ && 'product_attributes' === $_GET['page']
69
+ && 'product' === $_GET['post_type'];
70
 
71
+ if ( apply_filters( 'wcml_is_attributes_page', $is_attr_page ) ) {
72
+ add_action( 'admin_init', array( $this, 'not_translatable_html' ) );
73
+ add_action( 'woocommerce_attribute_added', array( $this, 'set_attribute_readonly_config' ), self::PRIORITY_AFTER_WC_INIT, 2 );
74
+ add_action( 'woocommerce_attribute_updated', array( $this, 'set_attribute_readonly_config' ), self::PRIORITY_AFTER_WC_INIT, 3 );
75
+ }
76
 
77
+ }
78
 
79
  public function not_translatable_html(){
80
  $attr_id = isset( $_GET[ 'edit' ] ) ? absint( $_GET[ 'edit' ] ) : false;
90
 
91
  }
92
 
93
+ /**
94
+ * @param int $id
95
+ * @param array $data
96
+ * @param bool $old_slug
97
+ */
98
+ public function set_attribute_readonly_config( $id, $data, $old_slug = false ){
99
 
100
+ if( isset( $_POST[ 'save_attribute' ] ) || isset( $_POST[ 'add_new_attribute' ] ) ) {
101
+
102
+ $is_translatable = (int)isset( $_POST['wcml-is-translatable-attr'] );
103
+
104
+ if( $_POST['attribute_name'] ){
105
+ $attribute_name = wc_sanitize_taxonomy_name( wp_unslash( $_POST['attribute_name'] ) );
106
+ }else{
107
+ $attribute_name = wc_sanitize_taxonomy_name( wc_clean( wp_unslash( $_POST['attribute_label'] ) ) );
108
+ }
109
+
110
+ $attribute_name = wc_attribute_taxonomy_name( $attribute_name );
111
+
112
+ if ( $is_translatable === 0 ) {
113
+ //delete all translated attributes terms if "Translatable?" option un-checked
114
+ $this->delete_translated_attribute_terms( $attribute_name );
115
+ $this->set_variations_to_use_original_attributes( $attribute_name );
116
+ $this->set_original_attributes_for_products( $attribute_name );
117
+ }
118
+
119
+ if( $old_slug !== $data[ 'attribute_name' ] ){
120
+ $this->fix_attribute_slug_in_translations_table( wc_attribute_taxonomy_name( $old_slug ), $attribute_name );
121
+ }
122
+
123
+ $this->set_attribute_config_in_settings( $attribute_name, $is_translatable );
124
+ }
125
  }
126
 
127
+ /**
128
+ * @param string $old_attribute_name
129
+ * @param string $new_attribute_name
130
+ */
131
+ private function fix_attribute_slug_in_translations_table( $old_attribute_name, $new_attribute_name ) {
132
+ $this->wpdb->update(
133
+ $this->wpdb->prefix . 'icl_translations',
134
+ array( 'element_type' => 'tax_' . $new_attribute_name ),
135
+ array( 'element_type' => 'tax_' . $old_attribute_name )
136
+ );
137
+ }
138
+
139
  public function set_attribute_config_in_settings( $attribute_name, $is_translatable ){
140
  $this->set_attribute_config_in_wcml_settings( $attribute_name, $is_translatable );
141
  $this->set_attribute_config_in_wpml_settings( $attribute_name, $is_translatable );
inc/class-wcml-cart.php CHANGED
@@ -273,7 +273,6 @@ class WCML_Cart {
273
 
274
  public function wcml_refresh_fragments() {
275
  WC()->cart->calculate_totals();
276
- $this->woocommerce_wpml->locale->wcml_refresh_text_domain();
277
  }
278
 
279
  /*
273
 
274
  public function wcml_refresh_fragments() {
275
  WC()->cart->calculate_totals();
 
276
  }
277
 
278
  /*
inc/class-wcml-compatibility.php CHANGED
@@ -3,99 +3,117 @@
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
  global $woocommerce;
40
 
41
- //WooCommerce Tab Manager plugin
42
  if ( class_exists( 'WC_Tab_Manager' ) ) {
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
  $this->table_rate_shipping->add_hooks();
51
  }
52
 
53
- //WooCommerce Subscriptions
54
  if ( class_exists( 'WC_Subscriptions' ) ) {
55
  $this->wp_subscriptions = new WCML_WC_Subscriptions( $this->woocommerce_wpml, $this->wpdb );
56
  $this->wp_subscriptions->add_hooks();
57
  }
58
 
59
- //WooCommerce Name Your Price
60
  if ( class_exists( 'WC_Name_Your_Price' ) ) {
61
  $this->name_your_price = new WCML_WC_Name_Your_Price();
62
  }
63
 
64
- //Product Bundle
65
  if ( class_exists( 'WC_Product_Bundle' ) && function_exists( 'WC_PB' ) ) {
66
  $product_bundle_items = new WCML_WC_Product_Bundles_Items();
67
  $this->product_bundles = new WCML_Product_Bundles( $this->sitepress, $this->woocommerce_wpml, $product_bundle_items, $this->wpdb );
68
  }
69
 
70
- // WooCommerce Variation Swatches and Photos
71
  if ( class_exists( 'WC_SwatchesPlugin' ) ) {
72
  $this->variation_sp = new WCML_Variation_Swatches_And_Photos( $this->sitepress );
73
  $this->variation_sp->add_hooks();
74
  }
75
 
76
- // Product Add-ons
77
  if ( defined( 'WC_PRODUCT_ADDONS_VERSION' ) || class_exists( 'Product_Addon_Display' ) ) {
78
  $this->product_addons = new WCML_Product_Addons( $this->sitepress, $this->woocommerce_wpml );
79
  $this->product_addons->add_hooks();
80
  }
81
 
82
- // Product Per Product Shipping
83
  if ( defined( 'PER_PRODUCT_SHIPPING_VERSION' ) ) {
84
  new WCML_Per_Product_Shipping();
85
  }
86
- //Store Exporter plugin
87
  if ( defined( 'WOO_CE_PATH' ) ) {
88
  $this->wc_exporter = new WCML_wcExporter( $this->sitepress, $this->woocommerce_wpml );
89
  $this->wc_exporter->add_hooks();
90
  }
91
 
92
- //Gravity Forms
93
  if ( class_exists( 'GFForms' ) ) {
94
  $this->gravityforms = new WCML_gravityforms( $this->sitepress, $this->woocommerce_wpml );
95
  $this->gravityforms->add_hooks();
96
  }
97
 
98
- //Sensei WooThemes
99
  if ( class_exists( 'WooThemes_Sensei' ) ) {
100
  $this->sensei = new WCML_Sensei(
101
  $this->sitepress,
@@ -105,28 +123,34 @@ class WCML_Compatibility {
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
  $this->dynamic_pricing->add_hooks();
117
  }
118
 
119
- // WooCommerce Bookings
120
  if ( defined( 'WC_BOOKINGS_VERSION' ) && version_compare( WC_BOOKINGS_VERSION, '1.7.8', '>=' ) ) {
121
  $this->bookings = new WCML_Bookings( $this->sitepress, $this->woocommerce_wpml, $woocommerce, $this->wpdb, $this->tp );
122
  $this->bookings->add_hooks();
123
 
124
- // WooCommerce Accommodation Bookings
125
  if ( defined( 'WC_ACCOMMODATION_BOOKINGS_VERSION' ) ) {
126
  $this->accomodation_bookings = new WCML_Accommodation_Bookings( $this->woocommerce_wpml );
127
  }
128
  }
129
 
 
 
 
 
 
 
130
  // WooCommerce Checkout Field Editor
131
  if ( function_exists( 'woocommerce_init_checkout_field_editor' ) ) {
132
  $this->checkout_field_editor = new WCML_Checkout_Field_Editor();
@@ -137,8 +161,8 @@ class WCML_Compatibility {
137
  $this->wc_bulk_stock_management = new WCML_Bulk_Stock_Management();
138
  }
139
 
140
- // WooCommerce Advanced Ajax Layered Navigation
141
- include_once( ABSPATH . 'wp-admin/includes/plugin.php' );
142
  if ( is_plugin_active( 'woocommerce-ajax-layered-nav/ajax_layered_nav-widget.php' ) ) {
143
  $this->wc_ajax_layered_nav_widget = new WCML_Ajax_Layered_Nav_Widget();
144
  }
@@ -147,15 +171,15 @@ class WCML_Compatibility {
147
  $this->wc_ajax_cart = new WCML_WC_Ajax_Cart();
148
  }
149
 
150
- // woocommerce composite products
151
  if ( isset( $GLOBALS['woocommerce_composite_products'] ) ) {
152
  $this->wc_composite_products = new WCML_Composite_Products( $this->sitepress, $this->woocommerce_wpml, $this->tp );
153
  $this->wc_composite_products->add_hooks();
154
  }
155
 
156
- // woocommerce checkout addons
157
- if ( function_exists( 'init_woocommerce_checkout_add_ons' ) ) {
158
  $this->wc_checkout_addons = new WCML_Checkout_Addons();
 
159
  }
160
 
161
  if ( class_exists( 'WC_Mix_and_Match' ) ) {
@@ -166,114 +190,121 @@ class WCML_Compatibility {
166
  $this->wpseo = new WCML_WPSEO();
167
  }
168
 
169
- //Adventure Tours theme
170
  if ( function_exists( 'adventure_tours_check' ) ) {
171
  $this->adventure_tours = new WCML_Adventure_tours( $this->woocommerce_wpml, $this->sitepress, $this->tp );
172
  $this->adventure_tours->add_hooks();
173
  }
174
 
175
- // flatsome theme
176
  if ( wp_get_theme()->get( 'Name' ) === 'Flatsome' ) {
177
  $this->flatsome = new WCML_Flatsome();
178
  }
179
 
180
- //Aurum Theme
181
  if ( wp_get_theme()->get( 'Name' ) === 'Aurum' ) {
182
  new WCML_Aurum();
183
  }
184
 
185
- // Visual Products Configurator
186
  if ( class_exists( 'Vpc' ) ) {
187
  $this->vpc = new WCML_Vpc();
188
  }
189
 
190
- // WooCommerce Show Single Variations
191
  if ( defined( 'JCK_WSSV_PATH' ) ) {
192
  new WCML_JCK_WSSV();
193
  }
194
 
195
- // WooCommerce Print Invoices
196
  if ( class_exists( 'WC_PIP' ) ) {
197
  $this->pip = new WCML_Pip();
198
  }
199
 
200
- // The Events Calendar
201
  if ( class_exists( 'Tribe__Events__Main' ) ) {
202
  new WCML_The_Events_Calendar( $this->sitepress, $this->woocommerce_wpml );
203
  }
204
 
205
- // Klarna Gateway
206
  if ( class_exists( 'WC_Gateway_Klarna' ) ) {
207
  $this->klarna_gateway = new WCML_Klarna_Gateway();
208
  $this->klarna_gateway->add_hooks();
209
  }
210
 
211
- // YITH_WCQV
212
  if ( class_exists( 'YITH_WCQV' ) ) {
213
  $this->yith_wcqv = new WCML_YITH_WCQV();
214
  $this->yith_wcqv->add_hooks();
215
  }
216
 
217
- // Woocommerce Memberships
218
  if ( class_exists( 'WC_Memberships' ) ) {
219
  $this->wc_memberships = new WCML_WC_Memberships( $this->sitepress->get_wp_api() );
220
  $this->wc_memberships->add_hooks();
221
  }
222
 
223
- // MaxStore-Pro Theme
224
  if ( function_exists( 'maxstore_pro_setup' ) ) {
225
  $this->maxstore = new WCML_MaxStore();
226
  $this->maxstore->add_hooks();
227
  }
228
 
229
- // MaxStore-Pro Theme
230
- if ( defined( 'ETHEME_THEME_NAME') && 'Blanco' === ETHEME_THEME_NAME ) {
231
  $this->etheme_blanco = new WCML_Etheme_Blanco();
232
  $this->etheme_blanco->add_hooks();
233
  }
234
 
235
- // WPBakery Page Builder
236
- if ( defined( 'WPB_VC_VERSION') ) {
237
- $this->wpb_vc= new WCML_Wpb_Vc();
238
  $this->wpb_vc->add_hooks();
239
  }
240
 
241
- // Relevanssi plugin
242
  if ( function_exists( 'relevanssi_insert_edit' ) ) {
243
  $this->relevanssi = new WCML_Relevanssi();
244
  $this->relevanssi->add_hooks();
245
  }
246
 
247
- // Woo Variations Table
248
- if ( defined( 'WOO_VARIATIONS_TABLE_VERSION') ) {
249
  $this->wpb_woo_var_table = new WCML_Woo_Var_Table( $this->sitepress->get_current_language() );
250
  $this->wpb_woo_var_table->add_hooks();
251
  }
252
 
253
- // LiteSpeed Cache
254
  if ( class_exists( 'LiteSpeed_Cache' ) ) {
255
  $this->litespeed_cache = new WCML_LiteSpeed_Cache();
256
  $this->litespeed_cache->add_hooks();
257
  }
258
 
259
- // WpFastest Cache
260
  if ( class_exists( 'WpFastestCache' ) ) {
261
  $this->wpfastestcache = new WCML_WpFastest_Cache();
262
  $this->wpfastestcache->add_hooks();
263
  }
264
 
265
- // WooCommerce Product Type Column
266
  if ( class_exists( 'WC_Product_Type_Column' ) ) {
267
  $this->wc_type_column = new WCML_WC_Product_Type_Column();
268
  $this->wc_type_column->add_hooks();
269
  }
270
 
271
- // Custom Product Tabs PRO
272
  if ( class_exists( 'YIKES_Custom_Product_Tabs_Pro' ) ) {
273
  $this->custom_product_tabs = new WCML_YIKES_Custom_Product_Tabs_Pro( $this->woocommerce_wpml, $this->sitepress, $this->tp );
274
  $this->custom_product_tabs->add_hooks();
275
  }
276
 
 
 
 
 
 
 
 
277
  }
278
 
279
  }
3
  class WCML_Compatibility {
4
 
5
  /**
6
+ * SitePress object.
7
+ *
8
  * @var SitePress
9
  */
10
  private $sitepress;
11
  /**
12
+ * Woocommerce_WPML object.
13
+ *
14
  * @var woocommerce_wpml
15
  */
16
  private $woocommerce_wpml;
17
  /**
18
+ * Database object.
19
+ *
20
  * @var wpdb
21
  */
22
  private $wpdb;
23
+ /**
24
+ * Element Translation Package.
25
+ *
26
+ * @var WPML_Element_Translation_Package
27
+ */
28
  private $tp;
29
+ /**
30
+ * @var WPML_Element_Translation
31
+ */
32
+ private $wpml_post_translations;
33
 
34
  /**
35
  * WCML_Compatibility constructor.
36
  *
37
+ * @param SitePress $sitepress SitePress object.
38
+ * @param woocommerce_wpml $woocommerce_wpml Woocommerce_WPML object.
39
+ * @param wpdb $wpdb Database object.
40
+ * @param WPML_Element_Translation_Package $tp Element Translation Package.
41
  */
42
+ function __construct( SitePress $sitepress, woocommerce_wpml $woocommerce_wpml, wpdb $wpdb, WPML_Element_Translation_Package $tp, WPML_Element_Translation $wpml_post_translations ) {
43
+ $this->sitepress = $sitepress;
44
+ $this->woocommerce_wpml = $woocommerce_wpml;
45
+ $this->wpdb = $wpdb;
46
+ $this->tp = $tp;
47
+ $this->wpml_post_translations = $wpml_post_translations;
48
  $this->init();
49
 
50
  }
51
 
52
+ /**
53
+ * Initialize class
54
+ */
55
+ public function init() {
56
+ // hardcoded list of extensions and check which ones the user has and then include the corresponding file from the ‘compatibility’ folder.
57
  global $woocommerce;
58
 
59
+ // WooCommerce Tab Manager plugin.
60
  if ( class_exists( 'WC_Tab_Manager' ) ) {
61
  $this->tab_manager = new WCML_Tab_Manager( $this->sitepress, $woocommerce, $this->woocommerce_wpml, $this->wpdb, $this->tp );
62
  $this->tab_manager->add_hooks();
63
  }
64
 
65
+ // WooCommerce Table Rate Shipping plugin.
66
  if ( defined( 'TABLE_RATE_SHIPPING_VERSION' ) ) {
67
  $this->table_rate_shipping = new WCML_Table_Rate_Shipping( $this->sitepress, $this->woocommerce_wpml );
68
  $this->table_rate_shipping->add_hooks();
69
  }
70
 
71
+ // WooCommerce Subscriptions.
72
  if ( class_exists( 'WC_Subscriptions' ) ) {
73
  $this->wp_subscriptions = new WCML_WC_Subscriptions( $this->woocommerce_wpml, $this->wpdb );
74
  $this->wp_subscriptions->add_hooks();
75
  }
76
 
77
+ // WooCommerce Name Your Price.
78
  if ( class_exists( 'WC_Name_Your_Price' ) ) {
79
  $this->name_your_price = new WCML_WC_Name_Your_Price();
80
  }
81
 
82
+ // Product Bundle.
83
  if ( class_exists( 'WC_Product_Bundle' ) && function_exists( 'WC_PB' ) ) {
84
  $product_bundle_items = new WCML_WC_Product_Bundles_Items();
85
  $this->product_bundles = new WCML_Product_Bundles( $this->sitepress, $this->woocommerce_wpml, $product_bundle_items, $this->wpdb );
86
  }
87
 
88
+ // WooCommerce Variation Swatches and Photos.
89
  if ( class_exists( 'WC_SwatchesPlugin' ) ) {
90
  $this->variation_sp = new WCML_Variation_Swatches_And_Photos( $this->sitepress );
91
  $this->variation_sp->add_hooks();
92
  }
93
 
94
+ // Product Add-ons.
95
  if ( defined( 'WC_PRODUCT_ADDONS_VERSION' ) || class_exists( 'Product_Addon_Display' ) ) {
96
  $this->product_addons = new WCML_Product_Addons( $this->sitepress, $this->woocommerce_wpml );
97
  $this->product_addons->add_hooks();
98
  }
99
 
100
+ // Product Per Product Shipping.
101
  if ( defined( 'PER_PRODUCT_SHIPPING_VERSION' ) ) {
102
  new WCML_Per_Product_Shipping();
103
  }
104
+ // Store Exporter plugin.
105
  if ( defined( 'WOO_CE_PATH' ) ) {
106
  $this->wc_exporter = new WCML_wcExporter( $this->sitepress, $this->woocommerce_wpml );
107
  $this->wc_exporter->add_hooks();
108
  }
109
 
110
+ // Gravity Forms.
111
  if ( class_exists( 'GFForms' ) ) {
112
  $this->gravityforms = new WCML_gravityforms( $this->sitepress, $this->woocommerce_wpml );
113
  $this->gravityforms->add_hooks();
114
  }
115
 
116
+ // Sensei WooThemes.
117
  if ( class_exists( 'WooThemes_Sensei' ) ) {
118
  $this->sensei = new WCML_Sensei(
119
  $this->sitepress,
123
  $this->sensei->add_hooks();
124
  }
125
 
126
+ // Extra Product Options.
127
  if ( class_exists( 'TM_Extra_Product_Options' ) ) {
128
  $this->extra_product_options = new WCML_Extra_Product_Options();
129
  }
130
 
131
+ // Dynamic Pricing.
132
  if ( class_exists( 'WC_Dynamic_Pricing' ) ) {
133
  $this->dynamic_pricing = new WCML_Dynamic_Pricing( $this->sitepress );
134
  $this->dynamic_pricing->add_hooks();
135
  }
136
 
137
+ // WooCommerce Bookings.
138
  if ( defined( 'WC_BOOKINGS_VERSION' ) && version_compare( WC_BOOKINGS_VERSION, '1.7.8', '>=' ) ) {
139
  $this->bookings = new WCML_Bookings( $this->sitepress, $this->woocommerce_wpml, $woocommerce, $this->wpdb, $this->tp );
140
  $this->bookings->add_hooks();
141
 
142
+ // WooCommerce Accommodation Bookings.
143
  if ( defined( 'WC_ACCOMMODATION_BOOKINGS_VERSION' ) ) {
144
  $this->accomodation_bookings = new WCML_Accommodation_Bookings( $this->woocommerce_wpml );
145
  }
146
  }
147
 
148
+ // WOOBE WooCommerce Bulk Editor
149
+ if ( defined( 'WOOBE_PATH' ) ) {
150
+ $this->woobe = new WCML_Woobe( $this->sitepress, $this->wpml_post_translations );
151
+ $this->woobe->add_hooks();
152
+ }
153
+
154
  // WooCommerce Checkout Field Editor
155
  if ( function_exists( 'woocommerce_init_checkout_field_editor' ) ) {
156
  $this->checkout_field_editor = new WCML_Checkout_Field_Editor();
161
  $this->wc_bulk_stock_management = new WCML_Bulk_Stock_Management();
162
  }
163
 
164
+ // WooCommerce Advanced Ajax Layered Navigation.
165
+ require_once ABSPATH . 'wp-admin/includes/plugin.php';
166
  if ( is_plugin_active( 'woocommerce-ajax-layered-nav/ajax_layered_nav-widget.php' ) ) {
167
  $this->wc_ajax_layered_nav_widget = new WCML_Ajax_Layered_Nav_Widget();
168
  }
171
  $this->wc_ajax_cart = new WCML_WC_Ajax_Cart();
172
  }
173
 
174
+ // woocommerce composite products.
175
  if ( isset( $GLOBALS['woocommerce_composite_products'] ) ) {
176
  $this->wc_composite_products = new WCML_Composite_Products( $this->sitepress, $this->woocommerce_wpml, $this->tp );
177
  $this->wc_composite_products->add_hooks();
178
  }
179
 
180
+ if ( class_exists( 'WC_Checkout_Add_Ons_Loader' ) ) {
 
181
  $this->wc_checkout_addons = new WCML_Checkout_Addons();
182
+ $this->wc_checkout_addons->add_hooks();
183
  }
184
 
185
  if ( class_exists( 'WC_Mix_and_Match' ) ) {
190
  $this->wpseo = new WCML_WPSEO();
191
  }
192
 
193
+ // Adventure Tours theme.
194
  if ( function_exists( 'adventure_tours_check' ) ) {
195
  $this->adventure_tours = new WCML_Adventure_tours( $this->woocommerce_wpml, $this->sitepress, $this->tp );
196
  $this->adventure_tours->add_hooks();
197
  }
198
 
199
+ // flatsome theme.
200
  if ( wp_get_theme()->get( 'Name' ) === 'Flatsome' ) {
201
  $this->flatsome = new WCML_Flatsome();
202
  }
203
 
204
+ // Aurum Theme.
205
  if ( wp_get_theme()->get( 'Name' ) === 'Aurum' ) {
206
  new WCML_Aurum();
207
  }
208
 
209
+ // Visual Products Configurator.
210
  if ( class_exists( 'Vpc' ) ) {
211
  $this->vpc = new WCML_Vpc();
212
  }
213
 
214
+ // WooCommerce Show Single Variations.
215
  if ( defined( 'JCK_WSSV_PATH' ) ) {
216
  new WCML_JCK_WSSV();
217
  }
218
 
219
+ // WooCommerce Print Invoices.
220
  if ( class_exists( 'WC_PIP' ) ) {
221
  $this->pip = new WCML_Pip();
222
  }
223
 
224
+ // The Events Calendar.
225
  if ( class_exists( 'Tribe__Events__Main' ) ) {
226
  new WCML_The_Events_Calendar( $this->sitepress, $this->woocommerce_wpml );
227
  }
228
 
229
+ // Klarna Gateway.
230
  if ( class_exists( 'WC_Gateway_Klarna' ) ) {
231
  $this->klarna_gateway = new WCML_Klarna_Gateway();
232
  $this->klarna_gateway->add_hooks();
233
  }
234
 
235
+ // YITH_WCQV.
236
  if ( class_exists( 'YITH_WCQV' ) ) {
237
  $this->yith_wcqv = new WCML_YITH_WCQV();
238
  $this->yith_wcqv->add_hooks();
239
  }
240
 
241
+ // Woocommerce Memberships.
242
  if ( class_exists( 'WC_Memberships' ) ) {
243
  $this->wc_memberships = new WCML_WC_Memberships( $this->sitepress->get_wp_api() );
244
  $this->wc_memberships->add_hooks();
245
  }
246
 
247
+ // MaxStore-Pro Theme.
248
  if ( function_exists( 'maxstore_pro_setup' ) ) {
249
  $this->maxstore = new WCML_MaxStore();
250
  $this->maxstore->add_hooks();
251
  }
252
 
253
+ // MaxStore-Pro Theme.
254
+ if ( defined( 'ETHEME_THEME_NAME' ) && 'Blanco' === ETHEME_THEME_NAME ) {
255
  $this->etheme_blanco = new WCML_Etheme_Blanco();
256
  $this->etheme_blanco->add_hooks();
257
  }
258
 
259
+ // WPBakery Page Builder.
260
+ if ( defined( 'WPB_VC_VERSION' ) ) {
261
+ $this->wpb_vc = new WCML_Wpb_Vc();
262
  $this->wpb_vc->add_hooks();
263
  }
264
 
265
+ // Relevanssi plugin.
266
  if ( function_exists( 'relevanssi_insert_edit' ) ) {
267
  $this->relevanssi = new WCML_Relevanssi();
268
  $this->relevanssi->add_hooks();
269
  }
270
 
271
+ // Woo Variations Table.
272
+ if ( defined( 'WOO_VARIATIONS_TABLE_VERSION' ) ) {
273
  $this->wpb_woo_var_table = new WCML_Woo_Var_Table( $this->sitepress->get_current_language() );
274
  $this->wpb_woo_var_table->add_hooks();
275
  }
276
 
277
+ // LiteSpeed Cache.
278
  if ( class_exists( 'LiteSpeed_Cache' ) ) {
279
  $this->litespeed_cache = new WCML_LiteSpeed_Cache();
280
  $this->litespeed_cache->add_hooks();
281
  }
282
 
283
+ // WpFastest Cache.
284
  if ( class_exists( 'WpFastestCache' ) ) {
285
  $this->wpfastestcache = new WCML_WpFastest_Cache();
286
  $this->wpfastestcache->add_hooks();
287
  }
288
 
289
+ // WooCommerce Product Type Column.
290
  if ( class_exists( 'WC_Product_Type_Column' ) ) {
291
  $this->wc_type_column = new WCML_WC_Product_Type_Column();
292
  $this->wc_type_column->add_hooks();
293
  }
294
 
295
+ // Custom Product Tabs PRO.
296
  if ( class_exists( 'YIKES_Custom_Product_Tabs_Pro' ) ) {
297
  $this->custom_product_tabs = new WCML_YIKES_Custom_Product_Tabs_Pro( $this->woocommerce_wpml, $this->sitepress, $this->tp );
298
  $this->custom_product_tabs->add_hooks();
299
  }
300
 
301
+ // WooCommerce Order Status Manager.
302
+ if ( class_exists( 'WC_Order_Status_Manager' ) ) {
303
+ $wp_query = new WP_Query();
304
+ $this->wc_order_status_manager = new WCML_Order_Status_Manager( $wp_query );
305
+ $this->wc_order_status_manager->add_hooks();
306
+ }
307
+
308
  }
309
 
310
  }
inc/class-wcml-dependencies.php CHANGED
@@ -2,9 +2,9 @@
2
 
3
  class WCML_Dependencies {
4
 
5
- const MIN_WPML = '4.2.8';
6
- const MIN_WPML_TM = '2.8.7';
7
- const MIN_WPML_ST = '2.10.6';
8
  const MIN_WOOCOMMERCE = '3.3.0';
9
 
10
  private $missing = array();
@@ -84,8 +84,6 @@ class WCML_Dependencies {
84
 
85
  if ( isset( $sitepress ) ) {
86
  $this->allok = $this->allok & $sitepress->setup();
87
- } else {
88
- $this->load_twig_support();
89
  }
90
 
91
  return $this->allok;
@@ -377,17 +375,4 @@ class WCML_Dependencies {
377
  return $url;
378
  }
379
 
380
- /**
381
- * The support for the Twig templates comes from WPML by default
382
- * When WPML is not active, WCML will load it
383
- */
384
- private function load_twig_support() {
385
-
386
- if ( ! class_exists( 'WCML\Twig_Autoloader' ) ) {
387
- WCML\Twig_Autoloader::register();
388
- }
389
-
390
- }
391
-
392
  }
393
-
2
 
3
  class WCML_Dependencies {
4
 
5
+ const MIN_WPML = '4.0.0';
6
+ const MIN_WPML_TM = '2.6';
7
+ const MIN_WPML_ST = '2.8';
8
  const MIN_WOOCOMMERCE = '3.3.0';
9
 
10
  private $missing = array();
84
 
85
  if ( isset( $sitepress ) ) {
86
  $this->allok = $this->allok & $sitepress->setup();
 
 
87
  }
88
 
89
  return $this->allok;
375
  return $url;
376
  }
377
 
 
 
 
 
 
 
 
 
 
 
 
 
378
  }
 
inc/class-wcml-emails.php CHANGED
@@ -1,15 +1,16 @@
1
  <?php
2
- class WCML_Emails{
3
 
4
- private $order_id = false;
5
- private $locale = false;
 
 
6
  private $admin_language = false;
7
- /** @var woocommerce_wpml */
8
- private $woocommerce_wpml;
9
- /** @var Sitepress */
10
- private $sitepress;
11
- /** @var WooCommerce */
12
- private $woocommerce;
13
  /** @var wpdb */
14
  private $wpdb;
15
 
@@ -21,318 +22,346 @@ class WCML_Emails{
21
  * @param WooCommerce $woocommerce
22
  * @param wpdb $wpdb
23
  */
24
- function __construct( woocommerce_wpml $woocommerce_wpml, SitePress $sitepress, WooCommerce $woocommerce, wpdb $wpdb ) {
25
- $this->woocommerce_wpml = $woocommerce_wpml;
26
- $this->sitepress = $sitepress;
27
- $this->woocommerce = $woocommerce;
28
- $this->wpdb = $wpdb;
29
- }
30
-
31
- function add_hooks(){
32
- global $pagenow;
33
- //wrappers for email's header
34
- if ( is_admin() && ! defined( 'DOING_AJAX' ) ) {
35
- add_action( 'woocommerce_order_status_completed_notification', array(
36
- $this,
37
- 'email_heading_completed'
38
- ), 9 );
39
- add_action( 'woocommerce_order_status_changed', array( $this, 'comments_language' ), 10 );
40
- }
41
-
42
- add_action( 'woocommerce_new_customer_note_notification', array( $this, 'email_heading_note' ), 9 );
43
-
44
- add_action( 'wp_ajax_woocommerce_mark_order_status', array( $this, 'email_refresh_in_ajax' ), 9 );
45
-
46
- foreach( array( 'pending', 'failed', 'cancelled', 'on-hold' ) as $state ) {
47
- add_action( 'woocommerce_order_status_' . $state . '_to_processing_notification', array(
48
- $this,
49
- 'email_heading_processing'
50
- ), 9 );
51
-
52
- add_action( 'woocommerce_order_status_' . $state . '_to_processing_notification', array(
53
- $this,
54
- 'refresh_email_lang'
55
- ), 9 );
56
- }
57
-
58
- foreach( array( 'pending', 'failed', 'cancelled' ) as $state ) {
59
- add_action( 'woocommerce_order_status_' . $state . '_to_on-hold_notification', array(
60
- $this,
61
- 'email_heading_on_hold'
62
- ), 9 );
63
- }
64
-
65
- //wrappers for email's body
66
- add_action( 'woocommerce_before_resend_order_emails', array( $this, 'email_header' ) );
67
- add_action( 'woocommerce_after_resend_order_email', array( $this, 'email_footer' ) );
68
-
69
- //filter string language before for emails
70
- add_filter( 'icl_current_string_language', array( $this, 'icl_current_string_language' ), 10, 2 );
71
-
72
- //change order status
73
- add_action( 'woocommerce_order_status_completed', array( $this, 'refresh_email_lang_complete' ), 9 );
74
-
75
- add_action( 'woocommerce_order_status_pending_to_on-hold_notification', array(
76
- $this,
77
- 'refresh_email_lang'
78
- ), 9 );
79
- add_action( 'woocommerce_new_customer_note', array( $this, 'refresh_email_lang' ), 9 );
80
-
81
- foreach( array( 'pending', 'failed' ) as $from_state ) {
82
- foreach ( array( 'processing', 'completed', 'on-hold' ) as $to_state ) {
83
- add_action( 'woocommerce_order_status_'.$from_state.'_to_'.$to_state.'_notification', array(
84
- $this,
85
- 'new_order_admin_email'
86
- ), 9 );
87
- }
88
- }
89
-
90
- add_action( 'woocommerce_before_resend_order_emails', array( $this, 'backend_new_order_admin_email' ), 9 );
91
-
92
- add_filter( 'icl_st_admin_string_return_cached', array( $this, 'admin_string_return_cached' ), 10, 2 );
93
-
94
- add_filter( 'plugin_locale', array( $this, 'set_locale_for_emails' ), 10, 2 );
95
- add_filter( 'woocommerce_countries', array( $this, 'translate_woocommerce_countries' ) );
96
-
97
- if ( is_admin() && $pagenow == 'admin.php' && isset( $_GET['page'] ) && $_GET['page'] == 'wc-settings' && isset( $_GET['tab'] ) && $_GET['tab'] == 'email' ) {
98
- add_action( 'admin_footer', array( $this, 'show_language_links_for_wc_emails' ) );
99
- $this->set_emails_string_language();
100
- }
101
-
102
- if (
103
- (
104
- ! isset( $_GET['post_type'] ) ||
105
- $_GET['post_type'] != 'shop_order'
106
- ) &&
107
- (
108
- ! isset( $_GET['action'] ) ||
109
- ! in_array( $_GET['action'], array(
110
- 'woocommerce_mark_order_status'
111
- ) )
112
- )
113
- ) {
114
- add_filter( 'woocommerce_order_items_meta_get_formatted', array( $this, 'filter_formatted_items' ), 10, 2 );
115
- }
116
-
117
- add_filter( 'woocommerce_allow_send_queued_transactional_email', array(
118
- $this,
119
- 'send_queued_transactional_email'
120
- ), 10, 3 );
121
-
122
- add_action( 'woocommerce_order_partially_refunded_notification', array( $this, 'refresh_email_lang' ), 9 );
123
- add_action( 'woocommerce_order_fully_refunded_notification', array( $this, 'refresh_email_lang' ), 9 );
124
- add_filter( 'woocommerce_email_get_option', array( $this, 'filter_refund_emails_strings' ), 10, 4 );
125
-
126
- add_filter( 'woocommerce_email_setup_locale', '__return_false' );
127
- add_filter( 'woocommerce_email_restore_locale', '__return_false' );
128
-
129
-
130
- add_filter( 'woocommerce_email_heading_new_order', array( $this, 'new_order_email_heading' ) );
131
- add_filter( 'woocommerce_email_subject_new_order', array( $this, 'new_order_email_subject' ) );
132
-
133
- add_filter( 'woocommerce_email_heading_customer_on_hold_order', array( $this, 'customer_on_hold_order_heading' ) );
134
- add_filter( 'woocommerce_email_subject_customer_on_hold_order', array( $this, 'customer_on_hold_order_subject' ) );
135
-
136
- add_filter( 'woocommerce_email_heading_customer_processing_order', array( $this, 'customer_processing_order_heading' ) );
137
- add_filter( 'woocommerce_email_subject_customer_processing_order', array( $this, 'customer_processing_order_subject' ) );
138
- }
139
-
140
- function email_refresh_in_ajax() {
141
- if ( isset( $_GET['order_id'] ) ) {
142
- $this->refresh_email_lang( $_GET['order_id'] );
143
-
144
- if ( isset( $_GET['status'] ) && 'completed' === $_GET['status'] ) {
145
- $this->email_heading_completed( $_GET['order_id'], true );
146
- }
147
-
148
- return true;
149
- }
150
- }
151
-
152
- function refresh_email_lang_complete( $order_id ){
153
-
154
- $this->order_id = $order_id;
155
- $this->refresh_email_lang( $order_id );
156
- $this->email_heading_completed( $order_id, true );
157
- }
158
-
159
- /**
160
- * Translate WooCommerce emails.
161
- *
162
- * @global type $sitepress
163
- * @global type $order_id
164
- * @return type
165
- */
166
- function email_header( $order ) {
167
-
168
- if( is_array( $order ) ) {
169
- $order = $order[ 'order_id' ];
170
- } elseif( is_object( $order ) ) {
171
- $order = method_exists( 'WC_Order', 'get_id' ) ? $order->get_id() : $order->id;
172
- }
173
-
174
- $this->refresh_email_lang( $order );
175
- }
176
-
177
-
178
- function refresh_email_lang( $order_id ){
179
-
180
- if ( is_array( $order_id ) ) {
181
- if ( isset( $order_id[ 'order_id' ] ) ) {
182
- $order_id = $order_id[ 'order_id' ];
183
- } else {
184
- return;
185
- }
186
- }
187
-
188
- $lang = get_post_meta( $order_id, 'wpml_language', true );
189
- if( !empty( $lang ) ){
190
- $this->change_email_language( $lang );
191
- }
192
- }
193
-
194
- /**
195
- * After email translation switch language to default.
196
- */
197
- function email_footer() {
198
- $this->sitepress->switch_lang( $this->sitepress->get_default_language() );
199
- }
200
-
201
- public function comments_language(){
 
 
 
 
 
 
 
 
 
 
 
 
202
 
203
  if ( is_admin() && false !== $this->admin_language ) {
204
  $this->change_email_language( $this->admin_language );
205
- }else{
206
  $this->change_email_language( $this->woocommerce_wpml->strings->get_domain_language( 'woocommerce' ) );
207
- }
208
  }
209
 
210
 
211
- function email_heading_completed( $order_id, $no_checking = false ){
212
 
213
- if( ( class_exists( 'WC_Email_Customer_Completed_Order' ) || $no_checking ) && isset( $this->woocommerce->mailer()->emails[ 'WC_Email_Customer_Completed_Order' ] ) ){
214
 
215
- $this->woocommerce->mailer()->emails['WC_Email_Customer_Completed_Order']->heading = $this->wcml_get_translated_email_string( 'admin_texts_woocommerce_customer_completed_order_settings', '[woocommerce_customer_completed_order_settings]heading' );
216
 
217
- $this->woocommerce->mailer()->emails['WC_Email_Customer_Completed_Order']->subject = $this->wcml_get_translated_email_string( 'admin_texts_woocommerce_customer_completed_order_settings', '[woocommerce_customer_completed_order_settings]subject' );
218
 
219
- $this->woocommerce->mailer()->emails['WC_Email_Customer_Completed_Order']->heading_downloadable = $this->wcml_get_translated_email_string( 'admin_texts_woocommerce_customer_completed_order_settings', '[woocommerce_customer_completed_order_settings]heading_downloadable' );
220
 
221
- $this->woocommerce->mailer()->emails['WC_Email_Customer_Completed_Order']->subject_downloadable = $this->wcml_get_translated_email_string( 'admin_texts_woocommerce_customer_completed_order_settings', '[woocommerce_customer_completed_order_settings]subject_downloadable' );
222
 
223
- $enabled = $this->woocommerce->mailer()->emails['WC_Email_Customer_Completed_Order']->enabled;
224
- $this->woocommerce->mailer()->emails['WC_Email_Customer_Completed_Order']->enabled = false;
225
- $this->woocommerce->mailer()->emails['WC_Email_Customer_Completed_Order']->trigger($order_id);
226
- $this->woocommerce->mailer()->emails['WC_Email_Customer_Completed_Order']->enabled = $enabled;
227
- }
228
- }
229
 
230
- function email_heading_processing($order_id){
231
- $this->translate_email_headings( $order_id, 'WC_Email_Customer_Processing_Order', 'woocommerce_customer_processing_order_settings' );
232
- }
233
 
234
- public function customer_processing_order_heading( $heading ){
235
  return $this->get_translated_order_strings( 'heading', $heading, 'WC_Email_Customer_Processing_Order' );
236
  }
237
 
238
- public function customer_processing_order_subject( $subject ){
239
  return $this->get_translated_order_strings( 'subject', $subject, 'WC_Email_Customer_Processing_Order' );
240
  }
241
 
242
 
243
- public function email_heading_on_hold( $order_id ){
244
- $this->translate_email_headings( $order_id, 'WC_Email_Customer_On_Hold_Order', 'woocommerce_customer_on_hold_order_settings' );
245
- }
246
 
247
  /**
248
  * @param int|string $order_id
249
  * @param string $class_name
250
  * @param string $string_name
251
  */
252
- private function translate_email_headings( $order_id, $class_name, $string_name ){
253
- if( class_exists( $class_name ) && isset( $this->woocommerce->mailer()->emails[ $class_name ] ) ){
254
- $this->woocommerce->mailer()->emails[ $class_name ]->heading = $this->wcml_get_translated_email_string( 'admin_texts_'.$string_name, '['.$string_name.']heading', $order_id );
255
- $this->woocommerce->mailer()->emails[ $class_name ]->subject = $this->wcml_get_translated_email_string( 'admin_texts_'.$string_name, '['.$string_name.']subject', $order_id );
256
- $enabled = $this->woocommerce->mailer()->emails[ $class_name ]->enabled;
257
- $this->woocommerce->mailer()->emails[ $class_name ]->enabled = false;
258
- $this->woocommerce->mailer()->emails[ $class_name ]->trigger($order_id);
259
- $this->woocommerce->mailer()->emails[ $class_name ]->enabled = $enabled;
260
- }
261
- }
262
-
263
- public function customer_on_hold_order_heading( $heading ){
264
  return $this->get_translated_order_strings( 'heading', $heading, 'WC_Email_Customer_On_Hold_Order' );
265
  }
266
 
267
- public function customer_on_hold_order_subject( $subject ){
268
  return $this->get_translated_order_strings( 'subject', $subject, 'WC_Email_Customer_On_Hold_Order' );
269
  }
270
 
271
- function email_heading_note($args){
272
 
273
- if( class_exists( 'WC_Email_Customer_Note' ) && isset( $this->woocommerce->mailer()->emails[ 'WC_Email_Customer_Note' ] ) ){
274
 
275
- $this->woocommerce->mailer()->emails['WC_Email_Customer_Note']->heading = $this->wcml_get_translated_email_string( 'admin_texts_woocommerce_customer_note_settings', '[woocommerce_customer_note_settings]heading' );
276
 
277
- $this->woocommerce->mailer()->emails['WC_Email_Customer_Note']->subject = $this->wcml_get_translated_email_string( 'admin_texts_woocommerce_customer_note_settings', '[woocommerce_customer_note_settings]subject' );
278
 
279
- $enabled = $this->woocommerce->mailer()->emails['WC_Email_Customer_Note']->enabled;
280
- $this->woocommerce->mailer()->emails['WC_Email_Customer_Note']->enabled = false;
281
- $this->woocommerce->mailer()->emails['WC_Email_Customer_Note']->trigger($args);
282
- $this->woocommerce->mailer()->emails['WC_Email_Customer_Note']->enabled = $enabled;
283
- }
284
- }
285
 
286
- public function filter_refund_emails_strings( $value, $object , $old_value, $key ){
287
 
288
- if( in_array( $key, array( 'subject_partial', 'subject_full', 'heading_partial', 'heading_full' ) ) && $object->object ){
289
- $translated_value = $this->get_refund_email_translated_string( $key, $object );
290
- }
 
 
 
 
 
291
 
292
- return !empty( $translated_value ) ? $translated_value : $value;
293
- }
294
 
295
- public function get_refund_email_translated_string( $key, $object){
296
 
297
- return $this->wcml_get_translated_email_string( 'admin_texts_woocommerce_customer_refunded_order_settings',
298
- '[woocommerce_customer_refunded_order_settings]'.$key, $object->object->get_id() );
299
 
300
  }
301
 
302
- function new_order_admin_email($order_id){
303
 
304
- if( isset( $this->woocommerce->mailer()->emails[ 'WC_Email_New_Order' ] ) ){
305
- $recipients = explode(',',$this->woocommerce->mailer()->emails['WC_Email_New_Order']->get_recipient());
306
- foreach($recipients as $recipient){
307
- $user = get_user_by('email',$recipient);
308
- if($user){
309
- $user_lang = $this->sitepress->get_user_admin_language($user->ID, true );
310
- }else{
311
- $user_lang = $this->sitepress->get_default_language();
312
- }
313
 
314
- $this->change_email_language( $user_lang );
 
 
 
 
 
 
 
 
 
315
 
316
- $this->woocommerce->mailer()->emails['WC_Email_New_Order']->heading = $this->wcml_get_translated_email_string( 'admin_texts_woocommerce_new_order_settings', '[woocommerce_new_order_settings]heading', $order_id, $user_lang );
317
 
318
- $this->woocommerce->mailer()->emails['WC_Email_New_Order']->subject = $this->wcml_get_translated_email_string( 'admin_texts_woocommerce_new_order_settings', '[woocommerce_new_order_settings]subject', $order_id, $user_lang );
319
 
320
- $this->woocommerce->mailer()->emails['WC_Email_New_Order']->recipient = $recipient;
321
 
322
- $this->woocommerce->mailer()->emails['WC_Email_New_Order']->trigger($order_id);
323
- }
324
- $this->woocommerce->mailer()->emails['WC_Email_New_Order']->enabled = false;
325
- $this->refresh_email_lang($order_id);
326
- }
327
- }
328
 
329
- public function new_order_email_heading( $heading ){
330
- return $this->get_translated_order_strings( 'heading', $heading, 'WC_Email_New_Order' );
331
- }
 
 
 
 
 
 
 
332
 
333
- public function new_order_email_subject( $subject ){
334
- return $this->get_translated_order_strings( 'subject', $subject, 'WC_Email_New_Order' );
335
- }
336
 
337
  /**
338
  * @param string $type
@@ -341,147 +370,143 @@ class WCML_Emails{
341
  *
342
  * @return string
343
  */
344
- private function get_translated_order_strings( $type, $string, $class_name ){
345
- if( 'heading' === $type ){
346
- $translated_string = $this->woocommerce->mailer()->emails[ $class_name ]->heading;
347
- }elseif( 'subject' === $type ){
348
- $translated_string = $this->woocommerce->mailer()->emails[ $class_name ]->subject;
349
- }else{
350
- return $string;
351
- }
352
 
353
- return $translated_string ? $this->woocommerce->mailer()->emails[ $class_name ]->format_string( $translated_string ): $string;
354
- }
355
 
356
- public function backend_new_order_admin_email( $order_id ){
357
- if( isset( $_POST[ 'wc_order_action' ] ) && in_array( $_POST[ 'wc_order_action' ], array( 'send_email_new_order', 'send_order_details_admin' ) ) ){
358
- $this->new_order_admin_email( $order_id );
359
- }
360
- }
 
 
 
361
 
362
- function filter_formatted_items( $formatted_meta, $object ){
363
 
364
- if( isset( $object->product->variation_id ) ){
365
 
366
- $current_prod_variation_id = apply_filters( 'translate_object_id', $object->product->variation_id, 'product_variation', false );
367
 
368
- if( !is_null( $current_prod_variation_id ) ) {
369
 
370
- foreach( $formatted_meta as $key => $formatted_var ){
371
 
372
- if( substr( $formatted_var[ 'key' ], 0, 3 ) ){
373
 
374
- $attribute = wc_sanitize_taxonomy_name( $formatted_var[ 'key' ] );
375
 
376
- if( taxonomy_exists( $attribute ) ){
377
- $attr_term = get_term_by( 'name', $formatted_meta[ $key ][ 'value' ], $attribute );
378
- $tr_id = apply_filters( 'translate_object_id', $attr_term->term_id, $attribute, false, $this->sitepress->get_current_language() );
379
 
380
- if( $tr_id ){
381
- $translated_term = $this->woocommerce_wpml->terms->wcml_get_term_by_id( $tr_id, $attribute );
382
- $formatted_meta[ $key ][ 'value' ] = $translated_term->name;
383
- }
384
 
385
- }else{
386
 
387
- $custom_attr_trnsl = $this->woocommerce_wpml->attributes->get_custom_attribute_translation( $object->product->id, $formatted_var[ 'key' ], array('is_taxonomy' => false), $this->sitepress->get_current_language() );
388
 
389
- if ( false !== $custom_attr_trnsl ) {
390
- $formatted_meta[ $key ][ 'label' ] = $custom_attr_trnsl['name'];
391
- }
392
- }
393
- }
394
- }
395
- }
396
- }
397
 
398
- return $formatted_meta;
399
 
400
- }
401
 
402
  function change_email_language( $lang ) {
403
- global $wp_locale;
404
-
405
  if ( ! $this->admin_language ) {
406
  $this->admin_language = $this->sitepress->get_user_admin_language( get_current_user_id(), true );
407
  }
408
 
409
  $this->sitepress->switch_lang( $lang, true );
410
  $this->locale = $this->sitepress->get_locale( $lang );
411
- unload_textdomain( 'woocommerce' );
412
- unload_textdomain( 'default' );
413
-
414
- $wp_locale = new WP_Locale();
415
- $this->woocommerce->load_plugin_textdomain();
416
- load_default_textdomain( $this->locale );
417
- }
418
-
419
- function admin_string_return_cached( $value, $option ){
420
- if( in_array( $option, array ( 'woocommerce_email_from_address', 'woocommerce_email_from_name' ) ) )
421
- return false;
422
-
423
- return $value;
424
- }
425
-
426
- function wcml_get_translated_email_string( $context, $name, $order_id = false, $language_code = null ){
427
-
428
- if( $order_id && !$language_code ){
429
- $order_language = get_post_meta( $order_id, 'wpml_language', true );
430
- if( $order_language ){
431
- $language_code = $order_language;
432
- }
433
- }
434
- $result = $this->wpdb->get_var( $this->wpdb->prepare( "SELECT value FROM {$this->wpdb->prefix}icl_strings WHERE context = %s AND name = %s ", $context, $name ) );
435
-
436
- return apply_filters( 'wpml_translate_single_string', $result, $context, $name, $language_code );
437
- }
438
-
439
- function icl_current_string_language( $current_language, $name ){
440
- $order_id = false;
441
-
442
- if( isset($_POST['action']) && $_POST['action'] == 'editpost' && isset($_POST['post_type']) && $_POST['post_type'] == 'shop_order' && isset( $_POST[ 'wc_order_action' ] ) && $_POST[ 'wc_order_action' ] != 'send_email_new_order' ){
443
- $order_id = filter_input( INPUT_POST, 'post_ID', FILTER_SANITIZE_NUMBER_INT );
444
- }elseif( isset($_POST['action']) && $_POST['action'] == 'woocommerce_add_order_note' && isset($_POST['note_type']) && $_POST['note_type'] == 'customer' ) {
445
- $order_id = filter_input( INPUT_POST, 'post_id', FILTER_SANITIZE_NUMBER_INT );
446
- }elseif( isset($_GET['action']) && isset($_GET['order_id']) && ( $_GET['action'] == 'woocommerce_mark_order_complete' || $_GET['action'] == 'woocommerce_mark_order_status') ){
447
- $order_id = filter_input( INPUT_GET, 'order_id', FILTER_SANITIZE_NUMBER_INT );
448
- }elseif(isset($_GET['action']) && $_GET['action'] == 'mark_completed' && $this->order_id){
449
- $order_id = $this->order_id;
450
- }elseif(isset($_POST['action']) && $_POST['action'] == 'woocommerce_refund_line_items'){
451
- $order_id = filter_input( INPUT_POST, 'order_id', FILTER_SANITIZE_NUMBER_INT );
452
- }elseif( empty( $_POST ) && isset( $_GET[ 'page' ] ) && $_GET[ 'page' ] == 'wc-settings' && isset( $_GET[ 'tab' ] ) && $_GET[ 'tab' ] == 'email' && substr( $name, 0, 12 ) == '[woocommerce' ){
453
- $email_string = explode( ']', str_replace( '[', '', $name ) );
454
- $email_option = get_option( $email_string[ 0 ], true );
455
- $context = 'admin_texts_'.$email_string[ 0 ];
456
-
457
- $current_language = $this->woocommerce_wpml->strings->get_string_language( $email_option[ $email_string[ 1 ] ], $context, $name );
458
- }elseif( $this->order_id ){
459
- $order_id = $this->order_id;
460
- }
461
-
462
- $order_id = apply_filters( 'wcml_send_email_order_id', $order_id );
463
-
464
- if( $order_id ){
465
- $order_language = get_post_meta( $order_id, 'wpml_language', true );
466
- if( $order_language ){
467
- $current_language = $order_language;
468
- }else{
469
- $current_language = $this->sitepress->get_current_language();
470
- }
471
- }
472
-
473
- return apply_filters( 'wcml_email_language', $current_language, $order_id );
474
- }
475
-
476
- // set correct locale code for emails
477
- function set_locale_for_emails( $locale, $domain ){
478
-
479
- if( $domain == 'woocommerce' && $this->locale ){
480
- $locale = $this->locale;
481
- }
482
-
483
- return $locale;
484
- }
485
 
486
  function show_language_links_for_wc_emails() {
487
 
@@ -564,51 +589,52 @@ class WCML_Emails{
564
  }
565
  }
566
 
567
- function set_emails_string_language(){
568
 
569
- foreach( $_POST as $key => $language ){
570
 
571
- if( substr( $key, 0, 9 ) == 'wcml_lang' ){
572
 
573
- $email_string = explode( '-', $key );
574
 
575
- if( isset( $email_string[2] ) ){
576
 
577
- $email_key = str_replace( '_settings', '', $email_string[1] );
578
- $email_key .= '_'.$email_string[2];
579
 
580
- $email_settings = get_option( $email_string[1], true );
581
- $opt_string_value = $email_settings[ $email_string[2] ];
582
 
583
- $string_value = isset( $_POST[ $email_key ] ) ? $_POST[ $email_key ] : $opt_string_value;
584
 
585
- $context = 'admin_texts_'.$email_string[1];
586
- $name = '['.$email_string[1].']'.$email_string[2];
587
 
588
- do_action('wpml_register_single_string', $context, $name, $string_value, false, $this->woocommerce_wpml->strings->get_string_language( $opt_string_value, $context ) );
589
 
590
- $this->woocommerce_wpml->strings->set_string_language( $string_value, $context, $name, $language );
591
- }
592
- }
593
- }
594
- }
595
 
596
- function translate_woocommerce_countries( $countries ){
597
 
598
- if( isset( $_POST[ 'wc_order_action' ] ) && $_POST[ 'wc_order_action' ] !== 'send_email_new_order' && isset( $_POST[ 'post_ID' ] ) ){
599
- $current_language = $this->sitepress->get_current_language();
600
- $this->refresh_email_lang( $_POST[ 'post_ID' ] );
601
- $countries = include( WC()->plugin_path() . '/i18n/countries.php' );
602
- $this->change_email_language( $current_language );
603
- }
 
 
 
604
 
605
- return $countries;
606
- }
607
 
 
 
608
 
609
- function send_queued_transactional_email( $allow, $filter, $args ){
610
- $this->order_id = $args[0];
611
- return $allow;
612
- }
613
 
614
  }
1
  <?php
 
2
 
3
+ class WCML_Emails {
4
+
5
+ private $order_id = false;
6
+ private $locale = false;
7
  private $admin_language = false;
8
+ /** @var woocommerce_wpml */
9
+ private $woocommerce_wpml;
10
+ /** @var Sitepress */
11
+ private $sitepress;
12
+ /** @var WooCommerce */
13
+ private $woocommerce;
14
  /** @var wpdb */
15
  private $wpdb;
16
 
22
  * @param WooCommerce $woocommerce
23
  * @param wpdb $wpdb
24
  */
25
+ function __construct( woocommerce_wpml $woocommerce_wpml, SitePress $sitepress, WooCommerce $woocommerce, wpdb $wpdb ) {
26
+ $this->woocommerce_wpml = $woocommerce_wpml;
27
+ $this->sitepress = $sitepress;
28
+ $this->woocommerce = $woocommerce;
29
+ $this->wpdb = $wpdb;
30
+ }
31
+
32
+ function add_hooks() {
33
+ global $pagenow;
34
+ //wrappers for email's header
35
+ if ( is_admin() && ! defined( 'DOING_AJAX' ) ) {
36
+ add_action( 'woocommerce_order_status_completed_notification', array(
37
+ $this,
38
+ 'email_heading_completed'
39
+ ), 9 );
40
+ add_action( 'woocommerce_order_status_changed', array( $this, 'comments_language' ), 10 );
41
+ }
42
+
43
+ add_action( 'woocommerce_new_customer_note_notification', array( $this, 'email_heading_note' ), 9 );
44
+
45
+ add_action( 'wp_ajax_woocommerce_mark_order_status', array( $this, 'email_refresh_in_ajax' ), 9 );
46
+
47
+ foreach ( array( 'pending', 'failed', 'cancelled', 'on-hold' ) as $state ) {
48
+ add_action( 'woocommerce_order_status_' . $state . '_to_processing_notification', array(
49
+ $this,
50
+ 'email_heading_processing'
51
+ ), 9 );
52
+
53
+ add_action( 'woocommerce_order_status_' . $state . '_to_processing_notification', array(
54
+ $this,
55
+ 'refresh_email_lang'
56
+ ), 9 );
57
+ }
58
+
59
+ foreach ( array( 'pending', 'failed', 'cancelled' ) as $state ) {
60
+ add_action( 'woocommerce_order_status_' . $state . '_to_on-hold_notification', array(
61
+ $this,
62
+ 'email_heading_on_hold'
63
+ ), 9 );
64
+ }
65
+
66
+ //wrappers for email's body
67
+ add_action( 'woocommerce_before_resend_order_emails', array( $this, 'email_header' ) );
68
+ add_action( 'woocommerce_after_resend_order_email', array( $this, 'email_footer' ) );
69
+
70
+ //filter string language before for emails
71
+ add_filter( 'icl_current_string_language', array( $this, 'icl_current_string_language' ), 10, 2 );
72
+
73
+ //change order status
74
+ add_action( 'woocommerce_order_status_completed', array( $this, 'refresh_email_lang_complete' ), 9 );
75
+
76
+ add_action( 'woocommerce_order_status_pending_to_on-hold_notification', array(
77
+ $this,
78
+ 'refresh_email_lang'
79
+ ), 9 );
80
+ add_action( 'woocommerce_new_customer_note', array( $this, 'refresh_email_lang' ), 9 );
81
+
82
+ foreach ( array( 'pending', 'failed' ) as $from_state ) {
83
+ foreach ( array( 'processing', 'completed', 'on-hold' ) as $to_state ) {
84
+ add_action( 'woocommerce_order_status_' . $from_state . '_to_' . $to_state . '_notification', array(
85
+ $this,
86
+ 'new_order_admin_email'
87
+ ), 9 );
88
+ }
89
+ }
90
+
91
+ add_action( 'woocommerce_before_resend_order_emails', array( $this, 'backend_new_order_admin_email' ), 9 );
92
+
93
+ add_filter( 'icl_st_admin_string_return_cached', array( $this, 'admin_string_return_cached' ), 10, 2 );
94
+
95
+ add_filter( 'plugin_locale', array( $this, 'set_locale_for_emails' ), 10, 2 );
96
+ add_filter( 'woocommerce_countries', array( $this, 'translate_woocommerce_countries' ) );
97
+
98
+ if ( is_admin() && $pagenow == 'admin.php' && isset( $_GET['page'] ) && $_GET['page'] == 'wc-settings' && isset( $_GET['tab'] ) && $_GET['tab'] == 'email' ) {
99
+ add_action( 'admin_footer', array( $this, 'show_language_links_for_wc_emails' ) );
100
+ $this->set_emails_string_language();
101
+ }
102
+
103
+ if (
104
+ (
105
+ ! isset( $_GET['post_type'] ) ||
106
+ $_GET['post_type'] != 'shop_order'
107
+ ) &&
108
+ (
109
+ ! isset( $_GET['action'] ) ||
110
+ ! in_array( $_GET['action'], array(
111
+ 'woocommerce_mark_order_status'
112
+ ) )
113
+ )
114
+ ) {
115
+ add_filter( 'woocommerce_order_items_meta_get_formatted', array( $this, 'filter_formatted_items' ), 10, 2 );
116
+ }
117
+
118
+ add_filter( 'woocommerce_allow_send_queued_transactional_email', array(
119
+ $this,
120
+ 'send_queued_transactional_email'
121
+ ), 10, 3 );
122
+
123
+ add_action( 'woocommerce_order_partially_refunded_notification', array( $this, 'refresh_email_lang' ), 9 );
124
+ add_action( 'woocommerce_order_fully_refunded_notification', array( $this, 'refresh_email_lang' ), 9 );
125
+ add_filter( 'woocommerce_email_get_option', array( $this, 'filter_refund_emails_strings' ), 10, 4 );
126
+
127
+ add_filter( 'woocommerce_email_setup_locale', '__return_false' );
128
+ add_filter( 'woocommerce_email_restore_locale', '__return_false' );
129
+
130
+
131
+ add_filter( 'woocommerce_email_heading_new_order', array( $this, 'new_order_email_heading' ) );
132
+ add_filter( 'woocommerce_email_subject_new_order', array( $this, 'new_order_email_subject' ) );
133
+
134
+ add_filter( 'woocommerce_email_heading_customer_on_hold_order', array(
135
+ $this,
136
+ 'customer_on_hold_order_heading'
137
+ ) );
138
+ add_filter( 'woocommerce_email_subject_customer_on_hold_order', array(
139
+ $this,
140
+ 'customer_on_hold_order_subject'
141
+ ) );
142
+
143
+ add_filter( 'woocommerce_email_heading_customer_processing_order', array(
144
+ $this,
145
+ 'customer_processing_order_heading'
146
+ ) );
147
+ add_filter( 'woocommerce_email_subject_customer_processing_order', array(
148
+ $this,
149
+ 'customer_processing_order_subject'
150
+ ) );
151
+ }
152
+
153
+ function email_refresh_in_ajax() {
154
+ if ( isset( $_GET['order_id'] ) ) {
155
+ $this->refresh_email_lang( $_GET['order_id'] );
156
+
157
+ if ( isset( $_GET['status'] ) && 'completed' === $_GET['status'] ) {
158
+ $this->email_heading_completed( $_GET['order_id'], true );
159
+ }
160
+
161
+ return true;
162
+ }
163
+ }
164
+
165
+ function refresh_email_lang_complete( $order_id ) {
166
+
167
+ $this->order_id = $order_id;
168
+ $this->refresh_email_lang( $order_id );
169
+ $this->email_heading_completed( $order_id, true );
170
+ }
171
+
172
+ /**
173
+ * Translate WooCommerce emails.
174
+ *
175
+ * @global type $sitepress
176
+ * @global type $order_id
177
+ * @return type
178
+ */
179
+ function email_header( $order ) {
180
+
181
+ if ( is_array( $order ) ) {
182
+ $order = $order['order_id'];
183
+ } elseif ( is_object( $order ) ) {
184
+ $order = method_exists( 'WC_Order', 'get_id' ) ? $order->get_id() : $order->id;
185
+ }
186
+
187
+ $this->refresh_email_lang( $order );
188
+ }
189
+
190
+
191
+ function refresh_email_lang( $order_id ) {
192
+
193
+ if ( is_array( $order_id ) ) {
194
+ if ( isset( $order_id['order_id'] ) ) {
195
+ $order_id = $order_id['order_id'];
196
+ } else {
197
+ return;
198
+ }
199
+ }
200
+
201
+ $lang = get_post_meta( $order_id, 'wpml_language', true );
202
+ if ( ! empty( $lang ) ) {
203
+ $this->change_email_language( $lang );
204
+ }
205
+ }
206
+
207
+ /**
208
+ * After email translation switch language to default.
209
+ */
210
+ function email_footer() {
211
+ $this->sitepress->switch_lang( $this->sitepress->get_default_language() );
212
+ }
213
+
214
+ public function comments_language() {
215
 
216
  if ( is_admin() && false !== $this->admin_language ) {
217
  $this->change_email_language( $this->admin_language );
218
+ } else {
219
  $this->change_email_language( $this->woocommerce_wpml->strings->get_domain_language( 'woocommerce' ) );
220
+ }
221
  }
222
 
223
 
224
+ function email_heading_completed( $order_id, $no_checking = false ) {
225
 
226
+ if ( ( class_exists( 'WC_Email_Customer_Completed_Order' ) || $no_checking ) && isset( $this->woocommerce->mailer()->emails['WC_Email_Customer_Completed_Order'] ) ) {
227
 
228
+ $this->woocommerce->mailer()->emails['WC_Email_Customer_Completed_Order']->heading = $this->wcml_get_translated_email_string( 'admin_texts_woocommerce_customer_completed_order_settings', '[woocommerce_customer_completed_order_settings]heading' );
229
 
230
+ $this->woocommerce->mailer()->emails['WC_Email_Customer_Completed_Order']->subject = $this->wcml_get_translated_email_string( 'admin_texts_woocommerce_customer_completed_order_settings', '[woocommerce_customer_completed_order_settings]subject' );
231
 
232
+ $this->woocommerce->mailer()->emails['WC_Email_Customer_Completed_Order']->heading_downloadable = $this->wcml_get_translated_email_string( 'admin_texts_woocommerce_customer_completed_order_settings', '[woocommerce_customer_completed_order_settings]heading_downloadable' );
233
 
234
+ $this->woocommerce->mailer()->emails['WC_Email_Customer_Completed_Order']->subject_downloadable = $this->wcml_get_translated_email_string( 'admin_texts_woocommerce_customer_completed_order_settings', '[woocommerce_customer_completed_order_settings]subject_downloadable' );
235
 
236
+ $enabled = $this->woocommerce->mailer()->emails['WC_Email_Customer_Completed_Order']->enabled;
237
+ $this->woocommerce->mailer()->emails['WC_Email_Customer_Completed_Order']->enabled = false;
238
+ $this->woocommerce->mailer()->emails['WC_Email_Customer_Completed_Order']->trigger( $order_id );
239
+ $this->woocommerce->mailer()->emails['WC_Email_Customer_Completed_Order']->enabled = $enabled;
240
+ }
241
+ }
242
 
243
+ function email_heading_processing( $order_id ) {
244
+ $this->translate_email_headings( $order_id, 'WC_Email_Customer_Processing_Order', 'woocommerce_customer_processing_order_settings' );
245
+ }
246
 
247
+ public function customer_processing_order_heading( $heading ) {
248
  return $this->get_translated_order_strings( 'heading', $heading, 'WC_Email_Customer_Processing_Order' );
249
  }
250
 
251
+ public function customer_processing_order_subject( $subject ) {
252
  return $this->get_translated_order_strings( 'subject', $subject, 'WC_Email_Customer_Processing_Order' );
253
  }
254
 
255
 
256
+ public function email_heading_on_hold( $order_id ) {
257
+ $this->translate_email_headings( $order_id, 'WC_Email_Customer_On_Hold_Order', 'woocommerce_customer_on_hold_order_settings' );
258
+ }
259
 
260
  /**
261
  * @param int|string $order_id
262
  * @param string $class_name
263
  * @param string $string_name
264
  */
265
+ private function translate_email_headings( $order_id, $class_name, $string_name ) {
266
+ if ( class_exists( $class_name ) && isset( $this->woocommerce->mailer()->emails[ $class_name ] ) ) {
267
+ $this->woocommerce->mailer()->emails[ $class_name ]->heading = $this->wcml_get_translated_email_string( 'admin_texts_' . $string_name, '[' . $string_name . ']heading', $order_id );
268
+ $this->woocommerce->mailer()->emails[ $class_name ]->subject = $this->wcml_get_translated_email_string( 'admin_texts_' . $string_name, '[' . $string_name . ']subject', $order_id );
269
+ $enabled = $this->woocommerce->mailer()->emails[ $class_name ]->enabled;
270
+ $this->woocommerce->mailer()->emails[ $class_name ]->enabled = false;
271
+ $this->woocommerce->mailer()->emails[ $class_name ]->trigger( $order_id );
272
+ $this->woocommerce->mailer()->emails[ $class_name ]->enabled = $enabled;
273
+ }
274
+ }
275
+
276
+ public function customer_on_hold_order_heading( $heading ) {
277
  return $this->get_translated_order_strings( 'heading', $heading, 'WC_Email_Customer_On_Hold_Order' );
278
  }
279
 
280
+ public function customer_on_hold_order_subject( $subject ) {
281
  return $this->get_translated_order_strings( 'subject', $subject, 'WC_Email_Customer_On_Hold_Order' );
282
  }
283
 
284
+ function email_heading_note( $args ) {
285
 
286
+ if ( class_exists( 'WC_Email_Customer_Note' ) && isset( $this->woocommerce->mailer()->emails['WC_Email_Customer_Note'] ) ) {
287
 
288
+ $this->woocommerce->mailer()->emails['WC_Email_Customer_Note']->heading = $this->wcml_get_translated_email_string( 'admin_texts_woocommerce_customer_note_settings', '[woocommerce_customer_note_settings]heading' );
289
 
290
+ $this->woocommerce->mailer()->emails['WC_Email_Customer_Note']->subject = $this->wcml_get_translated_email_string( 'admin_texts_woocommerce_customer_note_settings', '[woocommerce_customer_note_settings]subject' );
291
 
292
+ $enabled = $this->woocommerce->mailer()->emails['WC_Email_Customer_Note']->enabled;
293
+ $this->woocommerce->mailer()->emails['WC_Email_Customer_Note']->enabled = false;
294
+ $this->woocommerce->mailer()->emails['WC_Email_Customer_Note']->trigger( $args );
295
+ $this->woocommerce->mailer()->emails['WC_Email_Customer_Note']->enabled = $enabled;
296
+ }
297
+ }
298
 
299
+ public function filter_refund_emails_strings( $value, $object, $old_value, $key ) {
300
 
301
+ if ( in_array( $key, array(
302
+ 'subject_partial',
303
+ 'subject_full',
304
+ 'heading_partial',
305
+ 'heading_full'
306
+ ) ) && $object->object ) {
307
+ $translated_value = $this->get_refund_email_translated_string( $key, $object );
308
+ }
309
 
310
+ return ! empty( $translated_value ) ? $translated_value : $value;
311
+ }
312
 
313
+ public function get_refund_email_translated_string( $key, $object ) {
314
 
315
+ return $this->wcml_get_translated_email_string( 'admin_texts_woocommerce_customer_refunded_order_settings',
316
+ '[woocommerce_customer_refunded_order_settings]' . $key, $object->object->get_id() );
317
 
318
  }
319
 
320
+ function new_order_admin_email( $order_id ) {
321
 
322
+ if ( isset( $this->woocommerce->mailer()->emails['WC_Email_New_Order'] ) ) {
323
+ $recipients = explode( ',', $this->woocommerce->mailer()->emails['WC_Email_New_Order']->get_recipient() );
324
+ foreach ( $recipients as $recipient ) {
325
+ $user = get_user_by( 'email', $recipient );
326
+ if ( $user ) {
327
+ $admin_language = $this->sitepress->get_user_admin_language( $user->ID, true );
328
+ } else {
329
+ $admin_language = $this->sitepress->get_default_language();
330
+ }
331
 
332
+ /**
333
+ * Filter new order admin email language for recipient
334
+ *
335
+ * @since 4.7.0
336
+ *
337
+ * @param string $admin_language Admin language
338
+ * @param string $recipient Admin email
339
+ * @param int $order_id Order ID
340
+ */
341
+ $admin_language = apply_filters( 'wcml_new_order_admin_email_language', $admin_language, $recipient, $order_id );
342
 
343
+ $this->change_email_language( $admin_language );
344
 
345
+ $this->woocommerce->mailer()->emails['WC_Email_New_Order']->heading = $this->wcml_get_translated_email_string( 'admin_texts_woocommerce_new_order_settings', '[woocommerce_new_order_settings]heading', $order_id, $admin_language );
346
 
347
+ $this->woocommerce->mailer()->emails['WC_Email_New_Order']->subject = $this->wcml_get_translated_email_string( 'admin_texts_woocommerce_new_order_settings', '[woocommerce_new_order_settings]subject', $order_id, $admin_language );
348
 
349
+ $this->woocommerce->mailer()->emails['WC_Email_New_Order']->recipient = $recipient;
 
 
 
 
 
350
 
351
+ $this->woocommerce->mailer()->emails['WC_Email_New_Order']->trigger( $order_id );
352
+ }
353
+ $this->woocommerce->mailer()->emails['WC_Email_New_Order']->enabled = false;
354
+ $this->refresh_email_lang( $order_id );
355
+ }
356
+ }
357
+
358
+ public function new_order_email_heading( $heading ) {
359
+ return $this->get_translated_order_strings( 'heading', $heading, 'WC_Email_New_Order' );
360
+ }
361
 
362
+ public function new_order_email_subject( $subject ) {
363
+ return $this->get_translated_order_strings( 'subject', $subject, 'WC_Email_New_Order' );
364
+ }
365
 
366
  /**
367
  * @param string $type
370
  *
371
  * @return string
372
  */
373
+ private function get_translated_order_strings( $type, $string, $class_name ) {
374
+ if ( 'heading' === $type ) {
375
+ $translated_string = $this->woocommerce->mailer()->emails[ $class_name ]->heading;
376
+ } elseif ( 'subject' === $type ) {
377
+ $translated_string = $this->woocommerce->mailer()->emails[ $class_name ]->subject;
378
+ } else {
379
+ return $string;
380
+ }
381
 
382
+ return $translated_string ? $this->woocommerce->mailer()->emails[ $class_name ]->format_string( $translated_string ) : $string;
383
+ }
384
 
385
+ public function backend_new_order_admin_email( $order_id ) {
386
+ if ( isset( $_POST['wc_order_action'] ) && in_array( $_POST['wc_order_action'], array(
387
+ 'send_email_new_order',
388
+ 'send_order_details_admin'
389
+ ) ) ) {
390
+ $this->new_order_admin_email( $order_id );
391
+ }
392
+ }
393
 
394
+ function filter_formatted_items( $formatted_meta, $object ) {
395
 
396
+ if ( isset( $object->product->variation_id ) ) {
397
 
398
+ $current_prod_variation_id = apply_filters( 'translate_object_id', $object->product->variation_id, 'product_variation', false );
399
 
400
+ if ( ! is_null( $current_prod_variation_id ) ) {
401
 
402
+ foreach ( $formatted_meta as $key => $formatted_var ) {
403
 
404
+ if ( substr( $formatted_var['key'], 0, 3 ) ) {
405
 
406
+ $attribute = wc_sanitize_taxonomy_name( $formatted_var['key'] );
407
 
408
+ if ( taxonomy_exists( $attribute ) ) {
409
+ $attr_term = get_term_by( 'name', $formatted_meta[ $key ]['value'], $attribute );
410
+ $tr_id = apply_filters( 'translate_object_id', $attr_term->term_id, $attribute, false, $this->sitepress->get_current_language() );
411
 
412
+ if ( $tr_id ) {
413
+ $translated_term = $this->woocommerce_wpml->terms->wcml_get_term_by_id( $tr_id, $attribute );
414
+ $formatted_meta[ $key ]['value'] = $translated_term->name;
415
+ }
416
 
417
+ } else {
418
 
419
+ $custom_attr_trnsl = $this->woocommerce_wpml->attributes->get_custom_attribute_translation( $object->product->id, $formatted_var['key'], array( 'is_taxonomy' => false ), $this->sitepress->get_current_language() );
420
 
421
+ if ( false !== $custom_attr_trnsl ) {
422
+ $formatted_meta[ $key ]['label'] = $custom_attr_trnsl['name'];
423
+ }
424
+ }
425
+ }
426
+ }
427
+ }
428
+ }
429
 
430
+ return $formatted_meta;
431
 
432
+ }
433
 
434
  function change_email_language( $lang ) {
 
 
435
  if ( ! $this->admin_language ) {
436
  $this->admin_language = $this->sitepress->get_user_admin_language( get_current_user_id(), true );
437
  }
438
 
439
  $this->sitepress->switch_lang( $lang, true );
440
  $this->locale = $this->sitepress->get_locale( $lang );
441
+ }
442
+
443
+ function admin_string_return_cached( $value, $option ) {
444
+ if ( in_array( $option, array( 'woocommerce_email_from_address', 'woocommerce_email_from_name' ) ) ) {
445
+ return false;
446
+ }
447
+
448
+ return $value;
449
+ }
450
+
451
+ function wcml_get_translated_email_string( $context, $name, $order_id = false, $language_code = null ) {
452
+
453
+ if ( $order_id && ! $language_code ) {
454
+ $order_language = get_post_meta( $order_id, 'wpml_language', true );
455
+ if ( $order_language ) {
456
+ $language_code = $order_language;
457
+ }
458
+ }
459
+ $result = $this->wpdb->get_var( $this->wpdb->prepare( "SELECT value FROM {$this->wpdb->prefix}icl_strings WHERE context = %s AND name = %s ", $context, $name ) );
460
+
461
+ return apply_filters( 'wpml_translate_single_string', $result, $context, $name, $language_code );
462
+ }
463
+
464
+ function icl_current_string_language( $current_language, $name ) {
465
+ $order_id = false;
466
+
467
+ if ( isset( $_POST['action'] ) && $_POST['action'] == 'editpost' && isset( $_POST['post_type'] ) && $_POST['post_type'] == 'shop_order' && isset( $_POST['wc_order_action'] ) && $_POST['wc_order_action'] != 'send_email_new_order' ) {
468
+ $order_id = filter_input( INPUT_POST, 'post_ID', FILTER_SANITIZE_NUMBER_INT );
469
+ } elseif ( isset( $_POST['action'] ) && $_POST['action'] == 'woocommerce_add_order_note' && isset( $_POST['note_type'] ) && $_POST['note_type'] == 'customer' ) {
470
+ $order_id = filter_input( INPUT_POST, 'post_id', FILTER_SANITIZE_NUMBER_INT );
471
+ } elseif ( isset( $_GET['action'] ) && isset( $_GET['order_id'] ) && ( $_GET['action'] == 'woocommerce_mark_order_complete' || $_GET['action'] == 'woocommerce_mark_order_status' ) ) {
472
+ $order_id = filter_input( INPUT_GET, 'order_id', FILTER_SANITIZE_NUMBER_INT );
473
+ } elseif ( isset( $_GET['action'] ) && $_GET['action'] == 'mark_completed' && $this->order_id ) {
474
+ $order_id = $this->order_id;
475
+ } elseif ( isset( $_POST['action'] ) && $_POST['action'] == 'woocommerce_refund_line_items' ) {
476
+ $order_id = filter_input( INPUT_POST, 'order_id', FILTER_SANITIZE_NUMBER_INT );
477
+ } elseif ( empty( $_POST ) && isset( $_GET['page'] ) && $_GET['page'] == 'wc-settings' && isset( $_GET['tab'] ) && $_GET['tab'] == 'email' && substr( $name, 0, 12 ) == '[woocommerce' ) {
478
+ $email_string = explode( ']', str_replace( '[', '', $name ) );
479
+ $email_option = get_option( $email_string[0], true );
480
+ $context = 'admin_texts_' . $email_string[0];
481
+
482
+ $current_language = $this->woocommerce_wpml->strings->get_string_language( $email_option[ $email_string[1] ], $context, $name );
483
+ } elseif ( $this->order_id ) {
484
+ $order_id = $this->order_id;
485
+ }
486
+
487
+ $order_id = apply_filters( 'wcml_send_email_order_id', $order_id );
488
+
489
+ if ( $order_id ) {
490
+ $order_language = get_post_meta( $order_id, 'wpml_language', true );
491
+ if ( $order_language ) {
492
+ $current_language = $order_language;
493
+ } else {
494
+ $current_language = $this->sitepress->get_current_language();
495
+ }
496
+ }
497
+
498
+ return apply_filters( 'wcml_email_language', $current_language, $order_id );
499
+ }
500
+
501
+ // set correct locale code for emails
502
+ function set_locale_for_emails( $locale, $domain ) {
503
+
504
+ if ( $domain == 'woocommerce' && $this->locale ) {
505
+ $locale = $this->locale;
506
+ }
507
+
508
+ return $locale;
509
+ }
 
 
 
 
 
510
 
511
  function show_language_links_for_wc_emails() {
512
 
589
  }
590
  }
591
 
592
+ function set_emails_string_language() {
593
 
594
+ foreach ( $_POST as $key => $language ) {
595
 
596
+ if ( substr( $key, 0, 9 ) == 'wcml_lang' ) {
597
 
598
+ $email_string = explode( '-', $key );
599
 
600
+ if ( isset( $email_string[2] ) ) {
601
 
602
+ $email_key = str_replace( '_settings', '', $email_string[1] );
603
+ $email_key .= '_' . $email_string[2];
604
 
605
+ $email_settings = get_option( $email_string[1], true );
606
+ $opt_string_value = $email_settings[ $email_string[2] ];
607
 
608
+ $string_value = isset( $_POST[ $email_key ] ) ? $_POST[ $email_key ] : $opt_string_value;
609
 
610
+ $context = 'admin_texts_' . $email_string[1];
611
+ $name = '[' . $email_string[1] . ']' . $email_string[2];
612
 
613
+ do_action( 'wpml_register_single_string', $context, $name, $string_value, false, $this->woocommerce_wpml->strings->get_string_language( $opt_string_value, $context ) );
614
 
615
+ $this->woocommerce_wpml->strings->set_string_language( $string_value, $context, $name, $language );
616
+ }
617
+ }
618
+ }
619
+ }
620
 
621
+ function translate_woocommerce_countries( $countries ) {
622
 
623
+ if ( isset( $_POST['wc_order_action'] ) && $_POST['wc_order_action'] !== 'send_email_new_order' && isset( $_POST['post_ID'] ) ) {
624
+ $current_language = $this->sitepress->get_current_language();
625
+ $this->refresh_email_lang( $_POST['post_ID'] );
626
+ $countries = include( WC()->plugin_path() . '/i18n/countries.php' );
627
+ $this->change_email_language( $current_language );
628
+ }
629
+
630
+ return $countries;
631
+ }
632
 
 
 
633
 
634
+ function send_queued_transactional_email( $allow, $filter, $args ) {
635
+ $this->order_id = $args[0];
636
 
637
+ return $allow;
638
+ }
 
 
639
 
640
  }
inc/class-wcml-locale.php CHANGED
@@ -12,9 +12,6 @@ class WCML_Locale{
12
  $this->load_locale();
13
 
14
  add_filter( 'locale',array( $this, 'update_product_action_locale_check' ) );
15
- add_action( 'woocommerce_email', array( $this, 'woocommerce_email_refresh_text_domain' ) );
16
- add_action( 'wp_ajax_woocommerce_update_shipping_method', array( $this, 'wcml_refresh_text_domain' ), 9 );
17
- add_action( 'wp_ajax_nopriv_woocommerce_update_shipping_method', array( $this, 'wcml_refresh_text_domain' ), 9 );
18
 
19
  }
20
 
@@ -51,18 +48,4 @@ class WCML_Locale{
51
  }
52
  return $locale;
53
  }
54
-
55
- public function woocommerce_email_refresh_text_domain(){
56
- if( !isset( $_GET[ 'page' ] ) || ( isset( $_GET[ 'page' ] ) && $_GET[ 'page' ] != 'wc-settings' ) ){
57
- $this->wcml_refresh_text_domain();
58
- }
59
- }
60
-
61
- public function wcml_refresh_text_domain(){
62
- global $woocommerce;
63
- $domain = 'woocommerce';
64
- unload_textdomain( $domain );
65
- $woocommerce->load_plugin_textdomain();
66
- }
67
-
68
  }
12
  $this->load_locale();
13
 
14
  add_filter( 'locale',array( $this, 'update_product_action_locale_check' ) );
 
 
 
15
 
16
  }
17
 
48
  }
49
  return $locale;
50
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
51
  }
inc/class-wcml-media.php DELETED
@@ -1,170 +0,0 @@
1
- <?php
2
-
3
- class WCML_Media{
4
-
5
- /** @var woocommerce_wpml */
6
- private $woocommerce_wpml;
7
- /** @var SitePress */
8
- private $sitepress;
9
- /** @var wpdb */
10
- private $wpdb;
11
-
12
- public $settings = array();
13
-
14
- private $products_being_synced = array();
15
-
16
- public function __construct( $woocommerce_wpml, $sitepress, $wpdb ){
17
- $this->woocommerce_wpml = $woocommerce_wpml;
18
- $this->sitepress = $sitepress;
19
- $this->wpdb = $wpdb;
20
- }
21
-
22
- public function add_hooks(){
23
- //when save new attachment duplicate product gallery
24
- add_action( 'wpml_media_create_duplicate_attachment', array( $this, 'sync_product_gallery_duplicate_attachment' ), 11, 2 );
25
- }
26
-
27
- public function product_images_ids( $product_id ){
28
- $product_images_ids = array();
29
-
30
- //thumbnail image
31
- $tmb = get_post_meta( $product_id, '_thumbnail_id', true );
32
- if( $tmb ) {
33
- $product_images_ids[] = $tmb;
34
- }
35
-
36
- //product gallery
37
- $product_gallery = get_post_meta( $product_id, '_product_image_gallery', true );
38
- if( $product_gallery ) {
39
- $product_gallery = explode( ',', $product_gallery );
40
- foreach( $product_gallery as $img ){
41
- if( !in_array( $img, $product_images_ids ) ){
42
- $product_images_ids[] = $img;
43
- }
44
- }
45
- }
46
-
47
- foreach( wp_get_post_terms( $product_id, 'product_type', array( "fields" => "names" ) ) as $type ){
48
- $product_type = $type;
49
- }
50
-
51
- if( isset( $product_type ) && $product_type == 'variable' ){
52
- $get_post_variations_image = $this->wpdb->get_col(
53
- $this->wpdb->prepare(
54
- "SELECT pm.meta_value FROM {$this->wpdb->posts} AS p
55
- LEFT JOIN {$this->wpdb->postmeta} AS pm ON p.ID = pm.post_id
56
- WHERE pm.meta_key='_thumbnail_id'
57
- AND p.post_status IN ('publish','private')
58
- AND p.post_type = 'product_variation'
59
- AND p.post_parent = %d
60
- ORDER BY ID", $product_id )
61
- );
62
- foreach( $get_post_variations_image as $variation_image ){
63
- if( $variation_image && !in_array( $variation_image, $product_images_ids ) ){
64
- $product_images_ids[] = $variation_image;
65
- }
66
- }
67
- }
68
-
69
- foreach( $product_images_ids as $key => $image ){
70
- if( ! get_post_status ( $image ) ){
71
- unset( $product_images_ids[ $key ] );
72
- }
73
- }
74
-
75
- return $product_images_ids;
76
- }
77
-
78
- public function sync_thumbnail_id( $orig_post_id, $trnsl_post_id, $lang ) {
79
- if ( method_exists( 'WPML_Media_Attachments_Duplication', 'sync_post_thumbnail') ) {
80
- $factory = new WPML_Media_Attachments_Duplication_Factory();
81
- $media_duplicate = $factory->create();
82
- if( $media_duplicate ){
83
- $media_duplicate->sync_post_thumbnail( $orig_post_id );
84
- }
85
- }
86
- }
87
-
88
- public function sync_variation_thumbnail_id( $variation_id, $translated_variation_id, $lang ){
89
- $thumbnail_id = get_post_meta( $variation_id, '_thumbnail_id', true );
90
- $translated_thumbnail = apply_filters( 'translate_object_id', $thumbnail_id, 'attachment', false, $lang );
91
-
92
- if( is_null( $translated_thumbnail ) && $thumbnail_id ){
93
- $factory = new WPML_Media_Attachments_Duplication_Factory();
94
- $media_duplicate = $factory->create();
95
- $translated_thumbnail = $media_duplicate->create_duplicate_attachment( $thumbnail_id, wp_get_post_parent_id( $thumbnail_id ), $lang );
96
- }
97
- if( $translated_thumbnail ) {
98
- update_post_meta( $translated_variation_id, '_thumbnail_id', $translated_thumbnail );
99
- update_post_meta( $variation_id, '_wpml_media_duplicate', 1 );
100
- update_post_meta( $variation_id, '_wpml_media_featured', 1 );
101
- }
102
- }
103
-
104
-
105
- public function sync_product_gallery( $product_id ) {
106
-
107
- if( $this->is_media_duplication_enabled( $product_id ) ){
108
- $product_gallery = get_post_meta( $product_id, '_product_image_gallery', true );
109
- $gallery_ids = explode( ',', $product_gallery );
110
-
111
- $trid = $this->sitepress->get_element_trid( $product_id, 'post_product' );
112
- $translations = $this->sitepress->get_element_translations( $trid, 'post_product', true );
113
- foreach ( $translations as $translation ) {
114
- $duplicated_ids = '';
115
- if ( ! $translation->original ) {
116
- foreach ( $gallery_ids as $image_id ) {
117
- if ( get_post( $image_id ) ) {
118
- $duplicated_id = apply_filters( 'translate_object_id', $image_id, 'attachment', false, $translation->language_code );
119
- if ( is_null( $duplicated_id ) && $image_id ) {
120
- $duplicated_id = $this->create_base_media_translation( $image_id, $translation->element_id, $translation->language_code );
121
- }
122
- $duplicated_ids .= $duplicated_id . ',';
123
- }
124
- }
125
- $duplicated_ids = substr( $duplicated_ids, 0, strlen( $duplicated_ids ) - 1 );
126
- update_post_meta( $translation->element_id, '_product_image_gallery', $duplicated_ids );
127
- }
128
- }
129
- }
130
- }
131
-
132
- public function create_base_media_translation( $attachment_id, $parent_id, $target_lang ) {
133
-
134
- $factory = new WPML_Media_Attachments_Duplication_Factory();
135
- $media_duplicate = $factory->create();
136
- $duplicated_id = $media_duplicate->create_duplicate_attachment( $attachment_id, $parent_id, $target_lang );
137
-
138
- return $duplicated_id;
139
- }
140
-
141
- public function sync_product_gallery_duplicate_attachment( $att_id, $dup_att_id ) {
142
- $product_id = wp_get_post_parent_id( $att_id );
143
- $post_type = get_post_type( $product_id );
144
- if ( $post_type != 'product' || array_key_exists( $product_id, $this->products_being_synced ) ) {
145
- return;
146
- }
147
- $this->products_being_synced[ $product_id ] = 1;
148
- $this->sync_product_gallery( $product_id );
149
- unset( $this->products_being_synced[ $product_id ] );
150
- }
151
-
152
- public function is_media_duplication_enabled( $product_id ){
153
-
154
- $setting_value = get_post_meta( $product_id, $this->sitepress->get_wp_api()->constant( 'WPML_Admin_Post_Actions::DUPLICATE_MEDIA_META_KEY' ), true );
155
-
156
- if( '' === $setting_value ){
157
- // fallback to global setting
158
- $media_options = get_option( '_wpml_media', array() );
159
-
160
- $global_setting_key = $this->sitepress->get_wp_api()->constant( 'WPML_Admin_Post_Actions::DUPLICATE_MEDIA_GLOBAL_KEY' );
161
- if ( isset( $media_options['new_content_settings'][ $global_setting_key ] ) ) {
162
- $setting_value = $media_options['new_content_settings'][ $global_setting_key ];
163
- }
164
- }
165
-
166
- return (bool) $setting_value;
167
-
168
- }
169
-
170
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
inc/class-wcml-orders.php CHANGED
@@ -2,343 +2,373 @@
2
 
3
  class WCML_Orders {
4
 
5
- const DASHBOARD_COOKIE_NAME = '_wcml_dashboard_order_language';
6
- const COOKIE_TTL = 86400;
7
-
8
- private $woocommerce_wpml;
9
- private $sitepress;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
10
 
11
- private $standard_order_notes = array(
12
- 'Order status changed from %s to %s.',
13
- 'Order item stock reduced successfully.',
14
- 'Item #%s stock reduced from %s to %s.',
15
- 'Item #%s stock increased from %s to %s.',
16
- 'Awaiting BACS payment','Awaiting cheque payment',
17
- 'Payment to be made upon delivery.',
18
- 'Validation error: PayPal amounts do not match (gross %s).',
19
- 'Validation error: PayPal IPN response from a different email address (%s).',
20
- 'Payment pending: %s',
21
- 'Payment %s via IPN.',
22
- 'Validation error: PayPal amounts do not match (amt %s).',
23
- 'IPN payment completed','PDT payment completed'
24
- );
25
 
26
- public function __construct( &$woocommerce_wpml, &$sitepress ){
27
- $this->woocommerce_wpml = $woocommerce_wpml;
28
- $this->sitepress = $sitepress;
29
 
30
- add_action('init', array($this, 'init'));
31
 
32
- //checkout page
33
- add_action( 'wp_ajax_woocommerce_checkout',array($this,'switch_to_current'),9);
34
- add_action( 'wp_ajax_nopriv_woocommerce_checkout',array($this,'switch_to_current'),9);
35
 
36
- add_action( 'wp_ajax_wcml_order_delete_items', array( $this, 'order_delete_items' ) );
37
- }
 
38
 
39
- function init(){
40
 
41
- add_action('woocommerce_checkout_update_order_meta', array($this, 'set_order_language'));
 
 
 
 
42
 
43
- add_filter('icl_lang_sel_copy_parameters', array($this, 'append_query_parameters'));
 
44
 
45
- add_filter('the_comments', array($this, 'get_filtered_comments'));
 
 
 
 
 
46
 
47
- if ( $this->should_attach_new_order_note_data_filter() ) {
48
- add_filter( 'gettext', array( $this, 'filtered_woocommerce_new_order_note_data' ), 10, 3 );
49
- }
50
 
51
- add_filter( 'woocommerce_order_get_items', array( $this, 'woocommerce_order_get_items' ), 10, 2 );
 
52
 
53
- add_action( 'woocommerce_process_shop_order_meta', array( $this, 'set_order_language_backend'), 10, 2 );
54
- add_action( 'woocommerce_order_actions_start', array( $this, 'order_language_dropdown' ), 11 ); //after order currency drop-down
55
 
56
- //special case for wcml-741
57
- add_action('updated_post_meta', array($this,'update_order_currency'), 100,4);
58
 
59
- add_action( 'woocommerce_before_order_itemmeta', array( $this, 'backend_before_order_itemmeta' ), 100, 3 );
60
- add_action( 'woocommerce_after_order_itemmeta', array( $this, 'backend_after_order_itemmeta' ), 100, 3 );
61
 
62
- add_filter( 'woocommerce_get_item_downloads', array( $this, 'filter_downloadable_product_items' ), 10, 3 );
63
- add_filter( 'woocommerce_customer_get_downloadable_products', array( $this, 'filter_customer_get_downloadable_products' ), 10, 3 );
64
- }
 
 
65
 
66
- public function should_attach_new_order_note_data_filter() {
67
- $admin_language = $this->sitepress->get_user_admin_language( get_current_user_id(), true );
68
- $all_strings_in_english = get_option( 'wpml-st-all-strings-are-in-english' );
 
69
 
70
- return 'en' !== $admin_language || ! $all_strings_in_english;
71
- }
72
 
73
- function filtered_woocommerce_new_order_note_data($translations, $text, $domain ){
74
- if(in_array($text,$this->standard_order_notes)){
75
 
76
- $language = $this->woocommerce_wpml->strings->get_string_language( $text, 'woocommerce' );
77
 
78
- if( $this->sitepress->get_user_admin_language( get_current_user_id(), true ) != $language ){
 
79
 
80
- $string_id = icl_get_string_id( $text, 'woocommerce');
81
- $strings = icl_get_string_translations_by_id( $string_id );
82
- if($strings){
83
- $translations = $strings[ $this->sitepress->get_user_admin_language( get_current_user_id(), true ) ]['value'];
84
- }
85
 
86
- }else{
87
- return $text;
88
- }
89
- }
90
 
91
- return $translations;
92
- }
 
 
 
93
 
94
- function get_filtered_comments( $comments ){
95
 
96
- $user_id = get_current_user_id();
 
97
 
98
- if ( $user_id ) {
99
- $user_language = get_user_meta( $user_id, 'icl_admin_language', true );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
100
 
101
- foreach ( $comments as $key => $comment ) {
102
- $comment_string_id = icl_get_string_id( $comment->comment_content, 'woocommerce' );
103
 
104
- if ( $comment_string_id ) {
105
- $comment_strings = icl_get_string_translations_by_id( $comment_string_id );
 
 
 
106
 
107
- if ( $comment_strings && isset( $comment_strings[ $user_language ] ) ) {
108
- $comments[ $key ]->comment_content = $comment_strings[ $user_language ][ 'value' ];
109
- }
110
- }
111
- }
 
112
 
113
- }
 
 
 
 
 
 
 
 
 
114
 
115
- return $comments;
116
- }
117
 
118
- function woocommerce_order_get_items( $items, $order ){
 
 
 
 
 
 
 
 
 
 
 
119
 
120
- if ( $this->is_order_saving_action() ) {
121
- return $items;
122
- }
 
 
 
 
 
 
123
 
124
- if( isset( $_GET[ 'post' ] ) && get_post_type( $_GET[ 'post' ] ) == 'shop_order' ) {
125
- // on order edit page use admin default language
126
- $language_to_filter = $this->sitepress->get_user_admin_language( get_current_user_id(), true );
127
- }elseif( isset( $_GET[ 'action' ] ) && ( $_GET['action'] == 'woocommerce_mark_order_complete' || $_GET['action'] == 'woocommerce_mark_order_status' || $_GET['action'] == 'mark_processing') ){
128
- //backward compatibility for WC < 2.7
129
- $order_id = method_exists( 'WC_Order', 'get_id' ) ? $order->get_id() : $order->id;
130
- $order_language = get_post_meta( $order_id, 'wpml_language', true );
131
- $language_to_filter = $order_language ? $order_language : $this->sitepress->get_default_language();
132
- }else{
133
- $language_to_filter = $this->sitepress->get_current_language();
134
- }
135
 
136
- foreach( $items as $index => $item ){
137
- if( is_array( $item ) ){
138
- // WC < 2.7
139
- foreach( $item as $key => $item_data ){
140
- if( $key == 'product_id' ){
141
- $tr_product_id = apply_filters( 'translate_object_id', $item_data, 'product', false, $language_to_filter );
142
- if( !is_null( $tr_product_id ) ){
143
- $items[ $index ][ $key ] = $tr_product_id;
144
- $items[ $index ][ 'name'] = get_post( $tr_product_id )->post_title;
145
- }
146
- }
147
- if( $key == 'variation_id' ){
148
- $tr_variation_id = apply_filters( 'translate_object_id', $item_data, 'product_variation', false, $language_to_filter );
149
- if( !is_null($tr_variation_id)){
150
- $items[$index][$key] = $tr_variation_id;
151
- }
152
- }
153
 
154
- if (substr($key, 0, 3) == 'pa_') {
155
- //attr is taxonomy
156
 
157
- $term_id = $this->woocommerce_wpml->terms->wcml_get_term_id_by_slug( $key, $item_data );
158
- $tr_id = apply_filters( 'translate_object_id', $term_id, $key, false, $language_to_filter );
 
 
 
 
159
 
160
- if(!is_null($tr_id)){
161
- $translated_term = $this->woocommerce_wpml->terms->wcml_get_term_by_id( $tr_id, $key);
162
- $items[$index][$key] = $translated_term->slug;
163
- }
164
- }
 
 
 
 
 
165
 
166
- if( $key == 'type' && $item_data == 'shipping' && isset( $item[ 'method_id' ] ) ){
 
 
 
 
 
 
 
 
 
 
 
 
167
 
168
- $items[ $index ][ 'name' ] = $this->woocommerce_wpml->shipping->translate_shipping_method_title( $item[ 'name' ], $item[ 'method_id' ], $language_to_filter );
 
 
 
 
 
 
 
 
 
 
 
 
 
169
 
170
- }
171
- }
172
- }else{
173
- // WC >= 2.7
174
- if( $item instanceof WC_Order_Item_Product ){
175
- if( $item->get_type() == 'line_item' ){
176
- $item_product_id = $item->get_product_id();
177
- if( get_post_type( $item_product_id ) == 'product_variation' ){
178
- $item_product_id = wp_get_post_parent_id( $item_product_id );
179
- }
180
-
181
- $tr_product_id = apply_filters( 'translate_object_id', $item_product_id, 'product', false, $language_to_filter );
182
-
183
- if( !is_null( $tr_product_id ) ){
184
- $item->set_product_id( $tr_product_id );
185
- $item->set_name( get_post( $tr_product_id )->post_title );
186
- }
187
-
188
- $tr_variation_id = apply_filters( 'translate_object_id', $item->get_variation_id(), 'product_variation', false, $language_to_filter );
189
- if ( ! is_null( $tr_variation_id ) ) {
190
- $item->set_variation_id( $tr_variation_id );
191
- $item->set_name( wc_get_product( $tr_variation_id )->get_name() );
192
- }
193
- }
194
- }elseif( $item instanceof WC_Order_Item_Shipping ){
195
- if( $item->get_method_id() ){
196
-
197
- $shipping_id = $item->get_method_id();
198
- if( method_exists( $item ,'get_instance_id' ) ){
199
- $shipping_id .= $item->get_instance_id();
200
- }
201
-
202
- $item->set_method_title(
203
- $this->woocommerce_wpml->shipping->translate_shipping_method_title(
204
- $item->get_method_title(),
205
- $shipping_id,
206
- $language_to_filter
207
- )
208
- );
209
- }
210
- }
211
- }
212
- }
213
 
214
- return $items;
 
215
 
216
- }
217
 
218
- private function is_order_saving_action(){
219
- return isset( $_POST['post_type'] ) && $_POST['post_type'] === 'shop_order' && isset( $_POST['wc_order_action'] );
220
- }
221
 
222
- public function backend_before_order_itemmeta( $item_id, $item, $product ){
223
- global $sitepress;
 
224
 
225
- if( $this->get_order_language_by_item_id( $item_id ) != $sitepress->get_user_admin_language( get_current_user_id(), true ) ){
226
- foreach( $item[ 'item_meta' ] as $key => $item_meta ){
227
- if ( taxonomy_exists( wc_attribute_taxonomy_name( $key ) ) || substr( $key, 0, 3 ) == 'pa_' ) {
228
- //backward compatibility for WC < 2.7 - in WC 2.7 $item_meta is a single attribute value not an array
229
- if( !is_array( $item_meta ) ){
230
- $item_meta = array( $item_meta );
231
- }
232
 
233
- foreach( $item_meta as $value ){
234
- $this->force_update_itemmeta( $item_id, $key, $value, $sitepress->get_user_admin_language( get_current_user_id(), true ) );
235
- }
236
- }
237
- }
238
- }
239
- }
240
-
241
- public function backend_after_order_itemmeta( $item_id, $item, $product ){
242
- global $sitepress;
243
-
244
- $order_languge = $this->get_order_language_by_item_id( $item_id );
245
- if( $order_languge != $sitepress->get_user_admin_language( get_current_user_id(), true ) ){
246
- foreach( $item[ 'item_meta' ] as $key => $item_meta ){
247
- if ( taxonomy_exists( wc_attribute_taxonomy_name( $key ) ) || substr( $key, 0, 3 ) == 'pa_' ) {
248
- //backward compatibility for WC < 2.7 - in WC 2.7 $item_meta is a single attribute value not an array
249
- if( !is_array( $item_meta ) ){
250
- $item_meta = array( $item_meta );
251
- }
252
 
253
- foreach( $item_meta as $value ){
254
- $this->force_update_itemmeta( $item_id, $key, $value, $order_languge );
255
- }
256
- }
257
- }
258
- }
259
- }
260
-
261
- public function get_order_language_by_item_id( $item_id ){
262
- global $wpdb;
263
-
264
- $order_id = $wpdb->get_var( $wpdb->prepare( "SELECT order_id FROM {$wpdb->prefix}woocommerce_order_items WHERE order_item_id = %d", $item_id ) );
265
-
266
- return get_post_meta( $order_id, 'wpml_language', true );
267
- }
268
-
269
- //force update to display attribute in correct language on edit order page
270
- public function force_update_itemmeta( $item_id, $key, $value, $languge ){
271
- global $wpdb, $woocommerce_wpml;
272
-
273
- $taxonomy = substr( $key, 0, 3 ) != 'pa_' ? wc_attribute_taxonomy_name( $key ) : $key;
274
- $term_id = $woocommerce_wpml->terms->wcml_get_term_id_by_slug( $taxonomy, $value );
275
- $translated_term = $woocommerce_wpml->terms->wcml_get_translated_term( $term_id, $taxonomy, $languge );
276
-
277
- if( $translated_term ){
278
- $value = $translated_term->slug;
279
- $wpdb->update( $wpdb->prefix.'woocommerce_order_itemmeta', array( 'meta_value' => $value ), array( 'order_item_id' => $item_id, 'meta_key' => $key ) );
280
- }
281
- }
282
-
283
- /**
284
- * Adds language to order post type.
285
- *
286
- * @param type $order_id
287
- */
288
  function set_order_language( $order_id ) {
289
  if ( ! get_post_meta( $order_id, 'wpml_language' ) ) {
290
  update_post_meta( $order_id, 'wpml_language', ICL_LANGUAGE_CODE );
291
  }
292
  }
293
 
294
- function append_query_parameters($parameters){
295
 
296
- if(is_order_received_page() || is_checkout()){
297
- if(!in_array('order', $parameters)) $parameters[] = 'order';
298
- if(!in_array('key', $parameters)) $parameters[] = 'key';
299
- }
 
 
 
 
300
 
301
- return $parameters;
302
- }
303
 
304
- function switch_to_current(){
305
- $this->woocommerce_wpml->emails->change_email_language($this->sitepress->get_current_language());
306
- }
307
 
308
- function order_language_dropdown( $order_id ){
309
- if( !get_post_meta( $order_id, '_order_currency') ) {
310
- $languages = apply_filters( 'wpml_active_languages', array(), array( 'skip_missing' => 0, 'orderby' => 'code' ) );
311
- $selected_lang = isset( $_COOKIE [ self::DASHBOARD_COOKIE_NAME ] ) ? $_COOKIE [ self::DASHBOARD_COOKIE_NAME ] : $this->sitepress->get_default_language();
312
- ?>
 
 
 
313
  <li class="wide">
314
- <label><?php _e('Order language:'); ?></label>
315
  <select id="dropdown_shop_order_language" name="wcml_shop_order_language">
316
- <?php if (!empty($languages)): ?>
317
 
318
- <?php foreach ($languages as $l): ?>
319
 
320
  <option
321
- value="<?php echo $l['language_code'] ?>" <?php echo $selected_lang == $l['language_code'] ? 'selected="selected"' : ''; ?>><?php echo $l['translated_name']; ?></option>
322
 
323
- <?php endforeach; ?>
324
 
325
- <?php endif; ?>
326
  </select>
327
  </li>
328
- <?php
329
- $wcml_set_dashboard_order_language_nonce = wp_create_nonce( 'set_dashboard_order_language' );
330
- wc_enqueue_js( "
331
  var order_lang_current_value = jQuery('#dropdown_shop_order_language option:selected').val();
332
 
333
  jQuery('#dropdown_shop_order_language').on('change', function(){
334
- if(confirm('" . esc_js(__("All the products will be removed from the current order in order to change the language", 'woocommerce-multilingual')). "')){
335
  var lang = jQuery(this).val();
336
 
337
  jQuery.ajax({
338
  url: ajaxurl,
339
  type: 'post',
340
  dataType: 'json',
341
- data: {action: 'wcml_order_delete_items', order_id: woocommerce_admin_meta_boxes.post_id, lang: lang , wcml_nonce: '".$wcml_set_dashboard_order_language_nonce."' },
342
  success: function( response ){
343
  if(typeof response.error !== 'undefined'){
344
  alert(response.error);
@@ -353,76 +383,66 @@ class WCML_Orders {
353
  }
354
  });
355
 
356
- ");
357
- }else{
358
- $this->remove_dashboard_order_language_cookie();
359
- }
360
- }
361
 
362
- function order_delete_items(){
363
- $nonce = filter_input( INPUT_POST, 'wcml_nonce', FILTER_SANITIZE_FULL_SPECIAL_CHARS );
364
- if(!$nonce || !wp_verify_nonce($nonce, 'set_dashboard_order_language')){
365
- echo json_encode(array('error' => __('Invalid nonce', 'woocommerce-multilingual')));
366
- die();
367
- }
368
 
369
  setcookie( self::DASHBOARD_COOKIE_NAME, filter_input( INPUT_POST, 'lang', FILTER_SANITIZE_FULL_SPECIAL_CHARS ), time() + self::COOKIE_TTL, COOKIEPATH, COOKIE_DOMAIN );
370
- }
371
-
372
- private function remove_dashboard_order_language_cookie(){
373
- setcookie( self::DASHBOARD_COOKIE_NAME, '', time() - self::COOKIE_TTL, COOKIEPATH, COOKIE_DOMAIN );
374
- }
375
-
376
- function set_order_language_backend( $post_id, $post ){
377
-
378
- if( isset( $_POST['wcml_shop_order_language'] ) ){
379
- update_post_meta( $post_id, 'wpml_language', filter_input( INPUT_POST, 'wcml_shop_order_language', FILTER_SANITIZE_FULL_SPECIAL_CHARS ) );
380
- }
381
-
382
- }
383
-
384
- function update_order_currency( $meta_id, $object_id, $meta_key, $meta_value ){
385
 
386
- if( $this->woocommerce_wpml->settings['enable_multi_currency'] == WCML_MULTI_CURRENCIES_INDEPENDENT && get_post_type($object_id) == 'shop_order' && isset( $_GET['wc-ajax'] ) && $_GET['wc-ajax'] == 'checkout' ){
387
- update_post_meta( $object_id, '_order_currency', wcml_get_woocommerce_currency_option() );
388
- }
389
 
390
- }
391
 
 
 
 
392
 
393
- public function filter_downloadable_product_items( $files, $item, $object ){
394
 
395
- $order_language = get_post_meta( $object->get_id(), 'wpml_language', true );
396
 
397
- if( $item->get_variation_id() > 0 ){
398
- $item->set_variation_id( apply_filters( 'translate_object_id', $item->get_variation_id(), 'product_variation', false, $order_language ) );
399
- }else{
400
- $item->set_product_id( apply_filters( 'translate_object_id', $item->get_product_id(), 'product', false, $order_language ) );
401
- }
402
 
403
- remove_filter( 'woocommerce_get_item_downloads', array( $this, 'filter_downloadable_product_items' ), 10, 3 );
 
 
 
 
404
 
405
- $files = $item->get_item_downloads();
406
 
407
- add_filter( 'woocommerce_get_item_downloads', array( $this, 'filter_downloadable_product_items' ), 10, 3 );
408
 
409
- return $files;
410
- }
411
 
412
- public function filter_customer_get_downloadable_products( $downloads ){
 
413
 
414
- foreach( $downloads as $key => $download ){
415
 
416
- $translated_id = apply_filters( 'translate_object_id', $download['product_id'], get_post_type( $download['product_id'] ), false, $this->sitepress->get_current_language() );
417
 
418
- if( $translated_id ){
419
- $downloads[ $key ][ 'product_name' ] = get_the_title( $translated_id );
420
- }
421
 
422
- }
 
 
423
 
424
- return $downloads;
425
- }
426
 
 
 
427
 
428
  }
2
 
3
  class WCML_Orders {
4
 
5
+ const DASHBOARD_COOKIE_NAME = '_wcml_dashboard_order_language';
6
+ const COOKIE_TTL = 86400;
7
+
8
+ private $woocommerce_wpml;
9
+ private $sitepress;
10
+
11
+ private $standard_order_notes = array(
12
+ 'Order status changed from %s to %s.',
13
+ 'Order item stock reduced successfully.',
14
+ 'Item #%s stock reduced from %s to %s.',
15
+ 'Item #%s stock increased from %s to %s.',
16
+ 'Awaiting BACS payment',
17
+ 'Awaiting cheque payment',
18
+ 'Payment to be made upon delivery.',
19
+ 'Validation error: PayPal amounts do not match (gross %s).',
20
+ 'Validation error: PayPal IPN response from a different email address (%s).',
21
+ 'Payment pending: %s',
22
+ 'Payment %s via IPN.',
23
+ 'Validation error: PayPal amounts do not match (amt %s).',
24
+ 'IPN payment completed',
25
+ 'PDT payment completed'
26
+ );
27
+
28
+ public function __construct( $woocommerce_wpml, $sitepress ) {
29
+ $this->woocommerce_wpml = $woocommerce_wpml;
30
+ $this->sitepress = $sitepress;
31
+
32
+ add_action( 'init', array( $this, 'init' ) );
33
+
34
+ //checkout page
35
+ add_action( 'wp_ajax_woocommerce_checkout', array( $this, 'switch_to_current' ), 9 );
36
+ add_action( 'wp_ajax_nopriv_woocommerce_checkout', array( $this, 'switch_to_current' ), 9 );
37
+
38
+ add_action( 'wp_ajax_wcml_order_delete_items', array( $this, 'order_delete_items' ) );
39
+ }
40
 
41
+ function init() {
 
 
 
 
 
 
 
 
 
 
 
 
 
42
 
43
+ add_action( 'woocommerce_checkout_update_order_meta', array( $this, 'set_order_language' ) );
 
 
44
 
45
+ add_filter( 'icl_lang_sel_copy_parameters', array( $this, 'append_query_parameters' ) );
46
 
47
+ add_filter( 'the_comments', array( $this, 'get_filtered_comments' ) );
 
 
48
 
49
+ if ( $this->should_attach_new_order_note_data_filter() ) {
50
+ add_filter( 'gettext', array( $this, 'filtered_woocommerce_new_order_note_data' ), 10, 3 );
51
+ }
52
 
53
+ add_filter( 'woocommerce_order_get_items', array( $this, 'woocommerce_order_get_items' ), 10, 2 );
54
 
55
+ add_action( 'woocommerce_process_shop_order_meta', array( $this, 'set_order_language_backend' ), 10, 2 );
56
+ add_action( 'woocommerce_order_actions_start', array(
57
+ $this,
58
+ 'order_language_dropdown'
59
+ ), 11 ); //after order currency drop-down
60
 
61
+ add_action( 'woocommerce_before_order_itemmeta', array( $this, 'backend_before_order_itemmeta' ), 100, 3 );
62
+ add_action( 'woocommerce_after_order_itemmeta', array( $this, 'backend_after_order_itemmeta' ), 100, 3 );
63
 
64
+ add_filter( 'woocommerce_get_item_downloads', array( $this, 'filter_downloadable_product_items' ), 10, 3 );
65
+ add_filter( 'woocommerce_customer_get_downloadable_products', array(
66
+ $this,
67
+ 'filter_customer_get_downloadable_products'
68
+ ), 10, 3 );
69
+ }
70
 
71
+ public function should_attach_new_order_note_data_filter() {
72
+ $admin_language = $this->sitepress->get_user_admin_language( get_current_user_id(), true );
73
+ $all_strings_in_english = get_option( 'wpml-st-all-strings-are-in-english' );
74
 
75
+ return 'en' !== $admin_language || ! $all_strings_in_english;
76
+ }
77
 
78
+ function filtered_woocommerce_new_order_note_data( $translations, $text, $domain ) {
79
+ if ( in_array( $text, $this->standard_order_notes ) ) {
80
 
81
+ $language = $this->woocommerce_wpml->strings->get_string_language( $text, 'woocommerce' );
 
82
 
83
+ if ( $this->sitepress->get_user_admin_language( get_current_user_id(), true ) != $language ) {
 
84
 
85
+ $string_id = icl_get_string_id( $text, 'woocommerce' );
86
+ $strings = icl_get_string_translations_by_id( $string_id );
87
+ if ( $strings ) {
88
+ $translations = $strings[ $this->sitepress->get_user_admin_language( get_current_user_id(), true ) ]['value'];
89
+ }
90
 
91
+ } else {
92
+ return $text;
93
+ }
94
+ }
95
 
96
+ return $translations;
97
+ }
98
 
99
+ function get_filtered_comments( $comments ) {
 
100
 
101
+ $user_id = get_current_user_id();
102
 
103
+ if ( $user_id ) {
104
+ $user_language = get_user_meta( $user_id, 'icl_admin_language', true );
105
 
106
+ foreach ( $comments as $key => $comment ) {
107
+ $comment_string_id = icl_get_string_id( $comment->comment_content, 'woocommerce' );
 
 
 
108
 
109
+ if ( $comment_string_id ) {
110
+ $comment_strings = icl_get_string_translations_by_id( $comment_string_id );
 
 
111
 
112
+ if ( $comment_strings && isset( $comment_strings[ $user_language ] ) ) {
113
+ $comments[ $key ]->comment_content = $comment_strings[ $user_language ]['value'];
114
+ }
115
+ }
116
+ }
117
 
118
+ }
119
 
120
+ return $comments;
121
+ }
122
 
123
+ public function woocommerce_order_get_items( $items, $order ) {
124
+
125
+ if ( $items ) {
126
+
127
+ $language_to_filter = $this->get_order_items_language_to_filter( $order );
128
+
129
+ foreach ( $items as $index => $item ) {
130
+ if ( $item instanceof WC_Order_Item_Product ) {
131
+ if ( 'line_item' === $item->get_type() ) {
132
+ $this->adjust_product_item_if_translated( $item, $language_to_filter );
133
+ $this->adjust_variation_item_if_translated( $item, $language_to_filter );
134
+ }
135
+ } elseif ( $item instanceof WC_Order_Item_Shipping ) {
136
+ $shipping_id = $item->get_method_id();
137
+ if ( $shipping_id ) {
138
+
139
+ if ( method_exists( $item, 'get_instance_id' ) ) {
140
+ $shipping_id .= $item->get_instance_id();
141
+ }
142
+
143
+ $item->set_method_title(
144
+ $this->woocommerce_wpml->shipping->translate_shipping_method_title(
145
+ $item->get_method_title(),
146
+ $shipping_id,
147
+ $language_to_filter
148
+ )
149
+ );
150
+ }
151
+ }
152
+ $item->save();
153
+ }
154
+ }
155
 
156
+ return $items;
157
+ }
158
 
159
+ /**
160
+ * @param WC_Order_Item_Product $item
161
+ * @param string $language_to_filter
162
+ */
163
+ private function adjust_product_item_if_translated( $item, $language_to_filter ) {
164
 
165
+ $translated_product_id = apply_filters( 'translate_object_id', $this->get_item_product_id( $item ), 'product', false, $language_to_filter );
166
+ if ( ! is_null( $translated_product_id ) ) {
167
+ $item->set_product_id( $translated_product_id );
168
+ $item->set_name( get_post( $translated_product_id )->post_title );
169
+ }
170
+ }
171
 
172
+ /**
173
+ * @param WC_Order_Item_Product $item
174
+ *
175
+ * @return false|int
176
+ */
177
+ private function get_item_product_id( $item ) {
178
+ $item_product_id = $item->get_product_id();
179
+ if ( 'product_variation' === get_post_type( $item_product_id ) ) {
180
+ $item_product_id = wp_get_post_parent_id( $item_product_id );
181
+ }
182
 
183
+ return $item_product_id;
184
+ }
185
 
186
+ /**
187
+ * @param WC_Order_Item_Product $item
188
+ * @param string $language_to_filter
189
+ */
190
+ private function adjust_variation_item_if_translated( $item, $language_to_filter ) {
191
+ $translated_variation_id = apply_filters( 'translate_object_id', $item->get_variation_id(), 'product_variation', false, $language_to_filter );
192
+ if ( ! is_null( $translated_variation_id ) ) {
193
+ $item->set_variation_id( $translated_variation_id );
194
+ $item->set_name( wc_get_product( $translated_variation_id )->get_name() );
195
+ $this->update_attribute_item_meta_value( $item, $translated_variation_id );
196
+ }
197
+ }
198
 
199
+ /**
200
+ * @param WC_Order $order
201
+ *
202
+ * @return string
203
+ */
204
+ private function get_order_items_language_to_filter( $order ) {
205
+ if ( $this->is_on_order_edit_page() ) {
206
+ return $this->sitepress->get_user_admin_language( get_current_user_id(), true );
207
+ }
208
 
209
+ if ( $this->is_order_action_triggered_for_customer() ) {
210
+ $order_language = get_post_meta( $order->get_id(), 'wpml_language', true );
 
 
 
 
 
 
 
 
 
211
 
212
+ return $order_language ? $order_language : $this->sitepress->get_default_language();
213
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
214
 
215
+ return $this->sitepress->get_current_language();
216
+ }
217
 
218
+ /**
219
+ * @return bool
220
+ */
221
+ private function is_on_order_edit_page() {
222
+ return isset( $_GET['post'] ) && 'shop_order' === get_post_type( $_GET['post'] );
223
+ }
224
 
225
+ /**
226
+ * @return bool
227
+ */
228
+ private function is_order_action_triggered_for_customer() {
229
+ return isset( $_GET['action'] ) && wpml_collect( [
230
+ 'woocommerce_mark_order_complete',
231
+ 'woocommerce_mark_order_status',
232
+ 'mark_processing'
233
+ ] )->contains( $_GET['action'] );
234
+ }
235
 
236
+ /**
237
+ * @param WC_Order_Item_Product $item
238
+ * @param int $variation_id
239
+ */
240
+ private function update_attribute_item_meta_value( $item, $variation_id ) {
241
+ foreach ( $item->get_meta_data() as $meta_data ) {
242
+ $data = $meta_data->get_data();
243
+ $attribute_value = get_post_meta( $variation_id, 'attribute_' . $data['key'], true );
244
+ if ( $attribute_value ) {
245
+ $item->update_meta_data( $data['key'], $attribute_value, $data['id'] );
246
+ }
247
+ }
248
+ }
249
 
250
+ public function backend_before_order_itemmeta( $item_id, $item, $product ) {
251
+ global $sitepress;
252
+
253
+ if ( $this->get_order_language_by_item_id( $item_id ) != $sitepress->get_user_admin_language( get_current_user_id(), true ) ) {
254
+ foreach ( $item['item_meta'] as $key => $item_meta ) {
255
+ if ( taxonomy_exists( wc_attribute_taxonomy_name( $key ) ) || substr( $key, 0, 3 ) == 'pa_' ) {
256
+ $item_meta = (array) $item_meta;
257
+ foreach ( $item_meta as $value ) {
258
+ $this->force_update_itemmeta( $item_id, $key, $value, $sitepress->get_user_admin_language( get_current_user_id(), true ) );
259
+ }
260
+ }
261
+ }
262
+ }
263
+ }
264
 
265
+ public function backend_after_order_itemmeta( $item_id, $item, $product ) {
266
+ global $sitepress;
267
+
268
+ $order_languge = $this->get_order_language_by_item_id( $item_id );
269
+ if ( $order_languge != $sitepress->get_user_admin_language( get_current_user_id(), true ) ) {
270
+ foreach ( $item['item_meta'] as $key => $item_meta ) {
271
+ if ( taxonomy_exists( wc_attribute_taxonomy_name( $key ) ) || substr( $key, 0, 3 ) == 'pa_' ) {
272
+ $item_meta = (array) $item_meta;
273
+ foreach ( $item_meta as $value ) {
274
+ $this->force_update_itemmeta( $item_id, $key, $value, $order_languge );
275
+ }
276
+ }
277
+ }
278
+ }
279
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
280
 
281
+ public function get_order_language_by_item_id( $item_id ) {
282
+ global $wpdb;
283
 
284
+ $order_id = $wpdb->get_var( $wpdb->prepare( "SELECT order_id FROM {$wpdb->prefix}woocommerce_order_items WHERE order_item_id = %d", $item_id ) );
285
 
286
+ return get_post_meta( $order_id, 'wpml_language', true );
287
+ }
 
288
 
289
+ //force update to display attribute in correct language on edit order page
290
+ public function force_update_itemmeta( $item_id, $key, $value, $languge ) {
291
+ global $wpdb, $woocommerce_wpml;
292
 
293
+ $taxonomy = substr( $key, 0, 3 ) != 'pa_' ? wc_attribute_taxonomy_name( $key ) : $key;
294
+ $term_id = $woocommerce_wpml->terms->wcml_get_term_id_by_slug( $taxonomy, $value );
295
+ $translated_term = $woocommerce_wpml->terms->wcml_get_translated_term( $term_id, $taxonomy, $languge );
 
 
 
 
296
 
297
+ if ( $translated_term ) {
298
+ $value = $translated_term->slug;
299
+ $wpdb->update( $wpdb->prefix . 'woocommerce_order_itemmeta', array( 'meta_value' => $value ), array(
300
+ 'order_item_id' => $item_id,
301
+ 'meta_key' => $key
302
+ ) );
303
+ }
304
+ }
 
 
 
 
 
 
 
 
 
 
 
305
 
306
+ /**
307
+ * Adds language to order post type.
308
+ *
309
+ * @param type $order_id
310
+ */
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
311
  function set_order_language( $order_id ) {
312
  if ( ! get_post_meta( $order_id, 'wpml_language' ) ) {
313
  update_post_meta( $order_id, 'wpml_language', ICL_LANGUAGE_CODE );
314
  }
315
  }
316
 
317
+ function append_query_parameters( $parameters ) {
318
 
319
+ if ( is_order_received_page() || is_checkout() ) {
320
+ if ( ! in_array( 'order', $parameters ) ) {
321
+ $parameters[] = 'order';
322
+ }
323
+ if ( ! in_array( 'key', $parameters ) ) {
324
+ $parameters[] = 'key';
325
+ }
326
+ }
327
 
328
+ return $parameters;
329
+ }
330
 
331
+ function switch_to_current() {
332
+ $this->woocommerce_wpml->emails->change_email_language( $this->sitepress->get_current_language() );
333
+ }
334
 
335
+ function order_language_dropdown( $order_id ) {
336
+ if ( ! get_post_meta( $order_id, '_order_currency' ) ) {
337
+ $languages = apply_filters( 'wpml_active_languages', array(), array(
338
+ 'skip_missing' => 0,
339
+ 'orderby' => 'code'
340
+ ) );
341
+ $selected_lang = isset( $_COOKIE [ self::DASHBOARD_COOKIE_NAME ] ) ? $_COOKIE [ self::DASHBOARD_COOKIE_NAME ] : $this->sitepress->get_default_language();
342
+ ?>
343
  <li class="wide">
344
+ <label><?php _e( 'Order language:' ); ?></label>
345
  <select id="dropdown_shop_order_language" name="wcml_shop_order_language">
346
+ <?php if ( ! empty( $languages ) ): ?>
347
 
348
+ <?php foreach ( $languages as $l ): ?>
349
 
350
  <option
351
+ value="<?php echo $l['language_code'] ?>" <?php echo $selected_lang == $l['language_code'] ? 'selected="selected"' : ''; ?>><?php echo $l['translated_name']; ?></option>
352
 
353
+ <?php endforeach; ?>
354
 
355
+ <?php endif; ?>
356
  </select>
357
  </li>
358
+ <?php
359
+ $wcml_set_dashboard_order_language_nonce = wp_create_nonce( 'set_dashboard_order_language' );
360
+ wc_enqueue_js( "
361
  var order_lang_current_value = jQuery('#dropdown_shop_order_language option:selected').val();
362
 
363
  jQuery('#dropdown_shop_order_language').on('change', function(){
364
+ if(confirm('" . esc_js( __( "All the products will be removed from the current order in order to change the language", 'woocommerce-multilingual' ) ) . "')){
365
  var lang = jQuery(this).val();
366
 
367
  jQuery.ajax({
368
  url: ajaxurl,
369
  type: 'post',
370
  dataType: 'json',
371
+ data: {action: 'wcml_order_delete_items', order_id: woocommerce_admin_meta_boxes.post_id, lang: lang , wcml_nonce: '" . $wcml_set_dashboard_order_language_nonce . "' },
372
  success: function( response ){
373
  if(typeof response.error !== 'undefined'){
374
  alert(response.error);
383
  }
384
  });
385
 
386
+ " );
387
+ } else {
388
+ $this->remove_dashboard_order_language_cookie();
389
+ }
390
+ }
391
 
392
+ function order_delete_items() {
393
+ $nonce = filter_input( INPUT_POST, 'wcml_nonce', FILTER_SANITIZE_FULL_SPECIAL_CHARS );
394
+ if ( ! $nonce || ! wp_verify_nonce( $nonce, 'set_dashboard_order_language' ) ) {
395
+ echo json_encode( array( 'error' => __( 'Invalid nonce', 'woocommerce-multilingual' ) ) );
396
+ die();
397
+ }
398
 
399
  setcookie( self::DASHBOARD_COOKIE_NAME, filter_input( INPUT_POST, 'lang', FILTER_SANITIZE_FULL_SPECIAL_CHARS ), time() + self::COOKIE_TTL, COOKIEPATH, COOKIE_DOMAIN );
400
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
401
 
402
+ private function remove_dashboard_order_language_cookie() {
403
+ setcookie( self::DASHBOARD_COOKIE_NAME, '', time() - self::COOKIE_TTL, COOKIEPATH, COOKIE_DOMAIN );
404
+ }
405
 
406
+ function set_order_language_backend( $post_id, $post ) {
407
 
408
+ if ( isset( $_POST['wcml_shop_order_language'] ) ) {
409
+ update_post_meta( $post_id, 'wpml_language', filter_input( INPUT_POST, 'wcml_shop_order_language', FILTER_SANITIZE_FULL_SPECIAL_CHARS ) );
410
+ }
411
 
412
+ }
413
 
414
+ public function filter_downloadable_product_items( $files, $item, $object ) {
415
 
416
+ $order_language = get_post_meta( $object->get_id(), 'wpml_language', true );
 
 
 
 
417
 
418
+ if ( $item->get_variation_id() > 0 ) {
419
+ $item->set_variation_id( apply_filters( 'translate_object_id', $item->get_variation_id(), 'product_variation', false, $order_language ) );
420
+ } else {
421
+ $item->set_product_id( apply_filters( 'translate_object_id', $item->get_product_id(), 'product', false, $order_language ) );
422
+ }
423
 
424
+ remove_filter( 'woocommerce_get_item_downloads', array( $this, 'filter_downloadable_product_items' ), 10, 3 );
425
 
426
+ $files = $item->get_item_downloads();
427
 
428
+ add_filter( 'woocommerce_get_item_downloads', array( $this, 'filter_downloadable_product_items' ), 10, 3 );
 
429
 
430
+ return $files;
431
+ }
432
 
433
+ public function filter_customer_get_downloadable_products( $downloads ) {
434
 
435
+ foreach ( $downloads as $key => $download ) {
436
 
437
+ $translated_id = apply_filters( 'translate_object_id', $download['product_id'], get_post_type( $download['product_id'] ), false, $this->sitepress->get_current_language() );
 
 
438
 
439
+ if ( $translated_id ) {
440
+ $downloads[ $key ]['product_name'] = get_the_title( $translated_id );
441
+ }
442
 
443
+ }
 
444
 
445
+ return $downloads;
446
+ }
447
 
448
  }
inc/class-wcml-resources.php CHANGED
@@ -97,7 +97,7 @@ class WCML_Resources {
97
  self::load_taxonomy_translation_scripts();
98
 
99
  wp_register_script( 'jquery-cookie', WCML_PLUGIN_URL . '/res/js/jquery.cookie' . WCML_JS_MIN . '.js', array( 'jquery' ), WCML_VERSION, true );
100
- wp_register_script( 'wcml-dialogs', WCML_PLUGIN_URL . '/res/js/dialogs' . WCML_JS_MIN . '.js', array( 'jquery', 'jquery-ui-core', 'jquery-ui-dialog' ), WCML_VERSION, true );
101
  wp_register_script( 'wcml-troubleshooting', WCML_PLUGIN_URL . '/res/js/troubleshooting' . WCML_JS_MIN . '.js', array( 'jquery' ), WCML_VERSION, true );
102
 
103
  if( self::$woocommerce_wpml->is_wpml_prior_4_2() ){
97
  self::load_taxonomy_translation_scripts();
98
 
99
  wp_register_script( 'jquery-cookie', WCML_PLUGIN_URL . '/res/js/jquery.cookie' . WCML_JS_MIN . '.js', array( 'jquery' ), WCML_VERSION, true );
100
+ wp_register_script( 'wcml-dialogs', WCML_PLUGIN_URL . '/res/js/dialogs' . WCML_JS_MIN . '.js', array( 'jquery', 'jquery-ui-core', 'jquery-ui-dialog', 'underscore' ), WCML_VERSION, true );
101
  wp_register_script( 'wcml-troubleshooting', WCML_PLUGIN_URL . '/res/js/troubleshooting' . WCML_JS_MIN . '.js', array( 'jquery' ), WCML_VERSION, true );
102
 
103
  if( self::$woocommerce_wpml->is_wpml_prior_4_2() ){
inc/class-wcml-troubleshooting.php CHANGED
@@ -27,6 +27,7 @@ class WCML_Troubleshooting{
27
  add_action('wp_ajax_trbl_fix_product_type_terms', array($this,'trbl_fix_product_type_terms'));
28
  add_action( 'wp_ajax_trbl_sync_stock', array( $this, 'trbl_sync_stock' ) );
29
  add_action( 'wp_ajax_fix_translated_variations_relationships', array( $this, 'fix_translated_variations_relationships' ) );
 
30
  }
31
 
32
  function wcml_count_products_with_variations(){
@@ -262,9 +263,9 @@ class WCML_Troubleshooting{
262
  wp_send_json_success();
263
  }
264
 
265
- function wcml_count_product_stock_sync(){
266
 
267
- $results = $this->get_products_needs_stock_sync();
268
 
269
  return count( $results );
270
  }
@@ -276,7 +277,7 @@ class WCML_Troubleshooting{
276
  wp_send_json_error('Invalid nonce');
277
  }
278
 
279
- $results = $this->get_products_needs_stock_sync();
280
 
281
  foreach( $results as $product ){
282
 
@@ -307,7 +308,7 @@ class WCML_Troubleshooting{
307
  wp_send_json_success();
308
  }
309
 
310
- function get_products_needs_stock_sync(){
311
 
312
  $results = $this->wpdb->get_results("
313
  SELECT p.ID, t.trid, t.element_type
@@ -337,12 +338,6 @@ class WCML_Troubleshooting{
337
  }
338
 
339
  foreach ( array_slice( $translated_variations, 0, self::ITEMS_PER_AJAX, true ) as $key => $translated_variation ) {
340
- //delete broken variations
341
- if ( ! get_post_meta( $translated_variation->post_id, '_stock', true ) ) {
342
- wp_delete_post( $translated_variation->post_id );
343
- continue;
344
- }
345
-
346
  //check relationships
347
  $tr_info_for_original_variation = $this->get_translation_info_for_element( $translated_variation->meta_value, 'post_product_variation' );
348
 
@@ -419,4 +414,51 @@ class WCML_Troubleshooting{
419
  return count( $results );
420
  }
421
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
422
  }
27
  add_action('wp_ajax_trbl_fix_product_type_terms', array($this,'trbl_fix_product_type_terms'));
28
  add_action( 'wp_ajax_trbl_sync_stock', array( $this, 'trbl_sync_stock' ) );
29
  add_action( 'wp_ajax_fix_translated_variations_relationships', array( $this, 'fix_translated_variations_relationships' ) );
30
+ add_action( 'wp_ajax_sync_deleted_meta', array( $this, 'sync_deleted_meta' ) );
31
  }
32
 
33
  function wcml_count_products_with_variations(){
263
  wp_send_json_success();
264
  }
265
 
266
+ function wcml_count_products_and_variations(){
267
 
268
+ $results = $this->get_original_products_and_variations();
269
 
270
  return count( $results );
271
  }
277
  wp_send_json_error('Invalid nonce');
278
  }
279
 
280
+ $results = $this->get_original_products_and_variations();
281
 
282
  foreach( $results as $product ){
283
 
308
  wp_send_json_success();
309
  }
310
 
311
+ function get_original_products_and_variations(){
312
 
313
  $results = $this->wpdb->get_results("
314
  SELECT p.ID, t.trid, t.element_type
338
  }
339
 
340
  foreach ( array_slice( $translated_variations, 0, self::ITEMS_PER_AJAX, true ) as $key => $translated_variation ) {
 
 
 
 
 
 
341
  //check relationships
342
  $tr_info_for_original_variation = $this->get_translation_info_for_element( $translated_variation->meta_value, 'post_product_variation' );
343
 
414
  return count( $results );
415
  }
416
 
417
+
418
+ public function sync_deleted_meta(){
419
+
420
+ $nonce = array_key_exists( 'wcml_nonce', $_POST ) ? sanitize_text_field( $_POST['wcml_nonce'] ) : false;
421
+ if ( ! $nonce || ! wp_verify_nonce( $nonce, 'sync_deleted_meta' ) ) {
422
+ wp_send_json_error( 'Invalid nonce' );
423
+ }
424
+
425
+ if ( ! current_user_can( 'manage_options' ) ) {
426
+ wp_send_json_error( 'Access error' );
427
+ }
428
+
429
+ $products_needs_fix_postmeta = get_option( 'wcml_trbl_products_needs_fix_postmeta' );
430
+
431
+ if( !$products_needs_fix_postmeta ){
432
+ $products_needs_fix_postmeta = $this->get_original_products_and_variations();
433
+ }
434
+
435
+ $iclTranslationManagement = wpml_load_core_tm();
436
+ $settings_factory = new WPML_Custom_Field_Setting_Factory( $iclTranslationManagement );
437
+
438
+ foreach ( array_slice( $products_needs_fix_postmeta, 0, self::ITEMS_PER_AJAX, true ) as $key => $product ) {
439
+
440
+ $translations = $this->sitepress->get_element_translations( $product->trid, $product->element_type );
441
+
442
+ foreach ( $translations as $translation ){
443
+ if( !$translation->original ){
444
+ $all_post_meta_keys = $this->wpdb->get_col( $this->wpdb->prepare( "SELECT meta_key FROM {$this->wpdb->postmeta} WHERE post_id = %d", $translation->element_id ) );
445
+ foreach( $all_post_meta_keys as $meta_key ){
446
+ $setting = $settings_factory->post_meta_setting( $meta_key );
447
+ if ( WPML_COPY_CUSTOM_FIELD === $setting->status() ) {
448
+ if( !metadata_exists('post', $product->ID, $meta_key) ){
449
+ delete_post_meta( $translation->element_id, $meta_key );
450
+ }
451
+ }
452
+ }
453
+ }
454
+ }
455
+
456
+ unset( $products_needs_fix_postmeta[ $key ] );
457
+ }
458
+
459
+ update_option( 'wcml_trbl_products_needs_fix_postmeta', $products_needs_fix_postmeta );
460
+
461
+ wp_send_json_success();
462
+ }
463
+
464
  }
inc/class-wcml-upgrade.php CHANGED
@@ -29,6 +29,7 @@ class WCML_Upgrade{
29
  '4.3.5',
30
  '4.4.1',
31
  '4.4.3',
 
32
  );
33
 
34
  function __construct(){
@@ -775,4 +776,24 @@ class WCML_Upgrade{
775
  }
776
  }
777
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
778
  }
29
  '4.3.5',
30
  '4.4.1',
31
  '4.4.3',
32
+ '4.6.8',
33
  );
34
 
35
  function __construct(){
776
  }
777
  }
778
 
779
+ private function upgrade_4_6_8() {
780
+ global $wpdb;
781
+
782
+ $wpdb->query( "UPDATE {$wpdb->prefix}icl_strings
783
+ SET `context` = 'admin_texts_woocommerce_gateways',
784
+ `domain_name_context_md5` = MD5( CONCAT( 'admin_texts_woocommerce_gateways', `name`, `gettext_context` ) )
785
+ WHERE `context` = 'woocommerce' AND `name` LIKE '%_gateway_title'"
786
+ );
787
+ $wpdb->query( "UPDATE {$wpdb->prefix}icl_strings
788
+ SET `context` = 'admin_texts_woocommerce_gateways',
789
+ `domain_name_context_md5` = MD5( CONCAT( 'admin_texts_woocommerce_gateways', `name`, `gettext_context` ) )
790
+ WHERE `context` = 'woocommerce' AND `name` LIKE '%_gateway_description'"
791
+ );
792
+ $wpdb->query( "UPDATE {$wpdb->prefix}icl_strings
793
+ SET `context` = 'admin_texts_woocommerce_gateways',
794
+ `domain_name_context_md5` = MD5( CONCAT( 'admin_texts_woocommerce_gateways', `name`, `gettext_context` ) )
795
+ WHERE `context` = 'woocommerce' AND `name` LIKE '%_gateway_instructions'"
796
+ );
797
+ }
798
+
799
  }
inc/class-wcml-wc-gateways.php CHANGED
@@ -39,28 +39,42 @@ class WCML_WC_Gateways{
39
 
40
  if ( is_admin() && 'admin.php' === $pagenow && isset( $_GET['page'] ) && 'wc-settings' === $_GET['page'] && isset( $_GET['tab'] ) && 'checkout' === $_GET['tab'] ) {
41
  add_action( 'admin_footer', array( $this, 'show_language_links_for_gateways' ) );
42
- $this->register_and_set_gateway_strings_language();
43
-
44
  if ( isset( $_GET['section'] ) && 'bacs' === $_GET['section'] && wcml_is_multi_currency_on() ) {
 
45
  add_action( 'admin_footer', array( $this, 'append_currency_selector_to_bacs_account_settings' ) );
46
  }
47
  }
48
  }
49
 
50
-
51
  function loaded_woocommerce_payment_gateways( $load_gateways ){
52
 
53
  foreach( $load_gateways as $key => $gateway ){
54
 
55
  $load_gateway = is_string( $gateway ) ? new $gateway() : $gateway;
 
 
56
  $this->payment_gateways_filters( $load_gateway );
57
  $load_gateways[ $key ] = $load_gateway;
58
-
59
  }
60
 
61
  return $load_gateways;
62
  }
63
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
64
  function payment_gateways_filters( $gateway ){
65
 
66
  if( isset( $gateway->id ) ){
@@ -91,19 +105,57 @@ class WCML_WC_Gateways{
91
 
92
  }
93
 
94
- function translate_gateway_title( $title, $gateway_id, $language = false ) {
95
- $title = apply_filters( 'wpml_translate_single_string', $title, 'woocommerce', $gateway_id .'_gateway_title', $language ? $language : $this->current_language );
96
- return $title;
97
  }
98
 
99
- function translate_gateway_description( $description, $gateway_id) {
100
- $description = apply_filters( 'wpml_translate_single_string', $description, 'woocommerce', $gateway_id . '_gateway_description', $this->current_language );
101
- return $description;
102
  }
103
 
104
- function translate_gateway_instructions( $instructions, $gateway_id ){
105
- $instructions = apply_filters( 'wpml_translate_single_string', $instructions, 'woocommerce', $gateway_id . '_gateway_instructions', $this->current_language );
106
- return $instructions;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
107
  }
108
 
109
  function show_language_links_for_gateways(){
@@ -130,10 +182,7 @@ class WCML_WC_Gateways{
130
  $gateway_option = $payment_gateway->plugin_id.$payment_gateway->id.'_settings';
131
 
132
  $lang_selector = new WPML_Simple_Language_Selector( $this->sitepress );
133
- $language = $this->woocommerce_wpml->strings->get_string_language( $setting_value, 'woocommerce', $payment_gateway->id .'_gateway_'. $text_key );
134
- if( is_null( $language ) ) {
135
- $language = $this->sitepress->get_default_language();
136
- }
137
 
138
  $lang_selector->render( array(
139
  'id' => $gateway_option.'_'.$text_key.'_language_selector',
@@ -162,35 +211,30 @@ class WCML_WC_Gateways{
162
  }
163
  }
164
 
165
- function register_and_set_gateway_strings_language(){
 
 
 
 
 
 
 
 
 
 
 
 
 
 
166
 
167
  foreach( $_POST as $key => $value ){
168
 
169
  if( '_enabled' === substr( $key, -8 ) ){
170
  $gateway = str_replace( '_enabled', '', $key );
171
- $gateway_settings = get_option( $gateway.'_settings', array() );
172
  }
173
  }
174
 
175
  if ( isset( $gateway ) ) {
176
- $text_keys = $this->get_gateway_text_keys_to_translate();
177
-
178
- foreach ( $text_keys as $text_key ) {
179
- $gateway_string_name = str_replace( 'woocommerce_', '', $gateway ) . '_gateway_' . $text_key;
180
- $gateway_key = $gateway . '_' . $text_key;
181
- $context = 'woocommerce';
182
-
183
- $string_value = isset( $_POST[ $gateway_key ] ) ? $_POST[ $gateway_key ] : '';
184
- $opt_string_value = isset( $gateway_settings[ $text_key ] ) ? $gateway_settings[ $text_key ] : $string_value;
185
-
186
- $language_key = 'wcml_lang-' . $gateway . '_settings-' . $text_key;
187
- $language = isset( $_POST[ $language_key ] ) ? $_POST[ $language_key ] : $this->woocommerce_wpml->strings->get_string_language( $opt_string_value, $context );
188
-
189
- do_action( 'wpml_register_single_string', $context, $gateway_string_name, $string_value, false, $language );
190
-
191
- $this->woocommerce_wpml->strings->set_string_language( $string_value, $context, $gateway_string_name, $language );
192
- }
193
-
194
  if( 'woocommerce_bacs' === $gateway && isset( $_POST['bacs-currency'] ) ){
195
  update_option( self::WCML_BACS_ACCOUNTS_CURRENCIES_OPTION, filter_var_array( $_POST['bacs-currency'], FILTER_SANITIZE_STRING ) );
196
  }
39
 
40
  if ( is_admin() && 'admin.php' === $pagenow && isset( $_GET['page'] ) && 'wc-settings' === $_GET['page'] && isset( $_GET['tab'] ) && 'checkout' === $_GET['tab'] ) {
41
  add_action( 'admin_footer', array( $this, 'show_language_links_for_gateways' ) );
 
 
42
  if ( isset( $_GET['section'] ) && 'bacs' === $_GET['section'] && wcml_is_multi_currency_on() ) {
43
+ $this->set_bacs_gateway_currency();
44
  add_action( 'admin_footer', array( $this, 'append_currency_selector_to_bacs_account_settings' ) );
45
  }
46
  }
47
  }
48
 
 
49
  function loaded_woocommerce_payment_gateways( $load_gateways ){
50
 
51
  foreach( $load_gateways as $key => $gateway ){
52
 
53
  $load_gateway = is_string( $gateway ) ? new $gateway() : $gateway;
54
+
55
+ $this->register_gateway_settings_strings( $load_gateway->id, $load_gateway->settings );
56
  $this->payment_gateways_filters( $load_gateway );
57
  $load_gateways[ $key ] = $load_gateway;
 
58
  }
59
 
60
  return $load_gateways;
61
  }
62
 
63
+ /**
64
+ * @param string $gateway_id
65
+ * @param array $settings
66
+ */
67
+ public function register_gateway_settings_strings( $gateway_id, $settings ) {
68
+ if ( isset( $settings['enabled'] ) && 'yes' === $settings['enabled'] ) {
69
+ foreach ( $this->get_gateway_text_keys_to_translate() as $text_key ) {
70
+ if ( isset( $settings[ $text_key ] ) && !$this->get_gateway_string_id( $settings[ $text_key ], $gateway_id, $text_key ) ) {
71
+ $language = $this->gateway_setting_language( $settings[ $text_key ], $gateway_id, $text_key );
72
+ icl_register_string( 'admin_texts_woocommerce_gateways', $gateway_id . '_gateway_' . $text_key, $settings[ $text_key ], false, $language );
73
+ }
74
+ }
75
+ }
76
+ }
77
+
78
  function payment_gateways_filters( $gateway ){
79
 
80
  if( isset( $gateway->id ) ){
105
 
106
  }
107
 
108
+ public function translate_gateway_title( $title, $gateway_id ) {
109
+ return $this->get_translated_gateway_string( $title, $gateway_id, 'title' );
 
110
  }
111
 
112
+ public function translate_gateway_description( $description, $gateway_id) {
113
+ return $this->get_translated_gateway_string( $description, $gateway_id, 'description' );
 
114
  }
115
 
116
+ public function translate_gateway_instructions( $instructions, $gateway_id ) {
117
+ return $this->get_translated_gateway_string( $instructions, $gateway_id, 'instructions' );
118
+ }
119
+
120
+ public function get_translated_gateway_string( $string, $gateway_id, $name ) {
121
+ $translated_string = apply_filters(
122
+ 'wpml_translate_single_string',
123
+ $string,
124
+ 'admin_texts_woocommerce_gateways',
125
+ $gateway_id . '_gateway_' . $name,
126
+ $this->get_current_gateway_language()
127
+ );
128
+
129
+ if ( $translated_string === $string ) {
130
+ $translated_string = __( $string, 'woocommerce' );
131
+ if ( 'cheque' === $gateway_id && $translated_string === $string && 'title' === $name ) {
132
+ $translated_string = _x( $string, 'Check payment method', 'woocommerce' );
133
+ }
134
+ }
135
+
136
+ return $translated_string;
137
+ }
138
+
139
+ /**
140
+ * @return string
141
+ */
142
+ private function get_current_gateway_language(){
143
+
144
+ $language = $this->current_language;
145
+
146
+ $is_saving_new_order = isset( $_POST['action'] ) && 'editpost' === $_POST['action'] && isset( $_POST['save'] ) && $_POST['save'];
147
+ $is_send_order_details_action = isset( $_POST['wc_order_action'] ) && 'send_order_details' === $_POST['wc_order_action'];
148
+ $is_order_on_hold = isset( $_POST ['order_status'] ) && 'wc-on-hold' === $_POST ['order_status'];
149
+
150
+ if ( $is_order_on_hold && isset( $_POST['post_ID'] ) ) {
151
+ if( $is_send_order_details_action ){
152
+ $language = get_post_meta( $_POST['post_ID'], 'wpml_language', true );
153
+ }elseif( $is_saving_new_order && isset( $_COOKIE[ WCML_Orders::DASHBOARD_COOKIE_NAME ] ) ){
154
+ $language = $_COOKIE[ WCML_Orders::DASHBOARD_COOKIE_NAME ];
155
+ }
156
+ }
157
+
158
+ return $language;
159
  }
160
 
161
  function show_language_links_for_gateways(){
182
  $gateway_option = $payment_gateway->plugin_id.$payment_gateway->id.'_settings';
183
 
184
  $lang_selector = new WPML_Simple_Language_Selector( $this->sitepress );
185
+ $language = $this->gateway_setting_language( $setting_value, $payment_gateway->id, $text_key );
 
 
 
186
 
187
  $lang_selector->render( array(
188
  'id' => $gateway_option.'_'.$text_key.'_language_selector',
211
  }
212
  }
213
 
214
+ private function gateway_setting_language( $setting_value, $gateway_id, $text_key ){
215
+
216
+ if( $this->get_gateway_string_id( $setting_value, $gateway_id, $text_key ) ){
217
+ return $this->woocommerce_wpml->strings->get_string_language( $setting_value, 'admin_texts_woocommerce_gateways', $gateway_id .'_gateway_'. $text_key );
218
+ }else{
219
+ return $this->sitepress->get_default_language();
220
+ }
221
+
222
+ }
223
+
224
+ private function get_gateway_string_id( $value, $gateway_id, $name ){
225
+ return icl_get_string_id( $value, 'admin_texts_woocommerce_gateways', $gateway_id .'_gateway_'. $name );
226
+ }
227
+
228
+ function set_bacs_gateway_currency(){
229
 
230
  foreach( $_POST as $key => $value ){
231
 
232
  if( '_enabled' === substr( $key, -8 ) ){
233
  $gateway = str_replace( '_enabled', '', $key );
 
234
  }
235
  }
236
 
237
  if ( isset( $gateway ) ) {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
238
  if( 'woocommerce_bacs' === $gateway && isset( $_POST['bacs-currency'] ) ){
239
  update_option( self::WCML_BACS_ACCOUNTS_CURRENCIES_OPTION, filter_var_array( $_POST['bacs-currency'], FILTER_SANITIZE_STRING ) );
240
  }
inc/class-wcml-wc-shipping.php CHANGED
@@ -27,6 +27,7 @@ class WCML_WC_Shipping{
27
  add_filter('woocommerce_rate_label',array($this,'translate_woocommerce_rate_label'));
28
  add_filter( 'pre_update_option_woocommerce_flat_rate_settings', array( $this, 'update_woocommerce_shipping_settings_for_class_costs' ) );
29
  add_filter( 'pre_update_option_woocommerce_international_delivery_settings', array( $this, 'update_woocommerce_shipping_settings_for_class_costs' ) );
 
30
 
31
  $this->shipping_methods_filters();
32
  }
@@ -247,4 +248,22 @@ class WCML_WC_Shipping{
247
  return $inst_settings;
248
  }
249
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
250
  }
27
  add_filter('woocommerce_rate_label',array($this,'translate_woocommerce_rate_label'));
28
  add_filter( 'pre_update_option_woocommerce_flat_rate_settings', array( $this, 'update_woocommerce_shipping_settings_for_class_costs' ) );
29
  add_filter( 'pre_update_option_woocommerce_international_delivery_settings', array( $this, 'update_woocommerce_shipping_settings_for_class_costs' ) );
30
+ add_filter( 'woocommerce_shipping_flat_rate_instance_option', array( $this, 'get_original_shipping_class_rate' ), 10, 3 );
31
 
32
  $this->shipping_methods_filters();
33
  }
248
  return $inst_settings;
249
  }
250
 
251
+ /**
252
+ * @param string $rate
253
+ * @param string $class_name
254
+ * @param WC_Shipping_Method $shipping_method
255
+ *
256
+ * @return string
257
+ */
258
+ public function get_original_shipping_class_rate( $rate, $class_name, $shipping_method ){
259
+ if( !$rate && 'class_cost_' === substr( $class_name, 0, 11 ) ){
260
+ $original_class_id = $this->sitepress->term_translations()->get_original_element( substr( $class_name, 11 ) );
261
+ if( $original_class_id && isset( $shipping_method->instance_settings[ 'class_cost_'.$original_class_id ] ) ){
262
+ return $shipping_method->instance_settings[ 'class_cost_'.$original_class_id ];
263
+ }
264
+ }
265
+
266
+ return $rate;
267
+ }
268
+
269
  }
inc/currencies/class-wcml-multi-currency-prices.php CHANGED
@@ -2,6 +2,8 @@
2
 
3
  class WCML_Multi_Currency_Prices {
4
 
 
 
5
  /**
6
  * @var woocommerce_wpml
7
  */
@@ -37,8 +39,8 @@ class WCML_Multi_Currency_Prices {
37
  add_filter( 'get_post_metadata', array( $this, 'product_price_filter' ), 10, 4 );
38
  add_filter( 'get_post_metadata', array( $this, 'variation_prices_filter' ), 12, 4 ); // second
39
 
40
- add_filter( 'woocommerce_price_filter_widget_max_amount', array( $this, 'raw_price_filter' ), 99 );
41
- add_filter( 'woocommerce_price_filter_widget_min_amount', array( $this, 'raw_price_filter' ), 99 );
42
 
43
  add_filter( 'woocommerce_adjust_price', array( $this, 'raw_price_filter' ), 10 );
44
 
@@ -101,6 +103,34 @@ class WCML_Multi_Currency_Prices {
101
  return $currency;
102
  }
103
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
104
  public function raw_price_filter( $price, $currency = false ) {
105
 
106
  if ( $currency === false ) {
2
 
3
  class WCML_Multi_Currency_Prices {
4
 
5
+ const WC_DEFAULT_STEP = 10;
6
+
7
  /**
8
  * @var woocommerce_wpml
9
  */
39
  add_filter( 'get_post_metadata', array( $this, 'product_price_filter' ), 10, 4 );
40
  add_filter( 'get_post_metadata', array( $this, 'variation_prices_filter' ), 12, 4 ); // second
41
 
42
+ add_filter( 'woocommerce_price_filter_widget_max_amount', array( $this, 'filter_widget_max_amount' ), 99 );
43
+ add_filter( 'woocommerce_price_filter_widget_min_amount', array( $this, 'filter_widget_min_amount' ), 99 );
44
 
45
  add_filter( 'woocommerce_adjust_price', array( $this, 'raw_price_filter' ), 10 );
46
 
103
  return $currency;
104
  }
105
 
106
+ /**
107
+ * @param float $min_amount
108
+ *
109
+ * @return float
110
+ */
111
+ public function filter_widget_min_amount( $min_amount ){
112
+ $step = $this->get_filter_widget_amount_step();
113
+
114
+ return floor( $this->raw_price_filter( $min_amount ) / $step ) * $step;
115
+ }
116
+
117
+ /**
118
+ * @param float $max_price
119
+ *
120
+ * @return float
121
+ */
122
+ public function filter_widget_max_amount( $max_price ){
123
+ $step = $this->get_filter_widget_amount_step();
124
+ return ceil( $this->raw_price_filter( $max_price ) / $step ) * $step;
125
+ }
126
+
127
+ /**
128
+ * @return int
129
+ */
130
+ private function get_filter_widget_amount_step(){
131
+ return max( apply_filters( 'woocommerce_price_filter_widget_step', self::WC_DEFAULT_STEP ), 1 );
132
+ }
133
+
134
  public function raw_price_filter( $price, $currency = false ) {
135
 
136
  if ( $currency === false ) {
inc/template-classes/class-wcml-plugins-wrap.php CHANGED
@@ -1,76 +1,82 @@
1
  <?php
2
 
3
- use WCML\Twig_Loader_Filesystem;
4
- use WCML\Twig_Environment;
5
 
6
  class WCML_Plugins_Wrap {
7
 
8
- private $woocommerce_wpml;
9
- private $sitepress;
10
-
11
- private $twig;
12
-
13
  /** @var WCML_Tracking_Link */
14
  private $tracking_link;
15
 
16
- function __construct( &$woocommerce_wpml, &$sitepress ){
17
-
18
- $this->woocommerce_wpml = $woocommerce_wpml;
19
- $this->sitepress = $sitepress;
20
-
21
- $loader = new Twig_Loader_Filesystem( WCML_PLUGIN_PATH . '/templates' );
22
- $this->twig = new Twig_Environment( $loader );
23
-
24
- $this->tracking_link = new WCML_Tracking_Link();
25
- }
 
26
 
27
- public function get_model(){
 
 
 
28
 
29
- $model = array(
30
- 'link_url' => admin_url('admin.php?page=wpml-wcml'),
31
- 'old_wpml' => defined('ICL_SITEPRESS_VERSION') && version_compare( ICL_SITEPRESS_VERSION, '4.0', '<' ),
32
- 'tracking_link' => $this->tracking_link->generate( 'https://wpml.org/shop/account/', false, 'account' ),
33
- 'install_wpml_link' => $this->woocommerce_wpml->dependencies->required_plugin_install_link( 'wpml' ),
34
- 'icl_version' => defined('ICL_SITEPRESS_VERSION'),
35
- 'icl_setup' => $this->sitepress ? $this->sitepress->setup() : false,
36
- 'tm_version' => defined( 'WPML_TM_VERSION' ),
37
- 'st_version' => defined( 'WPML_ST_VERSION' ) && function_exists( 'icl_get_string_id' ),
38
- 'wc' => class_exists('WooCommerce') ,
39
- 'old_wc' => class_exists('WooCommerce') && version_compare( WC_VERSION, '3.3.0', '<'),
40
- 'wc_link' => 'http://wordpress.org/extend/plugins/woocommerce/',
41
- 'strings' => array(
42
- 'title' => __('WooCommerce Multilingual', 'woocommerce-multilingual'),
43
- 'required'=> __('Required plugins', 'woocommerce-multilingual'),
44
- 'plugins'=> __('Plugins Status', 'woocommerce-multilingual'),
45
- 'depends'=> __('WooCommerce Multilingual depends on several plugins to work. If any required plugin is missing, you should install and activate it.', 'woocommerce-multilingual'),
46
- 'old_wpml_link'=> sprintf( __( 'WooCommerce Multilingual is enabled but not effective. It is not compatible with <a href="%s">WPML</a> versions prior 4.0', 'woocommerce-multilingual' ), $this->tracking_link->generate( 'https://wpml.org/' ) ),
47
- 'update_wpml'=> __( 'Update WPML', 'woocommerce-multilingual' ),
48
- 'upgrade_wpml'=> __( 'Upgrade WPML', 'woocommerce-multilingual' ),
49
- 'get_wpml'=> __( 'Get WPML', 'woocommerce-multilingual' ),
50
- 'get_wpml_tm'=> __( 'Get WPML Translation Management', 'woocommerce-multilingual' ),
51
- 'get_wpml_st'=> __( 'Get WPML String Translation', 'woocommerce-multilingual' ),
52
- 'new_design_wpml_link'=> sprintf( __( 'You are using WooCommerce Multilingual %s. This version includes an important UI redesign for the configuration screens and it requires <a href="%s">WPML %s</a> or higher. Everything still works on the front end now but, in order to configure options for WooCommerce Multilingual, you need to upgrade WPML.', 'woocommerce-multilingual' ), WCML_VERSION, $this->tracking_link->generate( 'https://wpml.org/' ), '3.4' ),
53
- 'wpml' => '<strong>WPML</strong>',
54
- 'tm' => '<strong>WPML Translation Management</strong>',
55
- 'st' => '<strong>WPML String Translation</strong>',
56
- 'wc' => '<strong>WooCommerce</strong>',
57
- 'inst_active' => __( '%s is installed and active.', 'woocommerce-multilingual' ),
58
- 'is_setup' => __( '%s is set up.', 'woocommerce-multilingual' ),
59
- 'not_setup' => __( '%s is not set up.', 'woocommerce-multilingual' ),
60
- 'not_inst' => __( '%s is either not installed or not active.', 'woocommerce-multilingual' ),
61
- 'wpml_not_inst' => sprintf( __( '%s is either not installed or not active.', 'woocommerce-multilingual' ),'<strong><a title="' . esc_attr__('The WordPress Multilingual Plugin', 'woocommerce-multilingual') .'" href="' . $this->tracking_link->generate( 'https://wpml.org/' ) . '">WPML</a></strong>' ),
62
- 'old_wc' => sprintf( __( '%1$s is installed, but with incorrect version. You need %1$s %2$s or higher. ', 'woocommerce-multilingual' ), '<strong>WooCommerce</strong>', '3.3.0' ),
63
- 'download_wc' => __( 'Download WooCommerce', 'woocommerce-multilingual' ),
64
- )
65
- );
66
 
67
- return $model;
68
 
69
- }
70
 
71
- public function show(){
72
- $template = $this->twig->load( 'plugins-wrap.twig' );
73
- echo $template->render( $this->get_model() );
74
- }
 
 
 
75
 
76
- }
1
  <?php
2
 
3
+ use WPML\Core\Twig_Loader_Filesystem;
4
+ use WPML\Core\Twig_Environment;
5
 
6
  class WCML_Plugins_Wrap {
7
 
8
+ /** @var \woocommerce_wpml */
9
+ private $woocommerce_wpml;
10
+ /** @var \SitePress */
11
+ private $sitepress;
 
12
  /** @var WCML_Tracking_Link */
13
  private $tracking_link;
14
 
15
+ /**
16
+ * WCML_Plugins_Wrap constructor.
17
+ *
18
+ * @param woocommerce_wpml $woocommerce_wpml
19
+ * @param SitePress $sitepress
20
+ */
21
+ public function __construct( $woocommerce_wpml, $sitepress ) {
22
+ $this->woocommerce_wpml = $woocommerce_wpml;
23
+ $this->sitepress = $sitepress;
24
+ $this->tracking_link = new WCML_Tracking_Link();
25
+ }
26
 
27
+ /**
28
+ * @return array
29
+ */
30
+ public function get_model() {
31
 
32
+ $model = array(
33
+ 'link_url' => admin_url( 'admin.php?page=wpml-wcml' ),
34
+ 'old_wpml' => defined( 'ICL_SITEPRESS_VERSION' ) && version_compare( ICL_SITEPRESS_VERSION, '4.0', '<' ),
35
+ 'tracking_link' => $this->tracking_link->generate( 'https://wpml.org/shop/account/', false, 'account' ),
36
+ 'install_wpml_link' => $this->woocommerce_wpml->dependencies->required_plugin_install_link( 'wpml' ),
37
+ 'icl_version' => defined( 'ICL_SITEPRESS_VERSION' ),
38
+ 'icl_setup' => $this->sitepress ? $this->sitepress->setup() : false,
39
+ 'tm_version' => defined( 'WPML_TM_VERSION' ),
40
+ 'st_version' => defined( 'WPML_ST_VERSION' ) && function_exists( 'icl_get_string_id' ),
41
+ 'wc' => class_exists( 'WooCommerce' ),
42
+ 'old_wc' => class_exists( 'WooCommerce' ) && version_compare( WC_VERSION, '3.3.0', '<' ),
43
+ 'wc_link' => 'http://wordpress.org/extend/plugins/woocommerce/',
44
+ 'strings' => array(
45
+ 'title' => __( 'WooCommerce Multilingual', 'woocommerce-multilingual' ),
46
+ 'required' => __( 'Required plugins', 'woocommerce-multilingual' ),
47
+ 'plugins' => __( 'Plugins Status', 'woocommerce-multilingual' ),
48
+ 'depends' => __( 'WooCommerce Multilingual depends on several plugins to work. If any required plugin is missing, you should install and activate it.', 'woocommerce-multilingual' ),
49
+ 'old_wpml_link' => sprintf( __( 'WooCommerce Multilingual is enabled but not effective. It is not compatible with <a href="%s">WPML</a> versions prior 4.0', 'woocommerce-multilingual' ), $this->tracking_link->generate( 'https://wpml.org/' ) ),
50
+ 'update_wpml' => __( 'Update WPML', 'woocommerce-multilingual' ),
51
+ 'upgrade_wpml' => __( 'Upgrade WPML', 'woocommerce-multilingual' ),
52
+ 'get_wpml' => __( 'Get WPML', 'woocommerce-multilingual' ),
53
+ 'get_wpml_tm' => __( 'Get WPML Translation Management', 'woocommerce-multilingual' ),
54
+ 'get_wpml_st' => __( 'Get WPML String Translation', 'woocommerce-multilingual' ),
55
+ 'new_design_wpml_link' => sprintf( __( 'You are using WooCommerce Multilingual %s. This version includes an important UI redesign for the configuration screens and it requires <a href="%s">WPML %s</a> or higher. Everything still works on the front end now but, in order to configure options for WooCommerce Multilingual, you need to upgrade WPML.', 'woocommerce-multilingual' ), WCML_VERSION, $this->tracking_link->generate( 'https://wpml.org/' ), '3.4' ),
56
+ 'wpml' => '<strong>WPML</strong>',
57
+ 'tm' => '<strong>WPML Translation Management</strong>',
58
+ 'st' => '<strong>WPML String Translation</strong>',
59
+ 'wc' => '<strong>WooCommerce</strong>',
60
+ 'inst_active' => __( '%s is installed and active.', 'woocommerce-multilingual' ),
61
+ 'is_setup' => __( '%s is set up.', 'woocommerce-multilingual' ),
62
+ 'not_setup' => __( '%s is not set up.', 'woocommerce-multilingual' ),
63
+ 'not_inst' => __( '%s is either not installed or not active.', 'woocommerce-multilingual' ),
64
+ 'wpml_not_inst' => sprintf( __( '%s is either not installed or not active.', 'woocommerce-multilingual' ), '<strong><a title="' . esc_attr__( 'The WordPress Multilingual Plugin', 'woocommerce-multilingual' ) . '" href="' . $this->tracking_link->generate( 'https://wpml.org/' ) . '">WPML</a></strong>' ),
65
+ 'old_wc' => sprintf( __( '%1$s is installed, but with incorrect version. You need %1$s %2$s or higher. ', 'woocommerce-multilingual' ), '<strong>WooCommerce</strong>', '3.3.0' ),
66
+ 'download_wc' => __( 'Download WooCommerce', 'woocommerce-multilingual' ),
67
+ )
68
+ );
69
 
70
+ return $model;
71
 
72
+ }
73
 
74
+ /**
75
+ * Outputs the template.
76
+ */
77
+ public function show() {
78
+ $model = new \WPML\Templates\PHP\Model( $this->get_model() );
79
+ include WCML_PLUGIN_PATH . '/templates/php/plugins-wrap.php';
80
+ }
81
 
82
+ }
inc/template-classes/class-wcml-products-ui.php CHANGED
@@ -202,7 +202,8 @@ class WCML_Products_UI extends WCML_Templates_Factory {
202
  }else{
203
  $products[ $key ]->formated_date = date(' Y/m/d', strtotime( $product->post_modified ) );
204
  }
205
-
 
206
  }
207
 
208
  return array( 'products' => $products, 'products_count' => $products_info[ 'products_count' ] );
202
  }else{
203
  $products[ $key ]->formated_date = date(' Y/m/d', strtotime( $product->post_modified ) );
204
  }
205
+
206
+ $products[ $key ]->has_image = has_post_thumbnail($product->ID);
207
  }
208
 
209
  return array( 'products' => $products, 'products_count' => $products_info[ 'products_count' ] );
inc/template-classes/class-wcml-settings-ui.php CHANGED
@@ -1,6 +1,6 @@
1
  <?php
2
 
3
- use WCML\Twig_SimpleFunction;
4
 
5
  class WCML_Settings_UI extends WCML_Templates_Factory {
6
 
@@ -15,23 +15,23 @@ class WCML_Settings_UI extends WCML_Templates_Factory {
15
  * @param woocommerce_wpml $woocommerce_wpml
16
  * @param SitePress $sitepress
17
  */
18
- function __construct( woocommerce_wpml $woocommerce_wpml, Sitepress $sitepress ){
19
 
20
- $functions = array(
21
- new Twig_SimpleFunction( 'wp_do_action', array( $this, 'wp_do_action' ) )
22
- );
23
 
24
- parent::__construct( $functions );
25
 
26
- $this->woocommerce_wpml = $woocommerce_wpml;
27
- $this->sitepress = $sitepress;
28
- }
29
 
30
- public function wp_do_action( $hook ){
31
  do_action( $hook );
32
  }
33
 
34
- public function get_model(){
35
 
36
  $model = array(
37
  'form' => array(
1
  <?php
2
 
3
+ use WPML\Core\Twig_SimpleFunction;
4
 
5
  class WCML_Settings_UI extends WCML_Templates_Factory {
6
 
15
  * @param woocommerce_wpml $woocommerce_wpml
16
  * @param SitePress $sitepress
17
  */
18
+ function __construct( woocommerce_wpml $woocommerce_wpml, Sitepress $sitepress ) {
19
 
20
+ $functions = array(
21
+ new Twig_SimpleFunction( 'wp_do_action', array( $this, 'wp_do_action' ) )
22
+ );
23
 
24
+ parent::__construct( $functions );
25
 
26
+ $this->woocommerce_wpml = $woocommerce_wpml;
27
+ $this->sitepress = $sitepress;
28
+ }
29
 
30
+ public function wp_do_action( $hook ) {
31
  do_action( $hook );
32
  }
33
 
34
+ public function get_model(){
35
 
36
  $model = array(
37
  'form' => array(
inc/template-classes/class-wcml-templates-factory.php CHANGED
@@ -1,12 +1,12 @@
1
  <?php
2
 
3
- use WCML\Twig_Environment;
4
- use WCML\Twig_Error_Syntax;
5
- use WCML\Twig_Error_Runtime;
6
- use WCML\Twig_Error_Loader;
7
- use WCML\Twig_LoaderInterface;
8
- use WCML\Twig_Loader_String;
9
- use WCML\Twig_Loader_Filesystem;
10
 
11
  abstract class WCML_Templates_Factory extends WPML_Templates_Factory {
12
 
1
  <?php
2
 
3
+ use WPML\Core\Twig_Environment;
4
+ use WPML\Core\Twig_Error_Syntax;
5
+ use WPML\Core\Twig_Error_Runtime;
6
+ use WPML\Core\Twig_Error_Loader;
7
+ use WPML\Core\Twig_LoaderInterface;
8
+ use WPML\Core\Twig_Loader_String;
9
+ use WPML\Core\Twig_Loader_Filesystem;
10
 
11
  abstract class WCML_Templates_Factory extends WPML_Templates_Factory {
12
 
inc/template-classes/class-wcml-troubleshooting-ui.php CHANGED
@@ -26,7 +26,7 @@ class WCML_Troubleshooting_UI extends WCML_Templates_Factory {
26
  'prod_with_variations' => $this->woocommerce_wpml->troubleshooting->wcml_count_products_with_variations(),
27
  'prod_count' => $this->woocommerce_wpml->troubleshooting->wcml_count_products_for_gallery_sync(),
28
  'prod_categories_count' => $this->woocommerce_wpml->troubleshooting->wcml_count_product_categories(),
29
- 'sync_stock_count' => $this->woocommerce_wpml->troubleshooting->wcml_count_product_stock_sync(),
30
  'fix_relationships_count' => $this->woocommerce_wpml->troubleshooting->wcml_count_product_fix_relationships(),
31
  'all_products_taxonomies' => $this->get_all_products_taxonomies(),
32
  'product_type_sync_needed' => !empty( $translated_product_type_terms ) ? true : false,
@@ -47,6 +47,7 @@ class WCML_Troubleshooting_UI extends WCML_Templates_Factory {
47
  'delete_terms' => __( 'Fix product_type taxonomy terms', 'woocommerce-multilingual' ),
48
  'sync_stock' => __( 'Sync product stock quantity and status ( synchronizing min stock between translations )', 'woocommerce-multilingual' ),
49
  'sync_relationships' => __( 'Fix translated variations relationships', 'woocommerce-multilingual' ),
 
50
  'product_type_fix_done' => __( 'Done!', 'woocommerce-multilingual' )
51
  ),
52
  'nonces' => array(
@@ -58,6 +59,7 @@ class WCML_Troubleshooting_UI extends WCML_Templates_Factory {
58
  'trbl_product_type_terms' => wp_nonce_field('trbl_product_type_terms', 'trbl_product_type_terms_nonce'),
59
  'trbl_sync_stock' => wp_nonce_field('trbl_sync_stock', 'trbl_sync_stock_nonce'),
60
  'fix_relationships' => wp_nonce_field( 'fix_relationships', 'fix_relationships_nonce' ),
 
61
  )
62
  );
63
 
26
  'prod_with_variations' => $this->woocommerce_wpml->troubleshooting->wcml_count_products_with_variations(),
27
  'prod_count' => $this->woocommerce_wpml->troubleshooting->wcml_count_products_for_gallery_sync(),
28
  'prod_categories_count' => $this->woocommerce_wpml->troubleshooting->wcml_count_product_categories(),
29
+ 'product_and_variations_count' => $this->woocommerce_wpml->troubleshooting->wcml_count_products_and_variations(),
30
  'fix_relationships_count' => $this->woocommerce_wpml->troubleshooting->wcml_count_product_fix_relationships(),
31
  'all_products_taxonomies' => $this->get_all_products_taxonomies(),
32
  'product_type_sync_needed' => !empty( $translated_product_type_terms ) ? true : false,
47
  'delete_terms' => __( 'Fix product_type taxonomy terms', 'woocommerce-multilingual' ),
48
  'sync_stock' => __( 'Sync product stock quantity and status ( synchronizing min stock between translations )', 'woocommerce-multilingual' ),
49
  'sync_relationships' => __( 'Fix translated variations relationships', 'woocommerce-multilingual' ),
50
+ 'sync_deleted_meta' => __( 'Sync removed product meta from original products to translations', 'woocommerce-multilingual' ),
51
  'product_type_fix_done' => __( 'Done!', 'woocommerce-multilingual' )
52
  ),
53
  'nonces' => array(
59
  'trbl_product_type_terms' => wp_nonce_field('trbl_product_type_terms', 'trbl_product_type_terms_nonce'),
60
  'trbl_sync_stock' => wp_nonce_field('trbl_sync_stock', 'trbl_sync_stock_nonce'),
61
  'fix_relationships' => wp_nonce_field( 'fix_relationships', 'fix_relationships_nonce' ),
62
+ 'sync_deleted_meta' => wp_nonce_field( 'sync_deleted_meta', 'sync_deleted_meta_nonce' ),
63
  )
64
  );
65
 
inc/template-classes/currency-switcher/class-wcml-currency-switcher-template.php CHANGED
@@ -1,6 +1,6 @@
1
  <?php
2
 
3
- use WCML\Twig_SimpleFunction;
4
 
5
  class WCML_Currency_Switcher_Template extends WCML_Templates_Factory {
6
 
1
  <?php
2
 
3
+ use WPML\Core\Twig_SimpleFunction;
4
 
5
  class WCML_Currency_Switcher_Template extends WCML_Templates_Factory {
6
 
inc/template-classes/multi-currency/class-wcml-custom-currency-options.php CHANGED
@@ -1,6 +1,6 @@
1
  <?php
2
 
3
- use WCML\Twig_SimpleFunction;
4
 
5
  class WCML_Custom_Currency_Options extends WCML_Templates_Factory {
6
 
1
  <?php
2
 
3
+ use WPML\Core\Twig_SimpleFunction;
4
 
5
  class WCML_Custom_Currency_Options extends WCML_Templates_Factory {
6
 
inc/template-classes/multi-currency/class-wcml-multi-currency-ui.php CHANGED
@@ -1,6 +1,6 @@
1
  <?php
2
 
3
- use WCML\Twig_SimpleFunction;
4
 
5
  class WCML_Multi_Currency_UI extends WCML_Templates_Factory {
6
 
1
  <?php
2
 
3
+ use WPML\Core\Twig_SimpleFunction;
4
 
5
  class WCML_Multi_Currency_UI extends WCML_Templates_Factory {
6
 
inc/template-classes/setup/class-wcml-setup-header.php CHANGED
@@ -1,6 +1,6 @@
1
  <?php
2
 
3
- use WCML\Twig_SimpleFunction;
4
 
5
  class WCML_Setup_Header_UI extends WCML_Templates_Factory {
6
 
1
  <?php
2
 
3
+ use WPML\Core\Twig_SimpleFunction;
4
 
5
  class WCML_Setup_Header_UI extends WCML_Templates_Factory {
6
 
inc/template-classes/status/class-wcml-status-config-warnings-ui.php CHANGED
@@ -1,6 +1,6 @@
1
  <?php
2
 
3
- use WCML\Twig_SimpleFunction;
4
 
5
  class WCML_Status_Config_Warnings_UI extends WCML_Templates_Factory {
6
 
1
  <?php
2
 
3
+ use WPML\Core\Twig_SimpleFunction;
4
 
5
  class WCML_Status_Config_Warnings_UI extends WCML_Templates_Factory {
6
 
inc/template-classes/status/class-wcml-status-store-pages-ui.php CHANGED
@@ -1,6 +1,6 @@
1
  <?php
2
 
3
- use WCML\Twig_SimpleFunction;
4
 
5
  class WCML_Status_Store_Pages_UI extends WCML_Templates_Factory {
6
 
1
  <?php
2
 
3
+ use WPML\Core\Twig_SimpleFunction;
4
 
5
  class WCML_Status_Store_Pages_UI extends WCML_Templates_Factory {
6
 
inc/template-classes/store-urls/class-wcml-store-urls-translation-statuses-ui.php CHANGED
@@ -1,6 +1,6 @@
1
  <?php
2
 
3
- use WCML\Twig_SimpleFunction;
4
 
5
  /**
6
  * Created by OnTheGo Systems
1
  <?php
2
 
3
+ use WPML\Core\Twig_SimpleFunction;
4
 
5
  /**
6
  * Created by OnTheGo Systems
inc/translation-editor/class-wcml-synchronize-product-data.php CHANGED
@@ -2,7 +2,7 @@
2
 
3
  class WCML_Synchronize_Product_Data{
4
 
5
- const CUSTOM_FIELD_KEY_SEPARATOR = ':::';
6
 
7
  /** @var woocommerce_wpml */
8
  private $woocommerce_wpml;
@@ -49,6 +49,7 @@ class WCML_Synchronize_Product_Data{
49
  add_action( 'wpml_translation_update', array( $this, 'icl_connect_translations_action' ) );
50
 
51
  add_action( 'deleted_term_relationships', array( $this, 'delete_term_relationships_update_term_count' ), 10, 2 );
 
52
  }
53
 
54
  add_action( 'woocommerce_product_set_visibility', array( $this, 'sync_product_translations_visibility' ) );
@@ -181,29 +182,46 @@ class WCML_Synchronize_Product_Data{
181
  $taxonomy_exceptions = array( 'product_type', 'product_visibility' );
182
  $sync_taxonomies = $this->sitepress->get_setting( 'sync_post_taxonomies' );
183
 
 
 
 
 
 
 
 
184
  remove_filter( 'terms_clauses', array( $this->sitepress, 'terms_clauses' ), 10 );
185
- foreach ( $taxonomies as $taxonomy ) {
186
- if (
187
- $sync_taxonomies ||
188
- in_array( $taxonomy, $taxonomy_exceptions )
189
- ) {
190
- $terms = wp_get_object_terms( $original_product_id, $taxonomy );
 
 
 
191
  $tt_ids = array();
192
  $tt_names = array();
193
- if ( $terms ) {
194
- foreach ( $terms as $term ) {
195
- if ( in_array( $term->taxonomy, $taxonomy_exceptions ) ) {
196
- $tt_names[] = $term->name;
197
- continue;
198
- }
199
- $tt_ids[] = $term->term_id;
200
  }
201
-
202
- if ( ! $this->woocommerce_wpml->terms->is_translatable_wc_taxonomy( $taxonomy ) ) {
203
- wp_set_post_terms( $tr_product_id, $tt_names, $taxonomy );
204
- } else {
205
- $this->wcml_update_term_count_by_ids( $tt_ids, $lang, $taxonomy, $tr_product_id );
 
 
 
206
  }
 
 
 
 
 
 
 
207
  }
208
  }
209
  }
@@ -515,10 +533,10 @@ class WCML_Synchronize_Product_Data{
515
  }
516
 
517
  //duplicate product post meta
518
- public function duplicate_product_post_meta( $original_product_id, $trnsl_product_id, $data = false ){
519
  global $iclTranslationManagement;
520
 
521
- if( $this->check_if_product_fields_sync_needed( $original_product_id, $trnsl_product_id, 'postmeta_fields' ) || $data ){
522
  $all_meta = get_post_custom( $original_product_id );
523
  $post_fields = null;
524
 
@@ -535,17 +553,20 @@ class WCML_Synchronize_Product_Data{
535
 
536
  foreach ( $meta as $meta_value ) {
537
  if( $key == '_downloadable_files' ){
538
- $this->woocommerce_wpml->downloadable->sync_files_to_translations( $original_product_id, $trnsl_product_id, $data );
539
  }elseif ( $data ) {
540
  if ( WPML_TRANSLATE_CUSTOM_FIELD === $setting->status() ) {
541
- $post_fields = $this->sync_custom_field_value( $key, $data, $trnsl_product_id, $post_fields, $original_product_id );
542
  }
543
  }
544
  }
545
  }
 
 
 
546
  }
547
 
548
- do_action( 'wcml_after_duplicate_product_post_meta', $original_product_id, $trnsl_product_id, $data );
549
  }
550
 
551
  public function sync_custom_field_value( $custom_field, $translation_data, $trnsl_product_id, $post_fields, $original_product_id = false, $is_variation = false ){
@@ -775,5 +796,26 @@ class WCML_Synchronize_Product_Data{
775
  }
776
  }
777
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
778
 
779
  }
2
 
3
  class WCML_Synchronize_Product_Data{
4
 
5
+ const CUSTOM_FIELD_KEY_SEPARATOR = ':::';
6
 
7
  /** @var woocommerce_wpml */
8
  private $woocommerce_wpml;
49
  add_action( 'wpml_translation_update', array( $this, 'icl_connect_translations_action' ) );
50
 
51
  add_action( 'deleted_term_relationships', array( $this, 'delete_term_relationships_update_term_count' ), 10, 2 );
52
+ add_action( 'deleted_post_meta', array( $this, 'delete_empty_post_meta_for_translations' ), 10, 3 );
53
  }
54
 
55
  add_action( 'woocommerce_product_set_visibility', array( $this, 'sync_product_translations_visibility' ) );
182
  $taxonomy_exceptions = array( 'product_type', 'product_visibility' );
183
  $sync_taxonomies = $this->sitepress->get_setting( 'sync_post_taxonomies' );
184
 
185
+ $taxonomies = array_filter(
186
+ $taxonomies,
187
+ function ( $taxonomy ) use ( $sync_taxonomies, $taxonomy_exceptions ) {
188
+ return $sync_taxonomies || in_array( $taxonomy, $taxonomy_exceptions, true );
189
+ }
190
+ );
191
+
192
  remove_filter( 'terms_clauses', array( $this->sitepress, 'terms_clauses' ), 10 );
193
+
194
+ $found = false;
195
+ $all_terms = WPML_Non_Persistent_Cache::get( $original_product_id, __CLASS__, $found );
196
+ if ( ! $found ) {
197
+ $all_terms = wp_get_object_terms( $original_product_id, $taxonomies );
198
+ WPML_Non_Persistent_Cache::set( $original_product_id, $all_terms, __CLASS__ );
199
+ }
200
+ if ( ! is_wp_error( $all_terms ) ) {
201
+ foreach ( $taxonomies as $taxonomy ) {
202
  $tt_ids = array();
203
  $tt_names = array();
204
+ $terms = array_filter(
205
+ $all_terms,
206
+ function ( $term ) use ( $taxonomy ) {
207
+ return $term->taxonomy === $taxonomy;
 
 
 
208
  }
209
+ );
210
+ if ( ! $terms ) {
211
+ continue;
212
+ }
213
+ foreach ( $terms as $term ) {
214
+ if ( in_array( $term->taxonomy, $taxonomy_exceptions, true ) ) {
215
+ $tt_names[] = $term->name;
216
+ continue;
217
  }
218
+ $tt_ids[] = $term->term_id;
219
+ }
220
+
221
+ if ( ! $this->woocommerce_wpml->terms->is_translatable_wc_taxonomy( $taxonomy ) ) {
222
+ wp_set_post_terms( $tr_product_id, $tt_names, $taxonomy );
223
+ } else {
224
+ $this->wcml_update_term_count_by_ids( $tt_ids, $lang, $taxonomy, $tr_product_id );
225
  }
226
  }
227
  }
533
  }
534
 
535
  //duplicate product post meta
536
+ public function duplicate_product_post_meta( $original_product_id, $translated_product_id, $data = false ){
537
  global $iclTranslationManagement;
538
 
539
+ if( $this->check_if_product_fields_sync_needed( $original_product_id, $translated_product_id, 'postmeta_fields' ) || $data ){
540
  $all_meta = get_post_custom( $original_product_id );
541
  $post_fields = null;
542
 
553
 
554
  foreach ( $meta as $meta_value ) {
555
  if( $key == '_downloadable_files' ){
556
+ $this->woocommerce_wpml->downloadable->sync_files_to_translations( $original_product_id, $translated_product_id, $data );
557
  }elseif ( $data ) {
558
  if ( WPML_TRANSLATE_CUSTOM_FIELD === $setting->status() ) {
559
+ $post_fields = $this->sync_custom_field_value( $key, $data, $translated_product_id, $post_fields, $original_product_id );
560
  }
561
  }
562
  }
563
  }
564
+
565
+ $wcml_data_store = wcml_product_data_store_cpt();
566
+ $wcml_data_store->update_lookup_table_data( $translated_product_id );
567
  }
568
 
569
+ do_action( 'wcml_after_duplicate_product_post_meta', $original_product_id, $translated_product_id, $data );
570
  }
571
 
572
  public function sync_custom_field_value( $custom_field, $translation_data, $trnsl_product_id, $post_fields, $original_product_id = false, $is_variation = false ){
796
  }
797
  }
798
 
799
+ /**
800
+ * @param array $meta_ids An array of deleted metadata entry IDs.
801
+ * @param int $object_id Object ID.
802
+ * @param string $meta_key Meta key.
803
+ */
804
+ public function delete_empty_post_meta_for_translations( $meta_ids, $object_id, $meta_key ){
805
+
806
+ if(
807
+ wpml_collect( [ 'product', 'product_variation' ] )->contains( get_post_type( $object_id ) ) &&
808
+ $this->woocommerce_wpml->products->is_original_product( $object_id )
809
+ ){
810
+ $translations = $this->post_translations->get_element_translations( $object_id, false, true );
811
+ remove_action( 'deleted_post_meta', array( $this, 'delete_empty_post_meta_for_translations' ), 10, 3 );
812
+ foreach( $translations as $translation ) {
813
+ delete_post_meta( $translation, $meta_key );
814
+ }
815
+ add_action( 'deleted_post_meta', array( $this, 'delete_empty_post_meta_for_translations' ), 10, 3 );
816
+ }
817
+
818
+ }
819
+
820
 
821
  }
inc/translation-editor/class-wcml-synchronize-variations-data.php CHANGED
@@ -309,6 +309,8 @@ class WCML_Synchronize_Variations_Data{
309
  }
310
  }
311
  }
 
 
312
  }
313
  }
314
 
309
  }
310
  }
311
  }
312
+ $wcml_data_store = wcml_product_data_store_cpt();
313
+ $wcml_data_store->update_lookup_table_data( $variation_id );
314
  }
315
  }
316
 
inc/wcml-core-functions.php CHANGED
@@ -79,3 +79,16 @@ if ( ! function_exists( 'wcml_get_woocommerce_currency_option' ) ) {
79
  return get_option( 'woocommerce_currency' );
80
  }
81
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
79
  return get_option( 'woocommerce_currency' );
80
  }
81
  }
82
+
83
+ if ( ! function_exists( 'wcml_product_data_store_cpt' ) ) {
84
+ /**
85
+ * It returns a single instance of the class.
86
+ *
87
+ * @return \WCML_Product_Data_Store_CPT
88
+ *
89
+ * @since 4.6.8
90
+ */
91
+ function wcml_product_data_store_cpt() {
92
+ return new WCML_Product_Data_Store_CPT();
93
+ }
94
+ }
inc/wcml-switch-lang-request.php CHANGED
@@ -50,7 +50,7 @@ class WCML_Switch_Lang_Request{
50
  }
51
 
52
  /**
53
- * @return string language code stored in the user's _icl_current_language cookie
54
  */
55
  public function get_cookie_lang() {
56
  global $wpml_language_resolution;
@@ -65,7 +65,7 @@ class WCML_Switch_Lang_Request{
65
 
66
  public function get_cookie_name() {
67
 
68
- return '_icl_current_language';
69
  }
70
 
71
  /**
50
  }
51
 
52
  /**
53
+ * @return string language code stored in the user's wp_wpml_current_language cookie
54
  */
55
  public function get_cookie_lang() {
56
  global $wpml_language_resolution;
65
 
66
  public function get_cookie_name() {
67
 
68
+ return 'wp_wpml_current_language';
69
  }
70
 
71
  /**
lib/twig/lib/Twig/Autoloader.php DELETED
@@ -1,49 +0,0 @@
1
- <?php
2
-
3
- namespace WCML;
4
-
5
- /*
6
- * This file is part of Twig.
7
- *
8
- * (c) Fabien Potencier
9
- *
10
- * For the full copyright and license information, please view the LICENSE
11
- * file that was distributed with this source code.
12
- */
13
- @\trigger_error('The Twig_Autoloader class is deprecated since version 1.21 and will be removed in 2.0. Use Composer instead.', \E_USER_DEPRECATED);
14
- /**
15
- * Autoloads Twig classes.
16
- *
17
- * @author Fabien Potencier <fabien@symfony.com>
18
- *
19
- * @deprecated since 1.21 and will be removed in 2.0. Use Composer instead. 2.0.
20
- */
21
- class Twig_Autoloader
22
- {
23
- /**
24
- * Registers Twig_Autoloader as an SPL autoloader.
25
- *
26
- * @param bool $prepend whether to prepend the autoloader or not
27
- */
28
- public static function register($prepend = \false)
29
- {
30
- @\trigger_error('Using Twig_Autoloader is deprecated since version 1.21. Use Composer instead.', \E_USER_DEPRECATED);
31
- \spl_autoload_register([__CLASS__, 'autoload'], \true, $prepend);
32
- }
33
- /**
34
- * Handles autoloading of classes.
35
- *
36
- * @param string $class a class name
37
- */
38
- public static function autoload($class)
39
- {
40
- if (0 !== \strpos($class, 'Twig')) {
41
- return;
42
- }
43
- if (\is_file($file = __DIR__ . '/../' . \str_replace(['_', "\0"], ['/', ''], $class) . '.php')) {
44
- require $file;
45
- } elseif (\is_file($file = __DIR__ . '/../../src/' . \str_replace(['Twig\\', '\\', "\0"], ['', '/', ''], $class) . '.php')) {
46
- require $file;
47
- }
48
- }
49
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/twig/lib/Twig/BaseNodeVisitor.php DELETED
@@ -1,11 +0,0 @@
1
- <?php
2
-
3
- namespace WCML;
4
-
5
- use WCML\Twig\NodeVisitor\AbstractNodeVisitor;
6
- \class_exists('WCML\\Twig\\NodeVisitor\\AbstractNodeVisitor');
7
- if (\false) {
8
- class Twig_BaseNodeVisitor extends \WCML\Twig\NodeVisitor\AbstractNodeVisitor
9
- {
10
- }
11
- }
 
 
 
 
 
 
 
 
 
 
 
lib/twig/lib/Twig/Cache/Filesystem.php DELETED
@@ -1,11 +0,0 @@
1
- <?php
2
-
3
- namespace WCML;
4
-
5
- use WCML\Twig\Cache\FilesystemCache;
6
- \class_exists('WCML\\Twig\\Cache\\FilesystemCache');
7
- if (\false) {
8
- class Twig_Cache_Filesystem extends \WCML\Twig\Cache\FilesystemCache
9
- {
10
- }
11
- }
 
 
 
 
 
 
 
 
 
 
 
lib/twig/lib/Twig/Cache/Null.php DELETED
@@ -1,11 +0,0 @@
1
- <?php
2
-
3
- namespace WCML;
4
-
5
- use WCML\Twig\Cache\NullCache;
6
- \class_exists('WCML\\Twig\\Cache\\NullCache');
7
- if (\false) {
8
- class Twig_Cache_Null extends \WCML\Twig\Cache\NullCache
9
- {
10
- }
11
- }
 
 
 
 
 
 
 
 
 
 
 
lib/twig/lib/Twig/CacheInterface.php DELETED
@@ -1,11 +0,0 @@
1
- <?php
2
-
3
- namespace WCML;
4
-
5
- use WCML\Twig\Cache\CacheInterface;
6
- \class_exists('WCML\\Twig\\Cache\\CacheInterface');
7
- if (\false) {
8
- class Twig_CacheInterface extends \WCML\Twig\Cache\CacheInterface
9
- {
10
- }
11
- }
 
 
 
 
 
 
 
 
 
 
 
lib/twig/lib/Twig/Compiler.php DELETED
@@ -1,11 +0,0 @@
1
- <?php
2
-
3
- namespace WCML;
4
-
5
- use WCML\Twig\Compiler;
6
- \class_exists('WCML\\Twig\\Compiler');
7
- if (\false) {
8
- class Twig_Compiler extends \WCML\Twig\Compiler
9
- {
10
- }
11
- }
 
 
 
 
 
 
 
 
 
 
 
lib/twig/lib/Twig/CompilerInterface.php DELETED
@@ -1,34 +0,0 @@
1
- <?php
2
-
3
- namespace WCML;
4
-
5
- /*
6
- * This file is part of Twig.
7
- *
8
- * (c) Fabien Potencier
9
- *
10
- * For the full copyright and license information, please view the LICENSE
11
- * file that was distributed with this source code.
12
- */
13
- /**
14
- * Interface implemented by compiler classes.
15
- *
16
- * @author Fabien Potencier <fabien@symfony.com>
17
- *
18
- * @deprecated since 1.12 (to be removed in 3.0)
19
- */
20
- interface Twig_CompilerInterface
21
- {
22
- /**
23
- * Compiles a node.
24
- *
25
- * @return $this
26
- */
27
- public function compile(\WCML\Twig_NodeInterface $node);
28
- /**
29
- * Gets the current PHP code after compilation.
30
- *
31
- * @return string The PHP code
32
- */
33
- public function getSource();
34
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/twig/lib/Twig/ContainerRuntimeLoader.php DELETED
@@ -1,11 +0,0 @@
1
- <?php
2
-
3
- namespace WCML;
4
-
5
- use WCML\Twig\RuntimeLoader\ContainerRuntimeLoader;
6
- \class_exists('WCML\\Twig\\RuntimeLoader\\ContainerRuntimeLoader');
7
- if (\false) {
8
- class Twig_ContainerRuntimeLoader extends \WCML\Twig\RuntimeLoader\ContainerRuntimeLoader
9
- {
10
- }
11
- }
 
 
 
 
 
 
 
 
 
 
 
lib/twig/lib/Twig/Environment.php DELETED
@@ -1,11 +0,0 @@
1
- <?php
2
-
3
- namespace WCML;
4
-
5
- use WCML\Twig\Environment;
6
- \class_exists('WCML\\Twig\\Environment');
7
- if (\false) {
8
- class Twig_Environment extends \WCML\Twig\Environment
9
- {
10
- }
11
- }
 
 
 
 
 
 
 
 
 
 
 
lib/twig/lib/Twig/Error.php DELETED
@@ -1,11 +0,0 @@
1
- <?php
2
-
3
- namespace WCML;
4
-
5
- use WCML\Twig\Error\Error;
6
- \class_exists('WCML\\Twig\\Error\\Error');
7
- if (\false) {
8
- class Twig_Error extends \WCML\Twig\Error\Error
9
- {
10
- }
11
- }
 
 
 
 
 
 
 
 
 
 
 
lib/twig/lib/Twig/Error/Loader.php DELETED
@@ -1,11 +0,0 @@
1
- <?php
2
-
3
- namespace WCML;
4
-
5
- use WCML\Twig\Error\LoaderError;
6
- \class_exists('WCML\\Twig\\Error\\LoaderError');
7
- if (\false) {
8
- class Twig_Error_Loader extends \WCML\Twig\Error\LoaderError
9
- {
10
- }
11
- }
 
 
 
 
 
 
 
 
 
 
 
lib/twig/lib/Twig/Error/Runtime.php DELETED
@@ -1,11 +0,0 @@
1
- <?php
2
-
3
- namespace WCML;
4
-
5
- use WCML\Twig\Error\RuntimeError;
6
- \class_exists('WCML\\Twig\\Error\\RuntimeError');
7
- if (\false) {
8
- class Twig_Error_Runtime extends \WCML\Twig\Error\RuntimeError
9
- {
10
- }
11
- }
 
 
 
 
 
 
 
 
 
 
 
lib/twig/lib/Twig/Error/Syntax.php DELETED
@@ -1,11 +0,0 @@
1
- <?php
2
-
3
- namespace WCML;
4
-
5
- use WCML\Twig\Error\SyntaxError;
6
- \class_exists('WCML\\Twig\\Error\\SyntaxError');
7
- if (\false) {
8
- class Twig_Error_Syntax extends \WCML\Twig\Error\SyntaxError
9
- {
10
- }
11
- }
 
 
 
 
 
 
 
 
 
 
 
lib/twig/lib/Twig/ExistsLoaderInterface.php DELETED
@@ -1,11 +0,0 @@
1
- <?php
2
-
3
- namespace WCML;
4
-
5
- use WCML\Twig\Loader\ExistsLoaderInterface;
6
- \class_exists('WCML\\Twig\\Loader\\ExistsLoaderInterface');
7
- if (\false) {
8
- class Twig_ExistsLoaderInterface extends \WCML\Twig\Loader\ExistsLoaderInterface
9
- {
10
- }
11
- }
 
 
 
 
 
 
 
 
 
 
 
lib/twig/lib/Twig/ExpressionParser.php DELETED
@@ -1,11 +0,0 @@
1
- <?php
2
-
3
- namespace WCML;
4
-
5
- use WCML\Twig\ExpressionParser;
6
- \class_exists('WCML\\Twig\\ExpressionParser');
7
- if (\false) {
8
- class Twig_ExpressionParser extends \WCML\Twig\ExpressionParser
9
- {
10
- }
11
- }
 
 
 
 
 
 
 
 
 
 
 
lib/twig/lib/Twig/Extension.php DELETED
@@ -1,11 +0,0 @@
1
- <?php
2
-
3
- namespace WCML;
4
-
5
- use WCML\Twig\Extension\AbstractExtension;
6
- \class_exists('WCML\\Twig\\Extension\\AbstractExtension');
7
- if (\false) {
8
- class Twig_Extension extends \WCML\Twig\Extension\AbstractExtension
9
- {
10
- }
11
- }
 
 
 
 
 
 
 
 
 
 
 
lib/twig/lib/Twig/Extension/Core.php DELETED
@@ -1,11 +0,0 @@
1
- <?php
2
-
3
- namespace WCML;
4
-
5
- use WCML\Twig\Extension\CoreExtension;
6
- \class_exists('WCML\\Twig\\Extension\\CoreExtension');
7
- if (\false) {
8
- class Twig_Extension_Core extends \WCML\Twig\Extension\CoreExtension
9
- {
10
- }
11
- }
 
 
 
 
 
 
 
 
 
 
 
lib/twig/lib/Twig/Extension/Debug.php DELETED
@@ -1,11 +0,0 @@
1
- <?php
2
-
3
- namespace WCML;
4
-
5
- use WCML\Twig\Extension\DebugExtension;
6
- \class_exists('WCML\\Twig\\Extension\\DebugExtension');
7
- if (\false) {
8
- class Twig_Extension_Debug extends \WCML\Twig\Extension\DebugExtension
9
- {
10
- }
11
- }
 
 
 
 
 
 
 
 
 
 
 
lib/twig/lib/Twig/Extension/Escaper.php DELETED
@@ -1,11 +0,0 @@
1
- <?php
2
-
3
- namespace WCML;
4
-
5
- use WCML\Twig\Extension\EscaperExtension;
6
- \class_exists('WCML\\Twig\\Extension\\EscaperExtension');
7
- if (\false) {
8
- class Twig_Extension_Escaper extends \WCML\Twig\Extension\EscaperExtension
9
- {
10
- }
11
- }
 
 
 
 
 
 
 
 
 
 
 
lib/twig/lib/Twig/Extension/GlobalsInterface.php DELETED
@@ -1,11 +0,0 @@
1
- <?php
2
-
3
- namespace WCML;
4
-
5
- use WCML\Twig\Extension\GlobalsInterface;
6
- \class_exists('WCML\\Twig\\Extension\\GlobalsInterface');
7
- if (\false) {
8
- class Twig_Extension_GlobalsInterface extends \WCML\Twig\Extension\GlobalsInterface
9
- {
10
- }
11
- }
 
 
 
 
 
 
 
 
 
 
 
lib/twig/lib/Twig/Extension/InitRuntimeInterface.php DELETED
@@ -1,11 +0,0 @@
1
- <?php
2
-
3
- namespace WCML;
4
-
5
- use WCML\Twig\Extension\InitRuntimeInterface;
6
- \class_exists('WCML\\Twig\\Extension\\InitRuntimeInterface');
7
- if (\false) {
8
- class Twig_Extension_InitRuntimeInterface extends \WCML\Twig\Extension\InitRuntimeInterface
9
- {
10
- }
11
- }
 
 
 
 
 
 
 
 
 
 
 
lib/twig/lib/Twig/Extension/Optimizer.php DELETED
@@ -1,11 +0,0 @@
1
- <?php
2
-
3
- namespace WCML;
4
-
5
- use WCML\Twig\Extension\OptimizerExtension;
6
- \class_exists('WCML\\Twig\\Extension\\OptimizerExtension');
7
- if (\false) {
8
- class Twig_Extension_Optimizer extends \WCML\Twig\Extension\OptimizerExtension
9
- {
10
- }
11
- }
 
 
 
 
 
 
 
 
 
 
 
lib/twig/lib/Twig/Extension/Profiler.php DELETED
@@ -1,11 +0,0 @@
1
- <?php
2
-
3
- namespace WCML;
4
-
5
- use WCML\Twig\Extension\ProfilerExtension;
6
- \class_exists('WCML\\Twig\\Extension\\ProfilerExtension');
7
- if (\false) {
8
- class Twig_Extension_Profiler extends \WCML\Twig\Extension\ProfilerExtension
9
- {
10
- }
11
- }
 
 
 
 
 
 
 
 
 
 
 
lib/twig/lib/Twig/Extension/Sandbox.php DELETED
@@ -1,11 +0,0 @@
1
- <?php
2
-
3
- namespace WCML;
4
-
5
- use WCML\Twig\Extension\SandboxExtension;
6
- \class_exists('WCML\\Twig\\Extension\\SandboxExtension');
7
- if (\false) {
8
- class Twig_Extension_Sandbox extends \WCML\Twig\Extension\SandboxExtension
9
- {
10
- }
11
- }
 
 
 
 
 
 
 
 
 
 
 
lib/twig/lib/Twig/Extension/Staging.php DELETED
@@ -1,11 +0,0 @@
1
- <?php
2
-
3
- namespace WCML;
4
-
5
- use WCML\Twig\Extension\StagingExtension;
6
- \class_exists('WCML\\Twig\\Extension\\StagingExtension');
7
- if (\false) {
8
- class Twig_Extension_Staging extends \WCML\Twig\Extension\StagingExtension
9
- {
10
- }
11
- }
 
 
 
 
 
 
 
 
 
 
 
lib/twig/lib/Twig/Extension/StringLoader.php DELETED
@@ -1,11 +0,0 @@
1
- <?php
2
-
3
- namespace WCML;
4
-
5
- use WCML\Twig\Extension\StringLoaderExtension;
6
- \class_exists('WCML\\Twig\\Extension\\StringLoaderExtension');
7
- if (\false) {
8
- class Twig_Extension_StringLoader extends \WCML\Twig\Extension\StringLoaderExtension
9
- {
10
- }
11
- }
 
 
 
 
 
 
 
 
 
 
 
lib/twig/lib/Twig/ExtensionInterface.php DELETED
@@ -1,11 +0,0 @@
1
- <?php
2
-
3
- namespace WCML;
4
-
5
- use WCML\Twig\Extension\ExtensionInterface;
6
- \class_exists('WCML\\Twig\\Extension\\ExtensionInterface');
7
- if (\false) {
8
- class Twig_ExtensionInterface extends \WCML\Twig\Extension\ExtensionInterface
9
- {
10
- }
11
- }
 
 
 
 
 
 
 
 
 
 
 
lib/twig/lib/Twig/FactoryRuntimeLoader.php DELETED
@@ -1,11 +0,0 @@
1
- <?php
2
-
3
- namespace WCML;
4
-
5
- use WCML\Twig\RuntimeLoader\FactoryRuntimeLoader;
6
- \class_exists('WCML\\Twig\\RuntimeLoader\\FactoryRuntimeLoader');
7
- if (\false) {
8
- class Twig_FactoryRuntimeLoader extends \WCML\Twig\RuntimeLoader\FactoryRuntimeLoader
9
- {
10
- }
11
- }
 
 
 
 
 
 
 
 
 
 
 
lib/twig/lib/Twig/FileExtensionEscapingStrategy.php DELETED
@@ -1,11 +0,0 @@
1
- <?php
2
-
3
- namespace WCML;
4
-
5
- use WCML\Twig\FileExtensionEscapingStrategy;
6
- \class_exists('WCML\\Twig\\FileExtensionEscapingStrategy');
7
- if (\false) {
8
- class Twig_FileExtensionEscapingStrategy extends \WCML\Twig\FileExtensionEscapingStrategy
9
- {
10
- }
11
- }
 
 
 
 
 
 
 
 
 
 
 
lib/twig/lib/Twig/Filter.php DELETED
@@ -1,69 +0,0 @@
1
- <?php
2
-
3
- namespace WCML;
4
-
5
- /*
6
- * This file is part of Twig.
7
- *
8
- * (c) Fabien Potencier
9
- *
10
- * For the full copyright and license information, please view the LICENSE
11
- * file that was distributed with this source code.
12
- */
13
- use WCML\Twig\Node\Node;
14
- @\trigger_error('The Twig_Filter class is deprecated since version 1.12 and will be removed in 2.0. Use \\Twig\\TwigFilter instead.', \E_USER_DEPRECATED);
15
- /**
16
- * Represents a template filter.
17
- *
18
- * Use \Twig\TwigFilter instead.
19
- *
20
- * @author Fabien Potencier <fabien@symfony.com>
21
- *
22
- * @deprecated since 1.12 (to be removed in 2.0)
23
- */
24
- abstract class Twig_Filter implements \WCML\Twig_FilterInterface, \WCML\Twig_FilterCallableInterface
25
- {
26
- protected $options;
27
- protected $arguments = [];
28
- public function __construct(array $options = [])
29
- {
30
- $this->options = \array_merge(['needs_environment' => \false, 'needs_context' => \false, 'pre_escape' => null, 'preserves_safety' => null, 'callable' => null], $options);
31
- }
32
- public function setArguments($arguments)
33
- {
34
- $this->arguments = $arguments;
35
- }
36
- public function getArguments()
37
- {
38
- return $this->arguments;
39
- }
40
- public function needsEnvironment()
41
- {
42
- return $this->options['needs_environment'];
43
- }
44
- public function needsContext()
45
- {
46
- return $this->options['needs_context'];
47
- }
48
- public function getSafe(\WCML\Twig\Node\Node $filterArgs)
49
- {
50
- if (isset($this->options['is_safe'])) {
51
- return $this->options['is_safe'];
52
- }
53
- if (isset($this->options['is_safe_callback'])) {
54
- return \call_user_func($this->options['is_safe_callback'], $filterArgs);
55
- }
56
- }
57
- public function getPreservesSafety()
58
- {
59
- return $this->options['preserves_safety'];
60
- }
61
- public function getPreEscape()
62
- {
63
- return $this->options['pre_escape'];
64
- }
65
- public function getCallable()
66
- {
67
- return $this->options['callable'];
68
- }
69
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/twig/lib/Twig/Filter/Function.php DELETED
@@ -1,36 +0,0 @@
1
- <?php
2
-
3
- namespace WCML;
4
-
5
- /*
6
- * This file is part of Twig.
7
- *
8
- * (c) Fabien Potencier
9
- *
10
- * For the full copyright and license information, please view the LICENSE
11
- * file that was distributed with this source code.
12
- */
13
- @\trigger_error('The Twig_Filter_Function class is deprecated since version 1.12 and will be removed in 2.0. Use \\Twig\\TwigFilter instead.', \E_USER_DEPRECATED);
14
- /**
15
- * Represents a function template filter.
16
- *
17
- * Use \Twig\TwigFilter instead.
18
- *
19
- * @author Fabien Potencier <fabien@symfony.com>
20
- *
21
- * @deprecated since 1.12 (to be removed in 2.0)
22
- */
23
- class Twig_Filter_Function extends \WCML\Twig_Filter
24
- {
25
- protected $function;
26
- public function __construct($function, array $options = [])
27
- {
28
- $options['callable'] = $function;
29
- parent::__construct($options);
30
- $this->function = $function;
31
- }
32
- public function compile()
33
- {
34
- return $this->function;
35
- }
36
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/twig/lib/Twig/Filter/Method.php DELETED
@@ -1,39 +0,0 @@
1
- <?php
2
-
3
- namespace WCML;
4
-
5
- /*
6
- * This file is part of Twig.
7
- *
8
- * (c) Fabien Potencier
9
- *
10
- * For the full copyright and license information, please view the LICENSE
11
- * file that was distributed with this source code.
12
- */
13
- use WCML\Twig\Extension\ExtensionInterface;
14
- @\trigger_error('The Twig_Filter_Method class is deprecated since version 1.12 and will be removed in 2.0. Use \\Twig\\TwigFilter instead.', \E_USER_DEPRECATED);
15
- /**
16
- * Represents a method template filter.
17
- *
18
- * Use \Twig\TwigFilter instead.
19
- *
20
- * @author Fabien Potencier <fabien@symfony.com>
21
- *
22
- * @deprecated since 1.12 (to be removed in 2.0)
23
- */
24
- class Twig_Filter_Method extends \WCML\Twig_Filter
25
- {
26
- protected $extension;
27
- protected $method;
28
- public function __construct(\WCML\Twig\Extension\ExtensionInterface $extension, $method, array $options = [])
29
- {
30
- $options['callable'] = [$extension, $method];
31
- parent::__construct($options);
32
- $this->extension = $extension;
33
- $this->method = $method;
34
- }
35
- public function compile()
36
- {
37
- return \sprintf('$this->env->getExtension(\'%s\')->%s', \get_class($this->extension), $this->method);
38
- }
39
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/twig/lib/Twig/Filter/Node.php DELETED
@@ -1,38 +0,0 @@
1
- <?php
2
-
3
- namespace WCML;
4
-
5
- /*
6
- * This file is part of Twig.
7
- *
8
- * (c) Fabien Potencier
9
- *
10
- * For the full copyright and license information, please view the LICENSE
11
- * file that was distributed with this source code.
12
- */
13
- @\trigger_error('The Twig_Filter_Node class is deprecated since version 1.12 and will be removed in 2.0. Use \\Twig\\TwigFilter instead.', \E_USER_DEPRECATED);
14
- /**
15
- * Represents a template filter as a node.
16
- *
17
- * Use \Twig\TwigFilter instead.
18
- *
19
- * @author Fabien Potencier <fabien@symfony.com>
20
- *
21
- * @deprecated since 1.12 (to be removed in 2.0)
22
- */
23
- class Twig_Filter_Node extends \WCML\Twig_Filter
24
- {
25
- protected $class;
26
- public function __construct($class, array $options = [])
27
- {
28
- parent::__construct($options);
29
- $this->class = $class;
30
- }
31
- public function getClass()
32
- {
33
- return $this->class;
34
- }
35
- public function compile()
36
- {
37
- }
38
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/twig/lib/Twig/FilterCallableInterface.php DELETED
@@ -1,25 +0,0 @@
1
- <?php
2
-
3
- namespace WCML;
4
-
5
- /*
6
- * This file is part of Twig.
7
- *
8
- * (c) Fabien Potencier
9
- *
10
- * For the full copyright and license information, please view the LICENSE
11
- * file that was distributed with this source code.
12
- */
13
- /**
14
- * Represents a callable template filter.
15
- *
16
- * Use \Twig\TwigFilter instead.
17
- *
18
- * @author Fabien Potencier <fabien@symfony.com>
19
- *
20
- * @deprecated since 1.12 (to be removed in 2.0)
21
- */
22
- interface Twig_FilterCallableInterface
23
- {
24
- public function getCallable();
25
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/twig/lib/Twig/FilterInterface.php DELETED
@@ -1,38 +0,0 @@
1
- <?php
2
-
3
- namespace WCML;
4
-
5
- /*
6
- * This file is part of Twig.
7
- *
8
- * (c) Fabien Potencier
9
- *
10
- * For the full copyright and license information, please view the LICENSE
11
- * file that was distributed with this source code.
12
- */
13
- use WCML\Twig\Node\Node;
14
- /**
15
- * Represents a template filter.
16
- *
17
- * Use \Twig\TwigFilter instead.
18
- *
19
- * @author Fabien Potencier <fabien@symfony.com>
20
- *
21
- * @deprecated since 1.12 (to be removed in 2.0)
22
- */
23
- interface Twig_FilterInterface
24
- {
25
- /**
26
- * Compiles a filter.
27
- *
28
- * @return string The PHP code for the filter
29
- */
30
- public function compile();
31
- public function needsEnvironment();
32
- public function needsContext();
33
- public function getSafe(\WCML\Twig\Node\Node $filterArgs);
34
- public function getPreservesSafety();
35
- public function getPreEscape();
36
- public function setArguments($arguments);
37
- public function getArguments();
38
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/twig/lib/Twig/Function.php DELETED
@@ -1,62 +0,0 @@
1
- <?php
2
-
3
- namespace WCML;
4
-
5
- /*
6
- * This file is part of Twig.
7
- *
8
- * (c) Fabien Potencier
9
- *
10
- * For the full copyright and license information, please view the LICENSE
11
- * file that was distributed with this source code.
12
- */
13
- use WCML\Twig\Node\Node;
14
- @\trigger_error('The Twig_Function class is deprecated since version 1.12 and will be removed in 2.0. Use \\Twig\\TwigFunction instead.', \E_USER_DEPRECATED);
15
- /**
16
- * Represents a template function.
17
- *
18
- * Use \Twig\TwigFunction instead.
19
- *
20
- * @author Fabien Potencier <fabien@symfony.com>
21
- *
22
- * @deprecated since 1.12 (to be removed in 2.0)
23
- */
24
- abstract class Twig_Function implements \WCML\Twig_FunctionInterface, \WCML\Twig_FunctionCallableInterface
25
- {
26
- protected $options;
27
- protected $arguments = [];
28
- public function __construct(array $options = [])
29
- {
30
- $this->options = \array_merge(['needs_environment' => \false, 'needs_context' => \false, 'callable' => null], $options);
31
- }
32
- public function setArguments($arguments)
33
- {
34
- $this->arguments = $arguments;
35
- }
36
- public function getArguments()
37
- {
38
- return $this->arguments;
39
- }
40
- public function needsEnvironment()
41
- {
42
- return $this->options['needs_environment'];
43
- }
44
- public function needsContext()
45
- {
46
- return $this->options['needs_context'];
47
- }
48
- public function getSafe(\WCML\Twig\Node\Node $functionArgs)
49
- {
50
- if (isset($this->options['is_safe'])) {
51
- return $this->options['is_safe'];
52
- }
53
- if (isset($this->options['is_safe_callback'])) {
54
- return \call_user_func($this->options['is_safe_callback'], $functionArgs);
55
- }
56
- return [];
57
- }
58
- public function getCallable()
59
- {
60
- return $this->options['callable'];
61
- }
62
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/twig/lib/Twig/Function/Function.php DELETED
@@ -1,37 +0,0 @@
1
- <?php
2
-
3
- namespace WCML;
4
-
5
- /*
6
- * This file is part of Twig.
7
- *
8
- * (c) Fabien Potencier
9
- * (c) Arnaud Le Blanc
10
- *
11
- * For the full copyright and license information, please view the LICENSE
12
- * file that was distributed with this source code.
13
- */
14
- @\trigger_error('The Twig_Function_Function class is deprecated since version 1.12 and will be removed in 2.0. Use \\Twig\\TwigFunction instead.', \E_USER_DEPRECATED);
15
- /**
16
- * Represents a function template function.
17
- *
18
- * Use \Twig\TwigFunction instead.
19
- *
20
- * @author Arnaud Le Blanc <arnaud.lb@gmail.com>
21
- *
22
- * @deprecated since 1.12 (to be removed in 2.0)
23
- */
24
- class Twig_Function_Function extends \WCML\Twig_Function
25
- {
26
- protected $function;
27
- public function __construct($function, array $options = [])
28
- {
29
- $options['callable'] = $function;
30
- parent::__construct($options);
31
- $this->function = $function;
32
- }
33
- public function compile()
34
- {
35
- return $this->function;
36
- }
37
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/twig/lib/Twig/Function/Method.php DELETED
@@ -1,40 +0,0 @@
1
- <?php
2
-
3
- namespace WCML;
4
-
5
- /*
6
- * This file is part of Twig.
7
- *
8
- * (c) Fabien Potencier
9
- * (c) Arnaud Le Blanc
10
- *
11
- * For the full copyright and license information, please view the LICENSE
12
- * file that was distributed with this source code.
13
- */
14
- use WCML\Twig\Extension\ExtensionInterface;
15
- @\trigger_error('The Twig_Function_Method class is deprecated since version 1.12 and will be removed in 2.0. Use \\Twig\\TwigFunction instead.', \E_USER_DEPRECATED);
16
- /**
17
- * Represents a method template function.
18
- *
19
- * Use \Twig\TwigFunction instead.
20
- *
21
- * @author Arnaud Le Blanc <arnaud.lb@gmail.com>
22
- *
23
- * @deprecated since 1.12 (to be removed in 2.0)
24
- */
25
- class Twig_Function_Method extends \WCML\Twig_Function
26
- {
27
- protected $extension;
28
- protected $method;
29
- public function __construct(\WCML\Twig\Extension\ExtensionInterface $extension, $method, array $options = [])
30
- {
31
- $options['callable'] = [$extension, $method];
32
- parent::__construct($options);
33
- $this->extension = $extension;
34
- $this->method = $method;
35
- }
36
- public function compile()
37
- {
38
- return \sprintf('$this->env->getExtension(\'%s\')->%s', \get_class($this->extension), $this->method);
39
- }
40
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/twig/lib/Twig/Function/Node.php DELETED
@@ -1,38 +0,0 @@
1
- <?php
2
-
3
- namespace WCML;
4
-
5
- /*
6
- * This file is part of Twig.
7
- *
8
- * (c) Fabien Potencier
9
- *
10
- * For the full copyright and license information, please view the LICENSE
11
- * file that was distributed with this source code.
12
- */
13
- @\trigger_error('The Twig_Function_Node class is deprecated since version 1.12 and will be removed in 2.0. Use \\Twig\\TwigFunction instead.', \E_USER_DEPRECATED);
14
- /**
15
- * Represents a template function as a node.
16
- *
17
- * Use \Twig\TwigFunction instead.
18
- *
19
- * @author Fabien Potencier <fabien@symfony.com>
20
- *
21
- * @deprecated since 1.12 (to be removed in 2.0)
22
- */
23
- class Twig_Function_Node extends \WCML\Twig_Function
24
- {
25
- protected $class;
26
- public function __construct($class, array $options = [])
27
- {
28
- parent::__construct($options);
29
- $this->class = $class;
30
- }
31
- public function getClass()
32
- {
33
- return $this->class;
34
- }
35
- public function compile()
36
- {
37
- }
38
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/twig/lib/Twig/FunctionCallableInterface.php DELETED
@@ -1,25 +0,0 @@
1
- <?php
2
-
3
- namespace WCML;
4
-
5
- /*
6
- * This file is part of Twig.
7
- *
8
- * (c) Fabien Potencier
9
- *
10
- * For the full copyright and license information, please view the LICENSE
11
- * file that was distributed with this source code.
12
- */
13
- /**
14
- * Represents a callable template function.
15
- *
16
- * Use \Twig\TwigFunction instead.
17
- *
18
- * @author Fabien Potencier <fabien@symfony.com>
19
- *
20
- * @deprecated since 1.12 (to be removed in 2.0)
21
- */
22
- interface Twig_FunctionCallableInterface
23
- {
24
- public function getCallable();
25
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/twig/lib/Twig/FunctionInterface.php DELETED
@@ -1,37 +0,0 @@
1
- <?php
2
-
3
- namespace WCML;
4
-
5
- /*
6
- * This file is part of Twig.
7
- *
8
- * (c) Fabien Potencier
9
- * (c) Arnaud Le Blanc
10
- *
11
- * For the full copyright and license information, please view the LICENSE
12
- * file that was distributed with this source code.
13
- */
14
- use WCML\Twig\Node\Node;
15
- /**
16
- * Represents a template function.
17
- *
18
- * Use \Twig\TwigFunction instead.
19
- *
20
- * @author Arnaud Le Blanc <arnaud.lb@gmail.com>
21
- *
22
- * @deprecated since 1.12 (to be removed in 2.0)
23
- */
24
- interface Twig_FunctionInterface
25
- {
26
- /**
27
- * Compiles a function.
28
- *
29
- * @return string The PHP code for the function
30
- */
31
- public function compile();
32
- public function needsEnvironment();
33
- public function needsContext();
34
- public function getSafe(\WCML\Twig\Node\Node $filterArgs);
35
- public function setArguments($arguments);
36
- public function getArguments();
37
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/twig/lib/Twig/Lexer.php DELETED
@@ -1,11 +0,0 @@
1
- <?php
2
-
3
- namespace WCML;
4
-
5
- use WCML\Twig\Lexer;
6
- \class_exists('WCML\\Twig\\Lexer');
7
- if (\false) {
8
- class Twig_Lexer extends \WCML\Twig\Lexer
9
- {
10
- }
11
- }
 
 
 
 
 
 
 
 
 
 
 
lib/twig/lib/Twig/LexerInterface.php DELETED
@@ -1,36 +0,0 @@
1
- <?php
2
-
3
- namespace WCML;
4
-
5
- /*
6
- * This file is part of Twig.
7
- *
8
- * (c) Fabien Potencier
9
- *
10
- * For the full copyright and license information, please view the LICENSE
11
- * file that was distributed with this source code.
12
- */
13
- use WCML\Twig\Error\SyntaxError;
14
- use WCML\Twig\Source;
15
- use WCML\Twig\TokenStream;
16
- /**
17
- * Interface implemented by lexer classes.
18
- *
19
- * @author Fabien Potencier <fabien@symfony.com>
20
- *
21
- * @deprecated since 1.12 (to be removed in 3.0)
22
- */
23
- interface Twig_LexerInterface
24
- {
25
- /**
26
- * Tokenizes a source code.
27
- *
28
- * @param string|Source $code The source code
29
- * @param string $name A unique identifier for the source code
30
- *
31
- * @return TokenStream
32
- *
33
- * @throws SyntaxError When the code is syntactically wrong
34
- */
35
- public function tokenize($code, $name = null);
36
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/twig/lib/Twig/Loader/Array.php DELETED
@@ -1,11 +0,0 @@
1
- <?php
2
-
3
- namespace WCML;
4
-
5
- use WCML\Twig\Loader\ArrayLoader;
6
- \class_exists('WCML\\Twig\\Loader\\ArrayLoader');
7
- if (\false) {
8
- class Twig_Loader_Array extends \WCML\Twig\Loader\ArrayLoader
9
- {
10
- }
11
- }
 
 
 
 
 
 
 
 
 
 
 
lib/twig/lib/Twig/Loader/Chain.php DELETED
@@ -1,11 +0,0 @@
1
- <?php
2
-
3
- namespace WCML;
4
-
5
- use WCML\Twig\Loader\ChainLoader;
6
- \class_exists('WCML\\Twig\\Loader\\ChainLoader');
7
- if (\false) {
8
- class Twig_Loader_Chain extends \WCML\Twig\Loader\ChainLoader
9
- {
10
- }
11
- }
 
 
 
 
 
 
 
 
 
 
 
lib/twig/lib/Twig/Loader/Filesystem.php DELETED
@@ -1,11 +0,0 @@
1
- <?php
2
-
3
- namespace WCML;
4
-
5
- use WCML\Twig\Loader\FilesystemLoader;
6
- \class_exists('WCML\\Twig\\Loader\\FilesystemLoader');
7
- if (\false) {
8
- class Twig_Loader_Filesystem extends \WCML\Twig\Loader\FilesystemLoader
9
- {
10
- }
11
- }
 
 
 
 
 
 
 
 
 
 
 
lib/twig/lib/Twig/Loader/String.php DELETED
@@ -1,57 +0,0 @@
1
- <?php
2
-
3
- namespace WCML;
4
-
5
- /*
6
- * This file is part of Twig.
7
- *
8
- * (c) Fabien Potencier
9
- *
10
- * For the full copyright and license information, please view the LICENSE
11
- * file that was distributed with this source code.
12
- */
13
- use WCML\Twig\Loader\ExistsLoaderInterface;
14
- use WCML\Twig\Loader\LoaderInterface;
15
- use WCML\Twig\Loader\SourceContextLoaderInterface;
16
- use WCML\Twig\Source;
17
- @\trigger_error('The Twig_Loader_String class is deprecated since version 1.18.1 and will be removed in 2.0. Use "Twig\\Loader\\ArrayLoader" instead or "Twig\\Environment::createTemplate()".', \E_USER_DEPRECATED);
18
- /**
19
- * Loads a template from a string.
20
- *
21
- * This loader should NEVER be used. It only exists for Twig internal purposes.
22
- *
23
- * When using this loader with a cache mechanism, you should know that a new cache
24
- * key is generated each time a template content "changes" (the cache key being the
25
- * source code of the template). If you don't want to see your cache grows out of
26
- * control, you need to take care of clearing the old cache file by yourself.
27
- *
28
- * @deprecated since 1.18.1 (to be removed in 2.0)
29
- *
30
- * @internal
31
- *
32
- * @author Fabien Potencier <fabien@symfony.com>
33
- */
34
- class Twig_Loader_String implements \WCML\Twig\Loader\LoaderInterface, \WCML\Twig\Loader\ExistsLoaderInterface, \WCML\Twig\Loader\SourceContextLoaderInterface
35
- {
36
- public function getSource($name)
37
- {
38
- @\trigger_error(\sprintf('Calling "getSource" on "%s" is deprecated since 1.27. Use getSourceContext() instead.', \get_class($this)), \E_USER_DEPRECATED);
39
- return $name;
40
- }
41
- public function getSourceContext($name)
42
- {
43
- return new \WCML\Twig\Source($name, $name);
44
- }
45
- public function exists($name)
46
- {
47
- return \true;
48
- }
49
- public function getCacheKey($name)
50
- {
51
- return $name;
52
- }
53
- public function isFresh($name, $time)
54
- {
55
- return \true;
56
- }
57
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/twig/lib/Twig/LoaderInterface.php DELETED
@@ -1,11 +0,0 @@
1
- <?php
2
-
3
- namespace WCML;
4
-
5
- use WCML\Twig\Loader\LoaderInterface;
6
- \class_exists('WCML\\Twig\\Loader\\LoaderInterface');
7
- if (\false) {
8
- class Twig_LoaderInterface extends \WCML\Twig\Loader\LoaderInterface
9
- {
10
- }
11
- }
 
 
 
 
 
 
 
 
 
 
 
lib/twig/lib/Twig/Markup.php DELETED
@@ -1,11 +0,0 @@
1
- <?php
2
-
3
- namespace WCML;
4
-
5
- use WCML\Twig\Markup;
6
- \class_exists('WCML\\Twig\\Markup');
7
- if (\false) {
8
- class Twig_Markup extends \WCML\Twig\Markup
9
- {
10
- }
11
- }
 
 
 
 
 
 
 
 
 
 
 
lib/twig/lib/Twig/Node.php DELETED
@@ -1,11 +0,0 @@
1
- <?php
2
-
3
- namespace WCML;
4
-
5
- use WCML\Twig\Node\Node;
6
- \class_exists('WCML\\Twig\\Node\\Node');
7
- if (\false) {
8
- class Twig_Node extends \WCML\Twig\Node\Node
9
- {
10
- }
11
- }
 
 
 
 
 
 
 
 
 
 
 
lib/twig/lib/Twig/Node/AutoEscape.php DELETED
@@ -1,11 +0,0 @@
1
- <?php
2
-
3
- namespace WCML;
4
-
5
- use WCML\Twig\Node\AutoEscapeNode;
6
- \class_exists('WCML\\Twig\\Node\\AutoEscapeNode');
7
- if (\false) {
8
- class Twig_Node_AutoEscape extends \WCML\Twig\Node\AutoEscapeNode
9
- {
10
- }
11
- }
 
 
 
 
 
 
 
 
 
 
 
lib/twig/lib/Twig/Node/Block.php DELETED
@@ -1,11 +0,0 @@
1
- <?php
2
-
3
- namespace WCML;
4
-
5
- use WCML\Twig\Node\BlockNode;
6
- \class_exists('WCML\\Twig\\Node\\BlockNode');
7
- if (\false) {
8
- class Twig_Node_Block extends \WCML\Twig\Node\BlockNode
9
- {
10
- }
11
- }
 
 
 
 
 
 
 
 
 
 
 
lib/twig/lib/Twig/Node/BlockReference.php DELETED
@@ -1,11 +0,0 @@
1
- <?php
2
-
3
- namespace WCML;
4
-
5
- use WCML\Twig\Node\BlockReferenceNode;
6
- \class_exists('WCML\\Twig\\Node\\BlockReferenceNode');
7
- if (\false) {
8
- class Twig_Node_BlockReference extends \WCML\Twig\Node\BlockReferenceNode
9
- {
10
- }
11
- }
 
 
 
 
 
 
 
 
 
 
 
lib/twig/lib/Twig/Node/Body.php DELETED
@@ -1,11 +0,0 @@
1
- <?php
2
-
3
- namespace WCML;
4
-
5
- use WCML\Twig\Node\BodyNode;
6
- \class_exists('WCML\\Twig\\Node\\BodyNode');
7
- if (\false) {
8
- class Twig_Node_Body extends \WCML\Twig\Node\BodyNode
9
- {
10
- }
11
- }
 
 
 
 
 
 
 
 
 
 
 
lib/twig/lib/Twig/Node/CheckSecurity.php DELETED
@@ -1,11 +0,0 @@
1
- <?php
2
-
3
- namespace WCML;
4
-
5
- use WCML\Twig\Node\CheckSecurityNode;
6
- \class_exists('WCML\\Twig\\Node\\CheckSecurityNode');
7
- if (\false) {
8
- class Twig_Node_CheckSecurity extends \WCML\Twig\Node\CheckSecurityNode
9
- {
10
- }
11
- }
 
 
 
 
 
 
 
 
 
 
 
lib/twig/lib/Twig/Node/Deprecated.php DELETED
@@ -1,11 +0,0 @@
1
- <?php
2
-
3
- namespace WCML;
4
-
5
- use WCML\Twig\Node\DeprecatedNode;
6
- \class_exists('WCML\\Twig\\Node\\DeprecatedNode');
7
- if (\false) {
8
- class Twig_Node_Deprecated extends \WCML\Twig\Node\DeprecatedNode
9
- {
10
- }
11
- }
 
 
 
 
 
 
 
 
 
 
 
lib/twig/lib/Twig/Node/Do.php DELETED
@@ -1,11 +0,0 @@
1
- <?php
2
-
3
- namespace WCML;
4
-
5
- use WCML\Twig\Node\DoNode;
6
- \class_exists('WCML\\Twig\\Node\\DoNode');
7
- if (\false) {
8
- class Twig_Node_Do extends \WCML\Twig\Node\DoNode
9
- {
10
- }
11
- }
 
 
 
 
 
 
 
 
 
 
 
lib/twig/lib/Twig/Node/Embed.php DELETED
@@ -1,11 +0,0 @@
1
- <?php
2
-
3
- namespace WCML;
4
-
5
- use WCML\Twig\Node\EmbedNode;
6
- \class_exists('WCML\\Twig\\Node\\EmbedNode');
7
- if (\false) {
8
- class Twig_Node_Embed extends \WCML\Twig\Node\EmbedNode
9
- {
10
- }
11
- }
 
 
 
 
 
 
 
 
 
 
 
lib/twig/lib/Twig/Node/Expression.php DELETED
@@ -1,11 +0,0 @@
1
- <?php
2
-
3
- namespace WCML;
4
-
5
- use WCML\Twig\Node\Expression\AbstractExpression;
6
- \class_exists('WCML\\Twig\\Node\\Expression\\AbstractExpression');
7
- if (\false) {
8
- class Twig_Node_Expression extends \WCML\Twig\Node\Expression\AbstractExpression
9
- {
10
- }
11
- }
 
 
 
 
 
 
 
 
 
 
 
lib/twig/lib/Twig/Node/Expression/Array.php DELETED
@@ -1,11 +0,0 @@
1
- <?php
2
-
3
- namespace WCML;
4
-
5
- use WCML\Twig\Node\Expression\ArrayExpression;
6
- \class_exists('WCML\\Twig\\Node\\Expression\\ArrayExpression');
7
- if (\false) {
8
- class Twig_Node_Expression_Array extends \WCML\Twig\Node\Expression\ArrayExpression
9
- {
10
- }
11
- }
 
 
 
 
 
 
 
 
 
 
 
lib/twig/lib/Twig/Node/Expression/AssignName.php DELETED
@@ -1,11 +0,0 @@
1
- <?php
2
-
3
- namespace WCML;
4
-
5
- use WCML\Twig\Node\Expression\AssignNameExpression;
6
- \class_exists('WCML\\Twig\\Node\\Expression\\AssignNameExpression');
7
- if (\false) {
8
- class Twig_Node_Expression_AssignName extends \WCML\Twig\Node\Expression\AssignNameExpression
9
- {
10
- }
11
- }
 
 
 
 
 
 
 
 
 
 
 
lib/twig/lib/Twig/Node/Expression/Binary.php DELETED
@@ -1,11 +0,0 @@
1
- <?php
2
-
3
- namespace WCML;
4
-
5
- use WCML\Twig\Node\Expression\Binary\AbstractBinary;
6
- \class_exists('WCML\\Twig\\Node\\Expression\\Binary\\AbstractBinary');
7
- if (\false) {
8
- class Twig_Node_Expression_Binary extends \WCML\Twig\Node\Expression\Binary\AbstractBinary
9
- {
10
- }
11
- }
 
 
 
 
 
 
 
 
 
 
 
lib/twig/lib/Twig/Node/Expression/Binary/Add.php DELETED
@@ -1,11 +0,0 @@
1
- <?php
2
-
3
- namespace WCML;
4
-
5
- use WCML\Twig\Node\Expression\Binary\AddBinary;
6
- \class_exists('WCML\\Twig\\Node\\Expression\\Binary\\AddBinary');
7
- if (\false) {
8
- class Twig_Node_Expression_Binary_Add extends \WCML\Twig\Node\Expression\Binary\AddBinary
9
- {
10
- }
11
- }
 
 
 
 
 
 
 
 
 
 
 
lib/twig/lib/Twig/Node/Expression/Binary/And.php DELETED
@@ -1,11 +0,0 @@
1
- <?php
2
-
3
- namespace WCML;
4
-
5
- use WCML\Twig\Node\Expression\Binary\AndBinary;
6
- \class_exists('WCML\\Twig\\Node\\Expression\\Binary\\AndBinary');
7
- if (\false) {
8
- class Twig_Node_Expression_Binary_And extends \WCML\Twig\Node\Expression\Binary\AndBinary
9
- {
10
- }
11
- }
 
 
 
 
 
 
 
 
 
 
 
lib/twig/lib/Twig/Node/Expression/Binary/BitwiseAnd.php DELETED
@@ -1,11 +0,0 @@
1
- <?php
2
-
3
- namespace WCML;
4
-
5
- use WCML\Twig\Node\Expression\Binary\BitwiseAndBinary;
6
- \class_exists('WCML\\Twig\\Node\\Expression\\Binary\\BitwiseAndBinary');
7
- if (\false) {
8
- class Twig_Node_Expression_Binary_BitwiseAnd extends \WCML\Twig\Node\Expression\Binary\BitwiseAndBinary
9
- {
10
- }
11
- }
 
 
 
 
 
 
 
 
 
 
 
lib/twig/lib/Twig/Node/Expression/Binary/BitwiseOr.php DELETED
@@ -1,11 +0,0 @@
1
- <?php
2
-
3
- namespace WCML;
4
-
5
- use WCML\Twig\Node\Expression\Binary\BitwiseOrBinary;
6
- \class_exists('WCML\\Twig\\Node\\Expression\\Binary\\BitwiseOrBinary');
7
- if (\false) {
8
- class Twig_Node_Expression_Binary_BitwiseOr extends \WCML\Twig\Node\Expression\Binary\BitwiseOrBinary
9
- {
10
- }
11
- }
 
 
 
 
 
 
 
 
 
 
 
lib/twig/lib/Twig/Node/Expression/Binary/BitwiseXor.php DELETED
@@ -1,11 +0,0 @@
1
- <?php
2
-
3
- namespace WCML;
4
-
5
- use WCML\Twig\Node\Expression\Binary\BitwiseXorBinary;
6
- \class_exists('WCML\\Twig\\Node\\Expression\\Binary\\BitwiseXorBinary');
7
- if (\false) {
8
- class Twig_Node_Expression_Binary_BitwiseXor extends \WCML\Twig\Node\Expression\Binary\BitwiseXorBinary
9
- {
10
- }
11
- }
 
 
 
 
 
 
 
 
 
 
 
lib/twig/lib/Twig/Node/Expression/Binary/Concat.php DELETED
@@ -1,11 +0,0 @@
1
- <?php
2
-
3
- namespace WCML;
4
-
5
- use WCML\Twig\Node\Expression\Binary\ConcatBinary;
6
- \class_exists('WCML\\Twig\\Node\\Expression\\Binary\\ConcatBinary');
7
- if (\false) {
8
- class Twig_Node_Expression_Binary_Concat extends \WCML\Twig\Node\Expression\Binary\ConcatBinary
9
- {
10
- }
11
- }
 
 
 
 
 
 
 
 
 
 
 
lib/twig/lib/Twig/Node/Expression/Binary/Div.php DELETED
@@ -1,11 +0,0 @@
1
- <?php
2
-
3
- namespace WCML;
4
-
5
- use WCML\Twig\Node\Expression\Binary\DivBinary;
6
- \class_exists('WCML\\Twig\\Node\\Expression\\Binary\\DivBinary');
7
- if (\false) {
8
- class Twig_Node_Expression_Binary_Div extends \WCML\Twig\Node\Expression\Binary\DivBinary
9
- {
10
- }
11
- }
 
 
 
 
 
 
 
 
 
 
 
lib/twig/lib/Twig/Node/Expression/Binary/EndsWith.php DELETED
@@ -1,11 +0,0 @@
1
- <?php
2
-
3
- namespace WCML;
4
-
5
- use WCML\Twig\Node\Expression\Binary\EndsWithBinary;
6
- \class_exists('WCML\\Twig\\Node\\Expression\\Binary\\EndsWithBinary');
7
- if (\false) {
8
- class Twig_Node_Expression_Binary_EndsWith extends \WCML\Twig\Node\Expression\Binary\EndsWithBinary
9
- {
10
- }
11
- }
 
 
 
 
 
 
 
 
 
 
 
lib/twig/lib/Twig/Node/Expression/Binary/Equal.php DELETED
@@ -1,11 +0,0 @@
1
- <?php
2
-
3
- namespace WCML;
4
-
5
- use WCML\Twig\Node\Expression\Binary\EqualBinary;
6
- \class_exists('WCML\\Twig\\Node\\Expression\\Binary\\EqualBinary');
7
- if (\false) {
8
- class Twig_Node_Expression_Binary_Equal extends \WCML\Twig\Node\Expression\Binary\EqualBinary
9
- {
10
- }
11
- }
 
 
 
 
 
 
 
 
 
 
 
lib/twig/lib/Twig/Node/Expression/Binary/FloorDiv.php DELETED
@@ -1,11 +0,0 @@
1
- <?php
2
-
3
- namespace WCML;
4
-
5
- use WCML\Twig\Node\Expression\Binary\FloorDivBinary;
6
- \class_exists('WCML\\Twig\\Node\\Expression\\Binary\\FloorDivBinary');
7
- if (\false) {
8
- class Twig_Node_Expression_Binary_FloorDiv extends \WCML\Twig\Node\Expression\Binary\FloorDivBinary
9
- {
10
- }
11
- }
 
 
 
 
 
 
 
 
 
 
 
lib/twig/lib/Twig/Node/Expression/Binary/Greater.php DELETED
@@ -1,11 +0,0 @@
1
- <?php
2
-
3
- namespace WCML;
4
-
5
- use WCML\Twig\Node\Expression\Binary\GreaterBinary;
6
- \class_exists('WCML\\Twig\\Node\\Expression\\Binary\\GreaterBinary');
7
- if (\false) {
8
- class Twig_Node_Expression_Binary_Greater extends \WCML\Twig\Node\Expression\Binary\GreaterBinary
9
- {
10
- }
11
- }
 
 
 
 
 
 
 
 
 
 
 
lib/twig/lib/Twig/Node/Expression/Binary/GreaterEqual.php DELETED
@@ -1,11 +0,0 @@
1
- <?php
2
-
3
- namespace WCML;
4
-
5
- use WCML\Twig\Node\Expression\Binary\GreaterEqualBinary;
6
- \class_exists('WCML\\Twig\\Node\\Expression\\Binary\\GreaterEqualBinary');
7
- if (\false) {
8
- class Twig_Node_Expression_Binary_GreaterEqual extends \WCML\Twig\Node\Expression\Binary\GreaterEqualBinary
9
- {
10
- }
11
- }
 
 
 
 
 
 
 
 
 
 
 
lib/twig/lib/Twig/Node/Expression/Binary/In.php DELETED
@@ -1,11 +0,0 @@
1
- <?php
2
-
3
- namespace WCML;
4
-
5
- use WCML\Twig\Node\Expression\Binary\InBinary;
6
- \class_exists('WCML\\Twig\\Node\\Expression\\Binary\\InBinary');
7
- if (\false) {
8
- class Twig_Node_Expression_Binary_In extends \WCML\Twig\Node\Expression\Binary\InBinary
9
- {
10
- }
11
- }
 
 
 
 
 
 
 
 
 
 
 
lib/twig/lib/Twig/Node/Expression/Binary/Less.php DELETED
@@ -1,11 +0,0 @@
1
- <?php
2
-
3
- namespace WCML;
4
-
5
- use WCML\Twig\Node\Expression\Binary\LessBinary;
6
- \class_exists('WCML\\Twig\\Node\\Expression\\Binary\\LessBinary');
7
- if (\false) {
8
- class Twig_Node_Expression_Binary_Less extends \WCML\Twig\Node\Expression\Binary\LessBinary
9
- {
10
- }
11
- }
 
 
 
 
 
 
 
 
 
 
 
lib/twig/lib/Twig/Node/Expression/Binary/LessEqual.php DELETED
@@ -1,11 +0,0 @@
1
- <?php
2
-
3
- namespace WCML;
4
-
5
- use WCML\Twig\Node\Expression\Binary\LessEqualBinary;
6
- \class_exists('WCML\\Twig\\Node\\Expression\\Binary\\LessEqualBinary');
7
- if (\false) {
8
- class Twig_Node_Expression_Binary_LessEqual extends \WCML\Twig\Node\Expression\Binary\LessEqualBinary
9
- {
10
- }
11
- }
 
 
 
 
 
 
 
 
 
 
 
lib/twig/lib/Twig/Node/Expression/Binary/Matches.php DELETED
@@ -1,11 +0,0 @@
1
- <?php
2
-
3
- namespace WCML;
4
-
5
- use WCML\Twig\Node\Expression\Binary\MatchesBinary;
6
- \class_exists('WCML\\Twig\\Node\\Expression\\Binary\\MatchesBinary');
7
- if (\false) {
8
- class Twig_Node_Expression_Binary_Matches extends \WCML\Twig\Node\Expression\Binary\MatchesBinary
9
- {
10
- }
11
- }
 
 
 
 
 
 
 
 
 
 
 
lib/twig/lib/Twig/Node/Expression/Binary/Mod.php DELETED
@@ -1,11 +0,0 @@
1
- <?php
2
-
3
- namespace WCML;
4
-
5
- use WCML\Twig\Node\Expression\Binary\ModBinary;
6
- \class_exists('WCML\\Twig\\Node\\Expression\\Binary\\ModBinary');
7
- if (\false) {
8
- class Twig_Node_Expression_Binary_Mod extends \WCML\Twig\Node\Expression\Binary\ModBinary
9
- {
10
- }
11
- }
 
 
 
 
 
 
 
 
 
 
 
lib/twig/lib/Twig/Node/Expression/Binary/Mul.php DELETED
@@ -1,11 +0,0 @@
1
- <?php
2
-
3
- namespace WCML;
4
-
5
- use WCML\Twig\Node\Expression\Binary\MulBinary;
6
- \class_exists('WCML\\Twig\\Node\\Expression\\Binary\\MulBinary');
7
- if (\false) {
8
- class Twig_Node_Expression_Binary_Mul extends \WCML\Twig\Node\Expression\Binary\MulBinary
9
- {
10
- }
11
- }
 
 
 
 
 
 
 
 
 
 
 
lib/twig/lib/Twig/Node/Expression/Binary/NotEqual.php DELETED
@@ -1,11 +0,0 @@
1
- <?php
2
-
3
- namespace WCML;
4
-
5
- use WCML\Twig\Node\Expression\Binary\NotEqualBinary;
6
- \class_exists('WCML\\Twig\\Node\\Expression\\Binary\\NotEqualBinary');
7
- if (\false) {
8
- class Twig_Node_Expression_Binary_NotEqual extends \WCML\Twig\Node\Expression\Binary\NotEqualBinary
9
- {
10
- }
11
- }
 
 
 
 
 
 
 
 
 
 
 
lib/twig/lib/Twig/Node/Expression/Binary/NotIn.php DELETED
@@ -1,11 +0,0 @@
1
- <?php
2
-
3
- namespace WCML;
4
-
5
- use WCML\Twig\Node\Expression\Binary\NotInBinary;
6
- \class_exists('WCML\\Twig\\Node\\Expression\\Binary\\NotInBinary');
7
- if (\false) {
8
- class Twig_Node_Expression_Binary_NotIn extends \WCML\Twig\Node\Expression\Binary\NotInBinary
9
- {
10
- }
11
- }
 
 
 
 
 
 
 
 
 
 
 
lib/twig/lib/Twig/Node/Expression/Binary/Or.php DELETED
@@ -1,11 +0,0 @@
1
- <?php
2
-
3
- namespace WCML;
4
-
5
- use WCML\Twig\Node\Expression\Binary\OrBinary;
6
- \class_exists('WCML\\Twig\\Node\\Expression\\Binary\\OrBinary');
7
- if (\false) {
8
- class Twig_Node_Expression_Binary_Or extends \WCML\Twig\Node\Expression\Binary\OrBinary
9
- {
10
- }
11
- }
 
 
 
 
 
 
 
 
 
 
 
lib/twig/lib/Twig/Node/Expression/Binary/Power.php DELETED
@@ -1,11 +0,0 @@
1
- <?php
2
-
3
- namespace WCML;
4
-
5
- use WCML\Twig\Node\Expression\Binary\PowerBinary;
6
- \class_exists('WCML\\Twig\\Node\\Expression\\Binary\\PowerBinary');
7
- if (\false) {
8
- class Twig_Node_Expression_Binary_Power extends \WCML\Twig\Node\Expression\Binary\PowerBinary
9
- {
10
- }
11
- }
 
 
 
 
 
 
 
 
 
 
 
lib/twig/lib/Twig/Node/Expression/Binary/Range.php DELETED
@@ -1,11 +0,0 @@
1
- <?php
2
-
3
- namespace WCML;
4
-
5
- use WCML\Twig\Node\Expression\Binary\RangeBinary;
6
- \class_exists('WCML\\Twig\\Node\\Expression\\Binary\\RangeBinary');
7
- if (\false) {
8
- class Twig_Node_Expression_Binary_Range extends \WCML\Twig\Node\Expression\Binary\RangeBinary
9
- {
10
- }
11
- }
 
 
 
 
 
 
 
 
 
 
 
lib/twig/lib/Twig/Node/Expression/Binary/StartsWith.php DELETED
@@ -1,11 +0,0 @@
1
- <?php
2
-
3
- namespace WCML;
4
-
5
- use WCML\Twig\Node\Expression\Binary\StartsWithBinary;
6
- \class_exists('WCML\\Twig\\Node\\Expression\\Binary\\StartsWithBinary');
7
- if (\false) {
8
- class Twig_Node_Expression_Binary_StartsWith extends \WCML\Twig\Node\Expression\Binary\StartsWithBinary
9
- {
10
- }
11
- }
 
 
 
 
 
 
 
 
 
 
 
lib/twig/lib/Twig/Node/Expression/Binary/Sub.php DELETED
@@ -1,11 +0,0 @@
1
- <?php
2
-
3
- namespace WCML;
4
-
5
- use WCML\Twig\Node\Expression\Binary\SubBinary;
6
- \class_exists('WCML\\Twig\\Node\\Expression\\Binary\\SubBinary');
7
- if (\false) {
8
- class Twig_Node_Expression_Binary_Sub extends \WCML\Twig\Node\Expression\Binary\SubBinary
9
- {
10
- }
11
- }
 
 
 
 
 
 
 
 
 
 
 
lib/twig/lib/Twig/Node/Expression/BlockReference.php DELETED
@@ -1,11 +0,0 @@
1
- <?php
2
-
3
- namespace WCML;
4
-
5
- use WCML\Twig\Node\Expression\BlockReferenceExpression;
6
- \class_exists('WCML\\Twig\\Node\\Expression\\BlockReferenceExpression');
7
- if (\false) {
8
- class Twig_Node_Expression_BlockReference extends \WCML\Twig\Node\Expression\BlockReferenceExpression
9
- {
10
- }
11
- }
 
 
 
 
 
 
 
 
 
 
 
lib/twig/lib/Twig/Node/Expression/Call.php DELETED
@@ -1,11 +0,0 @@
1
- <?php
2
-
3
- namespace WCML;
4
-
5
- use WCML\Twig\Node\Expression\CallExpression;
6
- \class_exists('WCML\\Twig\\Node\\Expression\\CallExpression');
7
- if (\false) {
8
- class Twig_Node_Expression_Call extends \WCML\Twig\Node\Expression\CallExpression
9
- {
10
- }
11
- }
 
 
 
 
 
 
 
 
 
 
 
lib/twig/lib/Twig/Node/Expression/Conditional.php DELETED
@@ -1,11 +0,0 @@
1
- <?php
2
-
3
- namespace WCML;
4
-
5
- use WCML\Twig\Node\Expression\ConditionalExpression;
6
- \class_exists('WCML\\Twig\\Node\\Expression\\ConditionalExpression');
7
- if (\false) {
8
- class Twig_Node_Expression_Conditional extends \WCML\Twig\Node\Expression\ConditionalExpression
9
- {
10
- }
11
- }
 
 
 
 
 
 
 
 
 
 
 
lib/twig/lib/Twig/Node/Expression/Constant.php DELETED
@@ -1,11 +0,0 @@
1
- <?php
2
-
3
- namespace WCML;
4
-
5
- use WCML\Twig\Node\Expression\ConstantExpression;
6
- \class_exists('WCML\\Twig\\Node\\Expression\\ConstantExpression');
7
- if (\false) {
8
- class Twig_Node_Expression_Constant extends \WCML\Twig\Node\Expression\ConstantExpression
9
- {
10
- }
11
- }
 
 
 
 
 
 
 
 
 
 
 
lib/twig/lib/Twig/Node/Expression/ExtensionReference.php DELETED
@@ -1,33 +0,0 @@
1
- <?php
2
-
3
- namespace WCML;
4
-
5
- /*
6
- * This file is part of Twig.
7
- *
8
- * (c) Fabien Potencier
9
- *
10
- * For the full copyright and license information, please view the LICENSE
11
- * file that was distributed with this source code.
12
- */
13
- use WCML\Twig\Compiler;
14
- use WCML\Twig\Node\Expression\AbstractExpression;
15
- @\trigger_error('The Twig_Node_Expression_ExtensionReference class is deprecated since version 1.23 and will be removed in 2.0.', \E_USER_DEPRECATED);
16
- /**
17
- * Represents an extension call node.
18
- *
19
- * @author Fabien Potencier <fabien@symfony.com>
20
- *
21
- * @deprecated since 1.23 and will be removed in 2.0.
22
- */
23
- class Twig_Node_Expression_ExtensionReference extends \WCML\Twig\Node\Expression\AbstractExpression
24
- {
25
- public function __construct($name, $lineno, $tag = null)
26
- {
27
- parent::__construct([], ['name' => $name], $lineno, $tag);
28
- }
29
- public function compile(\WCML\Twig\Compiler $compiler)
30
- {
31
- $compiler->raw(\sprintf("\$this->env->getExtension('%s')", $this->getAttribute('name')));
32
- }
33
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/twig/lib/Twig/Node/Expression/Filter.php DELETED
@@ -1,11 +0,0 @@
1
- <?php
2
-
3
- namespace WCML;
4
-
5
- use WCML\Twig\Node\Expression\FilterExpression;
6
- \class_exists('WCML\\Twig\\Node\\Expression\\FilterExpression');
7
- if (\false) {
8
- class Twig_Node_Expression_Filter extends \WCML\Twig\Node\Expression\FilterExpression
9
- {
10
- }
11
- }
 
 
 
 
 
 
 
 
 
 
 
lib/twig/lib/Twig/Node/Expression/Filter/Default.php DELETED
@@ -1,11 +0,0 @@
1
- <?php
2
-
3
- namespace WCML;
4
-
5
- use WCML\Twig\Node\Expression\Filter\DefaultFilter;
6
- \class_exists('WCML\\Twig\\Node\\Expression\\Filter\\DefaultFilter');
7
- if (\false) {
8
- class Twig_Node_Expression_Filter_Default extends \WCML\Twig\Node\Expression\Filter\DefaultFilter
9
- {
10
- }
11
- }
 
 
 
 
 
 
 
 
 
 
 
lib/twig/lib/Twig/Node/Expression/Function.php DELETED
@@ -1,11 +0,0 @@
1
- <?php
2
-
3
- namespace WCML;
4
-
5
- use WCML\Twig\Node\Expression\FunctionExpression;
6
- \class_exists('WCML\\Twig\\Node\\Expression\\FunctionExpression');
7
- if (\false) {
8
- class Twig_Node_Expression_Function extends \WCML\Twig\Node\Expression\FunctionExpression
9
- {
10
- }
11
- }
 
 
 
 
 
 
 
 
 
 
 
lib/twig/lib/Twig/Node/Expression/GetAttr.php DELETED
@@ -1,11 +0,0 @@
1
- <?php
2
-
3
- namespace WCML;
4
-
5
- use WCML\Twig\Node\Expression\GetAttrExpression;
6
- \class_exists('WCML\\Twig\\Node\\Expression\\GetAttrExpression');
7
- if (\false) {
8
- class Twig_Node_Expression_GetAttr extends \WCML\Twig\Node\Expression\GetAttrExpression
9
- {
10
- }
11
- }
 
 
 
 
 
 
 
 
 
 
 
lib/twig/lib/Twig/Node/Expression/MethodCall.php DELETED
@@ -1,11 +0,0 @@
1
- <?php
2
-
3
- namespace WCML;
4
-
5
- use WCML\Twig\Node\Expression\MethodCallExpression;
6
- \class_exists('WCML\\Twig\\Node\\Expression\\MethodCallExpression');
7
- if (\false) {
8
- class Twig_Node_Expression_MethodCall extends \WCML\Twig\Node\Expression\MethodCallExpression
9
- {
10
- }
11
- }
 
 
 
 
 
 
 
 
 
 
 
lib/twig/lib/Twig/Node/Expression/Name.php DELETED
@@ -1,11 +0,0 @@
1
- <?php
2
-
3
- namespace WCML;
4
-
5
- use WCML\Twig\Node\Expression\NameExpression;
6
- \class_exists('WCML\\Twig\\Node\\Expression\\NameExpression');
7
- if (\false) {
8
- class Twig_Node_Expression_Name extends \WCML\Twig\Node\Expression\NameExpression
9
- {
10
- }
11
- }
 
 
 
 
 
 
 
 
 
 
 
lib/twig/lib/Twig/Node/Expression/NullCoalesce.php DELETED
@@ -1,11 +0,0 @@
1
- <?php
2
-
3
- namespace WCML;
4
-
5
- use WCML\Twig\Node\Expression\NullCoalesceExpression;
6
- \class_exists('WCML\\Twig\\Node\\Expression\\NullCoalesceExpression');
7
- if (\false) {
8
- class Twig_Node_Expression_NullCoalesce extends \WCML\Twig\Node\Expression\NullCoalesceExpression
9
- {
10
- }
11
- }
 
 
 
 
 
 
 
 
 
 
 
lib/twig/lib/Twig/Node/Expression/Parent.php DELETED
@@ -1,11 +0,0 @@
1
- <?php
2
-
3
- namespace WCML;
4
-
5
- use WCML\Twig\Node\Expression\ParentExpression;
6
- \class_exists('WCML\\Twig\\Node\\Expression\\ParentExpression');
7
- if (\false) {
8
- class Twig_Node_Expression_Parent extends \WCML\Twig\Node\Expression\ParentExpression
9
- {
10
- }
11
- }
 
 
 
 
 
 
 
 
 
 
 
lib/twig/lib/Twig/Node/Expression/TempName.php DELETED
@@ -1,11 +0,0 @@
1
- <?php
2
-
3
- namespace WCML;
4
-
5
- use WCML\Twig\Node\Expression\TempNameExpression;
6
- \class_exists('WCML\\Twig\\Node\\Expression\\TempNameExpression');
7
- if (\false) {
8
- class Twig_Node_Expression_TempName extends \WCML\Twig\Node\Expression\TempNameExpression
9
- {
10
- }
11
- }
 
 
 
 
 
 
 
 
 
 
 
lib/twig/lib/Twig/Node/Expression/Test.php DELETED
@@ -1,11 +0,0 @@
1
- <?php
2
-
3
- namespace WCML;
4
-
5
- use WCML\Twig\Node\Expression\TestExpression;
6
- \class_exists('WCML\\Twig\\Node\\Expression\\TestExpression');
7
- if (\false) {
8
- class Twig_Node_Expression_Test extends \WCML\Twig\Node\Expression\TestExpression
9
- {
10
- }
11
- }
 
 
 
 
 
 
 
 
 
 
 
lib/twig/lib/Twig/Node/Expression/Test/Constant.php DELETED
@@ -1,11 +0,0 @@
1
- <?php
2
-
3
- namespace WCML;
4
-
5
- use WCML\Twig\Node\Expression\Test\ConstantTest;
6
- \class_exists('WCML\\Twig\\Node\\Expression\\Test\\ConstantTest');
7
- if (\false) {
8
- class Twig_Node_Expression_Test_Constant extends \WCML\Twig\Node\Expression\Test\ConstantTest
9
- {
10
- }
11
- }
 
 
 
 
 
 
 
 
 
 
 
lib/twig/lib/Twig/Node/Expression/Test/Defined.php DELETED
@@ -1,11 +0,0 @@
1
- <?php
2
-
3
- namespace WCML;
4
-
5
- use WCML\Twig\Node\Expression\Test\DefinedTest;
6
- \class_exists('WCML\\Twig\\Node\\Expression\\Test\\DefinedTest');
7
- if (\false) {
8
- class Twig_Node_Expression_Test_Defined extends \WCML\Twig\Node\Expression\Test\DefinedTest
9
- {
10
- }
11
- }
 
 
 
 
 
 
 
 
 
 
 
lib/twig/lib/Twig/Node/Expression/Test/Divisibleby.php DELETED
@@ -1,11 +0,0 @@
1
- <?php
2
-
3
- namespace WCML;
4
-
5
- use WCML\Twig\Node\Expression\Test\DivisiblebyTest;
6
- \class_exists('WCML\\Twig\\Node\\Expression\\Test\\DivisiblebyTest');
7
- if (\false) {
8
- class Twig_Node_Expression_Test_Divisibleby extends \WCML\Twig\Node\Expression\Test\DivisiblebyTest
9
- {
10
- }
11
- }
 
 
 
 
 
 
 
 
 
 
 
lib/twig/lib/Twig/Node/Expression/Test/Even.php DELETED
@@ -1,11 +0,0 @@
1
- <?php
2
-
3
- namespace WCML;
4
-
5
- use WCML\Twig\Node\Expression\Test\EvenTest;
6
- \class_exists('WCML\\Twig\\Node\\Expression\\Test\\EvenTest');
7
- if (\false) {
8
- class Twig_Node_Expression_Test_Even extends \WCML\Twig\Node\Expression\Test\EvenTest
9
- {
10
- }
11
- }
 
 
 
 
 
 
 
 
 
 
 
lib/twig/lib/Twig/Node/Expression/Test/Null.php DELETED
@@ -1,11 +0,0 @@
1
- <?php
2
-
3
- namespace WCML;
4
-
5
- use WCML\Twig\Node\Expression\Test\NullTest;
6
- \class_exists('WCML\\Twig\\Node\\Expression\\Test\\NullTest');
7
- if (\false) {
8
- class Twig_Node_Expression_Test_Null extends \WCML\Twig\Node\Expression\Test\NullTest
9
- {
10
- }
11
- }
 
 
 
 
 
 
 
 
 
 
 
lib/twig/lib/Twig/Node/Expression/Test/Odd.php DELETED
@@ -1,11 +0,0 @@
1
- <?php
2
-
3
- namespace WCML;
4
-
5
- use WCML\Twig\Node\Expression\Test\OddTest;
6
- \class_exists('WCML\\Twig\\Node\\Expression\\Test\\OddTest');
7
- if (\false) {
8
- class Twig_Node_Expression_Test_Odd extends \WCML\Twig\Node\Expression\Test\OddTest
9
- {
10
- }
11
- }
 
 
 
 
 
 
 
 
 
 
 
lib/twig/lib/Twig/Node/Expression/Test/Sameas.php DELETED
@@ -1,11 +0,0 @@
1
- <?php
2
-
3
- namespace WCML;
4
-
5
- use WCML\Twig\Node\Expression\Test\SameasTest;
6
- \class_exists('WCML\\Twig\\Node\\Expression\\Test\\SameasTest');
7
- if (\false) {
8
- class Twig_Node_Expression_Test_Sameas extends \WCML\Twig\Node\Expression\Test\SameasTest
9
- {
10
- }
11
- }
 
 
 
 
 
 
 
 
 
 
 
lib/twig/lib/Twig/Node/Expression/Unary.php DELETED
@@ -1,11 +0,0 @@
1
- <?php
2
-
3
- namespace WCML;
4
-
5
- use WCML\Twig\Node\Expression\Unary\AbstractUnary;
6
- \class_exists('WCML\\Twig\\Node\\Expression\\Unary\\AbstractUnary');
7
- if (\false) {
8
- class Twig_Node_Expression_Unary extends \WCML\Twig\Node\Expression\Unary\AbstractUnary
9
- {
10
- }
11
- }
 
 
 
 
 
 
 
 
 
 
 
lib/twig/lib/Twig/Node/Expression/Unary/Neg.php DELETED
@@ -1,11 +0,0 @@
1
- <?php
2
-
3
- namespace WCML;
4
-
5
- use WCML\Twig\Node\Expression\Unary\NegUnary;
6
- \class_exists('WCML\\Twig\\Node\\Expression\\Unary\\NegUnary');
7
- if (\false) {
8
- class Twig_Node_Expression_Unary_Neg extends \WCML\Twig\Node\Expression\Unary\NegUnary
9
- {
10
- }
11
- }
 
 
 
 
 
 
 
 
 
 
 
lib/twig/lib/Twig/Node/Expression/Unary/Not.php DELETED
@@ -1,11 +0,0 @@
1
- <?php
2
-
3
- namespace WCML;
4
-
5
- use WCML\Twig\Node\Expression\Unary\NotUnary;
6
- \class_exists('WCML\\Twig\\Node\\Expression\\Unary\\NotUnary');
7
- if (\false) {
8
- class Twig_Node_Expression_Unary_Not extends \WCML\Twig\Node\Expression\Unary\NotUnary
9
- {
10
- }
11
- }
 
 
 
 
 
 
 
 
 
 
 
lib/twig/lib/Twig/Node/Expression/Unary/Pos.php DELETED
@@ -1,11 +0,0 @@
1
- <?php
2
-
3
- namespace WCML;
4
-
5
- use WCML\Twig\Node\Expression\Unary\PosUnary;
6
- \class_exists('WCML\\Twig\\Node\\Expression\\Unary\\PosUnary');
7
- if (\false) {
8
- class Twig_Node_Expression_Unary_Pos extends \WCML\Twig\Node\Expression\Unary\PosUnary
9
- {
10
- }
11
- }
 
 
 
 
 
 
 
 
 
 
 
lib/twig/lib/Twig/Node/Flush.php DELETED
@@ -1,11 +0,0 @@
1
- <?php
2
-
3
- namespace WCML;
4
-
5
- use WCML\Twig\Node\FlushNode;
6
- \class_exists('WCML\\Twig\\Node\\FlushNode');
7
- if (\false) {
8
- class Twig_Node_Flush extends \WCML\Twig\Node\FlushNode
9
- {
10
- }
11
- }
 
 
 
 
 
 
 
 
 
 
 
lib/twig/lib/Twig/Node/For.php DELETED
@@ -1,11 +0,0 @@
1
- <?php
2
-
3
- namespace WCML;
4
-
5
- use WCML\Twig\Node\ForNode;
6
- \class_exists('WCML\\Twig\\Node\\ForNode');
7
- if (\false) {
8
- class Twig_Node_For extends \WCML\Twig\Node\ForNode
9
- {
10
- }
11
- }
 
 
 
 
 
 
 
 
 
 
 
lib/twig/lib/Twig/Node/ForLoop.php DELETED
@@ -1,11 +0,0 @@
1
- <?php
2
-
3
- namespace WCML;
4
-
5
- use WCML\Twig\Node\ForLoopNode;
6
- \class_exists('WCML\\Twig\\Node\\ForLoopNode');
7
- if (\false) {
8
- class Twig_Node_ForLoop extends \WCML\Twig\Node\ForLoopNode
9
- {
10
- }
11
- }
 
 
 
 
 
 
 
 
 
 
 
lib/twig/lib/Twig/Node/If.php DELETED
@@ -1,11 +0,0 @@
1
- <?php
2
-
3
- namespace WCML;
4
-
5
- use WCML\Twig\Node\IfNode;
6
- \class_exists('WCML\\Twig\\Node\\IfNode');
7
- if (\false) {
8
- class Twig_Node_If extends \WCML\Twig\Node\IfNode
9
- {
10
- }
11
- }
 
 
 
 
 
 
 
 
 
 
 
lib/twig/lib/Twig/Node/Import.php DELETED
@@ -1,11 +0,0 @@
1
- <?php
2
-
3
- namespace WCML;
4
-
5
- use WCML\Twig\Node\ImportNode;
6
- \class_exists('WCML\\Twig\\Node\\ImportNode');
7
- if (\false) {
8
- class Twig_Node_Import extends \WCML\Twig\Node\ImportNode
9
- {
10
- }
11
- }
 
 
 
 
 
 
 
 
 
 
 
lib/twig/lib/Twig/Node/Include.php DELETED
@@ -1,11 +0,0 @@
1
- <?php
2
-
3
- namespace WCML;
4
-
5
- use WCML\Twig\Node\IncludeNode;
6
- \class_exists('WCML\\Twig\\Node\\IncludeNode');
7
- if (\false) {
8
- class Twig_Node_Include extends \WCML\Twig\Node\IncludeNode
9
- {
10
- }
11
- }
 
 
 
 
 
 
 
 
 
 
 
lib/twig/lib/Twig/Node/Macro.php DELETED
@@ -1,11 +0,0 @@
1
- <?php
2
-
3
- namespace WCML;
4
-
5
- use WCML\Twig\Node\MacroNode;
6
- \class_exists('WCML\\Twig\\Node\\MacroNode');
7
- if (\false) {
8
- class Twig_Node_Macro extends \WCML\Twig\Node\MacroNode
9
- {
10
- }
11
- }
 
 
 
 
 
 
 
 
 
 
 
lib/twig/lib/Twig/Node/Module.php DELETED
@@ -1,11 +0,0 @@
1
- <?php
2
-
3
- namespace WCML;
4
-
5
- use WCML\Twig\Node\ModuleNode;
6
- \class_exists('WCML\\Twig\\Node\\ModuleNode');
7
- if (\false) {
8
- class Twig_Node_Module extends \WCML\Twig\Node\ModuleNode
9
- {
10
- }
11
- }
 
 
 
 
 
 
 
 
 
 
 
lib/twig/lib/Twig/Node/Print.php DELETED
@@ -1,11 +0,0 @@
1
- <?php
2
-
3
- namespace WCML;
4
-
5
- use WCML\Twig\Node\PrintNode;
6
- \class_exists('WCML\\Twig\\Node\\PrintNode');
7
- if (\false) {
8
- class Twig_Node_Print extends \WCML\Twig\Node\PrintNode
9
- {
10
- }
11
- }
 
 
 
 
 
 
 
 
 
 
 
lib/twig/lib/Twig/Node/Sandbox.php DELETED
@@ -1,11 +0,0 @@
1
- <?php
2
-
3
- namespace WCML;
4
-
5
- use WCML\Twig\Node\SandboxNode;
6
- \class_exists('WCML\\Twig\\Node\\SandboxNode');
7
- if (\false) {
8
- class Twig_Node_Sandbox extends \WCML\Twig\Node\SandboxNode
9
- {
10
- }
11
- }
 
 
 
 
 
 
 
 
 
 
 
lib/twig/lib/Twig/Node/SandboxedPrint.php DELETED
@@ -1,11 +0,0 @@
1
- <?php
2
-
3
- namespace WCML;
4
-
5
- use WCML\Twig\Node\SandboxedPrintNode;
6
- \class_exists('WCML\\Twig\\Node\\SandboxedPrintNode');
7
- if (\false) {
8
- class Twig_Node_SandboxedPrint extends \WCML\Twig\Node\SandboxedPrintNode
9
- {
10
- }
11
- }
 
 
 
 
 
 
 
 
 
 
 
lib/twig/lib/Twig/Node/Set.php DELETED
@@ -1,11 +0,0 @@
1
- <?php
2
-
3
- namespace WCML;
4
-
5
- use WCML\Twig\Node\SetNode;
6
- \class_exists('WCML\\Twig\\Node\\SetNode');
7
- if (\false) {
8
- class Twig_Node_Set extends \WCML\Twig\Node\SetNode
9
- {
10
- }
11
- }
 
 
 
 
 
 
 
 
 
 
 
lib/twig/lib/Twig/Node/SetTemp.php DELETED
@@ -1,11 +0,0 @@
1
- <?php
2
-
3
- namespace WCML;
4
-
5
- use WCML\Twig\Node\SetTempNode;
6
- \class_exists('WCML\\Twig\\Node\\SetTempNode');
7
- if (\false) {
8
- class Twig_Node_SetTemp extends \WCML\Twig\Node\SetTempNode
9
- {
10
- }
11
- }
 
 
 
 
 
 
 
 
 
 
 
lib/twig/lib/Twig/Node/Spaceless.php DELETED
@@ -1,11 +0,0 @@
1
- <?php
2
-
3
- namespace WCML;
4
-
5
- use WCML\Twig\Node\SpacelessNode;
6
- \class_exists('WCML\\Twig\\Node\\SpacelessNode');
7
- if (\false) {
8
- class Twig_Node_Spaceless extends \WCML\Twig\Node\SpacelessNode
9
- {
10
- }
11
- }
 
 
 
 
 
 
 
 
 
 
 
lib/twig/lib/Twig/Node/Text.php DELETED
@@ -1,11 +0,0 @@
1
- <?php
2
-
3
- namespace WCML;
4
-
5
- use WCML\Twig\Node\TextNode;
6
- \class_exists('WCML\\Twig\\Node\\TextNode');
7
- if (\false) {
8
- class Twig_Node_Text extends \WCML\Twig\Node\TextNode
9
- {
10
- }
11
- }
 
 
 
 
 
 
 
 
 
 
 
lib/twig/lib/Twig/Node/With.php DELETED
@@ -1,11 +0,0 @@
1
- <?php
2
-
3
- namespace WCML;
4
-
5
- use WCML\Twig\Node\WithNode;
6
- \class_exists('WCML\\Twig\\Node\\WithNode');
7
- if (\false) {
8
- class Twig_Node_With extends \WCML\Twig\Node\WithNode
9
- {
10
- }
11
- }
 
 
 
 
 
 
 
 
 
 
 
lib/twig/lib/Twig/NodeCaptureInterface.php DELETED
@@ -1,11 +0,0 @@
1
- <?php
2
-
3
- namespace WCML;
4
-
5
- use WCML\Twig\Node\NodeCaptureInterface;
6
- \class_exists('WCML\\Twig\\Node\\NodeCaptureInterface');
7
- if (\false) {
8
- class Twig_NodeCaptureInterface extends \WCML\Twig\Node\NodeCaptureInterface
9
- {
10
- }
11
- }
 
 
 
 
 
 
 
 
 
 
 
lib/twig/lib/Twig/NodeInterface.php DELETED
@@ -1,32 +0,0 @@
1
- <?php
2
-
3
- namespace WCML;
4
-
5
- /*
6
- * This file is part of Twig.
7
- *
8
- * (c) Fabien Potencier
9
- *
10
- * For the full copyright and license information, please view the LICENSE
11
- * file that was distributed with this source code.
12
- */
13
- use WCML\Twig\Compiler;
14
- /**
15
- * Represents a node in the AST.
16
- *
17
- * @author Fabien Potencier <fabien@symfony.com>
18
- *
19
- * @deprecated since 1.12 (to be removed in 3.0)
20
- */
21
- interface Twig_NodeInterface extends \Countable, \IteratorAggregate
22
- {
23
- /**
24
- * Compiles the node to PHP.
25
- */
26
- public function compile(\WCML\Twig\Compiler $compiler);
27
- /**
28
- * @deprecated since 1.27 (to be removed in 2.0)
29
- */
30
- public function getLine();
31
- public function getNodeTag();
32
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/twig/lib/Twig/NodeOutputInterface.php DELETED
@@ -1,11 +0,0 @@
1
- <?php
2
-
3
- namespace WCML;
4
-
5
- use WCML\Twig\Node\NodeOutputInterface;
6
- \class_exists('WCML\\Twig\\Node\\NodeOutputInterface');
7
- if (\false) {
8
- class Twig_NodeOutputInterface extends \WCML\Twig\Node\NodeOutputInterface
9
- {
10
- }
11
- }
 
 
 
 
 
 
 
 
 
 
 
lib/twig/lib/Twig/NodeTraverser.php DELETED
@@ -1,11 +0,0 @@
1
- <?php
2
-
3
- namespace WCML;
4
-
5
- use WCML\Twig\NodeTraverser;
6
- \class_exists('WCML\\Twig\\NodeTraverser');
7
- if (\false) {
8
- class Twig_NodeTraverser extends \WCML\Twig\NodeTraverser
9
- {
10
- }
11
- }
 
 
 
 
 
 
 
 
 
 
 
lib/twig/lib/Twig/NodeVisitor/Escaper.php DELETED
@@ -1,11 +0,0 @@
1
- <?php
2
-
3
- namespace WCML;
4
-
5
- use WCML\Twig\NodeVisitor\EscaperNodeVisitor;
6
- \class_exists('WCML\\Twig\\NodeVisitor\\EscaperNodeVisitor');
7
- if (\false) {
8
- class Twig_NodeVisitor_Escaper extends \WCML\Twig\NodeVisitor\EscaperNodeVisitor
9
- {
10
- }
11
- }
 
 
 
 
 
 
 
 
 
 
 
lib/twig/lib/Twig/NodeVisitor/Optimizer.php DELETED
@@ -1,11 +0,0 @@
1
- <?php
2
-
3
- namespace WCML;
4
-
5
- use WCML\Twig\NodeVisitor\OptimizerNodeVisitor;
6
- \class_exists('WCML\\Twig\\NodeVisitor\\OptimizerNodeVisitor');
7
- if (\false) {
8
- class Twig_NodeVisitor_Optimizer extends \WCML\Twig\NodeVisitor\OptimizerNodeVisitor
9
- {
10
- }
11
- }
 
 
 
 
 
 
 
 
 
 
 
lib/twig/lib/Twig/NodeVisitor/SafeAnalysis.php DELETED
@@ -1,11 +0,0 @@
1
- <?php
2
-
3
- namespace WCML;
4
-
5
- use WCML\Twig\NodeVisitor\SafeAnalysisNodeVisitor;
6
- \class_exists('WCML\\Twig\\NodeVisitor\\SafeAnalysisNodeVisitor');
7
- if (\false) {
8
- class Twig_NodeVisitor_SafeAnalysis extends \WCML\Twig\NodeVisitor\SafeAnalysisNodeVisitor
9
- {
10
- }
11
- }
 
 
 
 
 
 
 
 
 
 
 
lib/twig/lib/Twig/NodeVisitor/Sandbox.php DELETED
@@ -1,11 +0,0 @@
1
- <?php
2
-
3
- namespace WCML;
4
-
5
- use WCML\Twig\NodeVisitor\SandboxNodeVisitor;
6
- \class_exists('WCML\\Twig\\NodeVisitor\\SandboxNodeVisitor');
7
- if (\false) {
8
- class Twig_NodeVisitor_Sandbox extends \WCML\Twig\NodeVisitor\SandboxNodeVisitor
9
- {
10
- }
11
- }
 
 
 
 
 
 
 
 
 
 
 
lib/twig/lib/Twig/NodeVisitorInterface.php DELETED
@@ -1,11 +0,0 @@
1
- <?php
2
-
3
- namespace WCML;
4
-
5
- use WCML\Twig\NodeVisitor\NodeVisitorInterface;
6
- \class_exists('WCML\\Twig\\NodeVisitor\\NodeVisitorInterface');
7
- if (\false) {
8
- class Twig_NodeVisitorInterface extends \WCML\Twig\NodeVisitor\NodeVisitorInterface
9
- {
10
- }
11
- }
 
 
 
 
 
 
 
 
 
 
 
lib/twig/lib/Twig/Parser.php DELETED
@@ -1,11 +0,0 @@
1
- <?php
2
-
3
- namespace WCML;
4
-
5
- use WCML\Twig\Parser;
6
- \class_exists('WCML\\Twig\\Parser');
7
- if (\false) {
8
- class Twig_Parser extends \WCML\Twig\Parser
9
- {
10
- }
11
- }
 
 
 
 
 
 
 
 
 
 
 
lib/twig/lib/Twig/ParserInterface.php DELETED
@@ -1,33 +0,0 @@
1
- <?php
2
-
3
- namespace WCML;
4
-
5
- /*
6
- * This file is part of Twig.
7
- *
8
- * (c) Fabien Potencier
9
- *
10
- * For the full copyright and license information, please view the LICENSE
11
- * file that was distributed with this source code.
12
- */
13
- use WCML\Twig\Error\SyntaxError;
14
- use WCML\Twig\Node\ModuleNode;
15
- use WCML\Twig\TokenStream;
16
- /**
17
- * Interface implemented by parser classes.
18
- *
19
- * @author Fabien Potencier <fabien@symfony.com>
20
- *
21
- * @deprecated since 1.12 (to be removed in 3.0)
22
- */
23
- interface Twig_ParserInterface
24
- {
25
- /**
26
- * Converts a token stream to a node tree.
27
- *
28
- * @return ModuleNode
29
- *
30
- * @throws SyntaxError When the token stream is syntactically or semantically wrong
31
- */
32
- public function parse(\WCML\Twig\TokenStream $stream);
33
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/twig/lib/Twig/Profiler/Dumper/Base.php DELETED
@@ -1,11 +0,0 @@
1
- <?php
2
-
3
- namespace WCML;
4
-
5
- use WCML\Twig\Profiler\Dumper\BaseDumper;
6
- \class_exists('WCML\\Twig\\Profiler\\Dumper\\BaseDumper');
7
- if (\false) {
8
- class Twig_Profiler_Dumper_Base extends \WCML\Twig\Profiler\Dumper\BaseDumper
9
- {
10
- }
11
- }
 
 
 
 
 
 
 
 
 
 
 
lib/twig/lib/Twig/Profiler/Dumper/Blackfire.php DELETED
@@ -1,11 +0,0 @@
1
- <?php
2
-
3
- namespace WCML;
4
-
5
- use WCML\Twig\Profiler\Dumper\BlackfireDumper;
6
- \class_exists('WCML\\Twig\\Profiler\\Dumper\\BlackfireDumper');
7
- if (\false) {
8
- class Twig_Profiler_Dumper_Blackfire extends \WCML\Twig\Profiler\Dumper\BlackfireDumper
9
- {
10
- }
11
- }
 
 
 
 
 
 
 
 
 
 
 
lib/twig/lib/Twig/Profiler/Dumper/Html.php DELETED
@@ -1,11 +0,0 @@
1
- <?php
2
-
3
- namespace WCML;
4
-
5
- use WCML\Twig\Profiler\Dumper\HtmlDumper;
6
- \class_exists('WCML\\Twig\\Profiler\\Dumper\\HtmlDumper');
7
- if (\false) {
8
- class Twig_Profiler_Dumper_Html extends \WCML\Twig\Profiler\Dumper\HtmlDumper
9
- {
10
- }
11
- }
 
 
 
 
 
 
 
 
 
 
 
lib/twig/lib/Twig/Profiler/Dumper/Text.php DELETED
@@ -1,11 +0,0 @@
1
- <?php
2
-
3
- namespace WCML;
4
-
5
- use WCML\Twig\Profiler\Dumper\TextDumper;
6
- \class_exists('WCML\\Twig\\Profiler\\Dumper\\TextDumper');
7
- if (\false) {
8
- class Twig_Profiler_Dumper_Text extends \WCML\Twig\Profiler\Dumper\TextDumper
9
- {
10
- }
11
- }
 
 
 
 
 
 
 
 
 
 
 
lib/twig/lib/Twig/Profiler/Node/EnterProfile.php DELETED
@@ -1,11 +0,0 @@
1
- <?php
2
-
3
- namespace WCML;
4
-
5
- use WCML\Twig\Profiler\Node\EnterProfileNode;
6
- \class_exists('WCML\\Twig\\Profiler\\Node\\EnterProfileNode');
7
- if (\false) {
8
- class Twig_Profiler_Node_EnterProfile extends \WCML\Twig\Profiler\Node\EnterProfileNode
9
- {
10
- }
11
- }
 
 
 
 
 
 
 
 
 
 
 
lib/twig/lib/Twig/Profiler/Node/LeaveProfile.php DELETED
@@ -1,11 +0,0 @@
1
- <?php
2
-
3
- namespace WCML;
4
-
5
- use WCML\Twig\Profiler\Node\LeaveProfileNode;
6
- \class_exists('WCML\\Twig\\Profiler\\Node\\LeaveProfileNode');
7
- if (\false) {
8
- class Twig_Profiler_Node_LeaveProfile extends \WCML\Twig\Profiler\Node\LeaveProfileNode
9
- {
10
- }
11
- }
 
 
 
 
 
 
 
 
 
 
 
lib/twig/lib/Twig/Profiler/NodeVisitor/Profiler.php DELETED
@@ -1,11 +0,0 @@
1
- <?php
2
-
3
- namespace WCML;
4
-
5
- use WCML\Twig\Profiler\NodeVisitor\ProfilerNodeVisitor;
6
- \class_exists('WCML\\Twig\\Profiler\\NodeVisitor\\ProfilerNodeVisitor');
7
- if (\false) {
8
- class Twig_Profiler_NodeVisitor_Profiler extends \WCML\Twig\Profiler\NodeVisitor\ProfilerNodeVisitor
9
- {
10
- }
11
- }
 
 
 
 
 
 
 
 
 
 
 
lib/twig/lib/Twig/Profiler/Profile.php DELETED
@@ -1,11 +0,0 @@
1
- <?php
2
-
3
- namespace WCML;
4
-
5
- use WCML\Twig\Profiler\Profile;
6
- \class_exists('WCML\\Twig\\Profiler\\Profile');
7
- if (\false) {
8
- class Twig_Profiler_Profile extends \WCML\Twig\Profiler\Profile
9
- {
10
- }
11
- }
 
 
 
 
 
 
 
 
 
 
 
lib/twig/lib/Twig/RuntimeLoaderInterface.php DELETED
@@ -1,11 +0,0 @@
1
- <?php
2
-
3
- namespace WCML;
4
-
5
- use WCML\Twig\RuntimeLoader\RuntimeLoaderInterface;
6
- \class_exists('WCML\\Twig\\RuntimeLoader\\RuntimeLoaderInterface');
7
- if (\false) {
8
- class Twig_RuntimeLoaderInterface extends \WCML\Twig\RuntimeLoader\RuntimeLoaderInterface
9
- {
10
- }
11
- }
 
 
 
 
 
 
 
 
 
 
 
lib/twig/lib/Twig/Sandbox/SecurityError.php DELETED
@@ -1,11 +0,0 @@
1
- <?php
2
-
3
- namespace WCML;
4
-
5
- use WCML\Twig\Sandbox\SecurityError;
6
- \class_exists('WCML\\Twig\\Sandbox\\SecurityError');
7
- if (\false) {
8
- class Twig_Sandbox_SecurityError extends \WCML\Twig\Sandbox\SecurityError
9
- {
10
- }
11
- }
 
 
 
 
 
 
 
 
 
 
 
lib/twig/lib/Twig/Sandbox/SecurityNotAllowedFilterError.php DELETED
@@ -1,11 +0,0 @@
1
- <?php
2
-
3
- namespace WCML;
4
-
5
- use WCML\Twig\Sandbox\SecurityNotAllowedFilterError;
6
- \class_exists('WCML\\Twig\\Sandbox\\SecurityNotAllowedFilterError');
7
- if (\false) {
8
- class Twig_Sandbox_SecurityNotAllowedFilterError extends \WCML\Twig\Sandbox\SecurityNotAllowedFilterError
9
- {
10
- }
11
- }
 
 
 
 
 
 
 
 
 
 
 
lib/twig/lib/Twig/Sandbox/SecurityNotAllowedFunctionError.php DELETED
@@ -1,11 +0,0 @@
1
- <?php
2
-
3
- namespace WCML;
4
-
5
- use WCML\Twig\Sandbox\SecurityNotAllowedFunctionError;
6
- \class_exists('WCML\\Twig\\Sandbox\\SecurityNotAllowedFunctionError');
7
- if (\false) {
8
- class Twig_Sandbox_SecurityNotAllowedFunctionError extends \WCML\Twig\Sandbox\SecurityNotAllowedFunctionError
9
- {
10
- }
11
- }
 
 
 
 
 
 
 
 
 
 
 
lib/twig/lib/Twig/Sandbox/SecurityNotAllowedMethodError.php DELETED
@@ -1,11 +0,0 @@
1
- <?php
2
-
3
- namespace WCML;
4
-
5
- use WCML\Twig\Sandbox\SecurityNotAllowedMethodError;
6
- \class_exists('WCML\\Twig\\Sandbox\\SecurityNotAllowedMethodError');
7
- if (\false) {
8
- class Twig_Sandbox_SecurityNotAllowedMethodError extends \WCML\Twig\Sandbox\SecurityNotAllowedMethodError
9
- {
10
- }
11
- }
 
 
 
 
 
 
 
 
 
 
 
lib/twig/lib/Twig/Sandbox/SecurityNotAllowedPropertyError.php DELETED
@@ -1,11 +0,0 @@
1
- <?php
2
-
3
- namespace WCML;
4
-
5
- use WCML\Twig\Sandbox\SecurityNotAllowedPropertyError;
6
- \class_exists('WCML\\Twig\\Sandbox\\SecurityNotAllowedPropertyError');
7
- if (\false) {
8
- class Twig_Sandbox_SecurityNotAllowedPropertyError extends \WCML\Twig\Sandbox\SecurityNotAllowedPropertyError
9
- {
10
- }
11
- }
 
 
 
 
 
 
 
 
 
 
 
lib/twig/lib/Twig/Sandbox/SecurityNotAllowedTagError.php DELETED
@@ -1,11 +0,0 @@
1
- <?php
2
-
3
- namespace WCML;
4
-
5
- use WCML\Twig\Sandbox\SecurityNotAllowedTagError;
6
- \class_exists('WCML\\Twig\\Sandbox\\SecurityNotAllowedTagError');
7
- if (\false) {
8
- class Twig_Sandbox_SecurityNotAllowedTagError extends \WCML\Twig\Sandbox\SecurityNotAllowedTagError
9
- {
10
- }
11
- }
 
 
 
 
 
 
 
 
 
 
 
lib/twig/lib/Twig/Sandbox/SecurityPolicy.php DELETED
@@ -1,11 +0,0 @@
1
- <?php
2
-
3
- namespace WCML;
4
-
5
- use WCML\Twig\Sandbox\SecurityPolicy;
6
- \class_exists('WCML\\Twig\\Sandbox\\SecurityPolicy');
7
- if (\false) {
8
- class Twig_Sandbox_SecurityPolicy extends \WCML\Twig\Sandbox\SecurityPolicy
9
- {
10
- }
11
- }
 
 
 
 
 
 
 
 
 
 
 
lib/twig/lib/Twig/Sandbox/SecurityPolicyInterface.php DELETED
@@ -1,11 +0,0 @@
1
- <?php
2
-
3
- namespace WCML;
4
-
5
- use WCML\Twig\Sandbox\SecurityPolicyInterface;
6
- \class_exists('WCML\\Twig\\Sandbox\\SecurityPolicyInterface');
7
- if (\false) {
8
- class Twig_Sandbox_SecurityPolicyInterface extends \WCML\Twig\Sandbox\SecurityPolicyInterface
9
- {
10
- }
11
- }
 
 
 
 
 
 
 
 
 
 
 
lib/twig/lib/Twig/SimpleFilter.php DELETED
@@ -1,11 +0,0 @@
1
- <?php
2
-
3
- namespace WCML;
4
-
5
- use WCML\Twig\TwigFilter;
6
- \class_exists('WCML\\Twig\\TwigFilter');
7
- if (\false) {
8
- class Twig_SimpleFilter extends \WCML\Twig\TwigFilter
9
- {
10
- }
11
- }
 
 
 
 
 
 
 
 
 
 
 
lib/twig/lib/Twig/SimpleFunction.php DELETED
@@ -1,11 +0,0 @@
1
- <?php
2
-
3
- namespace WCML;
4
-
5
- use WCML\Twig\TwigFunction;
6
- \class_exists('WCML\\Twig\\TwigFunction');
7
- if (\false) {
8
- class Twig_SimpleFunction extends \WCML\Twig\TwigFunction
9
- {
10
- }
11
- }
 
 
 
 
 
 
 
 
 
 
 
lib/twig/lib/Twig/SimpleTest.php DELETED
@@ -1,11 +0,0 @@
1
- <?php
2
-
3
- namespace WCML;
4
-
5
- use WCML\Twig\TwigTest;
6
- \class_exists('WCML\\Twig\\TwigTest');
7
- if (\false) {
8
- class Twig_SimpleTest extends \WCML\Twig\TwigTest
9
- {
10
- }
11
- }
 
 
 
 
 
 
 
 
 
 
 
lib/twig/lib/Twig/Source.php DELETED
@@ -1,11 +0,0 @@
1
- <?php
2
-
3
- namespace WCML;
4
-
5
- use WCML\Twig\Source;
6
- \class_exists('WCML\\Twig\\Source');
7
- if (\false) {
8
- class Twig_Source extends \WCML\Twig\Source
9
- {
10
- }
11
- }
 
 
 
 
 
 
 
 
 
 
 
lib/twig/lib/Twig/SourceContextLoaderInterface.php DELETED
@@ -1,11 +0,0 @@
1
- <?php
2
-
3
- namespace WCML;
4
-
5
- use WCML\Twig\Loader\SourceContextLoaderInterface;
6
- \class_exists('WCML\\Twig\\Loader\\SourceContextLoaderInterface');
7
- if (\false) {
8
- class Twig_SourceContextLoaderInterface extends \WCML\Twig\Loader\SourceContextLoaderInterface
9
- {
10
- }
11
- }
 
 
 
 
 
 
 
 
 
 
 
lib/twig/lib/Twig/Template.php DELETED
@@ -1,11 +0,0 @@
1
- <?php
2
-
3
- namespace WCML;
4
-
5
- use WCML\Twig\Template;
6
- \class_exists('WCML\\Twig\\Template');
7
- if (\false) {
8
- class Twig_Template extends \WCML\Twig\Template
9
- {
10
- }
11
- }
 
 
 
 
 
 
 
 
 
 
 
lib/twig/lib/Twig/TemplateInterface.php DELETED
@@ -1,47 +0,0 @@
1
- <?php
2
-
3
- namespace WCML;
4
-
5
- /*
6
- * This file is part of Twig.
7
- *
8
- * (c) Fabien Potencier
9
- *
10
- * For the full copyright and license information, please view the LICENSE
11
- * file that was distributed with this source code.
12
- */
13
- use WCML\Twig\Environment;
14
- /**
15
- * Interface implemented by all compiled templates.
16
- *
17
- * @author Fabien Potencier <fabien@symfony.com>
18
- *
19
- * @deprecated since 1.12 (to be removed in 3.0)
20
- */
21
- interface Twig_TemplateInterface
22
- {
23
- const ANY_CALL = 'any';
24
- const ARRAY_CALL = 'array';
25
- const METHOD_CALL = 'method';
26
- /**
27
- * Renders the template with the given context and returns it as string.
28
- *
29
- * @param array $context An array of parameters to pass to the template
30
- *
31
- * @return string The rendered template
32
- */
33
- public function render(array $context);
34
- /**
35
- * Displays the template with the given context.
36
- *
37
- * @param array $context An array of parameters to pass to the template
38
- * @param array $blocks An array of blocks to pass to the template
39
- */
40
- public function display(array $context, array $blocks = []);
41
- /**
42
- * Returns the bound environment for this template.
43
- *
44
- * @return Environment
45
- */
46
- public function getEnvironment();
47
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/twig/lib/Twig/TemplateWrapper.php DELETED
@@ -1,11 +0,0 @@
1
- <?php
2
-
3
- namespace WCML;
4
-
5
- use WCML\Twig\TemplateWrapper;
6
- \class_exists('WCML\\Twig\\TemplateWrapper');
7
- if (\false) {
8
- class Twig_TemplateWrapper extends \WCML\Twig\TemplateWrapper
9
- {
10
- }
11
- }
 
 
 
 
 
 
 
 
 
 
 
lib/twig/lib/Twig/Test.php DELETED
@@ -1,33 +0,0 @@
1
- <?php
2
-
3
- namespace WCML;
4
-
5
- /*
6
- * This file is part of Twig.
7
- *
8
- * (c) Fabien Potencier
9
- *
10
- * For the full copyright and license information, please view the LICENSE
11
- * file that was distributed with this source code.
12
- */
13
- @\trigger_error('The Twig_Test class is deprecated since version 1.12 and will be removed in 2.0. Use \\Twig\\TwigTest instead.', \E_USER_DEPRECATED);
14
- /**
15
- * Represents a template test.
16
- *
17
- * @author Fabien Potencier <fabien@symfony.com>
18
- *
19
- * @deprecated since 1.12 (to be removed in 2.0)
20
- */
21
- abstract class Twig_Test implements \WCML\Twig_TestInterface, \WCML\Twig_TestCallableInterface
22
- {
23
- protected $options;
24
- protected $arguments = [];
25
- public function __construct(array $options = [])
26
- {
27
- $this->options = \array_merge(['callable' => null], $options);
28
- }
29
- public function getCallable()
30
- {
31
- return $this->options['callable'];
32
- }
33
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/twig/lib/Twig/Test/Function.php DELETED
@@ -1,34 +0,0 @@
1
- <?php
2
-
3
- namespace WCML;
4
-
5
- /*
6
- * This file is part of Twig.
7
- *
8
- * (c) Fabien Potencier
9
- *
10
- * For the full copyright and license information, please view the LICENSE
11
- * file that was distributed with this source code.
12
- */
13
- @\trigger_error('The Twig_Test_Function class is deprecated since version 1.12 and will be removed in 2.0. Use \\Twig\\TwigTest instead.', \E_USER_DEPRECATED);
14
- /**
15
- * Represents a function template test.
16
- *
17
- * @author Fabien Potencier <fabien@symfony.com>
18
- *
19
- * @deprecated since 1.12 (to be removed in 2.0)
20
- */
21
- class Twig_Test_Function extends \WCML\Twig_Test
22
- {
23
- protected $function;
24
- public function __construct($function, array $options = [])
25
- {
26
- $options['callable'] = $function;
27
- parent::__construct($options);
28
- $this->function = $function;
29
- }
30
- public function compile()
31
- {
32
- return $this->function;
33
- }
34
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/twig/lib/Twig/Test/IntegrationTestCase.php DELETED
@@ -1,11 +0,0 @@
1
- <?php
2
-
3
- namespace WCML;
4
-
5
- use WCML\Twig\Test\IntegrationTestCase;
6
- \class_exists('WCML\\Twig\\Test\\IntegrationTestCase');
7
- if (\false) {
8
- class Twig_Test_IntegrationTestCase extends \WCML\Twig\Test\IntegrationTestCase
9
- {
10
- }
11
- }
 
 
 
 
 
 
 
 
 
 
 
lib/twig/lib/Twig/Test/Method.php DELETED
@@ -1,37 +0,0 @@
1
- <?php
2
-
3
- namespace WCML;
4
-
5
- /*
6
- * This file is part of Twig.
7
- *
8
- * (c) Fabien Potencier
9
- *
10
- * For the full copyright and license information, please view the LICENSE
11
- * file that was distributed with this source code.
12
- */
13
- use WCML\Twig\Extension\ExtensionInterface;
14
- @\trigger_error('The Twig_Test_Method class is deprecated since version 1.12 and will be removed in 2.0. Use \\Twig\\TwigTest instead.', \E_USER_DEPRECATED);
15
- /**
16
- * Represents a method template test.
17
- *
18
- * @author Fabien Potencier <fabien@symfony.com>
19
- *
20
- * @deprecated since 1.12 (to be removed in 2.0)
21
- */
22
- class Twig_Test_Method extends \WCML\Twig_Test
23
- {
24
- protected $extension;
25
- protected $method;
26
- public function __construct(\WCML\Twig\Extension\ExtensionInterface $extension, $method, array $options = [])
27
- {
28
- $options['callable'] = [$extension, $method];
29
- parent::__construct($options);
30
- $this->extension = $extension;
31
- $this->method = $method;
32
- }
33
- public function compile()
34
- {
35
- return \sprintf('$this->env->getExtension(\'%s\')->%s', \get_class($this->extension), $this->method);
36
- }
37
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/twig/lib/Twig/Test/Node.php DELETED
@@ -1,36 +0,0 @@
1
- <?php
2
-
3
- namespace WCML;
4
-
5
- /*
6
- * This file is part of Twig.
7
- *
8
- * (c) Fabien Potencier
9
- *
10
- * For the full copyright and license information, please view the LICENSE
11
- * file that was distributed with this source code.
12
- */
13
- @\trigger_error('The Twig_Test_Node class is deprecated since version 1.12 and will be removed in 2.0.', \E_USER_DEPRECATED);
14
- /**
15
- * Represents a template test as a Node.
16
- *
17
- * @author Fabien Potencier <fabien@symfony.com>
18
- *
19
- * @deprecated since 1.12 (to be removed in 2.0)
20
- */
21
- class Twig_Test_Node extends \WCML\Twig_Test
22
- {
23
- protected $class;
24
- public function __construct($class, array $options = [])
25
- {
26
- parent::__construct($options);
27
- $this->class = $class;
28
- }
29
- public function getClass()
30
- {
31
- return $this->class;
32
- }
33
- public function compile()
34
- {
35
- }
36
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/twig/lib/Twig/Test/NodeTestCase.php DELETED
@@ -1,11 +0,0 @@
1
- <?php
2
-
3
- namespace WCML;
4
-
5
- use WCML\Twig\Test\NodeTestCase;
6
- \class_exists('WCML\\Twig\\Test\\NodeTestCase');
7
- if (\false) {
8
- class Twig_Test_NodeTestCase extends \WCML\Twig\Test\NodeTestCase
9
- {
10
- }
11
- }
 
 
 
 
 
 
 
 
 
 
 
lib/twig/lib/Twig/TestCallableInterface.php DELETED
@@ -1,23 +0,0 @@
1
- <?php
2
-
3
- namespace WCML;
4
-
5
- /*
6
- * This file is part of Twig.
7
- *
8
- * (c) Fabien Potencier
9
- *
10
- * For the full copyright and license information, please view the LICENSE
11
- * file that was distributed with this source code.
12
- */
13
- /**
14
- * Represents a callable template test.
15
- *
16
- * @author Fabien Potencier <fabien@symfony.com>
17
- *
18
- * @deprecated since 1.12 (to be removed in 2.0)
19
- */
20
- interface Twig_TestCallableInterface
21
- {
22
- public function getCallable();
23
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/twig/lib/Twig/TestInterface.php DELETED
@@ -1,28 +0,0 @@
1
- <?php
2
-
3
- namespace WCML;
4
-
5
- /*
6
- * This file is part of Twig.
7
- *
8
- * (c) Fabien Potencier
9
- *
10
- * For the full copyright and license information, please view the LICENSE
11
- * file that was distributed with this source code.
12
- */
13
- /**
14
- * Represents a template test.
15
- *
16
- * @author Fabien Potencier <fabien@symfony.com>
17
- *
18
- * @deprecated since 1.12 (to be removed in 2.0)
19
- */
20
- interface Twig_TestInterface
21
- {
22
- /**
23
- * Compiles a test.
24
- *
25
- * @return string The PHP code for the test
26
- */
27
- public function compile();
28
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/twig/lib/Twig/Token.php DELETED
@@ -1,11 +0,0 @@
1
- <?php
2
-
3
- namespace WCML;
4
-
5
- use WCML\Twig\Token;
6
- \class_exists('WCML\\Twig\\Token');
7
- if (\false) {
8
- class Twig_Token extends \WCML\Twig\Token
9
- {
10
- }
11
- }
 
 
 
 
 
 
 
 
 
 
 
lib/twig/lib/Twig/TokenParser.php DELETED
@@ -1,11 +0,0 @@
1
- <?php
2
-
3
- namespace WCML;
4
-
5
- use WCML\Twig\TokenParser\AbstractTokenParser;
6
- \class_exists('WCML\\Twig\\TokenParser\\AbstractTokenParser');
7
- if (\false) {
8
- class Twig_TokenParser extends \WCML\Twig\TokenParser\AbstractTokenParser
9
- {
10
- }
11
- }
 
 
 
 
 
 
 
 
 
 
 
lib/twig/lib/Twig/TokenParser/AutoEscape.php DELETED
@@ -1,11 +0,0 @@
1
- <?php
2
-
3
- namespace WCML;
4
-
5
- use WCML\Twig\TokenParser\AutoEscapeTokenParser;
6
- \class_exists('WCML\\Twig\\TokenParser\\AutoEscapeTokenParser');
7
- if (\false) {
8
- class Twig_TokenParser_AutoEscape extends \WCML\Twig\TokenParser\AutoEscapeTokenParser
9
- {
10
- }
11
- }
 
 
 
 
 
 
 
 
 
 
 
lib/twig/lib/Twig/TokenParser/Block.php DELETED
@@ -1,11 +0,0 @@
1
- <?php
2
-
3
- namespace WCML;
4
-
5
- use WCML\Twig\TokenParser\BlockTokenParser;
6
- \class_exists('WCML\\Twig\\TokenParser\\BlockTokenParser');
7
- if (\false) {
8
- class Twig_TokenParser_Block extends \WCML\Twig\TokenParser\BlockTokenParser
9
- {
10
- }
11
- }
 
 
 
 
 
 
 
 
 
 
 
lib/twig/lib/Twig/TokenParser/Deprecated.php DELETED
@@ -1,11 +0,0 @@
1
- <?php
2
-
3
- namespace WCML;
4
-
5
- use WCML\Twig\TokenParser\DeprecatedTokenParser;
6
- \class_exists('WCML\\Twig\\TokenParser\\DeprecatedTokenParser');
7
- if (\false) {
8
- class Twig_TokenParser_Deprecated extends \WCML\Twig\TokenParser\DeprecatedTokenParser
9
- {
10
- }
11
- }
 
 
 
 
 
 
 
 
 
 
 
lib/twig/lib/Twig/TokenParser/Do.php DELETED
@@ -1,11 +0,0 @@
1
- <?php
2
-
3
- namespace WCML;
4
-
5
- use WCML\Twig\TokenParser\DoTokenParser;
6
- \class_exists('WCML\\Twig\\TokenParser\\DoTokenParser');
7
- if (\false) {
8
- class Twig_TokenParser_Do extends \WCML\Twig\TokenParser\DoTokenParser
9
- {
10
- }
11
- }
 
 
 
 
 
 
 
 
 
 
 
lib/twig/lib/Twig/TokenParser/Embed.php DELETED
@@ -1,11 +0,0 @@
1
- <?php
2
-
3
- namespace WCML;
4
-
5
- use WCML\Twig\TokenParser\EmbedTokenParser;
6
- \class_exists('WCML\\Twig\\TokenParser\\EmbedTokenParser');
7
- if (\false) {
8
- class Twig_TokenParser_Embed extends \WCML\Twig\TokenParser\EmbedTokenParser
9
- {
10
- }
11
- }
 
 
 
 
 
 
 
 
 
 
 
lib/twig/lib/Twig/TokenParser/Extends.php DELETED
@@ -1,11 +0,0 @@
1
- <?php
2
-
3
- namespace WCML;
4
-
5
- use WCML\Twig\TokenParser\ExtendsTokenParser;
6
- \class_exists('WCML\\Twig\\TokenParser\\ExtendsTokenParser');
7
- if (\false) {
8
- class Twig_TokenParser_Extends extends \WCML\Twig\TokenParser\ExtendsTokenParser
9
- {
10
- }
11
- }
 
 
 
 
 
 
 
 
 
 
 
lib/twig/lib/Twig/TokenParser/Filter.php DELETED
@@ -1,11 +0,0 @@
1
- <?php
2
-
3
- namespace WCML;
4
-
5
- use WCML\Twig\TokenParser\FilterTokenParser;
6
- \class_exists('WCML\\Twig\\TokenParser\\FilterTokenParser');
7
- if (\false) {
8
- class Twig_TokenParser_Filter extends \WCML\Twig\TokenParser\FilterTokenParser
9
- {
10
- }
11
- }
 
 
 
 
 
 
 
 
 
 
 
lib/twig/lib/Twig/TokenParser/Flush.php DELETED
@@ -1,11 +0,0 @@
1
- <?php
2
-
3
- namespace WCML;
4
-
5
- use WCML\Twig\TokenParser\FlushTokenParser;
6
- \class_exists('WCML\\Twig\\TokenParser\\FlushTokenParser');
7
- if (\false) {
8
- class Twig_TokenParser_Flush extends \WCML\Twig\TokenParser\FlushTokenParser
9
- {
10
- }
11
- }
 
 
 
 
 
 
 
 
 
 
 
lib/twig/lib/Twig/TokenParser/For.php DELETED
@@ -1,11 +0,0 @@
1
- <?php
2
-
3
- namespace WCML;
4
-
5
- use WCML\Twig\TokenParser\ForTokenParser;
6
- \class_exists('WCML\\Twig\\TokenParser\\ForTokenParser');
7
- if (\false) {
8
- class Twig_TokenParser_For extends \WCML\Twig\TokenParser\ForTokenParser
9
- {
10
- }
11
- }
 
 
 
 
 
 
 
 
 
 
 
lib/twig/lib/Twig/TokenParser/From.php DELETED
@@ -1,11 +0,0 @@
1
- <?php
2
-
3
- namespace WCML;
4
-
5
- use WCML\Twig\TokenParser\FromTokenParser;
6
- \class_exists('WCML\\Twig\\TokenParser\\FromTokenParser');
7
- if (\false) {
8
- class Twig_TokenParser_From extends \WCML\Twig\TokenParser\FromTokenParser
9
- {
10
- }
11
- }
 
 
 
 
 
 
 
 
 
 
 
lib/twig/lib/Twig/TokenParser/If.php DELETED
@@ -1,11 +0,0 @@
1
- <?php
2
-
3
- namespace WCML;
4
-
5
- use WCML\Twig\TokenParser\IfTokenParser;
6
- \class_exists('WCML\\Twig\\TokenParser\\IfTokenParser');
7
- if (\false) {
8
- class Twig_TokenParser_If extends \WCML\Twig\TokenParser\IfTokenParser
9
- {
10
- }
11
- }
 
 
 
 
 
 
 
 
 
 
 
lib/twig/lib/Twig/TokenParser/Import.php DELETED
@@ -1,11 +0,0 @@
1
- <?php
2
-
3
- namespace WCML;
4
-
5
- use WCML\Twig\TokenParser\ImportTokenParser;
6
- \class_exists('WCML\\Twig\\TokenParser\\ImportTokenParser');
7
- if (\false) {
8
- class Twig_TokenParser_Import extends \WCML\Twig\TokenParser\ImportTokenParser
9
- {
10
- }
11
- }
 
 
 
 
 
 
 
 
 
 
 
lib/twig/lib/Twig/TokenParser/Include.php DELETED
@@ -1,11 +0,0 @@
1
- <?php
2
-
3
- namespace WCML;
4
-
5
- use WCML\Twig\TokenParser\IncludeTokenParser;
6
- \class_exists('WCML\\Twig\\TokenParser\\IncludeTokenParser');
7
- if (\false) {
8
- class Twig_TokenParser_Include extends \WCML\Twig\TokenParser\IncludeTokenParser
9
- {
10
- }
11
- }
 
 
 
 
 
 
 
 
 
 
 
lib/twig/lib/Twig/TokenParser/Macro.php DELETED
@@ -1,11 +0,0 @@
1
- <?php
2
-
3
- namespace WCML;
4
-
5
- use WCML\Twig\TokenParser\MacroTokenParser;
6
- \class_exists('WCML\\Twig\\TokenParser\\MacroTokenParser');
7
- if (\false) {
8
- class Twig_TokenParser_Macro extends \WCML\Twig\TokenParser\MacroTokenParser
9
- {
10
- }
11
- }
 
 
 
 
 
 
 
 
 
 
 
lib/twig/lib/Twig/TokenParser/Sandbox.php DELETED
@@ -1,11 +0,0 @@
1
- <?php
2
-
3
- namespace WCML;
4
-
5
- use WCML\Twig\TokenParser\SandboxTokenParser;
6
- \class_exists('WCML\\Twig\\TokenParser\\SandboxTokenParser');
7
- if (\false) {
8
- class Twig_TokenParser_Sandbox extends \WCML\Twig\TokenParser\SandboxTokenParser
9
- {
10
- }
11
- }
 
 
 
 
 
 
 
 
 
 
 
lib/twig/lib/Twig/TokenParser/Set.php DELETED
@@ -1,11 +0,0 @@
1
- <?php
2
-
3
- namespace WCML;
4
-
5
- use WCML\Twig\TokenParser\SetTokenParser;
6
- \class_exists('WCML\\Twig\\TokenParser\\SetTokenParser');
7
- if (\false) {
8
- class Twig_TokenParser_Set extends \WCML\Twig\TokenParser\SetTokenParser
9
- {
10
- }
11
- }
 
 
 
 
 
 
 
 
 
 
 
lib/twig/lib/Twig/TokenParser/Spaceless.php DELETED
@@ -1,11 +0,0 @@
1
- <?php
2
-
3
- namespace WCML;
4
-
5
- use WCML\Twig\TokenParser\SpacelessTokenParser;
6
- \class_exists('WCML\\Twig\\TokenParser\\SpacelessTokenParser');
7
- if (\false) {
8
- class Twig_TokenParser_Spaceless extends \WCML\Twig\TokenParser\SpacelessTokenParser
9
- {
10
- }
11
- }
 
 
 
 
 
 
 
 
 
 
 
lib/twig/lib/Twig/TokenParser/Use.php DELETED
@@ -1,11 +0,0 @@
1
- <?php
2
-
3
- namespace WCML;
4
-
5
- use WCML\Twig\TokenParser\UseTokenParser;
6
- \class_exists('WCML\\Twig\\TokenParser\\UseTokenParser');
7
- if (\false) {
8
- class Twig_TokenParser_Use extends \WCML\Twig\TokenParser\UseTokenParser
9
- {
10
- }
11
- }
 
 
 
 
 
 
 
 
 
 
 
lib/twig/lib/Twig/TokenParser/With.php DELETED
@@ -1,11 +0,0 @@
1
- <?php
2
-
3
- namespace WCML;
4
-
5
- use WCML\Twig\TokenParser\WithTokenParser;
6
- \class_exists('WCML\\Twig\\TokenParser\\WithTokenParser');
7
- if (\false) {
8
- class Twig_TokenParser_With extends \WCML\Twig\TokenParser\WithTokenParser
9
- {
10
- }
11
- }
 
 
 
 
 
 
 
 
 
 
 
lib/twig/lib/Twig/TokenParserBroker.php DELETED
@@ -1,112 +0,0 @@
1
- <?php
2
-
3
- namespace WCML;
4
-
5
- /*
6
- * This file is part of Twig.
7
- *
8
- * (c) Fabien Potencier
9
- * (c) Arnaud Le Blanc
10
- *
11
- * For the full copyright and license information, please view the LICENSE
12
- * file that was distributed with this source code.
13
- */
14
- use WCML\Twig\TokenParser\TokenParserInterface;
15
- /**
16
- * Default implementation of a token parser broker.
17
- *
18
- * @author Arnaud Le Blanc <arnaud.lb@gmail.com>
19
- *
20
- * @deprecated since 1.12 (to be removed in 2.0)
21
- */
22
- class Twig_TokenParserBroker implements \WCML\Twig_TokenParserBrokerInterface
23
- {
24
- protected $parser;
25
- protected $parsers = [];
26
- protected $brokers = [];
27
- /**
28
- * @param array|\Traversable $parsers A \Traversable of Twig_TokenParserInterface instances
29
- * @param array|\Traversable $brokers A \Traversable of Twig_TokenParserBrokerInterface instances
30
- * @param bool $triggerDeprecationError
31
- */
32
- public function __construct($parsers = [], $brokers = [], $triggerDeprecationError = \true)
33
- {
34
- if ($triggerDeprecationError) {
35
- @\trigger_error('The ' . __CLASS__ . ' class is deprecated since version 1.12 and will be removed in 2.0.', \E_USER_DEPRECATED);
36
- }
37
- foreach ($parsers as $parser) {
38
- if (!$parser instanceof \WCML\Twig\TokenParser\TokenParserInterface) {
39
- throw new \LogicException('$parsers must a an array of Twig_TokenParserInterface.');
40
- }
41
- $this->parsers[$parser->getTag()] = $parser;
42
- }
43
- foreach ($brokers as $broker) {
44
- if (!$broker instanceof \WCML\Twig_TokenParserBrokerInterface) {
45
- throw new \LogicException('$brokers must a an array of Twig_TokenParserBrokerInterface.');
46
- }
47
- $this->brokers[] = $broker;
48
- }
49
- }
50
- public function addTokenParser(\WCML\Twig\TokenParser\TokenParserInterface $parser)
51
- {
52
- $this->parsers[$parser->getTag()] = $parser;
53
- }
54
- public function removeTokenParser(\WCML\Twig\TokenParser\TokenParserInterface $parser)
55
- {
56
- $name = $parser->getTag();
57
- if (isset($this->parsers[$name]) && $parser === $this->parsers[$name]) {
58
- unset($this->parsers[$name]);
59
- }
60
- }
61
- public function addTokenParserBroker(self $broker)
62
- {
63
- $this->brokers[] = $broker;
64
- }
65
- public function removeTokenParserBroker(self $broker)
66
- {
67
- if (\false !== ($pos = \array_search($broker, $this->brokers))) {
68
- unset($this->brokers[$pos]);
69
- }
70
- }
71
- /**
72
- * Gets a suitable TokenParser for a tag.
73
- *
74
- * First looks in parsers, then in brokers.
75
- *
76
- * @param string $tag A tag name
77
- *
78
- * @return TokenParserInterface|null A Twig_TokenParserInterface or null if no suitable TokenParser was found
79
- */
80
- public function getTokenParser($tag)
81
- {
82
- if (isset($this->parsers[$tag])) {
83
- return $this->parsers[$tag];
84
- }
85
- $broker = \end($this->brokers);
86
- while (\false !== $broker) {
87
- $parser = $broker->getTokenParser($tag);
88
- if (null !== $parser) {
89
- return $parser;
90
- }
91
- $broker = \prev($this->brokers);
92
- }
93
- }
94
- public function getParsers()
95
- {
96
- return $this->parsers;
97
- }
98
- public function getParser()
99
- {
100
- return $this->parser;
101
- }
102
- public function setParser(\WCML\Twig_ParserInterface $parser)
103
- {
104
- $this->parser = $parser;
105
- foreach ($this->parsers as $tokenParser) {
106
- $tokenParser->setParser($parser);
107
- }
108
- foreach ($this->brokers as $broker) {
109
- $broker->setParser($parser);
110
- }
111
- }
112
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/twig/lib/Twig/TokenParserBrokerInterface.php DELETED
@@ -1,44 +0,0 @@
1
- <?php
2
-
3
- namespace WCML;
4
-
5
- /*
6
- * This file is part of Twig.
7
- *
8
- * (c) Fabien Potencier
9
- * (c) Arnaud Le Blanc
10
- *
11
- * For the full copyright and license information, please view the LICENSE
12
- * file that was distributed with this source code.
13
- */
14
- use WCML\Twig\TokenParser\TokenParserInterface;
15
- /**
16
- * Interface implemented by token parser brokers.
17
- *
18
- * Token parser brokers allows to implement custom logic in the process of resolving a token parser for a given tag name.
19
- *
20
- * @author Arnaud Le Blanc <arnaud.lb@gmail.com>
21
- *
22
- * @deprecated since 1.12 (to be removed in 2.0)
23
- */
24
- interface Twig_TokenParserBrokerInterface
25
- {
26
- /**
27
- * Gets a TokenParser suitable for a tag.
28
- *
29
- * @param string $tag A tag name
30
- *
31
- * @return TokenParserInterface|null A Twig_TokenParserInterface or null if no suitable TokenParser was found
32
- */
33
- public function getTokenParser($tag);
34
- /**
35
- * Calls Twig\TokenParser\TokenParserInterface::setParser on all parsers the implementation knows of.
36
- */
37
- public function setParser(\WCML\Twig_ParserInterface $parser);
38
- /**
39
- * Gets the Twig_ParserInterface.
40
- *
41
- * @return Twig_ParserInterface|null A Twig_ParserInterface instance or null
42
- */
43
- public function getParser();
44
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/twig/lib/Twig/TokenParserInterface.php DELETED
@@ -1,11 +0,0 @@
1
- <?php
2
-
3
- namespace WCML;
4
-
5
- use WCML\Twig\TokenParser\TokenParserInterface;
6
- \class_exists('WCML\\Twig\\TokenParser\\TokenParserInterface');
7
- if (\false) {
8
- class Twig_TokenParserInterface extends \WCML\Twig\TokenParser\TokenParserInterface
9
- {
10
- }
11
- }
 
 
 
 
 
 
 
 
 
 
 
lib/twig/lib/Twig/TokenStream.php DELETED
@@ -1,11 +0,0 @@
1
- <?php
2
-
3
- namespace WCML;
4
-
5
- use WCML\Twig\TokenStream;
6
- \class_exists('WCML\\Twig\\TokenStream');
7
- if (\false) {
8
- class Twig_TokenStream extends \WCML\Twig\TokenStream
9
- {
10
- }
11
- }
 
 
 
 
 
 
 
 
 
 
 
lib/twig/lib/Twig/Util/DeprecationCollector.php DELETED
@@ -1,11 +0,0 @@
1
- <?php
2
-
3
- namespace WCML;
4
-
5
- use WCML\Twig\Util\DeprecationCollector;
6
- \class_exists('WCML\\Twig\\Util\\DeprecationCollector');
7
- if (\false) {
8
- class Twig_Util_DeprecationCollector extends \WCML\Twig\Util\DeprecationCollector
9
- {
10
- }
11
- }
 
 
 
 
 
 
 
 
 
 
 
lib/twig/lib/Twig/Util/TemplateDirIterator.php DELETED
@@ -1,11 +0,0 @@
1
- <?php
2
-
3
- namespace WCML;
4
-
5
- use WCML\Twig\Util\TemplateDirIterator;
6
- \class_exists('WCML\\Twig\\Util\\TemplateDirIterator');
7
- if (\false) {
8
- class Twig_Util_TemplateDirIterator extends \WCML\Twig\Util\TemplateDirIterator
9
- {
10
- }
11
- }
 
 
 
 
 
 
 
 
 
 
 
lib/twig/src/Cache/CacheInterface.php DELETED
@@ -1,55 +0,0 @@
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
- namespace WCML\Twig\Cache;
12
-
13
- /**
14
- * Interface implemented by cache classes.
15
- *
16
- * It is highly recommended to always store templates on the filesystem to
17
- * benefit from the PHP opcode cache. This interface is mostly useful if you
18
- * need to implement a custom strategy for storing templates on the filesystem.
19
- *
20
- * @author Andrew Tch <andrew@noop.lv>
21
- */
22
- interface CacheInterface
23
- {
24
- /**
25
- * Generates a cache key for the given template class name.
26
- *
27
- * @param string $name The template name
28
- * @param string $className The template class name
29
- *
30
- * @return string
31
- */
32
- public function generateKey($name, $className);
33
- /**
34
- * Writes the compiled template to cache.
35
- *
36
- * @param string $key The cache key
37
- * @param string $content The template representation as a PHP class
38
- */
39
- public function write($key, $content);
40
- /**
41
- * Loads a template from the cache.
42
- *
43
- * @param string $key The cache key
44
- */
45
- public function load($key);
46
- /**
47
- * Returns the modification timestamp of a key.
48
- *
49
- * @param string $key The cache key
50
- *
51
- * @return int
52
- */
53
- public function getTimestamp($key);
54
- }
55
- \class_alias('WCML\\Twig\\Cache\\CacheInterface', 'WCML\\Twig_CacheInterface');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/twig/src/Cache/FilesystemCache.php DELETED
@@ -1,79 +0,0 @@
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
- namespace WCML\Twig\Cache;
12
-
13
- /**
14
- * Implements a cache on the filesystem.
15
- *
16
- * @author Andrew Tch <andrew@noop.lv>
17
- */
18
- class FilesystemCache implements \WCML\Twig\Cache\CacheInterface
19
- {
20
- const FORCE_BYTECODE_INVALIDATION = 1;
21
- private $directory;
22
- private $options;
23
- /**
24
- * @param string $directory The root cache directory
25
- * @param int $options A set of options
26
- */
27
- public function __construct($directory, $options = 0)
28
- {
29
- $this->directory = \rtrim($directory, '\\/') . '/';
30
- $this->options = $options;
31
- }
32
- public function generateKey($name, $className)
33
- {
34
- $hash = \hash('sha256', $className);
35
- return $this->directory . $hash[0] . $hash[1] . '/' . $hash . '.php';
36
- }
37
- public function load($key)
38
- {
39
- if (\file_exists($key)) {
40
- @(include_once $key);
41
- }
42
- }
43
- public function write($key, $content)
44
- {
45
- $dir = \dirname($key);
46
- if (!\is_dir($dir)) {
47
- if (\false === @\mkdir($dir, 0777, \true)) {
48
- \clearstatcache(\true, $dir);
49
- if (!\is_dir($dir)) {
50
- throw new \RuntimeException(\sprintf('Unable to create the cache directory (%s).', $dir));
51
- }
52
- }
53
- } elseif (!\is_writable($dir)) {
54
- throw new \RuntimeException(\sprintf('Unable to write in the cache directory (%s).', $dir));
55
- }
56
- $tmpFile = \tempnam($dir, \basename($key));
57
- if (\false !== @\file_put_contents($tmpFile, $content) && @\rename($tmpFile, $key)) {
58
- @\chmod($key, 0666 & ~\umask());
59
- if (self::FORCE_BYTECODE_INVALIDATION == ($this->options & self::FORCE_BYTECODE_INVALIDATION)) {
60
- // Compile cached file into bytecode cache
61
- if (\function_exists('opcache_invalidate')) {
62
- \opcache_invalidate($key, \true);
63
- } elseif (\function_exists('apc_compile_file')) {
64
- \apc_compile_file($key);
65
- }
66
- }
67
- return;
68
- }
69
- throw new \RuntimeException(\sprintf('Failed to write cache file "%s".', $key));
70
- }
71
- public function getTimestamp($key)
72
- {
73
- if (!\file_exists($key)) {
74
- return 0;
75
- }
76
- return (int) @\filemtime($key);
77
- }
78
- }
79
- \class_alias('WCML\\Twig\\Cache\\FilesystemCache', 'WCML\\Twig_Cache_Filesystem');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/twig/src/Cache/NullCache.php DELETED
@@ -1,37 +0,0 @@
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
- namespace WCML\Twig\Cache;
12
-
13
- /**
14
- * Implements a no-cache strategy.
15
- *
16
- * @final
17
- *
18
- * @author Fabien Potencier <fabien@symfony.com>
19
- */
20
- class NullCache implements \WCML\Twig\Cache\CacheInterface
21
- {
22
- public function generateKey($name, $className)
23
- {
24
- return '';
25
- }
26
- public function write($key, $content)
27
- {
28
- }
29
- public function load($key)
30
- {
31
- }
32
- public function getTimestamp($key)
33
- {
34
- return 0;
35
- }
36
- }
37
- \class_alias('WCML\\Twig\\Cache\\NullCache', 'WCML\\Twig_Cache_Null');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/twig/src/Compiler.php DELETED
@@ -1,247 +0,0 @@
1
- <?php
2
-
3
- /*
4
- * This file is part of Twig.
5
- *
6
- * (c) Fabien Potencier
7
- * (c) Armin Ronacher
8
- *
9
- * For the full copyright and license information, please view the LICENSE
10
- * file that was distributed with this source code.
11
- */
12
- namespace WCML\Twig;
13
-
14
- use WCML\Twig\Node\ModuleNode;
15
- /**
16
- * Compiles a node to PHP code.
17
- *
18
- * @author Fabien Potencier <fabien@symfony.com>
19
- */
20
- class Compiler implements \WCML\Twig_CompilerInterface
21
- {
22
- protected $lastLine;
23
- protected $source;
24
- protected $indentation;
25
- protected $env;
26
- protected $debugInfo = [];
27
- protected $sourceOffset;
28
- protected $sourceLine;
29
- protected $filename;
30
- private $varNameSalt = 0;
31
- public function __construct(\WCML\Twig\Environment $env)
32
- {
33
- $this->env = $env;
34
- }
35
- /**
36
- * @deprecated since 1.25 (to be removed in 2.0)
37
- */
38
- public function getFilename()
39
- {
40
- @\trigger_error(\sprintf('The %s() method is deprecated since version 1.25 and will be removed in 2.0.', __FUNCTION__), \E_USER_DEPRECATED);
41
- return $this->filename;
42
- }
43
- /**
44
- * Returns the environment instance related to this compiler.
45
- *
46
- * @return Environment
47
- */
48
- public function getEnvironment()
49
- {
50
- return $this->env;
51
- }
52
- /**
53
- * Gets the current PHP code after compilation.
54
- *
55
- * @return string The PHP code
56
- */
57
- public function getSource()
58
- {
59
- return $this->source;
60
- }
61
- /**
62
- * Compiles a node.
63
- *
64
- * @param int $indentation The current indentation
65
- *
66
- * @return $this
67
- */
68
- public function compile(\WCML\Twig_NodeInterface $node, $indentation = 0)
69
- {
70
- $this->lastLine = null;
71
- $this->source = '';
72
- $this->debugInfo = [];
73
- $this->sourceOffset = 0;
74
- // source code starts at 1 (as we then increment it when we encounter new lines)
75
- $this->sourceLine = 1;
76
- $this->indentation = $indentation;
77
- $this->varNameSalt = 0;
78
- if ($node instanceof \WCML\Twig\Node\ModuleNode) {
79
- // to be removed in 2.0
80
- $this->filename = $node->getTemplateName();
81
- }
82
- $node->compile($this);
83
- return $this;
84
- }
85
- public function subcompile(\WCML\Twig_NodeInterface $node, $raw = \true)
86
- {
87
- if (\false === $raw) {
88
- $this->source .= \str_repeat(' ', $this->indentation * 4);
89
- }
90
- $node->compile($this);
91
- return $this;
92
- }
93
- /**
94
- * Adds a raw string to the compiled code.
95
- *
96
- * @param string $string The string
97
- *
98
- * @return $this
99
- */
100
- public function raw($string)
101
- {
102
- $this->source .= $string;
103
- return $this;
104
- }
105
- /**
106
- * Writes a string to the compiled code by adding indentation.
107
- *
108
- * @return $this
109
- */
110
- public function write()
111
- {
112
- $strings = \func_get_args();
113
- foreach ($strings as $string) {
114
- $this->source .= \str_repeat(' ', $this->indentation * 4) . $string;
115
- }
116
- return $this;
117
- }
118
- /**
119
- * Appends an indentation to the current PHP code after compilation.
120
- *
121
- * @return $this
122
- *
123
- * @deprecated since 1.27 (to be removed in 2.0).
124
- */
125
- public function addIndentation()
126
- {
127
- @\trigger_error('The ' . __METHOD__ . ' method is deprecated since version 1.27 and will be removed in 2.0. Use write(\'\') instead.', \E_USER_DEPRECATED);
128
- $this->source .= \str_repeat(' ', $this->indentation * 4);
129
- return $this;
130
- }
131
- /**
132
- * Adds a quoted string to the compiled code.
133
- *
134
- * @param string $value The string
135
- *
136
- * @return $this
137
- */
138
- public function string($value)
139
- {
140
- $this->source .= \sprintf('"%s"', \addcslashes($value, "\0\t\"\$\\"));
141
- return $this;
142
- }
143
- /**
144
- * Returns a PHP representation of a given value.
145
- *
146
- * @param mixed $value The value to convert
147
- *
148
- * @return $this
149
- */
150
- public function repr($value)
151
- {
152
- if (\is_int($value) || \is_float($value)) {
153
- if (\false !== ($locale = \setlocale(\LC_NUMERIC, '0'))) {
154
- \setlocale(\LC_NUMERIC, 'C');
155
- }
156
- $this->raw(\var_export($value, \true));
157
- if (\false !== $locale) {
158
- \setlocale(\LC_NUMERIC, $locale);
159
- }
160
- } elseif (null === $value) {
161
- $this->raw('null');
162
- } elseif (\is_bool($value)) {
163
- $this->raw($value ? 'true' : 'false');
164
- } elseif (\is_array($value)) {
165
- $this->raw('[');
166
- $first = \true;
167
- foreach ($value as $key => $v) {
168
- if (!$first) {
169
- $this->raw(', ');
170
- }
171
- $first = \false;
172
- $this->repr($key);
173
- $this->raw(' => ');
174
- $this->repr($v);
175
- }
176
- $this->raw(']');
177
- } else {
178
- $this->string($value);
179
- }
180
- return $this;
181
- }
182
- /**
183
- * Adds debugging information.
184
- *
185
- * @return $this
186
- */
187
- public function addDebugInfo(\WCML\Twig_NodeInterface $node)
188
- {
189
- if ($node->getTemplateLine() != $this->lastLine) {
190
- $this->write(\sprintf("// line %d\n", $node->getTemplateLine()));
191
- // when mbstring.func_overload is set to 2
192
- // mb_substr_count() replaces substr_count()
193
- // but they have different signatures!
194
- if ((int) \ini_get('mbstring.func_overload') & 2) {
195
- @\trigger_error('Support for having "mbstring.func_overload" different from 0 is deprecated version 1.29 and will be removed in 2.0.', \E_USER_DEPRECATED);
196
- // this is much slower than the "right" version
197
- $this->sourceLine += \mb_substr_count(\mb_substr($this->source, $this->sourceOffset), "\n");
198
- } else {
199
- $this->sourceLine += \substr_count($this->source, "\n", $this->sourceOffset);
200
- }
201
- $this->sourceOffset = \strlen($this->source);
202
- $this->debugInfo[$this->sourceLine] = $node->getTemplateLine();
203
- $this->lastLine = $node->getTemplateLine();
204
- }
205
- return $this;
206
- }
207
- public function getDebugInfo()
208
- {
209
- \ksort($this->debugInfo);
210
- return $this->debugInfo;
211
- }
212
- /**
213
- * Indents the generated code.
214
- *
215
- * @param int $step The number of indentation to add
216
- *
217
- * @return $this
218
- */
219
- public function indent($step = 1)
220
- {
221
- $this->indentation += $step;
222
- return $this;
223
- }
224
- /**
225
- * Outdents the generated code.
226
- *
227
- * @param int $step The number of indentation to remove
228
- *
229
- * @return $this
230
- *
231
- * @throws \LogicException When trying to outdent too much so the indentation would become negative
232
- */
233
- public function outdent($step = 1)
234
- {
235
- // can't outdent by more steps than the current indentation level
236
- if ($this->indentation < $step) {
237
- throw new \LogicException('Unable to call outdent() as the indentation would become negative.');
238
- }
239
- $this->indentation -= $step;
240
- return $this;
241
- }
242
- public function getVarName()
243
- {
244
- return \sprintf('__internal_%s', \hash('sha256', __METHOD__ . $this->varNameSalt++));
245
- }
246
- }
247
- \class_alias('WCML\\Twig\\Compiler', 'WCML\\Twig_Compiler');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/twig/src/Environment.php DELETED
@@ -1,1407 +0,0 @@
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
- namespace WCML\Twig;
12
-
13
- use WCML\Twig\Cache\CacheInterface;
14
- use WCML\Twig\Cache\FilesystemCache;
15
- use WCML\Twig\Cache\NullCache;
16
- use WCML\Twig\Error\Error;
17
- use WCML\Twig\Error\LoaderError;
18
- use WCML\Twig\Error\RuntimeError;
19
- use WCML\Twig\Error\SyntaxError;
20
- use WCML\Twig\Extension\CoreExtension;
21
- use WCML\Twig\Extension\EscaperExtension;
22
- use WCML\Twig\Extension\ExtensionInterface;
23
- use WCML\Twig\Extension\GlobalsInterface;
24
- use WCML\Twig\Extension\InitRuntimeInterface;
25
- use WCML\Twig\Extension\OptimizerExtension;
26
- use WCML\Twig\Extension\StagingExtension;
27
- use WCML\Twig\Loader\ArrayLoader;
28
- use WCML\Twig\Loader\ChainLoader;
29
- use WCML\Twig\Loader\LoaderInterface;
30
- use WCML\Twig\Loader\SourceContextLoaderInterface;
31
- use WCML\Twig\Node\ModuleNode;
32
- use WCML\Twig\NodeVisitor\NodeVisitorInterface;
33
- use WCML\Twig\RuntimeLoader\RuntimeLoaderInterface;
34
- use WCML\Twig\TokenParser\TokenParserInterface;
35
- /**
36
- * Stores the Twig configuration.
37
- *
38
- * @author Fabien Potencier <fabien@symfony.com>
39
- */
40
- class Environment
41
- {
42
- const VERSION = '1.42.2';
43
- const VERSION_ID = 14202;
44
- const MAJOR_VERSION = 1;
45
- const MINOR_VERSION = 42;
46
- const RELEASE_VERSION = 2;
47
- const EXTRA_VERSION = '';
48
- protected $charset;
49
- protected $loader;
50
- protected $debug;
51
- protected $autoReload;
52
- protected $cache;
53
- protected $lexer;
54
- protected $parser;
55
- protected $compiler;
56
- protected $baseTemplateClass;
57
- protected $extensions;
58
- protected $parsers;
59
- protected $visitors;
60
- protected $filters;
61
- protected $tests;
62
- protected $functions;
63
- protected $globals;
64
- protected $runtimeInitialized = \false;
65
- protected $extensionInitialized = \false;
66
- protected $loadedTemplates;
67
- protected $strictVariables;
68
- protected $unaryOperators;
69
- protected $binaryOperators;
70
- protected $templateClassPrefix = '\\WCML\\__TwigTemplate_';
71
- protected $functionCallbacks = [];
72
- protected $filterCallbacks = [];
73
- protected $staging;
74
- private $originalCache;
75
- private $bcWriteCacheFile = \false;
76
- private $bcGetCacheFilename = \false;
77
- private $lastModifiedExtension = 0;
78
- private $extensionsByClass = [];
79
- private $runtimeLoaders = [];
80
- private $runtimes = [];
81
- private $optionsHash;
82
- /**
83
- * Constructor.
84
- *
85
- * Available options:
86
- *
87
- * * debug: When set to true, it automatically set "auto_reload" to true as
88
- * well (default to false).
89
- *
90
- * * charset: The charset used by the templates (default to UTF-8).
91
- *
92
- * * base_template_class: The base template class to use for generated
93
- * templates (default to \Twig\Template).
94
- *
95
- * * cache: An absolute path where to store the compiled templates,
96
- * a \Twig\Cache\CacheInterface implementation,
97
- * or false to disable compilation cache (default).
98
- *
99
- * * auto_reload: Whether to reload the template if the original source changed.
100
- * If you don't provide the auto_reload option, it will be
101
- * determined automatically based on the debug value.
102
- *
103
- * * strict_variables: Whether to ignore invalid variables in templates
104
- * (default to false).
105
- *
106
- * * autoescape: Whether to enable auto-escaping (default to html):
107
- * * false: disable auto-escaping
108
- * * true: equivalent to html
109
- * * html, js: set the autoescaping to one of the supported strategies
110
- * * name: set the autoescaping strategy based on the template name extension
111
- * * PHP callback: a PHP callback that returns an escaping strategy based on the template "name"
112
- *
113
- * * optimizations: A flag that indicates which optimizations to apply
114
- * (default to -1 which means that all optimizations are enabled;
115
- * set it to 0 to disable).
116
- */
117
- public function __construct(\WCML\Twig\Loader\LoaderInterface $loader = null, $options = [])
118
- {
119
- if (null !== $loader) {
120
- $this->setLoader($loader);
121
- } else {
122
- @\trigger_error('Not passing a "Twig\\Lodaer\\LoaderInterface" as the first constructor argument of "Twig\\Environment" is deprecated since version 1.21.', \E_USER_DEPRECATED);
123
- }
124
- $options = \array_merge(['debug' => \false, 'charset' => 'UTF-8', 'base_template_class' => '\\WCML\\Twig\\Template', 'strict_variables' => \false, 'autoescape' => 'html', 'cache' => \false, 'auto_reload' => null, 'optimizations' => -1], $options);
125
- $this->debug = (bool) $options['debug'];
126
- $this->charset = \strtoupper($options['charset']);
127
- $this->baseTemplateClass = $options['base_template_class'];
128
- $this->autoReload = null === $options['auto_reload'] ? $this->debug : (bool) $options['auto_reload'];
129
- $this->strictVariables = (bool) $options['strict_variables'];
130
- $this->setCache($options['cache']);
131
- $this->addExtension(new \WCML\Twig\Extension\CoreExtension());
132
- $this->addExtension(new \WCML\Twig\Extension\EscaperExtension($options['autoescape']));
133
- $this->addExtension(new \WCML\Twig\Extension\OptimizerExtension($options['optimizations']));
134
- $this->staging = new \WCML\Twig\Extension\StagingExtension();
135
- // For BC
136
- if (\is_string($this->originalCache)) {
137
- $r = new \ReflectionMethod($this, 'writeCacheFile');
138
- if (__CLASS__ !== $r->getDeclaringClass()->getName()) {
139
- @\trigger_error('The Twig\\Environment::writeCacheFile method is deprecated since version 1.22 and will be removed in Twig 2.0.', \E_USER_DEPRECATED);
140
- $this->bcWriteCacheFile = \true;
141
- }
142
- $r = new \ReflectionMethod($this, 'getCacheFilename');
143
- if (__CLASS__ !== $r->getDeclaringClass()->getName()) {
144
- @\trigger_error('The Twig\\Environment::getCacheFilename method is deprecated since version 1.22 and will be removed in Twig 2.0.', \E_USER_DEPRECATED);
145
- $this->bcGetCacheFilename = \true;
146
- }
147
- }
148
- }
149
- /**
150
- * Gets the base template class for compiled templates.
151
- *
152
- * @return string The base template class name
153
- */
154
- public function getBaseTemplateClass()
155
- {
156
- return $this->baseTemplateClass;
157
- }
158
- /**
159
- * Sets the base template class for compiled templates.
160
- *
161
- * @param string $class The base template class name
162
- */
163
- public function setBaseTemplateClass($class)
164
- {
165
- $this->baseTemplateClass = $class;
166
- $this->updateOptionsHash();
167
- }
168
- /**
169
- * Enables debugging mode.
170
- */
171
- public function enableDebug()
172
- {
173
- $this->debug = \true;
174
- $this->updateOptionsHash();
175
- }
176
- /**
177
- * Disables debugging mode.
178
- */
179
- public function disableDebug()
180
- {
181
- $this->debug = \false;
182
- $this->updateOptionsHash();
183
- }
184
- /**
185
- * Checks if debug mode is enabled.
186
- *
187
- * @return bool true if debug mode is enabled, false otherwise
188
- */
189
- public function isDebug()
190
- {
191
- return $this->debug;
192
- }
193
- /**
194
- * Enables the auto_reload option.
195
- */
196
- public function enableAutoReload()
197
- {
198
- $this->autoReload = \true;
199
- }
200
- /**
201
- * Disables the auto_reload option.
202
- */
203
- public function disableAutoReload()
204
- {
205
- $this->autoReload = \false;
206
- }
207
- /**
208
- * Checks if the auto_reload option is enabled.
209
- *
210
- * @return bool true if auto_reload is enabled, false otherwise
211
- */
212
- public function isAutoReload()
213
- {
214
- return $this->autoReload;
215
- }
216
- /**
217
- * Enables the strict_variables option.
218
- */
219
- public function enableStrictVariables()
220
- {
221
- $this->strictVariables = \true;
222
- $this->updateOptionsHash();
223
- }
224
- /**
225
- * Disables the strict_variables option.
226
- */
227
- public function disableStrictVariables()
228
- {
229
- $this->strictVariables = \false;
230
- $this->updateOptionsHash();
231
- }
232
- /**
233
- * Checks if the strict_variables option is enabled.
234
- *
235
- * @return bool true if strict_variables is enabled, false otherwise
236
- */
237
- public function isStrictVariables()
238
- {
239
- return $this->strictVariables;
240
- }
241
- /**
242
- * Gets the current cache implementation.
243
- *
244
- * @param bool $original Whether to return the original cache option or the real cache instance
245
- *
246
- * @return CacheInterface|string|false A Twig\Cache\CacheInterface implementation,
247
- * an absolute path to the compiled templates,
248
- * or false to disable cache
249
- */
250
- public function getCache($original = \true)
251
- {
252
- return $original ? $this->originalCache : $this->cache;
253
- }
254
- /**
255
- * Sets the current cache implementation.
256
- *
257
- * @param CacheInterface|string|false $cache A Twig\Cache\CacheInterface implementation,
258
- * an absolute path to the compiled templates,
259
- * or false to disable cache
260
- */
261
- public function setCache($cache)
262
- {
263
- if (\is_string($cache)) {
264
- $this->originalCache = $cache;
265
- $this->cache = new \WCML\Twig\Cache\FilesystemCache($cache);
266
- } elseif (\false === $cache) {
267
- $this->originalCache = $cache;
268
- $this->cache = new \WCML\Twig\Cache\NullCache();
269
- } elseif (null === $cache) {
270
- @\trigger_error('Using "null" as the cache strategy is deprecated since version 1.23 and will be removed in Twig 2.0.', \E_USER_DEPRECATED);
271
- $this->originalCache = \false;
272
- $this->cache = new \WCML\Twig\Cache\NullCache();
273
- } elseif ($cache instanceof \WCML\Twig\Cache\CacheInterface) {
274
- $this->originalCache = $this->cache = $cache;
275
- } else {
276
- throw new \LogicException(\sprintf('Cache can only be a string, false, or a \\Twig\\Cache\\CacheInterface implementation.'));
277
- }
278
- }
279
- /**
280
- * Gets the cache filename for a given template.
281
- *
282
- * @param string $name The template name
283
- *
284
- * @return string|false The cache file name or false when caching is disabled
285
- *
286
- * @deprecated since 1.22 (to be removed in 2.0)
287
- */
288
- public function getCacheFilename($name)
289
- {
290
- @\trigger_error(\sprintf('The %s method is deprecated since version 1.22 and will be removed in Twig 2.0.', __METHOD__), \E_USER_DEPRECATED);
291
- $key = $this->cache->generateKey($name, $this->getTemplateClass($name));
292
- return !$key ? \false : $key;
293
- }
294
- /**
295
- * Gets the template class associated with the given string.
296
- *
297
- * The generated template class is based on the following parameters:
298
- *
299
- * * The cache key for the given template;
300
- * * The currently enabled extensions;
301
- * * Whether the Twig C extension is available or not;
302
- * * PHP version;
303
- * * Twig version;
304
- * * Options with what environment was created.
305
- *
306
- * @param string $name The name for which to calculate the template class name
307
- * @param int|null $index The index if it is an embedded template
308
- *
309
- * @return string The template class name
310
- */
311
- public function getTemplateClass($name, $index = null)
312
- {
313
- $key = $this->getLoader()->getCacheKey($name) . $this->optionsHash;
314
- return $this->templateClassPrefix . \hash('sha256', $key) . (null === $index ? '' : '___' . $index);
315
- }
316
- /**
317
- * Gets the template class prefix.
318
- *
319
- * @return string The template class prefix
320
- *
321
- * @deprecated since 1.22 (to be removed in 2.0)
322
- */
323
- public function getTemplateClassPrefix()
324
- {
325
- @\trigger_error(\sprintf('The %s method is deprecated since version 1.22 and will be removed in Twig 2.0.', __METHOD__), \E_USER_DEPRECATED);
326
- return $this->templateClassPrefix;
327
- }
328
- /**
329
- * Renders a template.
330
- *
331
- * @param string|TemplateWrapper $name The template name
332
- * @param array $context An array of parameters to pass to the template
333
- *
334
- * @return string The rendered template
335
- *
336
- * @throws LoaderError When the template cannot be found
337
- * @throws SyntaxError When an error occurred during compilation
338
- * @throws RuntimeError When an error occurred during rendering
339
- */
340
- public function render($name, array $context = [])
341
- {
342
- return $this->load($name)->render($context);
343
- }
344
- /**
345
- * Displays a template.
346
- *
347
- * @param string|TemplateWrapper $name The template name
348
- * @param array $context An array of parameters to pass to the template
349
- *
350
- * @throws LoaderError When the template cannot be found
351
- * @throws SyntaxError When an error occurred during compilation
352
- * @throws RuntimeError When an error occurred during rendering
353
- */
354
- public function display($name, array $context = [])
355
- {
356
- $this->load($name)->display($context);
357
- }
358
- /**
359
- * Loads a template.
360
- *
361
- * @param string|TemplateWrapper|\Twig\Template $name The template name
362
- *
363
- * @throws LoaderError When the template cannot be found
364
- * @throws RuntimeError When a previously generated cache is corrupted
365
- * @throws SyntaxError When an error occurred during compilation
366
- *
367
- * @return TemplateWrapper
368
- */
369
- public function load($name)
370
- {
371
- if ($name instanceof \WCML\Twig\TemplateWrapper) {
372
- return $name;
373
- }
374
- if ($name instanceof \WCML\Twig\Template) {
375
- return new \WCML\Twig\TemplateWrapper($this, $name);
376
- }
377
- return new \WCML\Twig\TemplateWrapper($this, $this->loadTemplate($name));
378
- }
379
- /**
380
- * Loads a template internal representation.
381
- *
382
- * This method is for internal use only and should never be called
383
- * directly.
384
- *
385
- * @param string $name The template name
386
- * @param int $index The index if it is an embedded template
387
- *
388
- * @return \Twig_TemplateInterface A template instance representing the given template name
389
- *
390
- * @throws LoaderError When the template cannot be found
391
- * @throws RuntimeError When a previously generated cache is corrupted
392
- * @throws SyntaxError When an error occurred during compilation
393
- *
394
- * @internal
395
- */
396
- public function loadTemplate($name, $index = null)
397
- {
398
- return $this->loadClass($this->getTemplateClass($name), $name, $index);
399
- }
400
- /**
401
- * @internal
402
- */
403
- public function loadClass($cls, $name, $index = null)
404
- {
405
- $mainCls = $cls;
406
- if (null !== $index) {
407
- $cls .= '___' . $index;
408
- }
409
- if (isset($this->loadedTemplates[$cls])) {
410
- return $this->loadedTemplates[$cls];
411
- }
412
- if (!\class_exists($cls, \false)) {
413
- if ($this->bcGetCacheFilename) {
414
- $key = $this->getCacheFilename($name);
415
- } else {
416
- $key = $this->cache->generateKey($name, $mainCls);
417
- }
418
- if (!$this->isAutoReload() || $this->isTemplateFresh($name, $this->cache->getTimestamp($key))) {
419
- $this->cache->load($key);
420
- }
421
- $source = null;
422
- if (!\class_exists($cls, \false)) {
423
- $loader = $this->getLoader();
424
- if (!$loader instanceof \WCML\Twig\Loader\SourceContextLoaderInterface) {
425
- $source = new \WCML\Twig\Source($loader->getSource($name), $name);
426
- } else {
427
- $source = $loader->getSourceContext($name);
428
- }
429
- $content = $this->compileSource($source);
430
- if ($this->bcWriteCacheFile) {
431
- $this->writeCacheFile($key, $content);
432
- } else {
433
- $this->cache->write($key, $content);
434
- $this->cache->load($key);
435
- }
436
- if (!\class_exists($mainCls, \false)) {
437
- /* Last line of defense if either $this->bcWriteCacheFile was used,
438
- * $this->cache is implemented as a no-op or we have a race condition
439
- * where the cache was cleared between the above calls to write to and load from
440
- * the cache.
441
- */
442
- eval('?>' . $content);
443
- }
444
- }
445
- if (!\class_exists($cls, \false)) {
446
- throw new \WCML\Twig\Error\RuntimeError(\sprintf('Failed to load Twig template "%s", index "%s": cache might be corrupted.', $name, $index), -1, $source);
447
- }
448
- }
449
- if (!$this->runtimeInitialized) {
450
- $this->initRuntime();
451
- }
452
- return $this->loadedTemplates[$cls] = new $cls($this);
453
- }
454
- /**
455
- * Creates a template from source.
456
- *
457
- * This method should not be used as a generic way to load templates.
458
- *
459
- * @param string $template The template name
460
- * @param string $name An optional name of the template to be used in error messages
461
- *
462
- * @return TemplateWrapper A template instance representing the given template name
463
- *
464
- * @throws LoaderError When the template cannot be found
465
- * @throws SyntaxError When an error occurred during compilation
466
- */
467
- public function createTemplate($template, $name = null)
468
- {
469
- $hash = \hash('sha256', $template, \false);
470
- if (null !== $name) {
471
- $name = \sprintf('%s (string template %s)', $name, $hash);
472
- } else {
473
- $name = \sprintf('__string_template__%s', $hash);
474
- }
475
- $loader = new \WCML\Twig\Loader\ChainLoader([new \WCML\Twig\Loader\ArrayLoader([$name => $template]), $current = $this->getLoader()]);
476
- $this->setLoader($loader);
477
- try {
478
- $template = new \WCML\Twig\TemplateWrapper($this, $this->loadTemplate($name));
479
- } catch (\Exception $e) {
480
- $this->setLoader($current);
481
- throw $e;
482
- } catch (\Throwable $e) {
483
- $this->setLoader($current);
484
- throw $e;
485
- }
486
- $this->setLoader($current);
487
- return $template;
488
- }
489
- /**
490
- * Returns true if the template is still fresh.
491
- *
492
- * Besides checking the loader for freshness information,
493
- * this method also checks if the enabled extensions have
494
- * not changed.
495
- *
496
- * @param string $name The template name
497
- * @param int $time The last modification time of the cached template
498
- *
499
- * @return bool true if the template is fresh, false otherwise
500
- */
501
- public function isTemplateFresh($name, $time)
502
- {
503
- if (0 === $this->lastModifiedExtension) {
504
- foreach ($this->extensions as $extension) {
505
- $r = new \ReflectionObject($extension);
506
- if (\file_exists($r->getFileName()) && ($extensionTime = \filemtime($r->getFileName())) > $this->lastModifiedExtension) {
507
- $this->lastModifiedExtension = $extensionTime;
508
- }
509
- }
510
- }
511
- return $this->lastModifiedExtension <= $time && $this->getLoader()->isFresh($name, $time);
512
- }
513
- /**
514
- * Tries to load a template consecutively from an array.
515
- *
516
- * Similar to load() but it also accepts instances of \Twig\Template and
517
- * \Twig\TemplateWrapper, and an array of templates where each is tried to be loaded.
518
- *
519
- * @param string|Template|\Twig\TemplateWrapper|array $names A template or an array of templates to try consecutively
520
- *
521
- * @return TemplateWrapper|Template
522
- *
523
- * @throws LoaderError When none of the templates can be found
524
- * @throws SyntaxError When an error occurred during compilation
525
- */
526
- public function resolveTemplate($names)
527
- {
528
- if (!\is_array($names)) {
529
- $names = [$names];
530
- }
531
- foreach ($names as $name) {
532
- if ($name instanceof \WCML\Twig\Template) {
533
- return $name;
534
- }
535
- if ($name instanceof \WCML\Twig\TemplateWrapper) {
536
- return $name;
537
- }
538
- try {
539
- return $this->loadTemplate($name);
540
- } catch (\WCML\Twig\Error\LoaderError $e) {
541
- if (1 === \count($names)) {
542
- throw $e;
543
- }
544
- }
545
- }
546
- throw new \WCML\Twig\Error\LoaderError(\sprintf('Unable to find one of the following templates: "%s".', \implode('", "', $names)));
547
- }
548
- /**
549
- * Clears the internal template cache.
550
- *
551
- * @deprecated since 1.18.3 (to be removed in 2.0)
552
- */
553
- public function clearTemplateCache()
554
- {
555
- @\trigger_error(\sprintf('The %s method is deprecated since version 1.18.3 and will be removed in Twig 2.0.', __METHOD__), \E_USER_DEPRECATED);
556
- $this->loadedTemplates = [];
557
- }
558
- /**
559
- * Clears the template cache files on the filesystem.
560
- *
561
- * @deprecated since 1.22 (to be removed in 2.0)
562
- */
563
- public function clearCacheFiles()
564
- {
565
- @\trigger_error(\sprintf('The %s method is deprecated since version 1.22 and will be removed in Twig 2.0.', __METHOD__), \E_USER_DEPRECATED);
566
- if (\is_string($this->originalCache)) {
567
- foreach (new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($this->originalCache), \RecursiveIteratorIterator::LEAVES_ONLY) as $file) {
568
- if ($file->isFile()) {
569
- @\unlink($file->getPathname());
570
- }
571
- }
572
- }
573
- }
574
- /**
575
- * Gets the Lexer instance.
576
- *
577
- * @return \Twig_LexerInterface
578
- *
579
- * @deprecated since 1.25 (to be removed in 2.0)
580
- */
581
- public function getLexer()
582
- {
583
- @\trigger_error(\sprintf('The %s() method is deprecated since version 1.25 and will be removed in 2.0.', __FUNCTION__), \E_USER_DEPRECATED);
584
- if (null === $this->lexer) {
585
- $this->lexer = new \WCML\Twig\Lexer($this);
586
- }
587
- return $this->lexer;
588
- }
589
- public function setLexer(\WCML\Twig_LexerInterface $lexer)
590
- {
591
- $this->lexer = $lexer;
592
- }
593
- /**
594
- * Tokenizes a source code.
595
- *
596
- * @param string|Source $source The template source code
597
- * @param string $name The template name (deprecated)
598
- *
599
- * @return TokenStream
600
- *
601
- * @throws SyntaxError When the code is syntactically wrong
602
- */
603
- public function tokenize($source, $name = null)
604
- {
605
- if (!$source instanceof \WCML\Twig\Source) {
606
- @\trigger_error(\sprintf('Passing a string as the $source argument of %s() is deprecated since version 1.27. Pass a Twig\\Source instance instead.', __METHOD__), \E_USER_DEPRECATED);
607
- $source = new \WCML\Twig\Source($source, $name);
608
- }
609
- if (null === $this->lexer) {
610
- $this->lexer = new \WCML\Twig\Lexer($this);
611
- }
612
- return $this->lexer->tokenize($source);
613
- }
614
- /**
615
- * Gets the Parser instance.
616
- *
617
- * @return \Twig_ParserInterface
618
- *
619
- * @deprecated since 1.25 (to be removed in 2.0)
620
- */
621
- public function getParser()
622
- {
623
- @\trigger_error(\sprintf('The %s() method is deprecated since version 1.25 and will be removed in 2.0.', __FUNCTION__), \E_USER_DEPRECATED);
624
- if (null === $this->parser) {
625
- $this->parser = new \WCML\Twig\Parser($this);
626
- }
627
- return $this->parser;
628
- }
629
- public function setParser(\WCML\Twig_ParserInterface $parser)
630
- {
631
- $this->parser = $parser;
632
- }
633
- /**
634
- * Converts a token stream to a node tree.
635
- *
636
- * @return ModuleNode
637
- *
638
- * @throws SyntaxError When the token stream is syntactically or semantically wrong
639
- */
640
- public function parse(\WCML\Twig\TokenStream $stream)
641
- {
642
- if (null === $this->parser) {
643
- $this->parser = new \WCML\Twig\Parser($this);
644
- }
645
- return $this->parser->parse($stream);
646
- }
647
- /**
648
- * Gets the Compiler instance.
649
- *
650
- * @return \Twig_CompilerInterface
651
- *
652
- * @deprecated since 1.25 (to be removed in 2.0)
653
- */
654
- public function getCompiler()
655
- {
656
- @\trigger_error(\sprintf('The %s() method is deprecated since version 1.25 and will be removed in 2.0.', __FUNCTION__), \E_USER_DEPRECATED);
657
- if (null === $this->compiler) {
658
- $this->compiler = new \WCML\Twig\Compiler($this);
659
- }
660
- return $this->compiler;
661
- }
662
- public function setCompiler(\WCML\Twig_CompilerInterface $compiler)
663
- {
664
- $this->compiler = $compiler;
665
- }
666
- /**
667
- * Compiles a node and returns the PHP code.
668
- *
669
- * @return string The compiled PHP source code
670
- */
671
- public function compile(\WCML\Twig_NodeInterface $node)
672
- {
673
- if (null === $this->compiler) {
674
- $this->compiler = new \WCML\Twig\Compiler($this);
675
- }
676
- return $this->compiler->compile($node)->getSource();
677
- }
678
- /**
679
- * Compiles a template source code.
680
- *
681
- * @param string|Source $source The template source code
682
- * @param string $name The template name (deprecated)
683
- *
684
- * @return string The compiled PHP source code
685
- *
686
- * @throws SyntaxError When there was an error during tokenizing, parsing or compiling
687
- */
688
- public function compileSource($source, $name = null)
689
- {
690
- if (!$source instanceof \WCML\Twig\Source) {
691
- @\trigger_error(\sprintf('Passing a string as the $source argument of %s() is deprecated since version 1.27. Pass a Twig\\Source instance instead.', __METHOD__), \E_USER_DEPRECATED);
692
- $source = new \WCML\Twig\Source($source, $name);
693
- }
694
- try {
695
- return $this->compile($this->parse($this->tokenize($source)));
696
- } catch (\WCML\Twig\Error\Error $e) {
697
- $e->setSourceContext($source);
698
- throw $e;
699
- } catch (\Exception $e) {
700
- throw new \WCML\Twig\Error\SyntaxError(\sprintf('An exception has been thrown during the compilation of a template ("%s").', $e->getMessage()), -1, $source, $e);
701
- }
702
- }
703
- public function setLoader(\WCML\Twig\Loader\LoaderInterface $loader)
704
- {
705
- if (!$loader instanceof \WCML\Twig\Loader\SourceContextLoaderInterface && 0 !== \strpos(\get_class($loader), 'Mock_')) {
706
- @\trigger_error(\sprintf('Twig loader "%s" should implement Twig\\Loader\\SourceContextLoaderInterface since version 1.27.', \get_class($loader)), \E_USER_DEPRECATED);
707
- }
708
- $this->loader = $loader;
709
- }
710
- /**
711
- * Gets the Loader instance.
712
- *
713
- * @return LoaderInterface
714
- */
715
- public function getLoader()
716
- {
717
- if (null === $this->loader) {
718
- throw new \LogicException('You must set a loader first.');
719
- }
720
- return $this->loader;
721
- }
722
- /**
723
- * Sets the default template charset.
724
- *
725
- * @param string $charset The default charset
726
- */
727
- public function setCharset($charset)
728
- {
729
- $this->charset = \strtoupper($charset);
730
- }
731
- /**
732
- * Gets the default template charset.
733
- *
734
- * @return string The default charset
735
- */
736
- public function getCharset()
737
- {
738
- return $this->charset;
739
- }
740
- /**
741
- * Initializes the runtime environment.
742
- *
743
- * @deprecated since 1.23 (to be removed in 2.0)
744
- */
745
- public function initRuntime()
746
- {
747
- $this->runtimeInitialized = \true;
748
- foreach ($this->getExtensions() as $name => $extension) {
749
- if (!$extension instanceof \WCML\Twig\Extension\InitRuntimeInterface) {
750
- $m = new \ReflectionMethod($extension, 'initRuntime');
751
- $parentClass = $m->getDeclaringClass()->getName();
752
- if ('Twig_Extension' !== $parentClass && 'Twig\\Extension\\AbstractExtension' !== $parentClass) {
753
- @\trigger_error(\sprintf('Defining the initRuntime() method in the "%s" extension is deprecated since version 1.23. Use the `needs_environment` option to get the \\Twig_Environment instance in filters, functions, or tests; or explicitly implement Twig\\Extension\\InitRuntimeInterface if needed (not recommended).', $name), \E_USER_DEPRECATED);
754
- }
755
- }
756
- $extension->initRuntime($this);
757
- }
758
- }
759
- /**
760
- * Returns true if the given extension is registered.
761
- *
762
- * @param string $class The extension class name
763
- *
764
- * @return bool Whether the extension is registered or not
765
- */
766
- public function hasExtension($class)
767
- {
768
- $class = \ltrim($class, '\\');
769
- if (!isset($this->extensionsByClass[$class]) && \class_exists($class, \false)) {
770
- // For BC/FC with namespaced aliases
771
- $class = new \ReflectionClass($class);
772
- $class = $class->name;
773
- }
774
- if (isset($this->extensions[$class])) {
775
- if ($class !== \get_class($this->extensions[$class])) {
776
- @\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);
777
- }
778
- return \true;
779
- }
780
- return isset($this->extensionsByClass[$class]);
781
- }
782
- /**
783
- * Adds a runtime loader.
784
- */
785
- public function addRuntimeLoader(\WCML\Twig\RuntimeLoader\RuntimeLoaderInterface $loader)
786
- {
787
- $this->runtimeLoaders[] = $loader;
788
- }
789
- /**
790
- * Gets an extension by class name.
791
- *
792
- * @param string $class The extension class name
793
- *
794
- * @return ExtensionInterface
795
- */
796
- public function getExtension($class)
797
- {
798
- $class = \ltrim($class, '\\');
799
- if (!isset($this->extensionsByClass[$class]) && \class_exists($class, \false)) {
800
- // For BC/FC with namespaced aliases
801
- $class = new \ReflectionClass($class);
802
- $class = $class->name;
803
- }
804
- if (isset($this->extensions[$class])) {
805
- if ($class !== \get_class($this->extensions[$class])) {
806
- @\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);
807
- }
808
- return $this->extensions[$class];
809
- }
810
- if (!isset($this->extensionsByClass[$class])) {
811
- throw new \WCML\Twig\Error\RuntimeError(\sprintf('The "%s" extension is not enabled.', $class));
812
- }
813
- return $this->extensionsByClass[$class];
814
- }
815
- /**
816
- * Returns the runtime implementation of a Twig element (filter/function/test).
817
- *
818
- * @param string $class A runtime class name
819
- *
820
- * @return object The runtime implementation
821
- *
822
- * @throws RuntimeError When the template cannot be found
823
- */
824
- public function getRuntime($class)
825
- {
826
- if (isset($this->runtimes[$class])) {
827
- return $this->runtimes[$class];
828
- }
829
- foreach ($this->runtimeLoaders as $loader) {
830
- if (null !== ($runtime = $loader->load($class))) {
831
- return $this->runtimes[$class] = $runtime;
832
- }
833
- }
834
- throw new \WCML\Twig\Error\RuntimeError(\sprintf('Unable to load the "%s" runtime.', $class));
835
- }
836
- public function addExtension(\WCML\Twig\Extension\ExtensionInterface $extension)
837
- {
838
- if ($this->extensionInitialized) {
839
- throw new \LogicException(\sprintf('Unable to register extension "%s" as extensions have already been initialized.', $extension->getName()));
840
- }
841
- $class = \get_class($extension);
842
- if ($class !== $extension->getName()) {
843
- if (isset($this->extensions[$extension->getName()])) {
844
- unset($this->extensions[$extension->getName()], $this->extensionsByClass[$class]);
845
- @\trigger_error(\sprintf('The possibility to register the same extension twice ("%s") is deprecated since version 1.23 and will be removed in Twig 2.0. Use proper PHP inheritance instead.', $extension->getName()), \E_USER_DEPRECATED);
846
- }
847
- }
848
- $this->lastModifiedExtension = 0;
849
- $this->extensionsByClass[$class] = $extension;
850
- $this->extensions[$extension->getName()] = $extension;
851
- $this->updateOptionsHash();
852
- }
853
- /**
854
- * Removes an extension by name.
855
- *
856
- * This method is deprecated and you should not use it.
857
- *
858
- * @param string $name The extension name
859
- *
860
- * @deprecated since 1.12 (to be removed in 2.0)
861
- */
862
- public function removeExtension($name)
863
- {
864
- @\trigger_error(\sprintf('The %s method is deprecated since version 1.12 and will be removed in Twig 2.0.', __METHOD__), \E_USER_DEPRECATED);
865
- if ($this->extensionInitialized) {
866
- throw new \LogicException(\sprintf('Unable to remove extension "%s" as extensions have already been initialized.', $name));
867
- }
868
- $class = \ltrim($name, '\\');
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
- if (isset($this->extensions[$class])) {
875
- if ($class !== \get_class($this->extensions[$class])) {
876
- @\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);
877
- }
878
- unset($this->extensions[$class]);
879
- }
880
- unset($this->extensions[$class]);
881
- $this->updateOptionsHash();
882
- }
883
- /**
884
- * Registers an array of extensions.
885
- *
886
- * @param array $extensions An array of extensions
887
- */
888
- public function setExtensions(array $extensions)
889
- {
890
- foreach ($extensions as $extension) {
891
- $this->addExtension($extension);
892
- }
893
- }
894
- /**
895
- * Returns all registered extensions.
896
- *
897
- * @return ExtensionInterface[] An array of extensions (keys are for internal usage only and should not be relied on)
898
- */
899
- public function getExtensions()
900
- {
901
- return $this->extensions;
902
- }
903
- public function addTokenParser(\WCML\Twig\TokenParser\TokenParserInterface $parser)
904
- {
905
- if ($this->extensionInitialized) {
906
- throw new \LogicException('Unable to add a token parser as extensions have already been initialized.');
907
- }
908
- $this->staging->addTokenParser($parser);
909
- }
910
- /**
911
- * Gets the registered Token Parsers.
912
- *
913
- * @return \Twig_TokenParserBrokerInterface
914
- *
915
- * @internal
916
- */
917
- public function getTokenParsers()
918
- {
919
- if (!$this->extensionInitialized) {
920
- $this->initExtensions();
921
- }
922
- return $this->parsers;
923
- }
924
- /**
925
- * Gets registered tags.
926
- *
927
- * Be warned that this method cannot return tags defined by \Twig_TokenParserBrokerInterface classes.
928
- *
929
- * @return TokenParserInterface[]
930
- *
931
- * @internal
932
- */
933
- public function getTags()
934
- {
935
- $tags = [];
936
- foreach ($this->getTokenParsers()->getParsers() as $parser) {
937
- if ($parser instanceof \WCML\Twig\TokenParser\TokenParserInterface) {
938
- $tags[$parser->getTag()] = $parser;
939
- }
940
- }
941
- return $tags;
942
- }
943
- public function addNodeVisitor(\WCML\Twig\NodeVisitor\NodeVisitorInterface $visitor)
944
- {
945
- if ($this->extensionInitialized) {
946
- throw new \LogicException('Unable to add a node visitor as extensions have already been initialized.');
947
- }
948
- $this->staging->addNodeVisitor($visitor);
949
- }
950
- /**
951
- * Gets the registered Node Visitors.
952
- *
953
- * @return NodeVisitorInterface[]
954
- *
955
- * @internal
956
- */
957
- public function getNodeVisitors()
958
- {
959
- if (!$this->extensionInitialized) {
960
- $this->initExtensions();
961
- }
962
- return $this->visitors;
963
- }
964
- /**
965
- * Registers a Filter.
966
- *
967
- * @param string|TwigFilter $name The filter name or a \Twig_SimpleFilter instance
968
- * @param \Twig_FilterInterface|TwigFilter $filter
969
- */
970
- public function addFilter($name, $filter = null)
971
- {
972
- if (!$name instanceof \WCML\Twig\TwigFilter && !($filter instanceof \WCML\Twig\TwigFilter || $filter instanceof \WCML\Twig_FilterInterface)) {
973
- throw new \LogicException('A filter must be an instance of \\Twig_FilterInterface or \\Twig_SimpleFilter.');
974
- }
975
- if ($name instanceof \WCML\Twig\TwigFilter) {
976
- $filter = $name;
977
- $name = $filter->getName();
978
- } else {
979
- @\trigger_error(\sprintf('Passing a name as a first argument to the %s method is deprecated since version 1.21. Pass an instance of "Twig_SimpleFilter" instead when defining filter "%s".', __METHOD__, $name), \E_USER_DEPRECATED);
980
- }
981
- if ($this->extensionInitialized) {
982
- throw new \LogicException(\sprintf('Unable to add filter "%s" as extensions have already been initialized.', $name));
983
- }
984
- $this->staging->addFilter($name, $filter);
985
- }
986
- /**
987
- * Get a filter by name.
988
- *
989
- * Subclasses may override this method and load filters differently;
990
- * so no list of filters is available.
991
- *
992
- * @param string $name The filter name
993
- *
994
- * @return \Twig_Filter|false
995
- *
996
- * @internal
997
- */
998
- public function getFilter($name)
999
- {
1000
- if (!$this->extensionInitialized) {
1001
- $this->initExtensions();
1002
- }
1003
- if (isset($this->filters[$name])) {
1004
- return $this->filters[$name];
1005
- }
1006
- foreach ($this->filters as $pattern => $filter) {
1007
- $pattern = \str_replace('\\*', '(.*?)', \preg_quote($pattern, '#'), $count);
1008
- if ($count) {
1009
- if (\preg_match('#^' . $pattern . '$#', $name, $matches)) {
1010
- \array_shift($matches);
1011
- $filter->setArguments($matches);
1012
- return $filter;
1013
- }
1014
- }
1015
- }
1016
- foreach ($this->filterCallbacks as $callback) {
1017
- if (\false !== ($filter = \call_user_func($callback, $name))) {
1018
- return $filter;
1019
- }
1020
- }
1021
- return \false;
1022
- }
1023
- public function registerUndefinedFilterCallback($callable)
1024
- {
1025
- $this->filterCallbacks[] = $callable;
1026
- }
1027
- /**
1028
- * Gets the registered Filters.
1029
- *
1030
- * Be warned that this method cannot return filters defined with registerUndefinedFilterCallback.
1031
- *
1032
- * @return \Twig_FilterInterface[]
1033
- *
1034
- * @see registerUndefinedFilterCallback
1035
- *
1036
- * @internal
1037
- */
1038
- public function getFilters()
1039
- {
1040
- if (!$this->extensionInitialized) {
1041
- $this->initExtensions();
1042
- }
1043
- return $this->filters;
1044
- }
1045
- /**
1046
- * Registers a Test.
1047
- *
1048
- * @param string|TwigTest $name The test name or a \Twig_SimpleTest instance
1049
- * @param \Twig_TestInterface|TwigTest $test A \Twig_TestInterface instance or a \Twig_SimpleTest instance
1050
- */
1051
- public function addTest($name, $test = null)
1052
- {
1053
- if (!$name instanceof \WCML\Twig\TwigTest && !($test instanceof \WCML\Twig\TwigTest || $test instanceof \WCML\Twig_TestInterface)) {
1054
- throw new \LogicException('A test must be an instance of \\Twig_TestInterface or \\Twig_SimpleTest.');
1055
- }
1056
- if ($name instanceof \WCML\Twig\TwigTest) {
1057
- $test = $name;
1058
- $name = $test->getName();
1059
- } else {
1060
- @\trigger_error(\sprintf('Passing a name as a first argument to the %s method is deprecated since version 1.21. Pass an instance of "Twig_SimpleTest" instead when defining test "%s".', __METHOD__, $name), \E_USER_DEPRECATED);
1061
- }
1062
- if ($this->extensionInitialized) {
1063
- throw new \LogicException(\sprintf('Unable to add test "%s" as extensions have already been initialized.', $name));
1064
- }
1065
- $this->staging->addTest($name, $test);
1066
- }
1067
- /**
1068
- * Gets the registered Tests.
1069
- *
1070
- * @return \Twig_TestInterface[]
1071
- *
1072
- * @internal
1073
- */
1074
- public function getTests()
1075
- {
1076
- if (!$this->extensionInitialized) {
1077
- $this->initExtensions();
1078
- }
1079
- return $this->tests;
1080
- }
1081
- /**
1082
- * Gets a test by name.
1083
- *
1084
- * @param string $name The test name
1085
- *
1086
- * @return \Twig_Test|false
1087
- *
1088
- * @internal
1089
- */
1090
- public function getTest($name)
1091
- {
1092
- if (!$this->extensionInitialized) {
1093
- $this->initExtensions();
1094
- }
1095
- if (isset($this->tests[$name])) {
1096
- return $this->tests[$name];
1097
- }
1098
- foreach ($this->tests as $pattern => $test) {
1099
- $pattern = \str_replace('\\*', '(.*?)', \preg_quote($pattern, '#'), $count);
1100
- if ($count) {
1101
- if (\preg_match('#^' . $pattern . '$#', $name, $matches)) {
1102
- \array_shift($matches);
1103
- $test->setArguments($matches);
1104
- return $test;
1105
- }
1106
- }
1107
- }
1108
- return \false;
1109
- }
1110
- /**
1111
- * Registers a Function.
1112
- *
1113
- * @param string|TwigFunction $name The function name or a \Twig_SimpleFunction instance
1114
- * @param \Twig_FunctionInterface|TwigFunction $function
1115
- */
1116
- public function addFunction($name, $function = null)
1117
- {
1118
- if (!$name instanceof \WCML\Twig\TwigFunction && !($function instanceof \WCML\Twig\TwigFunction || $function instanceof \WCML\Twig_FunctionInterface)) {
1119
- throw new \LogicException('A function must be an instance of \\Twig_FunctionInterface or \\Twig_SimpleFunction.');
1120
- }
1121
- if ($name instanceof \WCML\Twig\TwigFunction) {
1122
- $function = $name;
1123
- $name = $function->getName();
1124
- } else {
1125
- @\trigger_error(\sprintf('Passing a name as a first argument to the %s method is deprecated since version 1.21. Pass an instance of "Twig_SimpleFunction" instead when defining function "%s".', __METHOD__, $name), \E_USER_DEPRECATED);
1126
- }
1127
- if ($this->extensionInitialized) {
1128
- throw new \LogicException(\sprintf('Unable to add function "%s" as extensions have already been initialized.', $name));
1129
- }
1130
- $this->staging->addFunction($name, $function);
1131
- }
1132
- /**
1133
- * Get a function by name.
1134
- *
1135
- * Subclasses may override this method and load functions differently;
1136
- * so no list of functions is available.
1137
- *
1138
- * @param string $name function name
1139
- *
1140
- * @return \Twig_Function|false
1141
- *
1142
- * @internal
1143
- */
1144
- public function getFunction($name)
1145
- {
1146
- if (!$this->extensionInitialized) {
1147
- $this->initExtensions();
1148
- }
1149
- if (isset($this->functions[$name])) {
1150
- return $this->functions[$name];
1151
- }
1152
- foreach ($this->functions as $pattern => $function) {
1153
- $pattern = \str_replace('\\*', '(.*?)', \preg_quote($pattern, '#'), $count);
1154
- if ($count) {
1155
- if (\preg_match('#^' . $pattern . '$#', $name, $matches)) {
1156
- \array_shift($matches);
1157
- $function->setArguments($matches);
1158
- return $function;
1159
- }
1160
- }
1161
- }
1162
- foreach ($this->functionCallbacks as $callback) {
1163
- if (\false !== ($function = \call_user_func($callback, $name))) {
1164
- return $function;
1165
- }
1166
- }
1167
- return \false;
1168
- }
1169
- public function registerUndefinedFunctionCallback($callable)
1170
- {
1171
- $this->functionCallbacks[] = $callable;
1172
- }
1173
- /**
1174
- * Gets registered functions.
1175
- *
1176
- * Be warned that this method cannot return functions defined with registerUndefinedFunctionCallback.
1177
- *
1178
- * @return \Twig_FunctionInterface[]
1179
- *
1180
- * @see registerUndefinedFunctionCallback
1181
- *
1182
- * @internal
1183
- */
1184
- public function getFunctions()
1185
- {
1186
- if (!$this->extensionInitialized) {
1187
- $this->initExtensions();
1188
- }
1189
- return $this->functions;
1190
- }
1191
- /**
1192
- * Registers a Global.
1193
- *
1194
- * New globals can be added before compiling or rendering a template;
1195
- * but after, you can only update existing globals.
1196
- *
1197
- * @param string $name The global name
1198
- * @param mixed $value The global value
1199
- */
1200
- public function addGlobal($name, $value)
1201
- {
1202
- if ($this->extensionInitialized || $this->runtimeInitialized) {
1203
- if (null === $this->globals) {
1204
- $this->globals = $this->initGlobals();
1205
- }
1206
- if (!\array_key_exists($name, $this->globals)) {
1207
- // The deprecation notice must be turned into the following exception in Twig 2.0
1208
- @\trigger_error(\sprintf('Registering global variable "%s" at runtime or when the extensions have already been initialized is deprecated since version 1.21.', $name), \E_USER_DEPRECATED);
1209
- //throw new \LogicException(sprintf('Unable to add global "%s" as the runtime or the extensions have already been initialized.', $name));
1210
- }
1211
- }
1212
- if ($this->extensionInitialized || $this->runtimeInitialized) {
1213
- // update the value
1214
- $this->globals[$name] = $value;
1215
- } else {
1216
- $this->staging->addGlobal($name, $value);
1217
- }
1218
- }
1219
- /**
1220
- * Gets the registered Globals.
1221
- *
1222
- * @return array An array of globals
1223
- *
1224
- * @internal
1225
- */
1226
- public function getGlobals()
1227
- {
1228
- if (!$this->runtimeInitialized && !$this->extensionInitialized) {
1229
- return $this->initGlobals();
1230
- }
1231
- if (null === $this->globals) {
1232
- $this->globals = $this->initGlobals();
1233
- }
1234
- return $this->globals;
1235
- }
1236
- /**
1237
- * Merges a context with the defined globals.
1238
- *
1239
- * @param array $context An array representing the context
1240
- *
1241
- * @return array The context merged with the globals
1242
- */
1243
- public function mergeGlobals(array $context)
1244
- {
1245
- // we don't use array_merge as the context being generally
1246
- // bigger than globals, this code is faster.
1247
- foreach ($this->getGlobals() as $key => $value) {
1248
- if (!\array_key_exists($key, $context)) {
1249
- $context[$key] = $value;
1250
- }
1251
- }
1252
- return $context;
1253
- }
1254
- /**
1255
- * Gets the registered unary Operators.
1256
- *
1257
- * @return array An array of unary operators
1258
- *
1259
- * @internal
1260
- */
1261
- public function getUnaryOperators()
1262
- {
1263
- if (!$this->extensionInitialized) {
1264
- $this->initExtensions();
1265
- }
1266
- return $this->unaryOperators;
1267
- }
1268
- /**
1269
- * Gets the registered binary Operators.
1270
- *
1271
- * @return array An array of binary operators
1272
- *
1273
- * @internal
1274
- */
1275
- public function getBinaryOperators()
1276
- {
1277
- if (!$this->extensionInitialized) {
1278
- $this->initExtensions();
1279
- }
1280
- return $this->binaryOperators;
1281
- }
1282
- /**
1283
- * @deprecated since 1.23 (to be removed in 2.0)
1284
- */
1285
- public function computeAlternatives($name, $items)
1286
- {
1287
- @\trigger_error(\sprintf('The %s method is deprecated since version 1.23 and will be removed in Twig 2.0.', __METHOD__), \E_USER_DEPRECATED);
1288
- return \WCML\Twig\Error\SyntaxError::computeAlternatives($name, $items);
1289
- }
1290
- /**
1291
- * @internal
1292
- */
1293
- protected function initGlobals()
1294
- {
1295
- $globals = [];
1296
- foreach ($this->extensions as $name => $extension) {
1297
- if (!$extension instanceof \WCML\Twig\Extension\GlobalsInterface) {
1298
- $m = new \ReflectionMethod($extension, 'getGlobals');
1299
- $parentClass = $m->getDeclaringClass()->getName();
1300
- if ('Twig_Extension' !== $parentClass && 'Twig\\Extension\\AbstractExtension' !== $parentClass) {
1301
- @\trigger_error(\sprintf('Defining the getGlobals() method in the "%s" extension without explicitly implementing Twig\\Extension\\GlobalsInterface is deprecated since version 1.23.', $name), \E_USER_DEPRECATED);
1302
- }
1303
- }
1304
- $extGlob = $extension->getGlobals();
1305
- if (!\is_array($extGlob)) {
1306
- throw new \UnexpectedValueException(\sprintf('"%s::getGlobals()" must return an array of globals.', \get_class($extension)));
1307
- }
1308
- $globals[] = $extGlob;
1309
- }
1310
- $globals[] = $this->staging->getGlobals();
1311
- return \call_user_func_array('array_merge', $globals);
1312
- }
1313
- /**
1314
- * @internal
1315
- */
1316
- protected function initExtensions()
1317
- {
1318
- if ($this->extensionInitialized) {
1319
- return;
1320
- }
1321
- $this->parsers = new \WCML\Twig_TokenParserBroker([], [], \false);
1322
- $this->filters = [];
1323
- $this->functions = [];
1324
- $this->tests = [];
1325
- $this->visitors = [];
1326
- $this->unaryOperators = [];
1327
- $this->binaryOperators = [];
1328
- foreach ($this->extensions as $extension) {
1329
- $this->initExtension($extension);
1330
- }
1331
- $this->initExtension($this->staging);
1332
- // Done at the end only, so that an exception during initialization does not mark the environment as initialized when catching the exception
1333
- $this->extensionInitialized = \true;
1334
- }
1335
- /**
1336
- * @internal
1337
- */
1338
- protected function initExtension(\WCML\Twig\Extension\ExtensionInterface $extension)
1339
- {
1340
- // filters
1341
- foreach ($extension->getFilters() as $name => $filter) {
1342
- if ($filter instanceof \WCML\Twig\TwigFilter) {
1343
- $name = $filter->getName();
1344
- } else {
1345
- @\trigger_error(\sprintf('Using an instance of "%s" for filter "%s" is deprecated since version 1.21. Use \\Twig_SimpleFilter instead.', \get_class($filter), $name), \E_USER_DEPRECATED);
1346
- }
1347
- $this->filters[$name] = $filter;
1348
- }
1349
- // functions
1350
- foreach ($extension->getFunctions() as $name => $function) {
1351
- if ($function instanceof \WCML\Twig\TwigFunction) {
1352
- $name = $function->getName();
1353
- } else {
1354
- @\trigger_error(\sprintf('Using an instance of "%s" for function "%s" is deprecated since version 1.21. Use \\Twig_SimpleFunction instead.', \get_class($function), $name), \E_USER_DEPRECATED);
1355
- }
1356
- $this->functions[$name] = $function;
1357
- }
1358
- // tests
1359
- foreach ($extension->getTests() as $name => $test) {
1360
- if ($test instanceof \WCML\Twig\TwigTest) {
1361
- $name = $test->getName();
1362
- } else {
1363
- @\trigger_error(\sprintf('Using an instance of "%s" for test "%s" is deprecated since version 1.21. Use \\Twig_SimpleTest instead.', \get_class($test), $name), \E_USER_DEPRECATED);
1364
- }
1365
- $this->tests[$name] = $test;
1366
- }
1367
- // token parsers
1368
- foreach ($extension->getTokenParsers() as $parser) {
1369
- if ($parser instanceof \WCML\Twig\TokenParser\TokenParserInterface) {
1370
- $this->parsers->addTokenParser($parser);
1371
- } elseif ($parser instanceof \WCML\Twig_TokenParserBrokerInterface) {
1372
- @\trigger_error('Registering a \\Twig_TokenParserBrokerInterface instance is deprecated since version 1.21.', \E_USER_DEPRECATED);
1373
- $this->parsers->addTokenParserBroker($parser);
1374
- } else {
1375
- throw new \LogicException('getTokenParsers() must return an array of \\Twig_TokenParserInterface or \\Twig_TokenParserBrokerInterface instances.');
1376
- }
1377
- }
1378
- // node visitors
1379
- foreach ($extension->getNodeVisitors() as $visitor) {
1380
- $this->visitors[] = $visitor;
1381
- }
1382
- // operators
1383
- if ($operators = $extension->getOperators()) {
1384
- if (!\is_array($operators)) {
1385
- throw new \InvalidArgumentException(\sprintf('"%s::getOperators()" must return an array with operators, got "%s".', \get_class($extension), \is_object($operators) ? \get_class($operators) : \gettype($operators) . (\is_resource($operators) ? '' : '#' . $operators)));
1386
- }
1387
- if (2 !== \count($operators)) {
1388
- throw new \InvalidArgumentException(\sprintf('"%s::getOperators()" must return an array of 2 elements, got %d.', \get_class($extension), \count($operators)));
1389
- }
1390
- $this->unaryOperators = \array_merge($this->unaryOperators, $operators[0]);
1391
- $this->binaryOperators = \array_merge($this->binaryOperators, $operators[1]);
1392
- }
1393
- }
1394
- /**
1395
- * @deprecated since 1.22 (to be removed in 2.0)
1396
- */
1397
- protected function writeCacheFile($file, $content)
1398
- {
1399
- $this->cache->write($file, $content);
1400
- }
1401
- private function updateOptionsHash()
1402
- {
1403
- $hashParts = \array_merge(\array_keys($this->extensions), [(int) \function_exists('WCML\\twig_template_get_attributes'), \PHP_MAJOR_VERSION, \PHP_MINOR_VERSION, self::VERSION, (int) $this->debug, $this->baseTemplateClass, (int) $this->strictVariables]);
1404
- $this->optionsHash = \implode(':', $hashParts);
1405
- }
1406
- }
1407
- \class_alias('WCML\\Twig\\Environment', 'WCML\\Twig_Environment');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/twig/src/Error/Error.php DELETED
@@ -1,280 +0,0 @@
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
- namespace WCML\Twig\Error;
12
-
13
- use WCML\Twig\Source;
14
- use WCML\Twig\Template;
15
- /**
16
- * Twig base exception.
17
- *
18
- * This exception class and its children must only be used when
19
- * an error occurs during the loading of a template, when a syntax error
20
- * is detected in a template, or when rendering a template. Other
21
- * errors must use regular PHP exception classes (like when the template
22
- * cache directory is not writable for instance).
23
- *
24
- * To help debugging template issues, this class tracks the original template
25
- * name and line where the error occurred.
26
- *
27
- * Whenever possible, you must set these information (original template name
28
- * and line number) yourself by passing them to the constructor. If some or all
29
- * these information are not available from where you throw the exception, then
30
- * this class will guess them automatically (when the line number is set to -1
31
- * and/or the name is set to null). As this is a costly operation, this
32
- * can be disabled by passing false for both the name and the line number
33
- * when creating a new instance of this class.
34
- *
35
- * @author Fabien Potencier <fabien@symfony.com>
36
- */
37
- class Error extends \Exception
38
- {
39
- protected $lineno;
40
- // to be renamed to name in 2.0
41
- protected $filename;
42
- protected $rawMessage;
43
- private $sourcePath;
44
- private $sourceCode;
45
- /**
46
- * Constructor.
47
- *
48
- * Set the line number to -1 to enable its automatic guessing.
49
- * Set the name to null to enable its automatic guessing.
50
- *
51
- * @param string $message The error message
52
- * @param int $lineno The template line where the error occurred
53
- * @param Source|string|null $source The source context where the error occurred
54
- * @param \Exception $previous The previous exception
55
- */
56
- public function __construct($message, $lineno = -1, $source = null, \Exception $previous = null)
57
- {
58
- if (null === $source) {
59
- $name = null;
60
- } elseif (!$source instanceof \WCML\Twig\Source) {
61
- // for compat with the Twig C ext., passing the template name as string is accepted
62
- $name = $source;
63
- } else {
64
- $name = $source->getName();
65
- $this->sourceCode = $source->getCode();
66
- $this->sourcePath = $source->getPath();
67
- }
68
- parent::__construct('', 0, $previous);
69
- $this->lineno = $lineno;
70
- $this->filename = $name;
71
- $this->rawMessage = $message;
72
- $this->updateRepr();
73
- }
74
- /**
75
- * Gets the raw message.
76
- *
77
- * @return string The raw message
78
- */
79
- public function getRawMessage()
80
- {
81
- return $this->rawMessage;
82
- }
83
- /**
84
- * Gets the logical name where the error occurred.
85
- *
86
- * @return string The name
87
- *
88
- * @deprecated since 1.27 (to be removed in 2.0). Use getSourceContext() instead.
89
- */
90
- public function getTemplateFile()
91
- {
92
- @\trigger_error(\sprintf('The "%s" method is deprecated since version 1.27 and will be removed in 2.0. Use getSourceContext() instead.', __METHOD__), \E_USER_DEPRECATED);
93
- return $this->filename;
94
- }
95
- /**
96
- * Sets the logical name where the error occurred.
97
- *
98
- * @param string $name The name
99
- *
100
- * @deprecated since 1.27 (to be removed in 2.0). Use setSourceContext() instead.
101
- */
102
- public function setTemplateFile($name)
103
- {
104
- @\trigger_error(\sprintf('The "%s" method is deprecated since version 1.27 and will be removed in 2.0. Use setSourceContext() instead.', __METHOD__), \E_USER_DEPRECATED);
105
- $this->filename = $name;
106
- $this->updateRepr();
107
- }
108
- /**
109
- * Gets the logical name where the error occurred.
110
- *
111
- * @return string The name
112
- *
113
- * @deprecated since 1.29 (to be removed in 2.0). Use getSourceContext() instead.
114
- */
115
- public function getTemplateName()
116
- {
117
- @\trigger_error(\sprintf('The "%s" method is deprecated since version 1.29 and will be removed in 2.0. Use getSourceContext() instead.', __METHOD__), \E_USER_DEPRECATED);
118
- return $this->filename;
119
- }
120
- /**
121
- * Sets the logical name where the error occurred.
122
- *
123
- * @param string $name The name
124
- *
125
- * @deprecated since 1.29 (to be removed in 2.0). Use setSourceContext() instead.
126
- */
127
- public function setTemplateName($name)
128
- {
129
- @\trigger_error(\sprintf('The "%s" method is deprecated since version 1.29 and will be removed in 2.0. Use setSourceContext() instead.', __METHOD__), \E_USER_DEPRECATED);
130
- $this->filename = $name;
131
- $this->sourceCode = $this->sourcePath = null;
132
- $this->updateRepr();
133
- }
134
- /**
135
- * Gets the template line where the error occurred.
136
- *
137
- * @return int The template line
138
- */
139
- public function getTemplateLine()
140
- {
141
- return $this->lineno;
142
- }
143
- /**
144
- * Sets the template line where the error occurred.
145
- *
146
- * @param int $lineno The template line
147
- */
148
- public function setTemplateLine($lineno)
149
- {
150
- $this->lineno = $lineno;
151
- $this->updateRepr();
152
- }
153
- /**
154
- * Gets the source context of the Twig template where the error occurred.
155
- *
156
- * @return Source|null
157
- */
158
- public function getSourceContext()
159
- {
160
- return $this->filename ? new \WCML\Twig\Source($this->sourceCode, $this->filename, $this->sourcePath) : null;
161
- }
162
- /**
163
- * Sets the source context of the Twig template where the error occurred.
164
- */
165
- public function setSourceContext(\WCML\Twig\Source $source = null)
166
- {
167
- if (null === $source) {
168
- $this->sourceCode = $this->filename = $this->sourcePath = null;
169
- } else {
170
- $this->sourceCode = $source->getCode();
171
- $this->filename = $source->getName();
172
- $this->sourcePath = $source->getPath();
173
- }
174
- $this->updateRepr();
175
- }
176
- public function guess()
177
- {
178
- $this->guessTemplateInfo();
179
- $this->updateRepr();
180
- }
181
- public function appendMessage($rawMessage)
182
- {
183
- $this->rawMessage .= $rawMessage;
184
- $this->updateRepr();
185
- }
186
- /**
187
- * @internal
188
- */
189
- protected function updateRepr()
190
- {
191
- $this->message = $this->rawMessage;
192
- if ($this->sourcePath && $this->lineno > 0) {
193
- $this->file = $this->sourcePath;
194
- $this->line = $this->lineno;
195
- return;
196
- }
197
- $dot = \false;
198
- if ('.' === \substr($this->message, -1)) {
199
- $this->message = \substr($this->message, 0, -1);
200
- $dot = \true;
201
- }
202
- $questionMark = \false;
203
- if ('?' === \substr($this->message, -1)) {
204
- $this->message = \substr($this->message, 0, -1);
205
- $questionMark = \true;
206
- }
207
- if ($this->filename) {
208
- if (\is_string($this->filename) || \is_object($this->filename) && \method_exists($this->filename, '__toString')) {
209
- $name = \sprintf('"%s"', $this->filename);
210
- } else {
211
- $name = \json_encode($this->filename);
212
- }
213
- $this->message .= \sprintf(' in %s', $name);
214
- }
215
- if ($this->lineno && $this->lineno >= 0) {
216
- $this->message .= \sprintf(' at line %d', $this->lineno);
217
- }
218
- if ($dot) {
219
- $this->message .= '.';
220
- }
221
- if ($questionMark) {
222
- $this->message .= '?';
223
- }
224
- }
225
- /**
226
- * @internal
227
- */
228
- protected function guessTemplateInfo()
229
- {
230
- $template = null;
231
- $templateClass = null;
232
- $backtrace = \debug_backtrace(\DEBUG_BACKTRACE_IGNORE_ARGS | \DEBUG_BACKTRACE_PROVIDE_OBJECT);
233
- foreach ($backtrace as $trace) {
234
- if (isset($trace['object']) && $trace['object'] instanceof \WCML\Twig\Template && 'Twig_Template' !== \get_class($trace['object'])) {
235
- $currentClass = \get_class($trace['object']);
236
- $isEmbedContainer = 0 === \strpos($templateClass, $currentClass);
237
- if (null === $this->filename || $this->filename == $trace['object']->getTemplateName() && !$isEmbedContainer) {
238
- $template = $trace['object'];
239
- $templateClass = \get_class($trace['object']);
240
- }
241
- }
242
- }
243
- // update template name
244
- if (null !== $template && null === $this->filename) {
245
- $this->filename = $template->getTemplateName();
246
- }
247
- // update template path if any
248
- if (null !== $template && null === $this->sourcePath) {
249
- $src = $template->getSourceContext();
250
- $this->sourceCode = $src->getCode();
251
- $this->sourcePath = $src->getPath();
252
- }
253
- if (null === $template || $this->lineno > -1) {
254
- return;
255
- }
256
- $r = new \ReflectionObject($template);
257
- $file = $r->getFileName();
258
- $exceptions = [$e = $this];
259
- while ($e instanceof self && ($e = $e->getPrevious())) {
260
- $exceptions[] = $e;
261
- }
262
- while ($e = \array_pop($exceptions)) {
263
- $traces = $e->getTrace();
264
- \array_unshift($traces, ['file' => $e->getFile(), 'line' => $e->getLine()]);
265
- while ($trace = \array_shift($traces)) {
266
- if (!isset($trace['file']) || !isset($trace['line']) || $file != $trace['file']) {
267
- continue;
268
- }
269
- foreach ($template->getDebugInfo() as $codeLine => $templateLine) {
270
- if ($codeLine <= $trace['line']) {
271
- // update template line
272
- $this->lineno = $templateLine;
273
- return;
274
- }
275
- }
276
- }
277
- }
278
- }
279
- }
280
- \class_alias('WCML\\Twig\\Error\\Error', 'WCML\\Twig_Error');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/twig/src/Error/LoaderError.php DELETED
@@ -1,21 +0,0 @@
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
- namespace WCML\Twig\Error;
12
-
13
- /**
14
- * Exception thrown when an error occurs during template loading.
15
- *
16
- * @author Fabien Potencier <fabien@symfony.com>
17
- */
18
- class LoaderError extends \WCML\Twig\Error\Error
19
- {
20
- }
21
- \class_alias('WCML\\Twig\\Error\\LoaderError', 'WCML\\Twig_Error_Loader');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/twig/src/Error/RuntimeError.php DELETED
@@ -1,22 +0,0 @@
1
- <?php
2
-
3
- /*
4
- * This file is part of Twig.
5
- *
6
- * (c) Fabien Potencier
7
- * (c) Armin Ronacher
8
- *
9
- * For the full copyright and license information, please view the LICENSE
10
- * file that was distributed with this source code.
11
- */
12
- namespace WCML\Twig\Error;
13
-
14
- /**
15
- * Exception thrown when an error occurs at runtime.
16
- *
17
- * @author Fabien Potencier <fabien@symfony.com>
18
- */
19
- class RuntimeError extends \WCML\Twig\Error\Error
20
- {
21
- }
22
- \class_alias('WCML\\Twig\\Error\\RuntimeError', 'WCML\\Twig_Error_Runtime');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/twig/src/Error/SyntaxError.php DELETED
@@ -1,52 +0,0 @@
1
- <?php
2
-
3
- /*
4
- * This file is part of Twig.
5
- *
6
- * (c) Fabien Potencier
7
- * (c) Armin Ronacher
8
- *
9
- * For the full copyright and license information, please view the LICENSE
10
- * file that was distributed with this source code.
11
- */
12
- namespace WCML\Twig\Error;
13
-
14
- /**
15
- * \Exception thrown when a syntax error occurs during lexing or parsing of a template.
16
- *
17
- * @author Fabien Potencier <fabien@symfony.com>
18
- */
19
- class SyntaxError extends \WCML\Twig\Error\Error
20
- {
21
- /**
22
- * Tweaks the error message to include suggestions.
23
- *
24
- * @param string $name The original name of the item that does not exist
25
- * @param array $items An array of possible items
26
- */
27
- public function addSuggestions($name, array $items)
28
- {
29
- if (!($alternatives = self::computeAlternatives($name, $items))) {
30
- return;
31
- }
32
- $this->appendMessage(\sprintf(' Did you mean "%s"?', \implode('", "', $alternatives)));
33
- }
34
- /**
35
- * @internal
36
- *
37
- * To be merged with the addSuggestions() method in 2.0.
38
- */
39
- public static function computeAlternatives($name, $items)
40
- {
41
- $alternatives = [];
42
- foreach ($items as $item) {
43
- $lev = \levenshtein($name, $item);
44
- if ($lev <= \strlen($name) / 3 || \false !== \strpos($item, $name)) {
45
- $alternatives[$item] = $lev;
46
- }
47
- }
48
- \asort($alternatives);
49
- return \array_keys($alternatives);
50
- }
51
- }
52
- \class_alias('WCML\\Twig\\Error\\SyntaxError', 'WCML\\Twig_Error_Syntax');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/twig/src/ExpressionParser.php DELETED
@@ -1,684 +0,0 @@
1
- <?php
2
-
3
- /*
4
- * This file is part of Twig.
5
- *
6
- * (c) Fabien Potencier
7
- * (c) Armin Ronacher
8
- *
9
- * For the full copyright and license information, please view the LICENSE
10
- * file that was distributed with this source code.
11
- */
12
- namespace WCML\Twig;
13
-
14
- use WCML\Twig\Error\SyntaxError;
15
- use WCML\Twig\Node\Expression\ArrayExpression;
16
- use WCML\Twig\Node\Expression\ArrowFunctionExpression;
17
- use WCML\Twig\Node\Expression\AssignNameExpression;
18
- use WCML\Twig\Node\Expression\Binary\ConcatBinary;
19
- use WCML\Twig\Node\Expression\BlockReferenceExpression;
20
- use WCML\Twig\Node\Expression\ConditionalExpression;
21
- use WCML\Twig\Node\Expression\ConstantExpression;
22
- use WCML\Twig\Node\Expression\GetAttrExpression;
23
- use WCML\Twig\Node\Expression\MethodCallExpression;
24
- use WCML\Twig\Node\Expression\NameExpression;
25
- use WCML\Twig\Node\Expression\ParentExpression;
26
- use WCML\Twig\Node\Expression\Unary\NegUnary;
27
- use WCML\Twig\Node\Expression\Unary\NotUnary;
28
- use WCML\Twig\Node\Expression\Unary\PosUnary;
29
- use WCML\Twig\Node\Node;
30
- /**
31
- * Parses expressions.
32
- *
33
- * This parser implements a "Precedence climbing" algorithm.
34
- *
35
- * @see https://www.engr.mun.ca/~theo/Misc/exp_parsing.htm
36
- * @see https://en.wikipedia.org/wiki/Operator-precedence_parser
37
- *
38
- * @author Fabien Potencier <fabien@symfony.com>
39
- *
40
- * @internal
41
- */
42
- class ExpressionParser
43
- {
44
- const OPERATOR_LEFT = 1;
45
- const OPERATOR_RIGHT = 2;
46
- protected $parser;
47
- protected $unaryOperators;
48
- protected $binaryOperators;
49
- private $env;
50
- public function __construct(\WCML\Twig\Parser $parser, $env = null)
51
- {
52
- $this->parser = $parser;
53
- if ($env instanceof \WCML\Twig\Environment) {
54
- $this->env = $env;
55
- $this->unaryOperators = $env->getUnaryOperators();
56
- $this->binaryOperators = $env->getBinaryOperators();
57
- } else {
58
- @\trigger_error('Passing the operators as constructor arguments to ' . __METHOD__ . ' is deprecated since version 1.27. Pass the environment instead.', \E_USER_DEPRECATED);
59
- $this->env = $parser->getEnvironment();
60
- $this->unaryOperators = \func_get_arg(1);
61
- $this->binaryOperators = \func_get_arg(2);
62
- }
63
- }
64
- public function parseExpression($precedence = 0, $allowArrow = \false)
65
- {
66
- if ($allowArrow && ($arrow = $this->parseArrow())) {
67
- return $arrow;
68
- }
69
- $expr = $this->getPrimary();
70
- $token = $this->parser->getCurrentToken();
71
- while ($this->isBinary($token) && $this->binaryOperators[$token->getValue()]['precedence'] >= $precedence) {
72
- $op = $this->binaryOperators[$token->getValue()];
73
- $this->parser->getStream()->next();
74
- if ('is not' === $token->getValue()) {
75
- $expr = $this->parseNotTestExpression($expr);
76
- } elseif ('is' === $token->getValue()) {
77
- $expr = $this->parseTestExpression($expr);
78
- } elseif (isset($op['callable'])) {
79
- $expr = \call_user_func($op['callable'], $this->parser, $expr);
80
- } else {
81
- $expr1 = $this->parseExpression(self::OPERATOR_LEFT === $op['associativity'] ? $op['precedence'] + 1 : $op['precedence']);
82
- $class = $op['class'];
83
- $expr = new $class($expr, $expr1, $token->getLine());
84
- }
85
- $token = $this->parser->getCurrentToken();
86
- }
87
- if (0 === $precedence) {
88
- return $this->parseConditionalExpression($expr);
89
- }
90
- return $expr;
91
- }
92
- /**
93
- * @return ArrowFunctionExpression|null
94
- */
95
- private function parseArrow()
96
- {
97
- $stream = $this->parser->getStream();
98
- // short array syntax (one argument, no parentheses)?
99
- if ($stream->look(1)->test(\WCML\Twig\Token::ARROW_TYPE)) {
100
- $line = $stream->getCurrent()->getLine();
101
- $token = $stream->expect(\WCML\Twig\Token::NAME_TYPE);
102
- $names = [new \WCML\Twig\Node\Expression\AssignNameExpression($token->getValue(), $token->getLine())];
103
- $stream->expect(\WCML\Twig\Token::ARROW_TYPE);
104
- return new \WCML\Twig\Node\Expression\ArrowFunctionExpression($this->parseExpression(0), new \WCML\Twig\Node\Node($names), $line);
105
- }
106
- // first, determine if we are parsing an arrow function by finding => (long form)
107
- $i = 0;
108
- if (!$stream->look($i)->test(\WCML\Twig\Token::PUNCTUATION_TYPE, '(')) {
109
- return null;
110
- }
111
- ++$i;
112
- while (\true) {
113
- // variable name
114
- ++$i;
115
- if (!$stream->look($i)->test(\WCML\Twig\Token::PUNCTUATION_TYPE, ',')) {
116
- break;
117
- }
118
- ++$i;
119
- }
120
- if (!$stream->look($i)->test(\WCML\Twig\Token::PUNCTUATION_TYPE, ')')) {
121
- return null;
122
- }
123
- ++$i;
124
- if (!$stream->look($i)->test(\WCML\Twig\Token::ARROW_TYPE)) {
125
- return null;
126
- }
127
- // yes, let's parse it properly
128
- $token = $stream->expect(\WCML\Twig\Token::PUNCTUATION_TYPE, '(');
129
- $line = $token->getLine();
130
- $names = [];
131
- while (\true) {
132
- $token = $stream->expect(\WCML\Twig\Token::NAME_TYPE);
133
- $names[] = new \WCML\Twig\Node\Expression\AssignNameExpression($token->getValue(), $token->getLine());
134
- if (!$stream->nextIf(\WCML\Twig\Token::PUNCTUATION_TYPE, ',')) {
135
- break;
136
- }
137
- }
138
- $stream->expect(\WCML\Twig\Token::PUNCTUATION_TYPE, ')');
139
- $stream->expect(\WCML\Twig\Token::ARROW_TYPE);
140
- return new \WCML\Twig\Node\Expression\ArrowFunctionExpression($this->parseExpression(0), new \WCML\Twig\Node\Node($names), $line);
141
- }
142
- protected function getPrimary()
143
- {
144
- $token = $this->parser->getCurrentToken();
145
- if ($this->isUnary($token)) {
146
- $operator = $this->unaryOperators[$token->getValue()];
147
- $this->parser->getStream()->next();
148
- $expr = $this->parseExpression($operator['precedence']);
149
- $class = $operator['class'];
150
- return $this->parsePostfixExpression(new $class($expr, $token->getLine()));
151
- } elseif ($token->test(\WCML\Twig\Token::PUNCTUATION_TYPE, '(')) {
152
- $this->parser->getStream()->next();
153
- $expr = $this->parseExpression();
154
- $this->parser->getStream()->expect(\WCML\Twig\Token::PUNCTUATION_TYPE, ')', 'An opened parenthesis is not properly closed');
155
- return $this->parsePostfixExpression($expr);
156
- }
157
- return $this->parsePrimaryExpression();
158
- }
159
- protected function parseConditionalExpression($expr)
160
- {
161
- while ($this->parser->getStream()->nextIf(\WCML\Twig\Token::PUNCTUATION_TYPE, '?')) {
162
- if (!$this->parser->getStream()->nextIf(\WCML\Twig\Token::PUNCTUATION_TYPE, ':')) {
163
- $expr2 = $this->parseExpression();
164
- if ($this->parser->getStream()->nextIf(\WCML\Twig\Token::PUNCTUATION_TYPE, ':')) {
165
- $expr3 = $this->parseExpression();
166
- } else {
167
- $expr3 = new \WCML\Twig\Node\Expression\ConstantExpression('', $this->parser->getCurrentToken()->getLine());
168
- }
169
- } else {
170
- $expr2 = $expr;
171
- $expr3 = $this->parseExpression();
172
- }
173
- $expr = new \WCML\Twig\Node\Expression\ConditionalExpression($expr, $expr2, $expr3, $this->parser->getCurrentToken()->getLine());
174
- }
175
- return $expr;
176
- }
177
- protected function isUnary(\WCML\Twig\Token $token)
178
- {
179
- return $token->test(\WCML\Twig\Token::OPERATOR_TYPE) && isset($this->unaryOperators[$token->getValue()]);
180
- }
181
- protected function isBinary(\WCML\Twig\Token $token)
182
- {
183
- return $token->test(\WCML\Twig\Token::OPERATOR_TYPE) && isset($this->binaryOperators[$token->getValue()]);
184
- }
185
- public function parsePrimaryExpression()
186
- {
187
- $token = $this->parser->getCurrentToken();
188
- switch ($token->getType()) {
189
- case \WCML\Twig\Token::NAME_TYPE:
190
- $this->parser->getStream()->next();
191
- switch ($token->getValue()) {
192
- case 'true':
193
- case 'TRUE':
194
- $node = new \WCML\Twig\Node\Expression\ConstantExpression(\true, $token->getLine());
195
- break;
196
- case 'false':
197
- case 'FALSE':
198
- $node = new \WCML\Twig\Node\Expression\ConstantExpression(\false, $token->getLine());
199
- break;
200
- case 'none':
201
- case 'NONE':
202
- case 'null':
203
- case 'NULL':
204
- $node = new \WCML\Twig\Node\Expression\ConstantExpression(null, $token->getLine());
205
- break;
206
- default:
207
- if ('(' === $this->parser->getCurrentToken()->getValue()) {
208
- $node = $this->getFunctionNode($token->getValue(), $token->getLine());
209
- } else {
210
- $node = new \WCML\Twig\Node\Expression\NameExpression($token->getValue(), $token->getLine());
211
- }
212
- }
213
- break;
214
- case \WCML\Twig\Token::NUMBER_TYPE:
215
- $this->parser->getStream()->next();
216
- $node = new \WCML\Twig\Node\Expression\ConstantExpression($token->getValue(), $token->getLine());
217
- break;
218
- case \WCML\Twig\Token::STRING_TYPE:
219
- case \WCML\Twig\Token::INTERPOLATION_START_TYPE:
220
- $node = $this->parseStringExpression();
221
- break;
222
- case \WCML\Twig\Token::OPERATOR_TYPE:
223
- if (\preg_match(\WCML\Twig\Lexer::REGEX_NAME, $token->getValue(), $matches) && $matches[0] == $token->getValue()) {
224
- // in this context, string operators are variable names
225
- $this->parser->getStream()->next();
226
- $node = new \WCML\Twig\Node\Expression\NameExpression($token->getValue(), $token->getLine());
227
- break;
228
- } elseif (isset($this->unaryOperators[$token->getValue()])) {
229
- $class = $this->unaryOperators[$token->getValue()]['class'];
230
- $ref = new \ReflectionClass($class);
231
- $negClass = 'WCML\\Twig\\Node\\Expression\\Unary\\NegUnary';
232
- $posClass = 'WCML\\Twig\\Node\\Expression\\Unary\\PosUnary';
233
- if (!(\in_array($ref->getName(), [$negClass, $posClass, 'Twig_Node_Expression_Unary_Neg', 'Twig_Node_Expression_Unary_Pos']) || $ref->isSubclassOf($negClass) || $ref->isSubclassOf($posClass) || $ref->isSubclassOf('Twig_Node_Expression_Unary_Neg') || $ref->isSubclassOf('Twig_Node_Expression_Unary_Pos'))) {
234
- throw new \WCML\Twig\Error\SyntaxError(\sprintf('Unexpected unary operator "%s".', $token->getValue()), $token->getLine(), $this->parser->getStream()->getSourceContext());
235
- }
236
- $this->parser->getStream()->next();
237
- $expr = $this->parsePrimaryExpression();
238
- $node = new $class($expr, $token->getLine());
239
- break;
240
- }
241
- // no break
242
- default:
243
- if ($token->test(\WCML\Twig\Token::PUNCTUATION_TYPE, '[')) {
244
- $node = $this->parseArrayExpression();
245
- } elseif ($token->test(\WCML\Twig\Token::PUNCTUATION_TYPE, '{')) {
246
- $node = $this->parseHashExpression();
247
- } elseif ($token->test(\WCML\Twig\Token::OPERATOR_TYPE, '=') && ('==' === $this->parser->getStream()->look(-1)->getValue() || '!=' === $this->parser->getStream()->look(-1)->getValue())) {
248
- throw new \WCML\Twig\Error\SyntaxError(\sprintf('Unexpected operator of value "%s". Did you try to use "===" or "!==" for strict comparison? Use "is same as(value)" instead.', $token->getValue()), $token->getLine(), $this->parser->getStream()->getSourceContext());
249
- } else {
250
- throw new \WCML\Twig\Error\SyntaxError(\sprintf('Unexpected token "%s" of value "%s".', \WCML\Twig\Token::typeToEnglish($token->getType()), $token->getValue()), $token->getLine(), $this->parser->getStream()->getSourceContext());
251
- }
252
- }
253
- return $this->parsePostfixExpression($node);
254
- }
255
- public function parseStringExpression()
256
- {
257
- $stream = $this->parser->getStream();
258
- $nodes = [];
259
- // a string cannot be followed by another string in a single expression
260
- $nextCanBeString = \true;
261
- while (\true) {
262
- if ($nextCanBeString && ($token = $stream->nextIf(\WCML\Twig\Token::STRING_TYPE))) {
263
- $nodes[] = new \WCML\Twig\Node\Expression\ConstantExpression($token->getValue(), $token->getLine());
264
- $nextCanBeString = \false;
265
- } elseif ($stream->nextIf(\WCML\Twig\Token::INTERPOLATION_START_TYPE)) {
266
- $nodes[] = $this->parseExpression();
267
- $stream->expect(\WCML\Twig\Token::INTERPOLATION_END_TYPE);
268
- $nextCanBeString = \true;
269
- } else {
270
- break;
271
- }
272
- }
273
- $expr = \array_shift($nodes);
274
- foreach ($nodes as $node) {
275
- $expr = new \WCML\Twig\Node\Expression\Binary\ConcatBinary($expr, $node, $node->getTemplateLine());
276
- }
277
- return $expr;
278
- }
279
- public function parseArrayExpression()
280
- {
281
- $stream = $this->parser->getStream();
282
- $stream->expect(\WCML\Twig\Token::PUNCTUATION_TYPE, '[', 'An array element was expected');
283
- $node = new \WCML\Twig\Node\Expression\ArrayExpression([], $stream->getCurrent()->getLine());
284
- $first = \true;
285
- while (!$stream->test(\WCML\Twig\Token::PUNCTUATION_TYPE, ']')) {
286
- if (!$first) {
287
- $stream->expect(\WCML\Twig\Token::PUNCTUATION_TYPE, ',', 'An array element must be followed by a comma');
288
- // trailing ,?
289
- if ($stream->test(\WCML\Twig\Token::PUNCTUATION_TYPE, ']')) {
290
- break;
291
- }
292
- }
293
- $first = \false;
294
- $node->addElement($this->parseExpression());
295
- }
296
- $stream->expect(\WCML\Twig\Token::PUNCTUATION_TYPE, ']', 'An opened array is not properly closed');
297
- return $node;
298
- }
299
- public function parseHashExpression()
300
- {
301
- $stream = $this->parser->getStream();
302
- $stream->expect(\WCML\Twig\Token::PUNCTUATION_TYPE, '{', 'A hash element was expected');
303
- $node = new \WCML\Twig\Node\Expression\ArrayExpression([], $stream->getCurrent()->getLine());
304
- $first = \true;
305
- while (!$stream->test(\WCML\Twig\Token::PUNCTUATION_TYPE, '}')) {
306
- if (!$first) {
307
- $stream->expect(\WCML\Twig\Token::PUNCTUATION_TYPE, ',', 'A hash value must be followed by a comma');
308
- // trailing ,?
309
- if ($stream->test(\WCML\Twig\Token::PUNCTUATION_TYPE, '}')) {
310
- break;
311
- }
312
- }
313
- $first = \false;
314
- // a hash key can be:
315
- //
316
- // * a number -- 12
317
- // * a string -- 'a'
318
- // * a name, which is equivalent to a string -- a
319
- // * an expression, which must be enclosed in parentheses -- (1 + 2)
320
- if (($token = $stream->nextIf(\WCML\Twig\Token::STRING_TYPE)) || ($token = $stream->nextIf(\WCML\Twig\Token::NAME_TYPE)) || ($token = $stream->nextIf(\WCML\Twig\Token::NUMBER_TYPE))) {
321
- $key = new \WCML\Twig\Node\Expression\ConstantExpression($token->getValue(), $token->getLine());
322
- } elseif ($stream->test(\WCML\Twig\Token::PUNCTUATION_TYPE, '(')) {
323
- $key = $this->parseExpression();
324
- } else {
325
- $current = $stream->getCurrent();
326
- throw new \WCML\Twig\Error\SyntaxError(\sprintf('A hash key must be a quoted string, a number, a name, or an expression enclosed in parentheses (unexpected token "%s" of value "%s".', \WCML\Twig\Token::typeToEnglish($current->getType()), $current->getValue()), $current->getLine(), $stream->getSourceContext());
327
- }
328
- $stream->expect(\WCML\Twig\Token::PUNCTUATION_TYPE, ':', 'A hash key must be followed by a colon (:)');
329
- $value = $this->parseExpression();
330
- $node->addElement($value, $key);
331
- }
332
- $stream->expect(\WCML\Twig\Token::PUNCTUATION_TYPE, '}', 'An opened hash is not properly closed');
333
- return $node;
334
- }
335
- public function parsePostfixExpression($node)
336
- {
337
- while (\true) {
338
- $token = $this->parser->getCurrentToken();
339
- if (\WCML\Twig\Token::PUNCTUATION_TYPE == $token->getType()) {
340
- if ('.' == $token->getValue() || '[' == $token->getValue()) {
341
- $node = $this->parseSubscriptExpression($node);
342
- } elseif ('|' == $token->getValue()) {
343
- $node = $this->parseFilterExpression($node);
344
- } else {
345
- break;
346
- }
347
- } else {
348
- break;
349
- }
350
- }
351
- return $node;
352
- }
353
- public function getFunctionNode($name, $line)
354
- {
355
- switch ($name) {
356
- case 'parent':
357
- $this->parseArguments();
358
- if (!\count($this->parser->getBlockStack())) {
359
- throw new \WCML\Twig\Error\SyntaxError('Calling "parent" outside a block is forbidden.', $line, $this->parser->getStream()->getSourceContext());
360
- }
361
- if (!$this->parser->getParent() && !$this->parser->hasTraits()) {
362
- throw new \WCML\Twig\Error\SyntaxError('Calling "parent" on a template that does not extend nor "use" another template is forbidden.', $line, $this->parser->getStream()->getSourceContext());
363
- }
364
- return new \WCML\Twig\Node\Expression\ParentExpression($this->parser->peekBlockStack(), $line);
365
- case 'block':
366
- $args = $this->parseArguments();
367
- if (\count($args) < 1) {
368
- throw new \WCML\Twig\Error\SyntaxError('The "block" function takes one argument (the block name).', $line, $this->parser->getStream()->getSourceContext());
369
- }
370
- return new \WCML\Twig\Node\Expression\BlockReferenceExpression($args->getNode(0), \count($args) > 1 ? $args->getNode(1) : null, $line);
371
- case 'attribute':
372
- $args = $this->parseArguments();
373
- if (\count($args) < 2) {
374
- throw new \WCML\Twig\Error\SyntaxError('The "attribute" function takes at least two arguments (the variable and the attributes).', $line, $this->parser->getStream()->getSourceContext());
375
- }
376
- return new \WCML\Twig\Node\Expression\GetAttrExpression($args->getNode(0), $args->getNode(1), \count($args) > 2 ? $args->getNode(2) : null, \WCML\Twig\Template::ANY_CALL, $line);
377
- default:
378
- if (null !== ($alias = $this->parser->getImportedSymbol('function', $name))) {
379
- $arguments = new \WCML\Twig\Node\Expression\ArrayExpression([], $line);
380
- foreach ($this->parseArguments() as $n) {
381
- $arguments->addElement($n);
382
- }
383
- $node = new \WCML\Twig\Node\Expression\MethodCallExpression($alias['node'], $alias['name'], $arguments, $line);
384
- $node->setAttribute('safe', \true);
385
- return $node;
386
- }
387
- $args = $this->parseArguments(\true);
388
- $class = $this->getFunctionNodeClass($name, $line);
389
- return new $class($name, $args, $line);
390
- }
391
- }
392
- public function parseSubscriptExpression($node)
393
- {
394
- $stream = $this->parser->getStream();
395
- $token = $stream->next();
396
- $lineno = $token->getLine();
397
- $arguments = new \WCML\Twig\Node\Expression\ArrayExpression([], $lineno);
398
- $type = \WCML\Twig\Template::ANY_CALL;
399
- if ('.' == $token->getValue()) {
400
- $token = $stream->next();
401
- if (\WCML\Twig\Token::NAME_TYPE == $token->getType() || \WCML\Twig\Token::NUMBER_TYPE == $token->getType() || \WCML\Twig\Token::OPERATOR_TYPE == $token->getType() && \preg_match(\WCML\Twig\Lexer::REGEX_NAME, $token->getValue())) {
402
- $arg = new \WCML\Twig\Node\Expression\ConstantExpression($token->getValue(), $lineno);
403
- if ($stream->test(\WCML\Twig\Token::PUNCTUATION_TYPE, '(')) {
404
- $type = \WCML\Twig\Template::METHOD_CALL;
405
- foreach ($this->parseArguments() as $n) {
406
- $arguments->addElement($n);
407
- }
408
- }
409
- } else {
410
- throw new \WCML\Twig\Error\SyntaxError('Expected name or number.', $lineno, $stream->getSourceContext());
411
- }
412
- if ($node instanceof \WCML\Twig\Node\Expression\NameExpression && null !== $this->parser->getImportedSymbol('template', $node->getAttribute('name'))) {
413
- if (!$arg instanceof \WCML\Twig\Node\Expression\ConstantExpression) {
414
- throw new \WCML\Twig\Error\SyntaxError(\sprintf('Dynamic macro names are not supported (called on "%s").', $node->getAttribute('name')), $token->getLine(), $stream->getSourceContext());
415
- }
416
- $name = $arg->getAttribute('value');
417
- if ($this->parser->isReservedMacroName($name)) {
418
- throw new \WCML\Twig\Error\SyntaxError(\sprintf('"%s" cannot be called as macro as it is a reserved keyword.', $name), $token->getLine(), $stream->getSourceContext());
419
- }
420
- $node = new \WCML\Twig\Node\Expression\MethodCallExpression($node, 'get' . $name, $arguments, $lineno);
421
- $node->setAttribute('safe', \true);
422
- return $node;
423
- }
424
- } else {
425
- $type = \WCML\Twig\Template::ARRAY_CALL;
426
- // slice?
427
- $slice = \false;
428
- if ($stream->test(\WCML\Twig\Token::PUNCTUATION_TYPE, ':')) {
429
- $slice = \true;
430
- $arg = new \WCML\Twig\Node\Expression\ConstantExpression(0, $token->getLine());
431
- } else {
432
- $arg = $this->parseExpression();
433
- }
434
- if ($stream->nextIf(\WCML\Twig\Token::PUNCTUATION_TYPE, ':')) {
435
- $slice = \true;
436
- }
437
- if ($slice) {
438
- if ($stream->test(\WCML\Twig\Token::PUNCTUATION_TYPE, ']')) {
439
- $length = new \WCML\Twig\Node\Expression\ConstantExpression(null, $token->getLine());
440
- } else {
441
- $length = $this->parseExpression();
442
- }
443
- $class = $this->getFilterNodeClass('slice', $token->getLine());
444
- $arguments = new \WCML\Twig\Node\Node([$arg, $length]);
445
- $filter = new $class($node, new \WCML\Twig\Node\Expression\ConstantExpression('slice', $token->getLine()), $arguments, $token->getLine());
446
- $stream->expect(\WCML\Twig\Token::PUNCTUATION_TYPE, ']');
447
- return $filter;
448
- }
449
- $stream->expect(\WCML\Twig\Token::PUNCTUATION_TYPE, ']');
450
- }
451
- return new \WCML\Twig\Node\Expression\GetAttrExpression($node, $arg, $arguments, $type, $lineno);
452
- }
453
- public function parseFilterExpression($node)
454
- {
455
- $this->parser->getStream()->next();
456
- return $this->parseFilterExpressionRaw($node);
457
- }
458
- public function parseFilterExpressionRaw($node, $tag = null)
459
- {
460
- while (\true) {
461
- $token = $this->parser->getStream()->expect(\WCML\Twig\Token::NAME_TYPE);
462
- $name = new \WCML\Twig\Node\Expression\ConstantExpression($token->getValue(), $token->getLine());
463
- if (!$this->parser->getStream()->test(\WCML\Twig\Token::PUNCTUATION_TYPE, '(')) {
464
- $arguments = new \WCML\Twig\Node\Node();
465
- } else {
466
- $arguments = $this->parseArguments(\true, \false, \true);
467
- }
468
- $class = $this->getFilterNodeClass($name->getAttribute('value'), $token->getLine());
469
- $node = new $class($node, $name, $arguments, $token->getLine(), $tag);
470
- if (!$this->parser->getStream()->test(\WCML\Twig\Token::PUNCTUATION_TYPE, '|')) {
471
- break;
472
- }
473
- $this->parser->getStream()->next();
474
- }
475
- return $node;
476
- }
477
- /**
478
- * Parses arguments.
479
- *
480
- * @param bool $namedArguments Whether to allow named arguments or not
481
- * @param bool $definition Whether we are parsing arguments for a function definition
482
- *
483
- * @return Node
484
- *
485
- * @throws SyntaxError
486
- */
487
- public function parseArguments($namedArguments = \false, $definition = \false, $allowArrow = \false)
488
- {
489
- $args = [];
490
- $stream = $this->parser->getStream();
491
- $stream->expect(\WCML\Twig\Token::PUNCTUATION_TYPE, '(', 'A list of arguments must begin with an opening parenthesis');
492
- while (!$stream->test(\WCML\Twig\Token::PUNCTUATION_TYPE, ')')) {
493
- if (!empty($args)) {
494
- $stream->expect(\WCML\Twig\Token::PUNCTUATION_TYPE, ',', 'Arguments must be separated by a comma');
495
- }
496
- if ($definition) {
497
- $token = $stream->expect(\WCML\Twig\Token::NAME_TYPE, null, 'An argument must be a name');
498
- $value = new \WCML\Twig\Node\Expression\NameExpression($token->getValue(), $this->parser->getCurrentToken()->getLine());
499
- } else {
500
- $value = $this->parseExpression(0, $allowArrow);
501
- }
502
- $name = null;
503
- if ($namedArguments && ($token = $stream->nextIf(\WCML\Twig\Token::OPERATOR_TYPE, '='))) {
504
- if (!$value instanceof \WCML\Twig\Node\Expression\NameExpression) {
505
- throw new \WCML\Twig\Error\SyntaxError(\sprintf('A parameter name must be a string, "%s" given.', \get_class($value)), $token->getLine(), $stream->getSourceContext());
506
- }
507
- $name = $value->getAttribute('name');
508
- if ($definition) {
509
- $value = $this->parsePrimaryExpression();
510
- if (!$this->checkConstantExpression($value)) {
511
- throw new \WCML\Twig\Error\SyntaxError(\sprintf('A default value for an argument must be a constant (a boolean, a string, a number, or an array).'), $token->getLine(), $stream->getSourceContext());
512
- }
513
- } else {
514
- $value = $this->parseExpression(0, $allowArrow);
515
- }
516
- }
517
- if ($definition) {
518
- if (null === $name) {
519
- $name = $value->getAttribute('name');
520
- $value = new \WCML\Twig\Node\Expression\ConstantExpression(null, $this->parser->getCurrentToken()->getLine());
521
- }
522
- $args[$name] = $value;
523
- } else {
524
- if (null === $name) {
525
- $args[] = $value;
526
- } else {
527
- $args[$name] = $value;
528
- }
529
- }
530
- }
531
- $stream->expect(\WCML\Twig\Token::PUNCTUATION_TYPE, ')', 'A list of arguments must be closed by a parenthesis');
532
- return new \WCML\Twig\Node\Node($args);
533
- }
534
- public function parseAssignmentExpression()
535
- {
536
- $stream = $this->parser->getStream();
537
- $targets = [];
538
- while (\true) {
539
- $token = $this->parser->getCurrentToken();
540
- if ($stream->test(\WCML\Twig\Token::OPERATOR_TYPE) && \preg_match(\WCML\Twig\Lexer::REGEX_NAME, $token->getValue())) {
541
- // in this context, string operators are variable names
542
- $this->parser->getStream()->next();
543
- } else {
544
- $stream->expect(\WCML\Twig\Token::NAME_TYPE, null, 'Only variables can be assigned to');
545
- }
546
- $value = $token->getValue();
547
- if (\in_array(\strtolower($value), ['true', 'false', 'none', 'null'])) {
548
- throw new \WCML\Twig\Error\SyntaxError(\sprintf('You cannot assign a value to "%s".', $value), $token->getLine(), $stream->getSourceContext());
549
- }
550
- $targets[] = new \WCML\Twig\Node\Expression\AssignNameExpression($value, $token->getLine());
551
- if (!$stream->nextIf(\WCML\Twig\Token::PUNCTUATION_TYPE, ',')) {
552
- break;
553
- }
554
- }
555
- return new \WCML\Twig\Node\Node($targets);
556
- }
557
- public function parseMultitargetExpression()
558
- {
559
- $targets = [];
560
- while (\true) {
561
- $targets[] = $this->parseExpression();
562
- if (!$this->parser->getStream()->nextIf(\WCML\Twig\Token::PUNCTUATION_TYPE, ',')) {
563
- break;
564
- }
565
- }
566
- return new \WCML\Twig\Node\Node($targets);
567
- }
568
- private function parseNotTestExpression(\WCML\Twig_NodeInterface $node)
569
- {
570
- return new \WCML\Twig\Node\Expression\Unary\NotUnary($this->parseTestExpression($node), $this->parser->getCurrentToken()->getLine());
571
- }
572
- private function parseTestExpression(\WCML\Twig_NodeInterface $node)
573
- {
574
- $stream = $this->parser->getStream();
575
- list($name, $test) = $this->getTest($node->getTemplateLine());
576
- $class = $this->getTestNodeClass($test);
577
- $arguments = null;
578
- if ($stream->test(\WCML\Twig\Token::PUNCTUATION_TYPE, '(')) {
579
- $arguments = $this->parseArguments(\true);
580
- }
581
- return new $class($node, $name, $arguments, $this->parser->getCurrentToken()->getLine());
582
- }
583
- private function getTest($line)
584
- {
585
- $stream = $this->parser->getStream();
586
- $name = $stream->expect(\WCML\Twig\Token::NAME_TYPE)->getValue();
587
- if ($test = $this->env->getTest($name)) {
588
- return [$name, $test];
589
- }
590
- if ($stream->test(\WCML\Twig\Token::NAME_TYPE)) {
591
- // try 2-words tests
592
- $name = $name . ' ' . $this->parser->getCurrentToken()->getValue();
593
- if ($test = $this->env->getTest($name)) {
594
- $stream->next();
595
- return [$name, $test];
596
- }
597
- }
598
- $e = new \WCML\Twig\Error\SyntaxError(\sprintf('Unknown "%s" test.', $name), $line, $stream->getSourceContext());
599
- $e->addSuggestions($name, \array_keys($this->env->getTests()));
600
- throw $e;
601
- }
602
- private function getTestNodeClass($test)
603
- {
604
- if ($test instanceof \WCML\Twig\TwigTest && $test->isDeprecated()) {
605
- $stream = $this->parser->getStream();
606
- $message = \sprintf('Twig Test "%s" is deprecated', $test->getName());
607
- if (!\is_bool($test->getDeprecatedVersion())) {
608
- $message .= \sprintf(' since version %s', $test->getDeprecatedVersion());
609
- }
610
- if ($test->getAlternative()) {
611
- $message .= \sprintf('. Use "%s" instead', $test->getAlternative());
612
- }
613
- $src = $stream->getSourceContext();
614
- $message .= \sprintf(' in %s at line %d.', $src->getPath() ? $src->getPath() : $src->getName(), $stream->getCurrent()->getLine());
615
- @\trigger_error($message, \E_USER_DEPRECATED);
616
- }
617
- if ($test instanceof \WCML\Twig\TwigTest) {
618
- return $test->getNodeClass();
619
- }
620
- return $test instanceof \WCML\Twig_Test_Node ? $test->getClass() : 'Twig\\Node\\Expression\\TestExpression';
621
- }
622
- protected function getFunctionNodeClass($name, $line)
623
- {
624
- if (\false === ($function = $this->env->getFunction($name))) {
625
- $e = new \WCML\Twig\Error\SyntaxError(\sprintf('Unknown "%s" function.', $name), $line, $this->parser->getStream()->getSourceContext());
626
- $e->addSuggestions($name, \array_keys($this->env->getFunctions()));
627
- throw $e;
628
- }
629
- if ($function instanceof \WCML\Twig\TwigFunction && $function->isDeprecated()) {
630
- $message = \sprintf('Twig Function "%s" is deprecated', $function->getName());
631
- if (!\is_bool($function->getDeprecatedVersion())) {
632
- $message .= \sprintf(' since version %s', $function->getDeprecatedVersion());
633
- }
634
- if ($function->getAlternative()) {
635
- $message .= \sprintf('. Use "%s" instead', $function->getAlternative());
636
- }
637
- $src = $this->parser->getStream()->getSourceContext();
638
- $message .= \sprintf(' in %s at line %d.', $src->getPath() ? $src->getPath() : $src->getName(), $line);
639
- @\trigger_error($message, \E_USER_DEPRECATED);
640
- }
641
- if ($function instanceof \WCML\Twig\TwigFunction) {
642
- return $function->getNodeClass();
643
- }
644
- return $function instanceof \WCML\Twig_Function_Node ? $function->getClass() : 'Twig\\Node\\Expression\\FunctionExpression';
645
- }
646
- protected function getFilterNodeClass($name, $line)
647
- {
648
- if (\false === ($filter = $this->env->getFilter($name))) {
649
- $e = new \WCML\Twig\Error\SyntaxError(\sprintf('Unknown "%s" filter.', $name), $line, $this->parser->getStream()->getSourceContext());
650
- $e->addSuggestions($name, \array_keys($this->env->getFilters()));
651
- throw $e;
652
- }
653
- if ($filter instanceof \WCML\Twig\TwigFilter && $filter->isDeprecated()) {
654
- $message = \sprintf('Twig Filter "%s" is deprecated', $filter->getName());
655
- if (!\is_bool($filter->getDeprecatedVersion())) {
656
- $message .= \sprintf(' since version %s', $filter->getDeprecatedVersion());
657
- }
658
- if ($filter->getAlternative()) {
659
- $message .= \sprintf('. Use "%s" instead', $filter->getAlternative());
660
- }
661
- $src = $this->parser->getStream()->getSourceContext();
662
- $message .= \sprintf(' in %s at line %d.', $src->getPath() ? $src->getPath() : $src->getName(), $line);
663
- @\trigger_error($message, \E_USER_DEPRECATED);
664
- }
665
- if ($filter instanceof \WCML\Twig\TwigFilter) {
666
- return $filter->getNodeClass();
667
- }
668
- return $filter instanceof \WCML\Twig_Filter_Node ? $filter->getClass() : 'Twig\\Node\\Expression\\FilterExpression';
669
- }
670
- // checks that the node only contains "constant" elements
671
- protected function checkConstantExpression(\WCML\Twig_NodeInterface $node)
672
- {
673
- if (!($node instanceof \WCML\Twig\Node\Expression\ConstantExpression || $node instanceof \WCML\Twig\Node\Expression\ArrayExpression || $node instanceof \WCML\Twig\Node\Expression\Unary\NegUnary || $node instanceof \WCML\Twig\Node\Expression\Unary\PosUnary)) {
674
- return \false;
675
- }
676
- foreach ($node as $n) {
677
- if (!$this->checkConstantExpression($n)) {
678
- return \false;
679
- }
680
- }
681
- return \true;
682
- }
683
- }
684
- \class_alias('WCML\\Twig\\ExpressionParser', 'WCML\\Twig_ExpressionParser');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/twig/src/Extension/AbstractExtension.php DELETED
@@ -1,61 +0,0 @@
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
- namespace WCML\Twig\Extension;
12
-
13
- use WCML\Twig\Environment;
14
- abstract class AbstractExtension implements \WCML\Twig\Extension\ExtensionInterface
15
- {
16
- /**
17
- * @deprecated since 1.23 (to be removed in 2.0), implement \Twig_Extension_InitRuntimeInterface instead
18
- */
19
- public function initRuntime(\WCML\Twig\Environment $environment)
20
- {
21
- }
22
- public function getTokenParsers()
23
- {
24
- return [];
25
- }
26
- public function getNodeVisitors()
27
- {
28
- return [];
29
- }
30
- public function getFilters()
31
- {
32
- return [];
33
- }
34
- public function getTests()
35
- {
36
- return [];
37
- }
38
- public function getFunctions()
39
- {
40
- return [];
41
- }
42
- public function getOperators()
43
- {
44
- return [];
45
- }
46
- /**
47
- * @deprecated since 1.23 (to be removed in 2.0), implement \Twig_Extension_GlobalsInterface instead
48
- */
49
- public function getGlobals()
50
- {
51
- return [];
52
- }
53
- /**
54
- * @deprecated since 1.26 (to be removed in 2.0), not used anymore internally
55
- */
56
- public function getName()
57
- {
58
- return \get_class($this);
59
- }
60
- }
61
- \class_alias('WCML\\Twig\\Extension\\AbstractExtension', 'WCML\\Twig_Extension');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/twig/src/Extension/CoreExtension.php DELETED
@@ -1,1390 +0,0 @@
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
- namespace WCML\Twig\Extension;
12
-
13
- use WCML\Twig\ExpressionParser;
14
- use WCML\Twig\TokenParser\ApplyTokenParser;
15
- use WCML\Twig\TokenParser\BlockTokenParser;
16
- use WCML\Twig\TokenParser\DeprecatedTokenParser;
17
- use WCML\Twig\TokenParser\DoTokenParser;
18
- use WCML\Twig\TokenParser\EmbedTokenParser;
19
- use WCML\Twig\TokenParser\ExtendsTokenParser;
20
- use WCML\Twig\TokenParser\FilterTokenParser;
21
- use WCML\Twig\TokenParser\FlushTokenParser;
22
- use WCML\Twig\TokenParser\ForTokenParser;
23
- use WCML\Twig\TokenParser\FromTokenParser;
24
- use WCML\Twig\TokenParser\IfTokenParser;
25
- use WCML\Twig\TokenParser\ImportTokenParser;
26
- use WCML\Twig\TokenParser\IncludeTokenParser;
27
- use WCML\Twig\TokenParser\MacroTokenParser;
28
- use WCML\Twig\TokenParser\SetTokenParser;
29
- use WCML\Twig\TokenParser\SpacelessTokenParser;
30
- use WCML\Twig\TokenParser\UseTokenParser;
31
- use WCML\Twig\TokenParser\WithTokenParser;
32
- use WCML\Twig\TwigFilter;
33
- use WCML\Twig\TwigFunction;
34
- use WCML\Twig\TwigTest;
35
- /**
36
- * @final
37
- */
38
- class CoreExtension extends \WCML\Twig\Extension\AbstractExtension
39
- {
40
- protected $dateFormats = ['F j, Y H:i', '%d days'];
41
- protected $numberFormat = [0, '.', ','];
42
- protected $timezone = null;
43
- protected $escapers = [];
44
- /**
45
- * Defines a new escaper to be used via the escape filter.
46
- *
47
- * @param string $strategy The strategy name that should be used as a strategy in the escape call
48
- * @param callable $callable A valid PHP callable
49
- */
50
- public function setEscaper($strategy, $callable)
51
- {
52
- $this->escapers[$strategy] = $callable;
53
- }
54
- /**
55
- * Gets all defined escapers.
56
- *
57
- * @return array An array of escapers
58
- */
59
- public function getEscapers()
60
- {
61
- return $this->escapers;
62
- }
63
- /**
64
- * Sets the default format to be used by the date filter.
65
- *
66
- * @param string $format The default date format string
67
- * @param string $dateIntervalFormat The default date interval format string
68
- */
69
- public function setDateFormat($format = null, $dateIntervalFormat = null)
70
- {
71
- if (null !== $format) {
72
- $this->dateFormats[0] = $format;
73
- }
74
- if (null !== $dateIntervalFormat) {
75
- $this->dateFormats[1] = $dateIntervalFormat;
76
- }
77
- }
78
- /**
79
- * Gets the default format to be used by the date filter.
80
- *
81
- * @return array The default date format string and the default date interval format string
82
- */
83
- public function getDateFormat()
84
- {
85
- return $this->dateFormats;
86
- }
87
- /**
88
- * Sets the default timezone to be used by the date filter.
89
- *
90
- * @param \DateTimeZone|string $timezone The default timezone string or a \DateTimeZone object
91
- */
92
- public function setTimezone($timezone)
93
- {
94
- $this->timezone = $timezone instanceof \DateTimeZone ? $timezone : new \DateTimeZone($timezone);
95
- }
96
- /**
97
- * Gets the default timezone to be used by the date filter.
98
- *
99
- * @return \DateTimeZone The default timezone currently in use
100
- */
101
- public function getTimezone()
102
- {
103
- if (null === $this->timezone) {
104
- $this->timezone = new \DateTimeZone(\date_default_timezone_get());
105
- }
106
- return $this->timezone;
107
- }
108
- /**
109
- * Sets the default format to be used by the number_format filter.
110
- *
111
- * @param int $decimal the number of decimal places to use
112
- * @param string $decimalPoint the character(s) to use for the decimal point
113
- * @param string $thousandSep the character(s) to use for the thousands separator
114
- */
115
- public function setNumberFormat($decimal, $decimalPoint, $thousandSep)
116
- {
117
- $this->numberFormat = [$decimal, $decimalPoint, $thousandSep];
118
- }
119
- /**
120
- * Get the default format used by the number_format filter.
121
- *
122
- * @return array The arguments for number_format()
123
- */
124
- public function getNumberFormat()
125
- {
126
- return $this->numberFormat;
127
- }
128
- public function getTokenParsers()
129
- {
130
- return [new \WCML\Twig\TokenParser\ApplyTokenParser(), new \WCML\Twig\TokenParser\ForTokenParser(), new \WCML\Twig\TokenParser\IfTokenParser(), new \WCML\Twig\TokenParser\ExtendsTokenParser(), new \WCML\Twig\TokenParser\IncludeTokenParser(), new \WCML\Twig\TokenParser\BlockTokenParser(), new \WCML\Twig\TokenParser\UseTokenParser(), new \WCML\Twig\TokenParser\FilterTokenParser(), new \WCML\Twig\TokenParser\MacroTokenParser(), new \WCML\Twig\TokenParser\ImportTokenParser(), new \WCML\Twig\TokenParser\FromTokenParser(), new \WCML\Twig\TokenParser\SetTokenParser(), new \WCML\Twig\TokenParser\SpacelessTokenParser(), new \WCML\Twig\TokenParser\FlushTokenParser(), new \WCML\Twig\TokenParser\DoTokenParser(), new \WCML\Twig\TokenParser\EmbedTokenParser(), new \WCML\Twig\TokenParser\WithTokenParser(), new \WCML\Twig\TokenParser\DeprecatedTokenParser()];
131
- }
132
- public function getFilters()
133
- {
134
- $filters = [
135
- // formatting filters
136
- new \WCML\Twig\TwigFilter('date', '\\WCML\\twig_date_format_filter', ['needs_environment' => \true]),
137
- new \WCML\Twig\TwigFilter('date_modify', '\\WCML\\twig_date_modify_filter', ['needs_environment' => \true]),
138
- new \WCML\Twig\TwigFilter('format', 'sprintf'),
139
- new \WCML\Twig\TwigFilter('replace', '\\WCML\\twig_replace_filter'),
140
- new \WCML\Twig\TwigFilter('number_format', '\\WCML\\twig_number_format_filter', ['needs_environment' => \true]),
141
- new \WCML\Twig\TwigFilter('abs', 'abs'),
142
- new \WCML\Twig\TwigFilter('round', '\\WCML\\twig_round'),
143
- // encoding
144
- new \WCML\Twig\TwigFilter('url_encode', '\\WCML\\twig_urlencode_filter'),
145
- new \WCML\Twig\TwigFilter('json_encode', '\\WCML\\twig_jsonencode_filter'),
146
- new \WCML\Twig\TwigFilter('convert_encoding', '\\WCML\\twig_convert_encoding'),
147
- // string filters
148
- new \WCML\Twig\TwigFilter('title', '\\WCML\\twig_title_string_filter', ['needs_environment' => \true]),
149
- new \WCML\Twig\TwigFilter('capitalize', '\\WCML\\twig_capitalize_string_filter', ['needs_environment' => \true]),
150
- new \WCML\Twig\TwigFilter('upper', 'strtoupper'),
151
- new \WCML\Twig\TwigFilter('lower', 'strtolower'),
152
- new \WCML\Twig\TwigFilter('striptags', 'strip_tags'),
153
- new \WCML\Twig\TwigFilter('trim', '\\WCML\\twig_trim_filter'),
154
- new \WCML\Twig\TwigFilter('nl2br', 'nl2br', ['pre_escape' => 'html', 'is_safe' => ['html']]),
155
- new \WCML\Twig\TwigFilter('spaceless', '\\WCML\\twig_spaceless', ['is_safe' => ['html']]),
156
- // array helpers
157
- new \WCML\Twig\TwigFilter('join', '\\WCML\\twig_join_filter'),
158
- new \WCML\Twig\TwigFilter('split', '\\WCML\\twig_split_filter', ['needs_environment' => \true]),
159
- new \WCML\Twig\TwigFilter('sort', '\\WCML\\twig_sort_filter'),
160
- new \WCML\Twig\TwigFilter('merge', '\\WCML\\twig_array_merge'),
161
- new \WCML\Twig\TwigFilter('batch', '\\WCML\\twig_array_batch'),
162
- new \WCML\Twig\TwigFilter('filter', '\\WCML\\twig_array_filter'),
163
- new \WCML\Twig\TwigFilter('map', '\\WCML\\twig_array_map'),
164
- new \WCML\Twig\TwigFilter('reduce', '\\WCML\\twig_array_reduce'),
165
- // string/array filters
166
- new \WCML\Twig\TwigFilter('reverse', '\\WCML\\twig_reverse_filter', ['needs_environment' => \true]),
167
- new \WCML\Twig\TwigFilter('length', '\\WCML\\twig_length_filter', ['needs_environment' => \true]),
168
- new \WCML\Twig\TwigFilter('slice', '\\WCML\\twig_slice', ['needs_environment' => \true]),
169
- new \WCML\Twig\TwigFilter('first', '\\WCML\\twig_first', ['needs_environment' => \true]),
170
- new \WCML\Twig\TwigFilter('last', '\\WCML\\twig_last', ['needs_environment' => \true]),
171
- // iteration and runtime
172
- new \WCML\Twig\TwigFilter('default', '\\WCML\\_twig_default_filter', ['node_class' => 'WCML\\Twig\\Node\\Expression\\Filter\\DefaultFilter']),
173
- new \WCML\Twig\TwigFilter('keys', '\\WCML\\twig_get_array_keys_filter'),
174
- // escaping
175
- new \WCML\Twig\TwigFilter('escape', '\\WCML\\twig_escape_filter', ['needs_environment' => \true, 'is_safe_callback' => '\\WCML\\twig_escape_filter_is_safe']),
176
- new \WCML\Twig\TwigFilter('e', '\\WCML\\twig_escape_filter', ['needs_environment' => \true, 'is_safe_callback' => '\\WCML\\twig_escape_filter_is_safe']),
177
- ];
178
- if (\function_exists('mb_get_info')) {
179
- $filters[] = new \WCML\Twig\TwigFilter('upper', '\\WCML\\twig_upper_filter', ['needs_environment' => \true]);
180
- $filters[] = new \WCML\Twig\TwigFilter('lower', '\\WCML\\twig_lower_filter', ['needs_environment' => \true]);
181
- }
182
- return $filters;
183
- }
184
- public function getFunctions()
185
- {
186
- return [new \WCML\Twig\TwigFunction('max', 'max'), new \WCML\Twig\TwigFunction('min', 'min'), new \WCML\Twig\TwigFunction('range', 'range'), new \WCML\Twig\TwigFunction('constant', 'twig_constant'), new \WCML\Twig\TwigFunction('cycle', 'twig_cycle'), new \WCML\Twig\TwigFunction('random', 'twig_random', ['needs_environment' => \true]), new \WCML\Twig\TwigFunction('date', 'twig_date_converter', ['needs_environment' => \true]), new \WCML\Twig\TwigFunction('include', 'twig_include', ['needs_environment' => \true, 'needs_context' => \true, 'is_safe' => ['all']]), new \WCML\Twig\TwigFunction('source', 'twig_source', ['needs_environment' => \true, 'is_safe' => ['all']])];
187
- }
188
- public function getTests()
189
- {
190
- return [new \WCML\Twig\TwigTest('even', null, ['node_class' => 'WCML\\Twig\\Node\\Expression\\Test\\EvenTest']), new \WCML\Twig\TwigTest('odd', null, ['node_class' => 'WCML\\Twig\\Node\\Expression\\Test\\OddTest']), new \WCML\Twig\TwigTest('defined', null, ['node_class' => 'WCML\\Twig\\Node\\Expression\\Test\\DefinedTest']), new \WCML\Twig\TwigTest('sameas', null, ['node_class' => 'WCML\\Twig\\Node\\Expression\\Test\\SameasTest', 'deprecated' => '1.21', 'alternative' => 'same as']), new \WCML\Twig\TwigTest('same as', null, ['node_class' => 'WCML\\Twig\\Node\\Expression\\Test\\SameasTest']), new \WCML\Twig\TwigTest('none', null, ['node_class' => 'WCML\\Twig\\Node\\Expression\\Test\\NullTest']), new \WCML\Twig\TwigTest('null', null, ['node_class' => 'WCML\\Twig\\Node\\Expression\\Test\\NullTest']), new \WCML\Twig\TwigTest('divisibleby', null, ['node_class' => 'WCML\\Twig\\Node\\Expression\\Test\\DivisiblebyTest', 'deprecated' => '1.21', 'alternative' => 'divisible by']), new \WCML\Twig\TwigTest('divisible by', null, ['node_class' => 'WCML\\Twig\\Node\\Expression\\Test\\DivisiblebyTest']), new \WCML\Twig\TwigTest('constant', null, ['node_class' => 'WCML\\Twig\\Node\\Expression\\Test\\ConstantTest']), new \WCML\Twig\TwigTest('empty', 'twig_test_empty'), new \WCML\Twig\TwigTest('iterable', 'twig_test_iterable')];
191
- }
192
- public function getOperators()
193
- {
194
- return [['not' => ['precedence' => 50, 'class' => 'WCML\\Twig\\Node\\Expression\\Unary\\NotUnary'], '-' => ['precedence' => 500, 'class' => 'WCML\\Twig\\Node\\Expression\\Unary\\NegUnary'], '+' => ['precedence' => 500, 'class' => 'WCML\\Twig\\Node\\Expression\\Unary\\PosUnary']], ['or' => ['precedence' => 10, 'class' => 'WCML\\Twig\\Node\\Expression\\Binary\\OrBinary', 'associativity' => \WCML\Twig\ExpressionParser::OPERATOR_LEFT], 'and' => ['precedence' => 15, 'class' => 'WCML\\Twig\\Node\\Expression\\Binary\\AndBinary', 'associativity' => \WCML\Twig\ExpressionParser::OPERATOR_LEFT], 'b-or' => ['precedence' => 16, 'class' => 'WCML\\Twig\\Node\\Expression\\Binary\\BitwiseOrBinary', 'associativity' => \WCML\Twig\ExpressionParser::OPERATOR_LEFT], 'b-xor' => ['precedence' => 17, 'class' => 'WCML\\Twig\\Node\\Expression\\Binary\\BitwiseXorBinary', 'associativity' => \WCML\Twig\ExpressionParser::OPERATOR_LEFT], 'b-and' => ['precedence' => 18, 'class' => 'WCML\\Twig\\Node\\Expression\\Binary\\BitwiseAndBinary', 'associativity' => \WCML\Twig\ExpressionParser::OPERATOR_LEFT], '==' => ['precedence' => 20, 'class' => 'WCML\\Twig\\Node\\Expression\\Binary\\EqualBinary', 'associativity' => \WCML\Twig\ExpressionParser::OPERATOR_LEFT], '!=' => ['precedence' => 20, 'class' => 'WCML\\Twig\\Node\\Expression\\Binary\\NotEqualBinary', 'associativity' => \WCML\Twig\ExpressionParser::OPERATOR_LEFT], '<' => ['precedence' => 20, 'class' => 'WCML\\Twig\\Node\\Expression\\Binary\\LessBinary', 'associativity' => \WCML\Twig\ExpressionParser::OPERATOR_LEFT], '>' => ['precedence' => 20, 'class' => 'WCML\\Twig\\Node\\Expression\\Binary\\GreaterBinary', 'associativity' => \WCML\Twig\ExpressionParser::OPERATOR_LEFT], '>=' => ['precedence' => 20, 'class' => 'WCML\\Twig\\Node\\Expression\\Binary\\GreaterEqualBinary', 'associativity' => \WCML\Twig\ExpressionParser::OPERATOR_LEFT], '<=' => ['precedence' => 20, 'class' => 'WCML\\Twig\\Node\\Expression\\Binary\\LessEqualBinary', 'associativity' => \WCML\Twig\ExpressionParser::OPERATOR_LEFT], 'not in' => ['precedence' => 20, 'class' => 'WCML\\Twig\\Node\\Expression\\Binary\\NotInBinary', 'associativity' => \WCML\Twig\ExpressionParser::OPERATOR_LEFT], 'in' => ['precedence' => 20, 'class' => 'WCML\\Twig\\Node\\Expression\\Binary\\InBinary', 'associativity' => \WCML\Twig\ExpressionParser::OPERATOR_LEFT], 'matches' => ['precedence' => 20, 'class' => 'WCML\\Twig\\Node\\Expression\\Binary\\MatchesBinary', 'associativity' => \WCML\Twig\ExpressionParser::OPERATOR_LEFT], 'starts with' => ['precedence' => 20, 'class' => 'WCML\\Twig\\Node\\Expression\\Binary\\StartsWithBinary', 'associativity' => \WCML\Twig\ExpressionParser::OPERATOR_LEFT], 'ends with' => ['precedence' => 20, 'class' => 'WCML\\Twig\\Node\\Expression\\Binary\\EndsWithBinary', 'associativity' => \WCML\Twig\ExpressionParser::OPERATOR_LEFT], '..' => ['precedence' => 25, 'class' => 'WCML\\Twig\\Node\\Expression\\Binary\\RangeBinary', 'associativity' => \WCML\Twig\ExpressionParser::OPERATOR_LEFT], '+' => ['precedence' => 30, 'class' => 'WCML\\Twig\\Node\\Expression\\Binary\\AddBinary', 'associativity' => \WCML\Twig\ExpressionParser::OPERATOR_LEFT], '-' => ['precedence' => 30, 'class' => 'WCML\\Twig\\Node\\Expression\\Binary\\SubBinary', 'associativity' => \WCML\Twig\ExpressionParser::OPERATOR_LEFT], '~' => ['precedence' => 40, 'class' => 'WCML\\Twig\\Node\\Expression\\Binary\\ConcatBinary', 'associativity' => \WCML\Twig\ExpressionParser::OPERATOR_LEFT], '*' => ['precedence' => 60, 'class' => 'WCML\\Twig\\Node\\Expression\\Binary\\MulBinary', 'associativity' => \WCML\Twig\ExpressionParser::OPERATOR_LEFT], '/' => ['precedence' => 60, 'class' => 'WCML\\Twig\\Node\\Expression\\Binary\\DivBinary', 'associativity' => \WCML\Twig\ExpressionParser::OPERATOR_LEFT], '//' => ['precedence' => 60, 'class' => 'WCML\\Twig\\Node\\Expression\\Binary\\FloorDivBinary', 'associativity' => \WCML\Twig\ExpressionParser::OPERATOR_LEFT], '%' => ['precedence' => 60, 'class' => 'WCML\\Twig\\Node\\Expression\\Binary\\ModBinary', 'associativity' => \WCML\Twig\ExpressionParser::OPERATOR_LEFT], 'is' => ['precedence' => 100, 'associativity' => \WCML\Twig\ExpressionParser::OPERATOR_LEFT], 'is not' => ['precedence' => 100, 'associativity' => \WCML\Twig\ExpressionParser::OPERATOR_LEFT], '**' => ['precedence' => 200, 'class' => 'WCML\\Twig\\Node\\Expression\\Binary\\PowerBinary', 'associativity' => \WCML\Twig\ExpressionParser::OPERATOR_RIGHT], '??' => ['precedence' => 300, 'class' => 'WCML\\Twig\\Node\\Expression\\NullCoalesceExpression', 'associativity' => \WCML\Twig\ExpressionParser::OPERATOR_RIGHT]]];
195
- }
196
- public function getName()
197
- {
198
- return 'core';
199
- }
200
- }
201
- \class_alias('WCML\\Twig\\Extension\\CoreExtension', 'WCML\\Twig_Extension_Core');
202
- namespace WCML;
203
-
204
- use WCML\Twig\Environment;
205
- use WCML\Twig\Error\LoaderError;
206
- use WCML\Twig\Error\RuntimeError;
207
- use WCML\Twig\Loader\SourceContextLoaderInterface;
208
- use WCML\Twig\Markup;
209
- use WCML\Twig\Node\Expression\ConstantExpression;
210
- use WCML\Twig\Node\Node;
211
- /**
212
- * Cycles over a value.
213
- *
214
- * @param \ArrayAccess|array $values
215
- * @param int $position The cycle position
216
- *
217
- * @return string The next value in the cycle
218
- */
219
- function twig_cycle($values, $position)
220
- {
221
- if (!\is_array($values) && !$values instanceof \ArrayAccess) {
222
- return $values;
223
- }
224
- return $values[$position % \count($values)];
225
- }
226
- /**
227
- * Returns a random value depending on the supplied parameter type:
228
- * - a random item from a \Traversable or array
229
- * - a random character from a string
230
- * - a random integer between 0 and the integer parameter.
231
- *
232
- * @param \Traversable|array|int|float|string $values The values to pick a random item from
233
- * @param int|null $max Maximum value used when $values is an int
234
- *
235
- * @throws RuntimeError when $values is an empty array (does not apply to an empty string which is returned as is)
236
- *
237
- * @return mixed A random value from the given sequence
238
- */
239
- function twig_random(\WCML\Twig\Environment $env, $values = null, $max = null)
240
- {
241
- if (null === $values) {
242
- return null === $max ? \mt_rand() : \mt_rand(0, $max);
243
- }
244
- if (\is_int($values) || \is_float($values)) {
245
- if (null === $max) {
246
- if ($values < 0) {
247
- $max = 0;
248
- $min = $values;
249
- } else {
250
- $max = $values;
251
- $min = 0;
252
- }
253
- } else {
254
- $min = $values;
255
- $max = $max;
256
- }
257
- return \mt_rand($min, $max);
258
- }
259
- if (\is_string($values)) {
260
- if ('' === $values) {
261
- return '';
262
- }
263
- if (null !== ($charset = $env->getCharset())) {
264
- if ('UTF-8' !== $charset) {
265
- $values = \WCML\twig_convert_encoding($values, 'UTF-8', $charset);
266
- }
267
- // unicode version of str_split()
268
- // split at all positions, but not after the start and not before the end
269
- $values = \preg_split('/(?<!^)(?!$)/u', $values);
270
- if ('UTF-8' !== $charset) {
271
- foreach ($values as $i => $value) {
272
- $values[$i] = \WCML\twig_convert_encoding($value, $charset, 'UTF-8');
273
- }
274
- }
275
- } else {
276
- return $values[\mt_rand(0, \strlen($values) - 1)];
277
- }
278
- }
279
- if (!\WCML\twig_test_iterable($values)) {
280
- return $values;
281
- }
282
- $values = \WCML\twig_to_array($values);
283
- if (0 === \count($values)) {
284
- throw new \WCML\Twig\Error\RuntimeError('The random function cannot pick from an empty array.');
285
- }
286
- return $values[\array_rand($values, 1)];
287
- }
288
- /**
289
- * Converts a date to the given format.
290
- *
291
- * {{ post.published_at|date("m/d/Y") }}
292
- *
293
- * @param \DateTime|\DateTimeInterface|\DateInterval|string $date A date
294
- * @param string|null $format The target format, null to use the default
295
- * @param \DateTimeZone|string|false|null $timezone The target timezone, null to use the default, false to leave unchanged
296
- *
297
- * @return string The formatted date
298
- */
299
- function twig_date_format_filter(\WCML\Twig\Environment $env, $date, $format = null, $timezone = null)
300
- {
301
- if (null === $format) {
302
- $formats = $env->getExtension('WCML\\Twig\\Extension\\CoreExtension')->getDateFormat();
303
- $format = $date instanceof \DateInterval ? $formats[1] : $formats[0];
304
- }
305
- if ($date instanceof \DateInterval) {
306
- return $date->format($format);
307
- }
308
- return \WCML\twig_date_converter($env, $date, $timezone)->format($format);
309
- }
310
- /**
311
- * Returns a new date object modified.
312
- *
313
- * {{ post.published_at|date_modify("-1day")|date("m/d/Y") }}
314
- *
315
- * @param \DateTime|string $date A date
316
- * @param string $modifier A modifier string
317
- *
318
- * @return \DateTime
319
- */
320
- function twig_date_modify_filter(\WCML\Twig\Environment $env, $date, $modifier)
321
- {
322
- $date = \WCML\twig_date_converter($env, $date, \false);
323
- $resultDate = $date->modify($modifier);
324
- // This is a hack to ensure PHP 5.2 support and support for \DateTimeImmutable
325
- // \DateTime::modify does not return the modified \DateTime object < 5.3.0
326
- // and \DateTimeImmutable does not modify $date.
327
- return null === $resultDate ? $date : $resultDate;
328
- }
329
- /**
330
- * Converts an input to a \DateTime instance.
331
- *
332
- * {% if date(user.created_at) < date('+2days') %}
333
- * {# do something #}
334
- * {% endif %}
335
- *
336
- * @param \DateTime|\DateTimeInterface|string|null $date A date
337
- * @param \DateTimeZone|string|false|null $timezone The target timezone, null to use the default, false to leave unchanged
338
- *
339
- * @return \DateTime
340
- */
341
- function twig_date_converter(\WCML\Twig\Environment $env, $date = null, $timezone = null)
342
- {
343
- // determine the timezone
344
- if (\false !== $timezone) {
345
- if (null === $timezone) {
346
- $timezone = $env->getExtension('WCML\\Twig\\Extension\\CoreExtension')->getTimezone();
347
- } elseif (!$timezone instanceof \DateTimeZone) {
348
- $timezone = new \DateTimeZone($timezone);
349
- }
350
- }
351
- // immutable dates
352
- if ($date instanceof \DateTimeImmutable) {
353
- return \false !== $timezone ? $date->setTimezone($timezone) : $date;
354
- }
355
- if ($date instanceof \DateTime || $date instanceof \DateTimeInterface) {
356
- $date = clone $date;
357
- if (\false !== $timezone) {
358
- $date->setTimezone($timezone);
359
- }
360
- return $date;
361
- }
362
- if (null === $date || 'now' === $date) {
363
- return new \DateTime($date, \false !== $timezone ? $timezone : $env->getExtension('WCML\\Twig\\Extension\\CoreExtension')->getTimezone());
364
- }
365
- $asString = (string) $date;
366
- if (\ctype_digit($asString) || !empty($asString) && '-' === $asString[0] && \ctype_digit(\substr($asString, 1))) {
367
- $date = new \DateTime('@' . $date);
368
- } else {
369
- $date = new \DateTime($date, $env->getExtension('WCML\\Twig\\Extension\\CoreExtension')->getTimezone());
370
- }
371
- if (\false !== $timezone) {
372
- $date->setTimezone($timezone);
373
- }
374
- return $date;
375
- }
376
- /**
377
- * Replaces strings within a string.
378
- *
379
- * @param string $str String to replace in
380
- * @param array|\Traversable $from Replace values
381
- * @param string|null $to Replace to, deprecated (@see https://secure.php.net/manual/en/function.strtr.php)
382
- *
383
- * @return string
384
- */
385
- function twig_replace_filter($str, $from, $to = null)
386
- {
387
- if (\is_string($from) && \is_string($to)) {
388
- @\trigger_error('Using "replace" with character by character replacement is deprecated since version 1.22 and will be removed in Twig 2.0', \E_USER_DEPRECATED);
389
- return \strtr($str, $from, $to);
390
- }
391
- if (!\WCML\twig_test_iterable($from)) {
392
- throw new \WCML\Twig\Error\RuntimeError(\sprintf('The "replace" filter expects an array or "Traversable" as replace values, got "%s".', \is_object($from) ? \get_class($from) : \gettype($from)));
393
- }
394
- return \strtr($str, \WCML\twig_to_array($from));
395
- }
396
- /**
397
- * Rounds a number.
398
- *
399
- * @param int|float $value The value to round
400
- * @param int|float $precision The rounding precision
401
- * @param string $method The method to use for rounding
402
- *
403
- * @return int|float The rounded number
404
- */
405
- function twig_round($value, $precision = 0, $method = 'common')
406
- {
407
- if ('common' == $method) {
408
- return \round($value, $precision);
409
- }
410
- if ('ceil' != $method && 'floor' != $method) {
411
- throw new \WCML\Twig\Error\RuntimeError('The round filter only supports the "common", "ceil", and "floor" methods.');
412
- }
413
- return $method($value * \pow(10, $precision)) / \pow(10, $precision);
414
- }
415
- /**
416
- * Number format filter.
417
- *
418
- * All of the formatting options can be left null, in that case the defaults will
419
- * be used. Supplying any of the parameters will override the defaults set in the
420
- * environment object.
421
- *
422
- * @param mixed $number A float/int/string of the number to format
423
- * @param int $decimal the number of decimal points to display
424
- * @param string $decimalPoint the character(s) to use for the decimal point
425
- * @param string $thousandSep the character(s) to use for the thousands separator
426
- *
427
- * @return string The formatted number
428
- */
429
- function twig_number_format_filter(\WCML\Twig\Environment $env, $number, $decimal = null, $decimalPoint = null, $thousandSep = null)
430
- {
431
- $defaults = $env->getExtension('WCML\\Twig\\Extension\\CoreExtension')->getNumberFormat();
432
- if (null === $decimal) {
433
- $decimal = $defaults[0];
434
- }
435
- if (null === $decimalPoint) {
436
- $decimalPoint = $defaults[1];
437
- }
438
- if (null === $thousandSep) {
439
- $thousandSep = $defaults[2];
440
- }
441
- return \number_format((float) $number, $decimal, $decimalPoint, $thousandSep);
442
- }
443
- /**
444
- * URL encodes (RFC 3986) a string as a path segment or an array as a query string.
445
- *
446
- * @param string|array $url A URL or an array of query parameters
447
- *
448
- * @return string The URL encoded value
449
- */
450
- function twig_urlencode_filter($url)
451
- {
452
- if (\is_array($url)) {
453
- if (\defined('PHP_QUERY_RFC3986')) {
454
- return \http_build_query($url, '', '&', \PHP_QUERY_RFC3986);
455
- }
456
- return \http_build_query($url, '', '&');
457
- }
458
- return \rawurlencode($url);
459
- }
460
- /**
461
- * JSON encodes a variable.
462
- *
463
- * @param mixed $value the value to encode
464
- * @param int $options Bitmask consisting of JSON_HEX_QUOT, JSON_HEX_TAG, JSON_HEX_AMP, JSON_HEX_APOS, JSON_NUMERIC_CHECK, JSON_PRETTY_PRINT, JSON_UNESCAPED_SLASHES, JSON_FORCE_OBJECT
465
- *
466
- * @return mixed The JSON encoded value
467
- */
468
- function twig_jsonencode_filter($value, $options = 0)
469
- {
470
- if ($value instanceof \WCML\Twig\Markup) {
471
- $value = (string) $value;
472
- } elseif (\is_array($value)) {
473
- \array_walk_recursive($value, '\\WCML\\_twig_markup2string');
474
- }
475
- return \json_encode($value, $options);
476
- }
477
- function _twig_markup2string(&$value)
478
- {
479
- if ($value instanceof \WCML\Twig\Markup) {
480
- $value = (string) $value;
481
- }
482
- }
483
- /**
484
- * Merges an array with another one.
485
- *
486
- * {% set items = { 'apple': 'fruit', 'orange': 'fruit' } %}
487
- *
488
- * {% set items = items|merge({ 'peugeot': 'car' }) %}
489
- *
490
- * {# items now contains { 'apple': 'fruit', 'orange': 'fruit', 'peugeot': 'car' } #}
491
- *
492
- * @param array|\Traversable $arr1 An array
493
- * @param array|\Traversable $arr2 An array
494
- *
495
- * @return array The merged array
496
- */
497
- function twig_array_merge($arr1, $arr2)
498
- {
499
- if (!\WCML\twig_test_iterable($arr1)) {
500
- throw new \WCML\Twig\Error\RuntimeError(\sprintf('The merge filter only works with arrays or "Traversable", got "%s" as first argument.', \gettype($arr1)));
501
- }
502
- if (!\WCML\twig_test_iterable($arr2)) {
503
- throw new \WCML\Twig\Error\RuntimeError(\sprintf('The merge filter only works with arrays or "Traversable", got "%s" as second argument.', \gettype($arr2)));
504
- }
505
- return \array_merge(\WCML\twig_to_array($arr1), \WCML\twig_to_array($arr2));
506
- }
507
- /**
508
- * Slices a variable.
509
- *
510
- * @param mixed $item A variable
511
- * @param int $start Start of the slice
512
- * @param int $length Size of the slice
513
- * @param bool $preserveKeys Whether to preserve key or not (when the input is an array)
514
- *
515
- * @return mixed The sliced variable
516
- */
517
- function twig_slice(\WCML\Twig\Environment $env, $item, $start, $length = null, $preserveKeys = \false)
518
- {
519
- if ($item instanceof \Traversable) {
520
- while ($item instanceof \IteratorAggregate) {
521
- $item = $item->getIterator();
522
- }
523
- if ($start >= 0 && $length >= 0 && $item instanceof \Iterator) {
524
- try {
525
- return \iterator_to_array(new \LimitIterator($item, $start, null === $length ? -1 : $length), $preserveKeys);
526
- } catch (\OutOfBoundsException $e) {
527
- return [];
528
- }
529
- }
530
- $item = \iterator_to_array($item, $preserveKeys);
531
- }
532
- if (\is_array($item)) {
533
- return \array_slice($item, $start, $length, $preserveKeys);
534
- }
535
- $item = (string) $item;
536
- if (\function_exists('mb_get_info') && null !== ($charset = $env->getCharset())) {
537
- return (string) \mb_substr($item, $start, null === $length ? \mb_strlen($item, $charset) - $start : $length, $charset);
538
- }
539
- return (string) (null === $length ? \substr($item, $start) : \substr($item, $start, $length));
540
- }
541
- /**
542
- * Returns the first element of the item.
543
- *
544
- * @param mixed $item A variable
545
- *
546
- * @return mixed The first element of the item
547
- */
548
- function twig_first(\WCML\Twig\Environment $env, $item)
549
- {
550
- $elements = \WCML\twig_slice($env, $item, 0, 1, \false);
551
- return \is_string($elements) ? $elements : \current($elements);
552
- }
553
- /**
554
- * Returns the last element of the item.
555
- *
556
- * @param mixed $item A variable
557
- *
558
- * @return mixed The last element of the item
559
- */
560
- function twig_last(\WCML\Twig\Environment $env, $item)
561
- {
562
- $elements = \WCML\twig_slice($env, $item, -1, 1, \false);
563
- return \is_string($elements) ? $elements : \current($elements);
564
- }
565
- /**
566
- * Joins the values to a string.
567
- *
568
- * The separators between elements are empty strings per default, you can define them with the optional parameters.
569
- *
570
- * {{ [1, 2, 3]|join(', ', ' and ') }}
571
- * {# returns 1, 2 and 3 #}
572
- *
573
- * {{ [1, 2, 3]|join('|') }}
574
- * {# returns 1|2|3 #}
575
- *
576
- * {{ [1, 2, 3]|join }}
577
- * {# returns 123 #}
578
- *
579
- * @param array $value An array
580
- * @param string $glue The separator
581
- * @param string|null $and The separator for the last pair
582
- *
583
- * @return string The concatenated string
584
- */
585
- function twig_join_filter($value, $glue = '', $and = null)
586
- {
587
- if (!\WCML\twig_test_iterable($value)) {
588
- $value = (array) $value;
589
- }
590
- $value = \WCML\twig_to_array($value, \false);
591
- if (0 === \count($value)) {
592
- return '';
593
- }
594
- if (null === $and || $and === $glue) {
595
- return \implode($glue, $value);
596
- }
597
- if (1 === \count($value)) {
598
- return $value[0];
599
- }
600
- return \implode($glue, \array_slice($value, 0, -1)) . $and . $value[\count($value) - 1];
601
- }
602
- /**
603
- * Splits the string into an array.
604
- *
605
- * {{ "one,two,three"|split(',') }}
606
- * {# returns [one, two, three] #}
607
- *
608
- * {{ "one,two,three,four,five"|split(',', 3) }}
609
- * {# returns [one, two, "three,four,five"] #}
610
- *
611
- * {{ "123"|split('') }}
612
- * {# returns [1, 2, 3] #}
613
- *
614
- * {{ "aabbcc"|split('', 2) }}
615
- * {# returns [aa, bb, cc] #}
616
- *
617
- * @param string $value A string
618
- * @param string $delimiter The delimiter
619
- * @param int $limit The limit
620
- *
621
- * @return array The split string as an array
622
- */
623
- function twig_split_filter(\WCML\Twig\Environment $env, $value, $delimiter, $limit = null)
624
- {
625
- if (!empty($delimiter)) {
626
- return null === $limit ? \explode($delimiter, $value) : \explode($delimiter, $value, $limit);
627
- }
628
- if (!\function_exists('mb_get_info') || null === ($charset = $env->getCharset())) {
629
- return \str_split($value, null === $limit ? 1 : $limit);
630
- }
631
- if ($limit <= 1) {
632
- return \preg_split('/(?<!^)(?!$)/u', $value);
633
- }
634
- $length = \mb_strlen($value, $charset);
635
- if ($length < $limit) {
636
- return [$value];
637
- }
638
- $r = [];
639
- for ($i = 0; $i < $length; $i += $limit) {
640
- $r[] = \mb_substr($value, $i, $limit, $charset);
641
- }
642
- return $r;
643
- }
644
- // The '_default' filter is used internally to avoid using the ternary operator
645
- // which costs a lot for big contexts (before PHP 5.4). So, on average,
646
- // a function call is cheaper.
647
- /**
648
- * @internal
649
- */
650
- function _twig_default_filter($value, $default = '')
651
- {
652
- if (\WCML\twig_test_empty($value)) {
653
- return $default;
654
- }
655
- return $value;
656
- }
657
- /**
658
- * Returns the keys for the given array.
659
- *
660
- * It is useful when you want to iterate over the keys of an array:
661
- *
662
- * {% for key in array|keys %}
663
- * {# ... #}
664
- * {% endfor %}
665
- *
666
- * @param array $array An array
667
- *
668
- * @return array The keys
669
- */
670
- function twig_get_array_keys_filter($array)
671
- {
672
- if ($array instanceof \Traversable) {
673
- while ($array instanceof \IteratorAggregate) {
674
- $array = $array->getIterator();
675
- }
676
- if ($array instanceof \Iterator) {
677
- $keys = [];
678
- $array->rewind();
679
- while ($array->valid()) {
680
- $keys[] = $array->key();
681
- $array->next();
682
- }
683
- return $keys;
684
- }
685
- $keys = [];
686
- foreach ($array as $key => $item) {
687
- $keys[] = $key;
688
- }
689
- return $keys;
690
- }
691
- if (!\is_array($array)) {
692
- return [];
693
- }
694
- return \array_keys($array);
695
- }
696
- /**
697
- * Reverses a variable.
698
- *
699
- * @param array|\Traversable|string $item An array, a \Traversable instance, or a string
700
- * @param bool $preserveKeys Whether to preserve key or not
701
- *
702
- * @return mixed The reversed input
703
- */
704
- function twig_reverse_filter(\WCML\Twig\Environment $env, $item, $preserveKeys = \false)
705
- {
706
- if ($item instanceof \Traversable) {
707
- return \array_reverse(\iterator_to_array($item), $preserveKeys);
708
- }
709
- if (\is_array($item)) {
710
- return \array_reverse($item, $preserveKeys);
711
- }
712
- if (null !== ($charset = $env->getCharset())) {
713
- $string = (string) $item;
714
- if ('UTF-8' !== $charset) {
715
- $item = \WCML\twig_convert_encoding($string, 'UTF-8', $charset);
716
- }
717
- \preg_match_all('/./us', $item, $matches);
718
- $string = \implode('', \array_reverse($matches[0]));
719
- if ('UTF-8' !== $charset) {
720
- $string = \WCML\twig_convert_encoding($string, $charset, 'UTF-8');
721
- }
722
- return $string;
723
- }
724
- return \strrev((string) $item);
725
- }
726
- /**
727
- * Sorts an array.
728
- *
729
- * @param array|\Traversable $array
730
- *
731
- * @return array
732
- */
733
- function twig_sort_filter($array)
734
- {
735
- if ($array instanceof \Traversable) {
736
- $array = \iterator_to_array($array);
737
- } elseif (!\is_array($array)) {
738
- throw new \WCML\Twig\Error\RuntimeError(\sprintf('The sort filter only works with arrays or "Traversable", got "%s".', \gettype($array)));
739
- }
740
- \asort($array);
741
- return $array;
742
- }
743
- /**
744
- * @internal
745
- */
746
- function twig_in_filter($value, $compare)
747
- {
748
- if ($value instanceof \WCML\Twig\Markup) {
749
- $value = (string) $value;
750
- }
751
- if ($compare instanceof \WCML\Twig\Markup) {
752
- $compare = (string) $compare;
753
- }
754
- if (\is_array($compare)) {
755
- return \in_array($value, $compare, \is_object($value) || \is_resource($value));
756
- } elseif (\is_string($compare) && (\is_string($value) || \is_int($value) || \is_float($value))) {
757
- return '' === $value || \false !== \strpos($compare, (string) $value);
758
- } elseif ($compare instanceof \Traversable) {
759
- if (\is_object($value) || \is_resource($value)) {
760
- foreach ($compare as $item) {
761
- if ($item === $value) {
762
- return \true;
763
- }
764
- }
765
- } else {
766
- foreach ($compare as $item) {
767
- if ($item == $value) {
768
- return \true;
769
- }
770
- }
771
- }
772
- return \false;
773
- }
774
- return \false;
775
- }
776
- /**
777
- * Returns a trimmed string.
778
- *
779
- * @return string
780
- *
781
- * @throws RuntimeError When an invalid trimming side is used (not a string or not 'left', 'right', or 'both')
782
- */
783
- function twig_trim_filter($string, $characterMask = null, $side = 'both')
784
- {
785
- if (null === $characterMask) {
786
- $characterMask = " \t\n\r\0\v";
787
- }
788
- switch ($side) {
789
- case 'both':
790
- return \trim($string, $characterMask);
791
- case 'left':
792
- return \ltrim($string, $characterMask);
793
- case 'right':
794
- return \rtrim($string, $characterMask);
795
- default:
796
- throw new \WCML\Twig\Error\RuntimeError('Trimming side must be "left", "right" or "both".');
797
- }
798
- }
799
- /**
800
- * Removes whitespaces between HTML tags.
801
- *
802
- * @return string
803
- */
804
- function twig_spaceless($content)
805
- {
806
- return \trim(\preg_replace('/>\\s+</', '><', $content));
807
- }
808
- /**
809
- * Escapes a string.
810
- *
811
- * @param mixed $string The value to be escaped
812
- * @param string $strategy The escaping strategy
813
- * @param string $charset The charset
814
- * @param bool $autoescape Whether the function is called by the auto-escaping feature (true) or by the developer (false)
815
- *
816
- * @return string
817
- */
818
- function twig_escape_filter(\WCML\Twig\Environment $env, $string, $strategy = 'html', $charset = null, $autoescape = \false)
819
- {
820
- if ($autoescape && $string instanceof \WCML\Twig\Markup) {
821
- return $string;
822
- }
823
- if (!\is_string($string)) {
824
- if (\is_object($string) && \method_exists($string, '__toString')) {
825
- $string = (string) $string;
826
- } elseif (\in_array($strategy, ['html', 'js', 'css', 'html_attr', 'url'])) {
827
- return $string;
828
- }
829
- }
830
- if ('' === $string) {
831
- return '';
832
- }
833
- if (null === $charset) {
834
- $charset = $env->getCharset();
835
- }
836
- switch ($strategy) {
837
- case 'html':
838
- // see https://secure.php.net/htmlspecialchars
839
- // Using a static variable to avoid initializing the array
840
- // each time the function is called. Moving the declaration on the
841
- // top of the function slow downs other escaping strategies.
842
- static $htmlspecialcharsCharsets = ['ISO-8859-1' => \true, 'ISO8859-1' => \true, 'ISO-8859-15' => \true, 'ISO8859-15' => \true, 'utf-8' => \true, 'UTF-8' => \true, 'CP866' => \true, 'IBM866' => \true, '866' => \true, 'CP1251' => \true, 'WINDOWS-1251' => \true, 'WIN-1251' => \true, '1251' => \true, 'CP1252' => \true, 'WINDOWS-1252' => \true, '1252' => \true, 'KOI8-R' => \true, 'KOI8-RU' => \true, 'KOI8R' => \true, 'BIG5' => \true, '950' => \true, 'GB2312' => \true, '936' => \true, 'BIG5-HKSCS' => \true, 'SHIFT_JIS' => \true, 'SJIS' => \true, '932' => \true, 'EUC-JP' => \true, 'EUCJP' => \true, 'ISO8859-5' => \true, 'ISO-8859-5' => \true, 'MACROMAN' => \true];
843
- if (isset($htmlspecialcharsCharsets[$charset])) {
844
- return \htmlspecialchars($string, \ENT_QUOTES | \ENT_SUBSTITUTE, $charset);
845
- }
846
- if (isset($htmlspecialcharsCharsets[\strtoupper($charset)])) {
847
- // cache the lowercase variant for future iterations
848
- $htmlspecialcharsCharsets[$charset] = \true;
849
- return \htmlspecialchars($string, \ENT_QUOTES | \ENT_SUBSTITUTE, $charset);
850
- }
851
- $string = \WCML\twig_convert_encoding($string, 'UTF-8', $charset);
852
- $string = \htmlspecialchars($string, \ENT_QUOTES | \ENT_SUBSTITUTE, 'UTF-8');
853
- return \WCML\twig_convert_encoding($string, $charset, 'UTF-8');
854
- case 'js':
855
- // escape all non-alphanumeric characters
856
- // into their \x or \uHHHH representations
857
- if ('UTF-8' !== $charset) {
858
- $string = \WCML\twig_convert_encoding($string, 'UTF-8', $charset);
859
- }
860
- if (!\preg_match('//u', $string)) {
861
- throw new \WCML\Twig\Error\RuntimeError('The string to escape is not a valid UTF-8 string.');
862
- }
863
- $string = \preg_replace_callback('#[^a-zA-Z0-9,\\._]#Su', '\\WCML\\_twig_escape_js_callback', $string);
864
- if ('UTF-8' !== $charset) {
865
- $string = \WCML\twig_convert_encoding($string, $charset, 'UTF-8');
866
- }
867
- return $string;
868
- case 'css':
869
- if ('UTF-8' !== $charset) {
870
- $string = \WCML\twig_convert_encoding($string, 'UTF-8', $charset);
871
- }
872
- if (!\preg_match('//u', $string)) {
873
- throw new \WCML\Twig\Error\RuntimeError('The string to escape is not a valid UTF-8 string.');
874
- }
875
- $string = \preg_replace_callback('#[^a-zA-Z0-9]#Su', '\\WCML\\_twig_escape_css_callback', $string);
876
- if ('UTF-8' !== $charset) {
877
- $string = \WCML\twig_convert_encoding($string, $charset, 'UTF-8');
878
- }
879
- return $string;
880
- case 'html_attr':
881
- if ('UTF-8' !== $charset) {
882
- $string = \WCML\twig_convert_encoding($string, 'UTF-8', $charset);
883
- }
884
- if (!\preg_match('//u', $string)) {
885
- throw new \WCML\Twig\Error\RuntimeError('The string to escape is not a valid UTF-8 string.');
886
- }
887
- $string = \preg_replace_callback('#[^a-zA-Z0-9,\\.\\-_]#Su', '\\WCML\\_twig_escape_html_attr_callback', $string);
888
- if ('UTF-8' !== $charset) {
889
- $string = \WCML\twig_convert_encoding($string, $charset, 'UTF-8');
890
- }
891
- return $string;
892
- case 'url':
893
- return \rawurlencode($string);
894
- default:
895
- static $escapers;
896
- if (null === $escapers) {
897
- $escapers = $env->getExtension('WCML\\Twig\\Extension\\CoreExtension')->getEscapers();
898
- }
899
- if (isset($escapers[$strategy])) {
900
- return \call_user_func($escapers[$strategy], $env, $string, $charset);
901
- }
902
- $validStrategies = \implode(', ', \array_merge(['html', 'js', 'url', 'css', 'html_attr'], \array_keys($escapers)));
903
- throw new \WCML\Twig\Error\RuntimeError(\sprintf('Invalid escaping strategy "%s" (valid ones: %s).', $strategy, $validStrategies));
904
- }
905
- }
906
- /**
907
- * @internal
908
- */
909
- function twig_escape_filter_is_safe(\WCML\Twig\Node\Node $filterArgs)
910
- {
911
- foreach ($filterArgs as $arg) {
912
- if ($arg instanceof \WCML\Twig\Node\Expression\ConstantExpression) {
913
- return [$arg->getAttribute('value')];
914
- }
915
- return [];
916
- }
917
- return ['html'];
918
- }
919
- if (\function_exists('mb_convert_encoding')) {
920
- function twig_convert_encoding($string, $to, $from)
921
- {
922
- return \mb_convert_encoding($string, $to, $from);
923
- }
924
- } elseif (\function_exists('iconv')) {
925
- function twig_convert_encoding($string, $to, $from)
926
- {
927
- return \iconv($from, $to, $string);
928
- }
929
- } else {
930
- function twig_convert_encoding($string, $to, $from)
931
- {
932
- throw new \WCML\Twig\Error\RuntimeError('No suitable convert encoding function (use UTF-8 as your encoding or install the iconv or mbstring extension).');
933
- }
934
- }
935
- if (\function_exists('mb_ord')) {
936
- function twig_ord($string)
937
- {
938
- return \mb_ord($string, 'UTF-8');
939
- }
940
- } else {
941
- function twig_ord($string)
942
- {
943
- $code = ($string = \unpack('C*', \substr($string, 0, 4))) ? $string[1] : 0;
944
- if (0xf0 <= $code) {
945
- return ($code - 0xf0 << 18) + ($string[2] - 0x80 << 12) + ($string[3] - 0x80 << 6) + $string[4] - 0x80;
946
- }
947
- if (0xe0 <= $code) {
948
- return ($code - 0xe0 << 12) + ($string[2] - 0x80 << 6) + $string[3] - 0x80;
949
- }
950
- if (0xc0 <= $code) {
951
- return ($code - 0xc0 << 6) + $string[2] - 0x80;
952
- }
953
- return $code;
954
- }
955
- }
956
- function _twig_escape_js_callback($matches)
957
- {
958
- $char = $matches[0];
959
- /*
960
- * A few characters have short escape sequences in JSON and JavaScript.
961
- * Escape sequences supported only by JavaScript, not JSON, are ommitted.
962
- * \" is also supported but omitted, because the resulting string is not HTML safe.
963
- */
964
- static $shortMap = ['\\' => '\\\\', '/' => '\\/', "\10" => '\\b', "\f" => '\\f', "\n" => '\\n', "\r" => '\\r', "\t" => '\\t'];
965
- if (isset($shortMap[$char])) {
966
- return $shortMap[$char];
967
- }
968
- // \uHHHH
969
- $char = \WCML\twig_convert_encoding($char, 'UTF-16BE', 'UTF-8');
970
- $char = \strtoupper(\bin2hex($char));
971
- if (4 >= \strlen($char)) {
972
- return \sprintf('\\u%04s', $char);
973
- }
974
- return \sprintf('\\u%04s\\u%04s', \substr($char, 0, -4), \substr($char, -4));
975
- }
976
- function _twig_escape_css_callback($matches)
977
- {
978
- $char = $matches[0];
979
- return \sprintf('\\%X ', 1 === \strlen($char) ? \ord($char) : \WCML\twig_ord($char));
980
- }
981
- /**
982
- * This function is adapted from code coming from Zend Framework.
983
- *
984
- * @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (https://www.zend.com)
985
- * @license https://framework.zend.com/license/new-bsd New BSD License
986
- */
987
- function _twig_escape_html_attr_callback($matches)
988
- {
989
- $chr = $matches[0];
990
- $ord = \ord($chr);
991
- /*
992
- * The following replaces characters undefined in HTML with the
993
- * hex entity for the Unicode replacement character.
994
- */
995
- if ($ord <= 0x1f && "\t" != $chr && "\n" != $chr && "\r" != $chr || $ord >= 0x7f && $ord <= 0x9f) {
996
- return '&#xFFFD;';
997
- }
998
- /*
999
- * Check if the current character to escape has a name entity we should
1000
- * replace it with while grabbing the hex value of the character.
1001
- */
1002
- if (1 == \strlen($chr)) {
1003
- /*
1004
- * While HTML supports far more named entities, the lowest common denominator
1005
- * has become HTML5's XML Serialisation which is restricted to the those named
1006
- * entities that XML supports. Using HTML entities would result in this error:
1007
- * XML Parsing Error: undefined entity
1008
- */
1009
- static $entityMap = [
1010
- 34 => '&quot;',
1011
- /* quotation mark */
1012
- 38 => '&amp;',
1013
- /* ampersand */
1014
- 60 => '&lt;',
1015
- /* less-than sign */
1016
- 62 => '&gt;',
1017
- ];
1018
- if (isset($entityMap[$ord])) {
1019
- return $entityMap[$ord];
1020
- }
1021
- return \sprintf('&#x%02X;', $ord);
1022
- }
1023
- /*
1024
- * Per OWASP recommendations, we'll use hex entities for any other
1025
- * characters where a named entity does not exist.
1026
- */
1027
- return \sprintf('&#x%04X;', \WCML\twig_ord($chr));
1028
- }
1029
- // add multibyte extensions if possible
1030
- if (\function_exists('mb_get_info')) {
1031
- /**
1032
- * Returns the length of a variable.
1033
- *
1034
- * @param mixed $thing A variable
1035
- *
1036
- * @return int The length of the value
1037
- */
1038
- function twig_length_filter(\WCML\Twig\Environment $env, $thing)
1039
- {
1040
- if (null === $thing) {
1041
- return 0;
1042
- }
1043
- if (\is_scalar($thing)) {
1044
- return \mb_strlen($thing, $env->getCharset());
1045
- }
1046
- if ($thing instanceof \Countable || \is_array($thing) || $thing instanceof \SimpleXMLElement) {
1047
- return \count($thing);
1048
- }
1049
- if ($thing instanceof \Traversable) {
1050
- return \iterator_count($thing);
1051
- }
1052
- if (\is_object($thing) && \method_exists($thing, '__toString')) {
1053
- return \mb_strlen((string) $thing, $env->getCharset());
1054
- }
1055
- return 1;
1056
- }
1057
- /**
1058
- * Converts a string to uppercase.
1059
- *
1060
- * @param string $string A string
1061
- *
1062
- * @return string The uppercased string
1063
- */
1064
- function twig_upper_filter(\WCML\Twig\Environment $env, $string)
1065
- {
1066
- if (null !== ($charset = $env->getCharset())) {
1067
- return \mb_strtoupper($string, $charset);
1068
- }
1069
- return \strtoupper($string);
1070
- }
1071
- /**
1072
- * Converts a string to lowercase.
1073
- *
1074
- * @param string $string A string
1075
- *
1076
- * @return string The lowercased string
1077
- */
1078
- function twig_lower_filter(\WCML\Twig\Environment $env, $string)
1079
- {
1080
- if (null !== ($charset = $env->getCharset())) {
1081
- return \mb_strtolower($string, $charset);
1082
- }
1083
- return \strtolower($string);
1084
- }
1085
- /**
1086
- * Returns a titlecased string.
1087
- *
1088
- * @param string $string A string
1089
- *
1090
- * @return string The titlecased string
1091
- */
1092
- function twig_title_string_filter(\WCML\Twig\Environment $env, $string)
1093
- {
1094
- if (null !== ($charset = $env->getCharset())) {
1095
- return \mb_convert_case($string, \MB_CASE_TITLE, $charset);
1096
- }
1097
- return \ucwords(\strtolower($string));
1098
- }
1099
- /**
1100
- * Returns a capitalized string.
1101
- *
1102
- * @param string $string A string
1103
- *
1104
- * @return string The capitalized string
1105
- */
1106
- function twig_capitalize_string_filter(\WCML\Twig\Environment $env, $string)
1107
- {
1108
- if (null !== ($charset = $env->getCharset())) {
1109
- return \mb_strtoupper(\mb_substr($string, 0, 1, $charset), $charset) . \mb_strtolower(\mb_substr($string, 1, \mb_strlen($string, $charset), $charset), $charset);
1110
- }
1111
- return \ucfirst(\strtolower($string));
1112
- }
1113
- } else {
1114
- /**
1115
- * Returns the length of a variable.
1116
- *
1117
- * @param mixed $thing A variable
1118
- *
1119
- * @return int The length of the value
1120
- */
1121
- function twig_length_filter(\WCML\Twig\Environment $env, $thing)
1122
- {
1123
- if (null === $thing) {
1124
- return 0;
1125
- }
1126
- if (\is_scalar($thing)) {
1127
- return \strlen($thing);
1128
- }
1129
- if ($thing instanceof \SimpleXMLElement) {
1130
- return \count($thing);
1131
- }
1132
- if (\is_object($thing) && \method_exists($thing, '__toString') && !$thing instanceof \Countable) {
1133
- return \strlen((string) $thing);
1134
- }
1135
- if ($thing instanceof \Countable || \is_array($thing)) {
1136
- return \count($thing);
1137
- }
1138
- if ($thing instanceof \IteratorAggregate) {
1139
- return \iterator_count($thing);
1140
- }
1141
- return 1;
1142
- }
1143
- /**
1144
- * Returns a titlecased string.
1145
- *
1146
- * @param string $string A string
1147
- *
1148
- * @return string The titlecased string
1149
- */
1150
- function twig_title_string_filter(\WCML\Twig\Environment $env, $string)
1151
- {
1152
- return \ucwords(\strtolower($string));
1153
- }
1154
- /**
1155
- * Returns a capitalized string.
1156
- *
1157
- * @param string $string A string
1158
- *
1159
- * @return string The capitalized string
1160
- */
1161
- function twig_capitalize_string_filter(\WCML\Twig\Environment $env, $string)
1162
- {
1163
- return \ucfirst(\strtolower($string));
1164
- }
1165
- }
1166
- /**
1167
- * @internal
1168
- */
1169
- function twig_ensure_traversable($seq)
1170
- {
1171
- if ($seq instanceof \Traversable || \is_array($seq)) {
1172
- return $seq;
1173
- }
1174
- return [];
1175
- }
1176
- /**
1177
- * @internal
1178
- */
1179
- function twig_to_array($seq, $preserveKeys = \true)
1180
- {
1181
- if ($seq instanceof \Traversable) {
1182
- return \iterator_to_array($seq, $preserveKeys);
1183
- }
1184
- if (!\is_array($seq)) {
1185
- return $seq;
1186
- }
1187
- return $preserveKeys ? $seq : \array_values($seq);
1188
- }
1189
- /**
1190
- * Checks if a variable is empty.
1191
- *
1192
- * {# evaluates to true if the foo variable is null, false, or the empty string #}
1193
- * {% if foo is empty %}
1194
- * {# ... #}
1195
- * {% endif %}
1196
- *
1197
- * @param mixed $value A variable
1198
- *
1199
- * @return bool true if the value is empty, false otherwise
1200
- */
1201
- function twig_test_empty($value)
1202
- {
1203
- if ($value instanceof \Countable) {
1204
- return 0 == \count($value);
1205
- }
1206
- if (\is_object($value) && \method_exists($value, '__toString')) {
1207
- return '' === (string) $value;
1208
- }
1209
- return '' === $value || \false === $value || null === $value || [] === $value;
1210
- }
1211
- /**
1212
- * Checks if a variable is traversable.
1213
- *
1214
- * {# evaluates to true if the foo variable is an array or a traversable object #}
1215
- * {% if foo is iterable %}
1216
- * {# ... #}
1217
- * {% endif %}
1218
- *
1219
- * @param mixed $value A variable
1220
- *
1221
- * @return bool true if the value is traversable
1222
- */
1223
- function twig_test_iterable($value)
1224
- {
1225
- return $value instanceof \Traversable || \is_array($value);
1226
- }
1227
- /**
1228
- * Renders a template.
1229
- *
1230
- * @param array $context
1231
- * @param string|array $template The template to render or an array of templates to try consecutively
1232
- * @param array $variables The variables to pass to the template
1233
- * @param bool $withContext
1234
- * @param bool $ignoreMissing Whether to ignore missing templates or not
1235
- * @param bool $sandboxed Whether to sandbox the template or not
1236
- *
1237
- * @return string The rendered template
1238
- */
1239
- function twig_include(\WCML\Twig\Environment $env, $context, $template, $variables = [], $withContext = \true, $ignoreMissing = \false, $sandboxed = \false)
1240
- {
1241
- $alreadySandboxed = \false;
1242
- $sandbox = null;
1243
- if ($withContext) {
1244
- $variables = \array_merge($context, $variables);
1245
- }
1246
- if ($isSandboxed = $sandboxed && $env->hasExtension('WCML\\Twig\\Extension\\SandboxExtension')) {
1247
- $sandbox = $env->getExtension('WCML\\Twig\\Extension\\SandboxExtension');
1248
- if (!($alreadySandboxed = $sandbox->isSandboxed())) {
1249
- $sandbox->enableSandbox();
1250
- }
1251
- }
1252
- $loaded = null;
1253
- try {
1254
- $loaded = $env->resolveTemplate($template);
1255
- } catch (\WCML\Twig\Error\LoaderError $e) {
1256
- if (!$ignoreMissing) {
1257
- if ($isSandboxed && !$alreadySandboxed) {
1258
- $sandbox->disableSandbox();
1259
- }
1260
- throw $e;
1261
- }
1262
- } catch (\Throwable $e) {
1263
- if ($isSandboxed && !$alreadySandboxed) {
1264
- $sandbox->disableSandbox();
1265
- }
1266
- throw $e;
1267
- } catch (\Exception $e) {
1268
- if ($isSandboxed && !$alreadySandboxed) {
1269
- $sandbox->disableSandbox();
1270
- }
1271
- throw $e;
1272
- }
1273
- try {
1274
- $ret = $loaded ? $loaded->render($variables) : '';
1275
- } catch (\Exception $e) {
1276
- if ($isSandboxed && !$alreadySandboxed) {
1277
- $sandbox->disableSandbox();
1278
- }
1279
- throw $e;
1280
- }
1281
- if ($isSandboxed && !$alreadySandboxed) {
1282
- $sandbox->disableSandbox();
1283
- }
1284
- return $ret;
1285
- }
1286
- /**
1287
- * Returns a template content without rendering it.
1288
- *
1289
- * @param string $name The template name
1290
- * @param bool $ignoreMissing Whether to ignore missing templates or not
1291
- *
1292
- * @return string The template source
1293
- */
1294
- function twig_source(\WCML\Twig\Environment $env, $name, $ignoreMissing = \false)
1295
- {
1296
- $loader = $env->getLoader();
1297
- try {
1298
- if (!$loader instanceof \WCML\Twig\Loader\SourceContextLoaderInterface) {
1299
- return $loader->getSource($name);
1300
- } else {
1301
- return $loader->getSourceContext($name)->getCode();
1302
- }
1303
- } catch (\WCML\Twig\Error\LoaderError $e) {
1304
- if (!$ignoreMissing) {
1305
- throw $e;
1306
- }
1307
- }
1308
- }
1309
- /**
1310
- * Provides the ability to get constants from instances as well as class/global constants.
1311
- *
1312
- * @param string $constant The name of the constant
1313
- * @param object|null $object The object to get the constant from
1314
- *
1315
- * @return string
1316
- */
1317
- function twig_constant($constant, $object = null)
1318
- {
1319
- if (null !== $object) {
1320
- $constant = \get_class($object) . '::' . $constant;
1321
- }
1322
- return \constant($constant);
1323
- }
1324
- /**
1325
- * Checks if a constant exists.
1326
- *
1327
- * @param string $constant The name of the constant
1328
- * @param object|null $object The object to get the constant from
1329
- *
1330
- * @return bool
1331
- */
1332
- function twig_constant_is_defined($constant, $object = null)
1333
- {
1334
- if (null !== $object) {
1335
- $constant = \get_class($object) . '::' . $constant;
1336
- }
1337
- return \defined($constant);
1338
- }
1339
- /**
1340
- * Batches item.
1341
- *
1342
- * @param array $items An array of items
1343
- * @param int $size The size of the batch
1344
- * @param mixed $fill A value used to fill missing items
1345
- *
1346
- * @return array
1347
- */
1348
- function twig_array_batch($items, $size, $fill = null, $preserveKeys = \true)
1349
- {
1350
- if (!\WCML\twig_test_iterable($items)) {
1351
- throw new \WCML\Twig\Error\RuntimeError(\sprintf('The "batch" filter expects an array or "Traversable", got "%s".', \is_object($items) ? \get_class($items) : \gettype($items)));
1352
- }
1353
- $size = \ceil($size);
1354
- $result = \array_chunk(\WCML\twig_to_array($items, $preserveKeys), $size, $preserveKeys);
1355
- if (null !== $fill && $result) {
1356
- $last = \count($result) - 1;
1357
- if ($fillCount = $size - \count($result[$last])) {
1358
- for ($i = 0; $i < $fillCount; ++$i) {
1359
- $result[$last][] = $fill;
1360
- }
1361
- }
1362
- }
1363
- return $result;
1364
- }
1365
- function twig_array_filter($array, $arrow)
1366
- {
1367
- if (\is_array($array)) {
1368
- if (\PHP_VERSION_ID >= 50600) {
1369
- return \array_filter($array, $arrow, \ARRAY_FILTER_USE_BOTH);
1370
- }
1371
- return \array_filter($array, $arrow);
1372
- }
1373
- // the IteratorIterator wrapping is needed as some internal PHP classes are \Traversable but do not implement \Iterator
1374
- return new \CallbackFilterIterator(new \IteratorIterator($array), $arrow);
1375
- }
1376
- function twig_array_map($array, $arrow)
1377
- {
1378
- $r = [];
1379
- foreach ($array as $k => $v) {
1380
- $r[$k] = $arrow($v, $k);
1381
- }
1382
- return $r;
1383
- }
1384
- function twig_array_reduce($array, $arrow, $initial = null)
1385
- {
1386
- if (!\is_array($array)) {
1387
- $array = \iterator_to_array($array);
1388
- }
1389
- return \array_reduce($array, $arrow, $initial);
1390
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/twig/src/Extension/DebugExtension.php DELETED
@@ -1,56 +0,0 @@
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
- namespace WCML\Twig\Extension;
12
-
13
- use WCML\Twig\TwigFunction;
14
- /**
15
- * @final
16
- */
17
- class DebugExtension extends \WCML\Twig\Extension\AbstractExtension
18
- {
19
- public function getFunctions()
20
- {
21
- // dump is safe if var_dump is overridden by xdebug
22
- $isDumpOutputHtmlSafe = \extension_loaded('xdebug') && (\false === \ini_get('xdebug.overload_var_dump') || \ini_get('xdebug.overload_var_dump')) && (\false === \ini_get('html_errors') || \ini_get('html_errors')) || 'cli' === \PHP_SAPI;
23
- return [new \WCML\Twig\TwigFunction('dump', 'twig_var_dump', ['is_safe' => $isDumpOutputHtmlSafe ? ['html'] : [], 'needs_context' => \true, 'needs_environment' => \true, 'is_variadic' => \true])];
24
- }
25
- public function getName()
26
- {
27
- return 'debug';
28
- }
29
- }
30
- \class_alias('WCML\\Twig\\Extension\\DebugExtension', 'WCML\\Twig_Extension_Debug');
31
- namespace WCML;
32
-
33
- use WCML\Twig\Environment;
34
- use WCML\Twig\Template;
35
- use WCML\Twig\TemplateWrapper;
36
- function twig_var_dump(\WCML\Twig\Environment $env, $context, array $vars = [])
37
- {
38
- if (!$env->isDebug()) {
39
- return;
40
- }
41
- \ob_start();
42
- if (!$vars) {
43
- $vars = [];
44
- foreach ($context as $key => $value) {
45
- if (!$value instanceof \WCML\Twig\Template && !$value instanceof \WCML\Twig\TemplateWrapper) {
46
- $vars[$key] = $value;
47
- }
48
- }
49
- \var_dump($vars);
50
- } else {
51
- foreach ($vars as $var) {
52
- \var_dump($var);
53
- }
54
- }
55
- return \ob_get_clean();
56
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/twig/src/Extension/EscaperExtension.php DELETED
@@ -1,101 +0,0 @@
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
- namespace WCML\Twig\Extension;
12
-
13
- use WCML\Twig\NodeVisitor\EscaperNodeVisitor;
14
- use WCML\Twig\TokenParser\AutoEscapeTokenParser;
15
- use WCML\Twig\TwigFilter;
16
- /**
17
- * @final
18
- */
19
- class EscaperExtension extends \WCML\Twig\Extension\AbstractExtension
20
- {
21
- protected $defaultStrategy;
22
- /**
23
- * @param string|false|callable $defaultStrategy An escaping strategy
24
- *
25
- * @see setDefaultStrategy()
26
- */
27
- public function __construct($defaultStrategy = 'html')
28
- {
29
- $this->setDefaultStrategy($defaultStrategy);
30
- }
31
- public function getTokenParsers()
32
- {
33
- return [new \WCML\Twig\TokenParser\AutoEscapeTokenParser()];
34
- }
35
- public function getNodeVisitors()
36
- {
37
- return [new \WCML\Twig\NodeVisitor\EscaperNodeVisitor()];
38
- }
39
- public function getFilters()
40
- {
41
- return [new \WCML\Twig\TwigFilter('raw', 'twig_raw_filter', ['is_safe' => ['all']])];
42
- }
43
- /**
44
- * Sets the default strategy to use when not defined by the user.
45
- *
46
- * The strategy can be a valid PHP callback that takes the template
47
- * name as an argument and returns the strategy to use.
48
- *
49
- * @param string|false|callable $defaultStrategy An escaping strategy
50
- */
51
- public function setDefaultStrategy($defaultStrategy)
52
- {
53
- // for BC
54
- if (\true === $defaultStrategy) {
55
- @\trigger_error('Using "true" as the default strategy is deprecated since version 1.21. Use "html" instead.', \E_USER_DEPRECATED);
56
- $defaultStrategy = 'html';
57
- }
58
- if ('filename' === $defaultStrategy) {
59
- @\trigger_error('Using "filename" as the default strategy is deprecated since version 1.27. Use "name" instead.', \E_USER_DEPRECATED);
60
- $defaultStrategy = 'name';
61
- }
62
- if ('name' === $defaultStrategy) {
63
- $defaultStrategy = ['WCML\\Twig\\FileExtensionEscapingStrategy', 'guess'];
64
- }
65
- $this->defaultStrategy = $defaultStrategy;
66
- }
67
- /**
68
- * Gets the default strategy to use when not defined by the user.
69
- *
70
- * @param string $name The template name
71
- *
72
- * @return string|false The default strategy to use for the template
73
- */
74
- public function getDefaultStrategy($name)
75
- {
76
- // disable string callables to avoid calling a function named html or js,
77
- // or any other upcoming escaping strategy
78
- if (!\is_string($this->defaultStrategy) && \false !== $this->defaultStrategy) {
79
- return \call_user_func($this->defaultStrategy, $name);
80
- }
81
- return $this->defaultStrategy;
82
- }
83
- public function getName()
84
- {
85
- return 'escaper';
86
- }
87
- }
88
- \class_alias('WCML\\Twig\\Extension\\EscaperExtension', 'WCML\\Twig_Extension_Escaper');
89
- namespace WCML;
90
-
91
- /**
92
- * Marks a variable as being safe.
93
- *
94
- * @param string $string A PHP variable
95
- *
96
- * @return string
97
- */
98
- function twig_raw_filter($string)
99
- {
100
- return $string;
101
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/twig/src/Extension/ExtensionInterface.php DELETED
@@ -1,89 +0,0 @@
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
- namespace WCML\Twig\Extension;
12
-
13
- use WCML\Twig\Environment;
14
- use WCML\Twig\NodeVisitor\NodeVisitorInterface;
15
- use WCML\Twig\TokenParser\TokenParserInterface;
16
- use WCML\Twig\TwigFilter;
17
- use WCML\Twig\TwigFunction;
18
- use WCML\Twig\TwigTest;
19
- /**
20
- * Interface implemented by extension classes.
21
- *
22
- * @author Fabien Potencier <fabien@symfony.com>
23
- */
24
- interface ExtensionInterface
25
- {
26
- /**
27
- * Initializes the runtime environment.
28
- *
29
- * This is where you can load some file that contains filter functions for instance.
30
- *
31
- * @deprecated since 1.23 (to be removed in 2.0), implement \Twig_Extension_InitRuntimeInterface instead
32
- */
33
- public function initRuntime(\WCML\Twig\Environment $environment);
34
- /**
35
- * Returns the token parser instances to add to the existing list.
36
- *
37
- * @return TokenParserInterface[]
38
- */
39
- public function getTokenParsers();
40
- /**
41
- * Returns the node visitor instances to add to the existing list.
42
- *
43
- * @return NodeVisitorInterface[]
44
- */
45
- public function getNodeVisitors();
46
- /**
47
- * Returns a list of filters to add to the existing list.
48
- *
49
- * @return TwigFilter[]
50
- */
51
- public function getFilters();
52
- /**
53
- * Returns a list of tests to add to the existing list.
54
- *
55
- * @return TwigTest[]
56
- */
57
- public function getTests();
58
- /**
59
- * Returns a list of functions to add to the existing list.
60
- *
61
- * @return TwigFunction[]
62
- */
63
- public function getFunctions();
64
- /**
65
- * Returns a list of operators to add to the existing list.
66
- *
67
- * @return array<array> First array of unary operators, second array of binary operators
68
- */
69
- public function getOperators();
70
- /**
71
- * Returns a list of global variables to add to the existing list.
72
- *
73
- * @return array An array of global variables
74
- *
75
- * @deprecated since 1.23 (to be removed in 2.0), implement \Twig_Extension_GlobalsInterface instead
76
- */
77
- public function getGlobals();
78
- /**
79
- * Returns the name of the extension.
80
- *
81
- * @return string The extension name
82
- *
83
- * @deprecated since 1.26 (to be removed in 2.0), not used anymore internally
84
- */
85
- public function getName();
86
- }
87
- \class_alias('WCML\\Twig\\Extension\\ExtensionInterface', 'WCML\\Twig_ExtensionInterface');
88
- // Ensure that the aliased name is loaded to keep BC for classes implementing the typehint with the old aliased name.
89
- \class_exists('WCML\\Twig\\Environment');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/twig/src/Extension/GlobalsInterface.php DELETED
@@ -1,24 +0,0 @@
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
- namespace WCML\Twig\Extension;
12
-
13
- /**
14
- * Enables usage of the deprecated Twig\Extension\AbstractExtension::getGlobals() method.
15
- *
16
- * Explicitly implement this interface if you really need to implement the
17
- * deprecated getGlobals() method in your extensions.
18
- *
19
- * @author Fabien Potencier <fabien@symfony.com>
20
- */
21
- interface GlobalsInterface
22
- {
23
- }
24
- \class_alias('WCML\\Twig\\Extension\\GlobalsInterface', 'WCML\\Twig_Extension_GlobalsInterface');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/twig/src/Extension/InitRuntimeInterface.php DELETED
@@ -1,24 +0,0 @@
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
- namespace WCML\Twig\Extension;
12
-
13
- /**
14
- * Enables usage of the deprecated Twig\Extension\AbstractExtension::initRuntime() method.
15
- *
16
- * Explicitly implement this interface if you really need to implement the
17
- * deprecated initRuntime() method in your extensions.
18
- *
19
- * @author Fabien Potencier <fabien@symfony.com>
20
- */
21
- interface InitRuntimeInterface
22
- {
23
- }
24
- \class_alias('WCML\\Twig\\Extension\\InitRuntimeInterface', 'WCML\\Twig_Extension_InitRuntimeInterface');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/twig/src/Extension/OptimizerExtension.php DELETED
@@ -1,33 +0,0 @@
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
- namespace WCML\Twig\Extension;
12
-
13
- use WCML\Twig\NodeVisitor\OptimizerNodeVisitor;
14
- /**
15
- * @final
16
- */
17
- class OptimizerExtension extends \WCML\Twig\Extension\AbstractExtension
18
- {
19
- protected $optimizers;
20
- public function __construct($optimizers = -1)
21
- {
22
- $this->optimizers = $optimizers;
23
- }
24
- public function getNodeVisitors()
25
- {
26
- return [new \WCML\Twig\NodeVisitor\OptimizerNodeVisitor($this->optimizers)];
27
- }
28
- public function getName()
29
- {
30
- return 'optimizer';
31
- }
32
- }
33
- \class_alias('WCML\\Twig\\Extension\\OptimizerExtension', 'WCML\\Twig_Extension_Optimizer');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/twig/src/Extension/ProfilerExtension.php DELETED
@@ -1,44 +0,0 @@
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
- namespace WCML\Twig\Extension;
12
-
13
- use WCML\Twig\Profiler\NodeVisitor\ProfilerNodeVisitor;
14
- use WCML\Twig\Profiler\Profile;
15
- class ProfilerExtension extends \WCML\Twig\Extension\AbstractExtension
16
- {
17
- private $actives = [];
18
- public function __construct(\WCML\Twig\Profiler\Profile $profile)
19
- {
20
- $this->actives[] = $profile;
21
- }
22
- public function enter(\WCML\Twig\Profiler\Profile $profile)
23
- {
24
- $this->actives[0]->addProfile($profile);
25
- \array_unshift($this->actives, $profile);
26
- }
27
- public function leave(\WCML\Twig\Profiler\Profile $profile)
28
- {
29
- $profile->leave();
30
- \array_shift($this->actives);
31
- if (1 === \count($this->actives)) {
32
- $this->actives[0]->leave();
33
- }
34
- }
35
- public function getNodeVisitors()
36
- {
37
- return [new \WCML\Twig\Profiler\NodeVisitor\ProfilerNodeVisitor(\get_class($this))];
38
- }
39
- public function getName()
40
- {
41
- return 'profiler';
42
- }
43
- }
44
- \class_alias('WCML\\Twig\\Extension\\ProfilerExtension', 'WCML\\Twig_Extension_Profiler');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/twig/src/Extension/RuntimeExtensionInterface.php DELETED
@@ -1,18 +0,0 @@
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
- namespace WCML\Twig\Extension;
12
-
13
- /**
14
- * @author Grégoire Pineau <lyrixx@lyrixx.info>
15
- */
16
- interface RuntimeExtensionInterface
17
- {
18
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/twig/src/Extension/SandboxExtension.php DELETED
@@ -1,91 +0,0 @@
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
- namespace WCML\Twig\Extension;
12
-
13
- use WCML\Twig\NodeVisitor\SandboxNodeVisitor;
14
- use WCML\Twig\Sandbox\SecurityPolicyInterface;
15
- use WCML\Twig\TokenParser\SandboxTokenParser;
16
- /**
17
- * @final
18
- */
19
- class SandboxExtension extends \WCML\Twig\Extension\AbstractExtension
20
- {
21
- protected $sandboxedGlobally;
22
- protected $sandboxed;
23
- protected $policy;
24
- public function __construct(\WCML\Twig\Sandbox\SecurityPolicyInterface $policy, $sandboxed = \false)
25
- {
26
- $this->policy = $policy;
27
- $this->sandboxedGlobally = $sandboxed;
28
- }
29
- public function getTokenParsers()
30
- {
31
- return [new \WCML\Twig\TokenParser\SandboxTokenParser()];
32
- }
33
- public function getNodeVisitors()
34
- {
35
- return [new \WCML\Twig\NodeVisitor\SandboxNodeVisitor()];
36
- }
37
- public function enableSandbox()
38
- {
39
- $this->sandboxed = \true;
40
- }
41
- public function disableSandbox()
42
- {
43
- $this->sandboxed = \false;
44
- }
45
- public function isSandboxed()
46
- {
47
- return $this->sandboxedGlobally || $this->sandboxed;
48
- }
49
- public function isSandboxedGlobally()
50
- {
51
- return $this->sandboxedGlobally;
52
- }
53
- public function setSecurityPolicy(\WCML\Twig\Sandbox\SecurityPolicyInterface $policy)
54
- {
55
- $this->policy = $policy;
56
- }
57
- public function getSecurityPolicy()
58
- {
59
- return $this->policy;
60
- }
61
- public function checkSecurity($tags, $filters, $functions)
62
- {
63
- if ($this->isSandboxed()) {
64
- $this->policy->checkSecurity($tags, $filters, $functions);
65
- }
66
- }
67
- public function checkMethodAllowed($obj, $method)
68
- {
69
- if ($this->isSandboxed()) {
70
- $this->policy->checkMethodAllowed($obj, $method);
71
- }
72
- }
73
- public function checkPropertyAllowed($obj, $method)
74
- {
75
- if ($this->isSandboxed()) {
76
- $this->policy->checkPropertyAllowed($obj, $method);
77
- }
78
- }
79
- public function ensureToStringAllowed($obj)
80
- {
81
- if ($this->isSandboxed() && \is_object($obj) && \method_exists($obj, '__toString')) {
82
- $this->policy->checkMethodAllowed($obj, '__toString');
83
- }
84
- return $obj;
85
- }
86
- public function getName()
87
- {
88
- return 'sandbox';
89
- }
90
- }
91
- \class_alias('WCML\\Twig\\Extension\\SandboxExtension', 'WCML\\Twig_Extension_Sandbox');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/twig/src/Extension/StagingExtension.php DELETED
@@ -1,97 +0,0 @@
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
- namespace WCML\Twig\Extension;
12
-
13
- use WCML\Twig\NodeVisitor\NodeVisitorInterface;
14
- use WCML\Twig\TokenParser\TokenParserInterface;
15
- /**
16
- * Internal class.
17
- *
18
- * This class is used by \Twig\Environment as a staging area and must not be used directly.
19
- *
20
- * @author Fabien Potencier <fabien@symfony.com>
21
- *
22
- * @internal
23
- */
24
- class StagingExtension extends \WCML\Twig\Extension\AbstractExtension
25
- {
26
- protected $functions = [];
27
- protected $filters = [];
28
- protected $visitors = [];
29
- protected $tokenParsers = [];
30
- protected $globals = [];
31
- protected $tests = [];
32
- public function addFunction($name, $function)
33
- {
34
- if (isset($this->functions[$name])) {
35
- @\trigger_error(\sprintf('Overriding function "%s" that is already registered is deprecated since version 1.30 and won\'t be possible anymore in 2.0.', $name), \E_USER_DEPRECATED);
36
- }
37
- $this->functions[$name] = $function;
38
- }
39
- public function getFunctions()
40
- {
41
- return $this->functions;
42
- }
43
- public function addFilter($name, $filter)
44
- {
45
- if (isset($this->filters[$name])) {
46
- @\trigger_error(\sprintf('Overriding filter "%s" that is already registered is deprecated since version 1.30 and won\'t be possible anymore in 2.0.', $name), \E_USER_DEPRECATED);
47
- }
48
- $this->filters[$name] = $filter;
49
- }
50
- public function getFilters()
51
- {
52
- return $this->filters;
53
- }
54
- public function addNodeVisitor(\WCML\Twig\NodeVisitor\NodeVisitorInterface $visitor)
55
- {
56
- $this->visitors[] = $visitor;
57
- }
58
- public function getNodeVisitors()
59
- {
60
- return $this->visitors;
61
- }
62
- public function addTokenParser(\WCML\Twig\TokenParser\TokenParserInterface $parser)
63
- {
64
- if (isset($this->tokenParsers[$parser->getTag()])) {
65
- @\trigger_error(\sprintf('Overriding tag "%s" that is already registered is deprecated since version 1.30 and won\'t be possible anymore in 2.0.', $parser->getTag()), \E_USER_DEPRECATED);
66
- }
67
- $this->tokenParsers[$parser->getTag()] = $parser;
68
- }
69
- public function getTokenParsers()
70
- {
71
- return $this->tokenParsers;
72
- }
73
- public function addGlobal($name, $value)
74
- {
75
- $this->globals[$name] = $value;
76
- }
77
- public function getGlobals()
78
- {
79
- return $this->globals;
80
- }
81
- public function addTest($name, $test)
82
- {
83
- if (isset($this->tests[$name])) {
84
- @\trigger_error(\sprintf('Overriding test "%s" that is already registered is deprecated since version 1.30 and won\'t be possible anymore in 2.0.', $name), \E_USER_DEPRECATED);
85
- }
86
- $this->tests[$name] = $test;
87
- }
88
- public function getTests()
89
- {
90
- return $this->tests;
91
- }
92
- public function getName()
93
- {
94
- return 'staging';
95
- }
96
- }
97
- \class_alias('WCML\\Twig\\Extension\\StagingExtension', 'WCML\\Twig_Extension_Staging');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/twig/src/Extension/StringLoaderExtension.php DELETED
@@ -1,46 +0,0 @@
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
- namespace WCML\Twig\Extension;
12
-
13
- use WCML\Twig\TwigFunction;
14
- /**
15
- * @final
16
- */
17
- class StringLoaderExtension extends \WCML\Twig\Extension\AbstractExtension
18
- {
19
- public function getFunctions()
20
- {
21
- return [new \WCML\Twig\TwigFunction('template_from_string', 'twig_template_from_string', ['needs_environment' => \true])];
22
- }
23
- public function getName()
24
- {
25
- return 'string_loader';
26
- }
27
- }
28
- \class_alias('WCML\\Twig\\Extension\\StringLoaderExtension', 'WCML\\Twig_Extension_StringLoader');
29
- namespace WCML;
30
-
31
- use WCML\Twig\Environment;
32
- use WCML\Twig\TemplateWrapper;
33
- /**
34
- * Loads a template from a string.
35
- *
36
- * {{ include(template_from_string("Hello {{ name }}")) }}
37
- *
38
- * @param string $template A template as a string or object implementing __toString()
39
- * @param string $name An optional name of the template to be used in error messages
40
- *
41
- * @return TemplateWrapper
42
- */
43
- function twig_template_from_string(\WCML\Twig\Environment $env, $template, $name = null)
44
- {
45
- return $env->createTemplate((string) $template, $name);
46
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/twig/src/FileExtensionEscapingStrategy.php DELETED
@@ -1,55 +0,0 @@
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
- namespace WCML\Twig;
12
-
13
- /**
14
- * Default autoescaping strategy based on file names.
15
- *
16
- * This strategy sets the HTML as the default autoescaping strategy,
17
- * but changes it based on the template name.
18
- *
19
- * Note that there is no runtime performance impact as the
20
- * default autoescaping strategy is set at compilation time.
21
- *
22
- * @author Fabien Potencier <fabien@symfony.com>
23
- */
24
- class FileExtensionEscapingStrategy
25
- {
26
- /**
27
- * Guesses the best autoescaping strategy based on the file name.
28
- *
29
- * @param string $name The template name
30
- *
31
- * @return string|false The escaping strategy name to use or false to disable
32
- */
33
- public static function guess($name)
34
- {
35
- if (\in_array(\substr($name, -1), ['/', '\\'])) {
36
- return 'html';
37
- // return html for directories
38
- }
39
- if ('.twig' === \substr($name, -5)) {
40
- $name = \substr($name, 0, -5);
41
- }
42
- $extension = \pathinfo($name, \PATHINFO_EXTENSION);
43
- switch ($extension) {
44
- case 'js':
45
- return 'js';
46
- case 'css':
47
- return 'css';
48
- case 'txt':
49
- return \false;
50
- default:
51
- return 'html';
52
- }
53
- }
54
- }
55
- \class_alias('WCML\\Twig\\FileExtensionEscapingStrategy', 'WCML\\Twig_FileExtensionEscapingStrategy');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/twig/src/Lexer.php DELETED
@@ -1,392 +0,0 @@
1
- <?php
2
-
3
- /*
4
- * This file is part of Twig.
5
- *
6
- * (c) Fabien Potencier
7
- * (c) Armin Ronacher
8
- *
9
- * For the full copyright and license information, please view the LICENSE
10
- * file that was distributed with this source code.
11
- */
12
- namespace WCML\Twig;
13
-
14
- use WCML\Twig\Error\SyntaxError;
15
- /**
16
- * Lexes a template string.
17
- *
18
- * @author Fabien Potencier <fabien@symfony.com>
19
- */
20
- class Lexer implements \WCML\Twig_LexerInterface
21
- {
22
- protected $tokens;
23
- protected $code;
24
- protected $cursor;
25
- protected $lineno;
26
- protected $end;
27
- protected $state;
28
- protected $states;
29
- protected $brackets;
30
- protected $env;
31
- // to be renamed to $name in 2.0 (where it is private)
32
- protected $filename;
33
- protected $options;
34
- protected $regexes;
35
- protected $position;
36
- protected $positions;
37
- protected $currentVarBlockLine;
38
- private $source;
39
- const STATE_DATA = 0;
40
- const STATE_BLOCK = 1;
41
- const STATE_VAR = 2;
42
- const STATE_STRING = 3;
43
- const STATE_INTERPOLATION = 4;
44
- const REGEX_NAME = '/[a-zA-Z_\\x7f-\\xff][a-zA-Z0-9_\\x7f-\\xff]*/A';
45
- const REGEX_NUMBER = '/[0-9]+(?:\\.[0-9]+)?/A';
46
- const REGEX_STRING = '/"([^#"\\\\]*(?:\\\\.[^#"\\\\]*)*)"|\'([^\'\\\\]*(?:\\\\.[^\'\\\\]*)*)\'/As';
47
- const REGEX_DQ_STRING_DELIM = '/"/A';
48
- const REGEX_DQ_STRING_PART = '/[^#"\\\\]*(?:(?:\\\\.|#(?!\\{))[^#"\\\\]*)*/As';
49
- const PUNCTUATION = '()[]{}?:.,|';
50
- public function __construct(\WCML\Twig\Environment $env, array $options = [])
51
- {
52
- $this->env = $env;
53
- $this->options = \array_merge(['tag_comment' => ['{#', '#}'], 'tag_block' => ['{%', '%}'], 'tag_variable' => ['{{', '}}'], 'whitespace_trim' => '-', 'whitespace_line_trim' => '~', 'whitespace_line_chars' => ' \\t\\0\\x0B', 'interpolation' => ['#{', '}']], $options);
54
- // when PHP 7.3 is the min version, we will be able to remove the '#' part in preg_quote as it's part of the default
55
- $this->regexes = [
56
- // }}
57
- 'lex_var' => '{
58
- \\s*
59
- (?:' . \preg_quote($this->options['whitespace_trim'] . $this->options['tag_variable'][1], '#') . '\\s*' . '|' . \preg_quote($this->options['whitespace_line_trim'] . $this->options['tag_variable'][1], '#') . '[' . $this->options['whitespace_line_chars'] . ']*' . '|' . \preg_quote($this->options['tag_variable'][1], '#') . ')
60
- }Ax',
61
- // %}
62
- 'lex_block' => '{
63
- \\s*
64
- (?:' . \preg_quote($this->options['whitespace_trim'] . $this->options['tag_block'][1], '#') . '\\s*\\n?' . '|' . \preg_quote($this->options['whitespace_line_trim'] . $this->options['tag_block'][1], '#') . '[' . $this->options['whitespace_line_chars'] . ']*' . '|' . \preg_quote($this->options['tag_block'][1], '#') . '\\n?' . ')
65
- }Ax',
66
- // {% endverbatim %}
67
- 'lex_raw_data' => '{' . \preg_quote($this->options['tag_block'][0], '#') . '(' . $this->options['whitespace_trim'] . '|' . $this->options['whitespace_line_trim'] . ')?\\s*' . '(?:end%s)' . '\\s*' . '(?:' . \preg_quote($this->options['whitespace_trim'] . $this->options['tag_block'][1], '#') . '\\s*' . '|' . \preg_quote($this->options['whitespace_line_trim'] . $this->options['tag_block'][1], '#') . '[' . $this->options['whitespace_line_chars'] . ']*' . '|' . \preg_quote($this->options['tag_block'][1], '#') . ')
68
- }sx',
69
- 'operator' => $this->getOperatorRegex(),
70
- // #}
71
- 'lex_comment' => '{
72
- (?:' . \preg_quote($this->options['whitespace_trim']) . \preg_quote($this->options['tag_comment'][1], '#') . '\\s*\\n?' . '|' . \preg_quote($this->options['whitespace_line_trim'] . $this->options['tag_comment'][1], '#') . '[' . $this->options['whitespace_line_chars'] . ']*' . '|' . \preg_quote($this->options['tag_comment'][1], '#') . '\\n?' . ')
73
- }sx',
74
- // verbatim %}
75
- 'lex_block_raw' => '{
76
- \\s*
77
- (raw|verbatim)
78
- \\s*
79
- (?:' . \preg_quote($this->options['whitespace_trim'] . $this->options['tag_block'][1], '#') . '\\s*' . '|' . \preg_quote($this->options['whitespace_line_trim'] . $this->options['tag_block'][1], '#') . '[' . $this->options['whitespace_line_chars'] . ']*' . '|' . \preg_quote($this->options['tag_block'][1], '#') . ')
80
- }Asx',
81
- 'lex_block_line' => '{\\s*line\\s+(\\d+)\\s*' . \preg_quote($this->options['tag_block'][1], '#') . '}As',
82
- // {{ or {% or {#
83
- 'lex_tokens_start' => '{
84
- (' . \preg_quote($this->options['tag_variable'][0], '#') . '|' . \preg_quote($this->options['tag_block'][0], '#') . '|' . \preg_quote($this->options['tag_comment'][0], '#') . ')(' . \preg_quote($this->options['whitespace_trim'], '#') . '|' . \preg_quote($this->options['whitespace_line_trim'], '#') . ')?
85
- }sx',
86
- 'interpolation_start' => '{' . \preg_quote($this->options['interpolation'][0], '#') . '\\s*}A',
87
- 'interpolation_end' => '{\\s*' . \preg_quote($this->options['interpolation'][1], '#') . '}A',
88
- ];
89
- }
90
- public function tokenize($code, $name = null)
91
- {
92
- if (!$code instanceof \WCML\Twig\Source) {
93
- @\trigger_error(\sprintf('Passing a string as the $code argument of %s() is deprecated since version 1.27 and will be removed in 2.0. Pass a \\Twig\\Source instance instead.', __METHOD__), \E_USER_DEPRECATED);
94
- $this->source = new \WCML\Twig\Source($code, $name);
95
- } else {
96
- $this->source = $code;
97
- }
98
- if ((int) \ini_get('mbstring.func_overload') & 2) {
99
- @\trigger_error('Support for having "mbstring.func_overload" different from 0 is deprecated version 1.29 and will be removed in 2.0.', \E_USER_DEPRECATED);
100
- }
101
- if (\function_exists('mb_internal_encoding') && (int) \ini_get('mbstring.func_overload') & 2) {
102
- $mbEncoding = \mb_internal_encoding();
103
- \mb_internal_encoding('ASCII');
104
- } else {
105
- $mbEncoding = null;
106
- }
107
- $this->code = \str_replace(["\r\n", "\r"], "\n", $this->source->getCode());
108
- $this->filename = $this->source->getName();
109
- $this->cursor = 0;
110
- $this->lineno = 1;
111
- $this->end = \strlen($this->code);
112
- $this->tokens = [];
113
- $this->state = self::STATE_DATA;
114
- $this->states = [];
115
- $this->brackets = [];
116
- $this->position = -1;
117
- // find all token starts in one go
118
- \preg_match_all($this->regexes['lex_tokens_start'], $this->code, $matches, \PREG_OFFSET_CAPTURE);
119
- $this->positions = $matches;
120
- while ($this->cursor < $this->end) {
121
- // dispatch to the lexing functions depending
122
- // on the current state
123
- switch ($this->state) {
124
- case self::STATE_DATA:
125
- $this->lexData();
126
- break;
127
- case self::STATE_BLOCK:
128
- $this->lexBlock();
129
- break;
130
- case self::STATE_VAR:
131
- $this->lexVar();
132
- break;
133
- case self::STATE_STRING:
134
- $this->lexString();
135
- break;
136
- case self::STATE_INTERPOLATION:
137
- $this->lexInterpolation();
138
- break;
139
- }
140
- }
141
- $this->pushToken(\WCML\Twig\Token::EOF_TYPE);
142
- if (!empty($this->brackets)) {
143
- list($expect, $lineno) = \array_pop($this->brackets);
144
- throw new \WCML\Twig\Error\SyntaxError(\sprintf('Unclosed "%s".', $expect), $lineno, $this->source);
145
- }
146
- if ($mbEncoding) {
147
- \mb_internal_encoding($mbEncoding);
148
- }
149
- return new \WCML\Twig\TokenStream($this->tokens, $this->source);
150
- }
151
- protected function lexData()
152
- {
153
- // if no matches are left we return the rest of the template as simple text token
154
- if ($this->position == \count($this->positions[0]) - 1) {
155
- $this->pushToken(\WCML\Twig\Token::TEXT_TYPE, \substr($this->code, $this->cursor));
156
- $this->cursor = $this->end;
157
- return;
158
- }
159
- // Find the first token after the current cursor
160
- $position = $this->positions[0][++$this->position];
161
- while ($position[1] < $this->cursor) {
162
- if ($this->position == \count($this->positions[0]) - 1) {
163
- return;
164
- }
165
- $position = $this->positions[0][++$this->position];
166
- }
167
- // push the template text first
168
- $text = $textContent = \substr($this->code, $this->cursor, $position[1] - $this->cursor);
169
- // trim?
170
- if (isset($this->positions[2][$this->position][0])) {
171
- if ($this->options['whitespace_trim'] === $this->positions[2][$this->position][0]) {
172
- // whitespace_trim detected ({%-, {{- or {#-)
173
- $text = \rtrim($text);
174
- } elseif ($this->options['whitespace_line_trim'] === $this->positions[2][$this->position][0]) {
175
- // whitespace_line_trim detected ({%~, {{~ or {#~)
176
- // don't trim \r and \n
177
- $text = \rtrim($text, " \t\0\v");
178
- }
179
- }
180
- $this->pushToken(\WCML\Twig\Token::TEXT_TYPE, $text);
181
- $this->moveCursor($textContent . $position[0]);
182
- switch ($this->positions[1][$this->position][0]) {
183
- case $this->options['tag_comment'][0]:
184
- $this->lexComment();
185
- break;
186
- case $this->options['tag_block'][0]:
187
- // raw data?
188
- if (\preg_match($this->regexes['lex_block_raw'], $this->code, $match, 0, $this->cursor)) {
189
- $this->moveCursor($match[0]);
190
- $this->lexRawData($match[1]);
191
- // {% line \d+ %}
192
- } elseif (\preg_match($this->regexes['lex_block_line'], $this->code, $match, 0, $this->cursor)) {
193
- $this->moveCursor($match[0]);
194
- $this->lineno = (int) $match[1];
195
- } else {
196
- $this->pushToken(\WCML\Twig\Token::BLOCK_START_TYPE);
197
- $this->pushState(self::STATE_BLOCK);
198
- $this->currentVarBlockLine = $this->lineno;
199
- }
200
- break;
201
- case $this->options['tag_variable'][0]:
202
- $this->pushToken(\WCML\Twig\Token::VAR_START_TYPE);
203
- $this->pushState(self::STATE_VAR);
204
- $this->currentVarBlockLine = $this->lineno;
205
- break;
206
- }
207
- }
208
- protected function lexBlock()
209
- {
210
- if (empty($this->brackets) && \preg_match($this->regexes['lex_block'], $this->code, $match, 0, $this->cursor)) {
211
- $this->pushToken(\WCML\Twig\Token::BLOCK_END_TYPE);
212
- $this->moveCursor($match[0]);
213
- $this->popState();
214
- } else {
215
- $this->lexExpression();
216
- }
217
- }
218
- protected function lexVar()
219
- {
220
- if (empty($this->brackets) && \preg_match($this->regexes['lex_var'], $this->code, $match, 0, $this->cursor)) {
221
- $this->pushToken(\WCML\Twig\Token::VAR_END_TYPE);
222
- $this->moveCursor($match[0]);
223
- $this->popState();
224
- } else {
225
- $this->lexExpression();
226
- }
227
- }
228
- protected function lexExpression()
229
- {
230
- // whitespace
231
- if (\preg_match('/\\s+/A', $this->code, $match, 0, $this->cursor)) {
232
- $this->moveCursor($match[0]);
233
- if ($this->cursor >= $this->end) {
234
- throw new \WCML\Twig\Error\SyntaxError(\sprintf('Unclosed "%s".', self::STATE_BLOCK === $this->state ? 'block' : 'variable'), $this->currentVarBlockLine, $this->source);
235
- }
236
- }
237
- // arrow function
238
- if ('=' === $this->code[$this->cursor] && '>' === $this->code[$this->cursor + 1]) {
239
- $this->pushToken(\WCML\Twig\Token::ARROW_TYPE, '=>');
240
- $this->moveCursor('=>');
241
- } elseif (\preg_match($this->regexes['operator'], $this->code, $match, 0, $this->cursor)) {
242
- $this->pushToken(\WCML\Twig\Token::OPERATOR_TYPE, \preg_replace('/\\s+/', ' ', $match[0]));
243
- $this->moveCursor($match[0]);
244
- } elseif (\preg_match(self::REGEX_NAME, $this->code, $match, 0, $this->cursor)) {
245
- $this->pushToken(\WCML\Twig\Token::NAME_TYPE, $match[0]);
246
- $this->moveCursor($match[0]);
247
- } elseif (\preg_match(self::REGEX_NUMBER, $this->code, $match, 0, $this->cursor)) {
248
- $number = (float) $match[0];
249
- // floats
250
- if (\ctype_digit($match[0]) && $number <= \PHP_INT_MAX) {
251
- $number = (int) $match[0];
252
- // integers lower than the maximum
253
- }
254
- $this->pushToken(\WCML\Twig\Token::NUMBER_TYPE, $number);
255
- $this->moveCursor($match[0]);
256
- } elseif (\false !== \strpos(self::PUNCTUATION, $this->code[$this->cursor])) {
257
- // opening bracket
258
- if (\false !== \strpos('([{', $this->code[$this->cursor])) {
259
- $this->brackets[] = [$this->code[$this->cursor], $this->lineno];
260
- } elseif (\false !== \strpos(')]}', $this->code[$this->cursor])) {
261
- if (empty($this->brackets)) {
262
- throw new \WCML\Twig\Error\SyntaxError(\sprintf('Unexpected "%s".', $this->code[$this->cursor]), $this->lineno, $this->source);
263
- }
264
- list($expect, $lineno) = \array_pop($this->brackets);
265
- if ($this->code[$this->cursor] != \strtr($expect, '([{', ')]}')) {
266
- throw new \WCML\Twig\Error\SyntaxError(\sprintf('Unclosed "%s".', $expect), $lineno, $this->source);
267
- }
268
- }
269
- $this->pushToken(\WCML\Twig\Token::PUNCTUATION_TYPE, $this->code[$this->cursor]);
270
- ++$this->cursor;
271
- } elseif (\preg_match(self::REGEX_STRING, $this->code, $match, 0, $this->cursor)) {
272
- $this->pushToken(\WCML\Twig\Token::STRING_TYPE, \stripcslashes(\substr($match[0], 1, -1)));
273
- $this->moveCursor($match[0]);
274
- } elseif (\preg_match(self::REGEX_DQ_STRING_DELIM, $this->code, $match, 0, $this->cursor)) {
275
- $this->brackets[] = ['"', $this->lineno];
276
- $this->pushState(self::STATE_STRING);
277
- $this->moveCursor($match[0]);
278
- } else {
279
- throw new \WCML\Twig\Error\SyntaxError(\sprintf('Unexpected character "%s".', $this->code[$this->cursor]), $this->lineno, $this->source);
280
- }
281
- }
282
- protected function lexRawData($tag)
283
- {
284
- if ('raw' === $tag) {
285
- @\trigger_error(\sprintf('Twig Tag "raw" is deprecated since version 1.21. Use "verbatim" instead in %s at line %d.', $this->filename, $this->lineno), \E_USER_DEPRECATED);
286
- }
287
- if (!\preg_match(\str_replace('%s', $tag, $this->regexes['lex_raw_data']), $this->code, $match, \PREG_OFFSET_CAPTURE, $this->cursor)) {
288
- throw new \WCML\Twig\Error\SyntaxError(\sprintf('Unexpected end of file: Unclosed "%s" block.', $tag), $this->lineno, $this->source);
289
- }
290
- $text = \substr($this->code, $this->cursor, $match[0][1] - $this->cursor);
291
- $this->moveCursor($text . $match[0][0]);
292
- // trim?
293
- if (isset($match[1][0])) {
294
- if ($this->options['whitespace_trim'] === $match[1][0]) {
295
- // whitespace_trim detected ({%-, {{- or {#-)
296
- $text = \rtrim($text);
297
- } else {
298
- // whitespace_line_trim detected ({%~, {{~ or {#~)
299
- // don't trim \r and \n
300
- $text = \rtrim($text, " \t\0\v");
301
- }
302
- }
303
- $this->pushToken(\WCML\Twig\Token::TEXT_TYPE, $text);
304
- }
305
- protected function lexComment()
306
- {
307
- if (!\preg_match($this->regexes['lex_comment'], $this->code, $match, \PREG_OFFSET_CAPTURE, $this->cursor)) {
308
- throw new \WCML\Twig\Error\SyntaxError('Unclosed comment.', $this->lineno, $this->source);
309
- }
310
- $this->moveCursor(\substr($this->code, $this->cursor, $match[0][1] - $this->cursor) . $match[0][0]);
311
- }
312
- protected function lexString()
313
- {
314
- if (\preg_match($this->regexes['interpolation_start'], $this->code, $match, 0, $this->cursor)) {
315
- $this->brackets[] = [$this->options['interpolation'][0], $this->lineno];
316
- $this->pushToken(\WCML\Twig\Token::INTERPOLATION_START_TYPE);
317
- $this->moveCursor($match[0]);
318
- $this->pushState(self::STATE_INTERPOLATION);
319
- } elseif (\preg_match(self::REGEX_DQ_STRING_PART, $this->code, $match, 0, $this->cursor) && \strlen($match[0]) > 0) {
320
- $this->pushToken(\WCML\Twig\Token::STRING_TYPE, \stripcslashes($match[0]));
321
- $this->moveCursor($match[0]);
322
- } elseif (\preg_match(self::REGEX_DQ_STRING_DELIM, $this->code, $match, 0, $this->cursor)) {
323
- list($expect, $lineno) = \array_pop($this->brackets);
324
- if ('"' != $this->code[$this->cursor]) {
325
- throw new \WCML\Twig\Error\SyntaxError(\sprintf('Unclosed "%s".', $expect), $lineno, $this->source);
326
- }
327
- $this->popState();
328
- ++$this->cursor;
329
- } else {
330
- // unlexable
331
- throw new \WCML\Twig\Error\SyntaxError(\sprintf('Unexpected character "%s".', $this->code[$this->cursor]), $this->lineno, $this->source);
332
- }
333
- }
334
- protected function lexInterpolation()
335
- {
336
- $bracket = \end($this->brackets);
337
- if ($this->options['interpolation'][0] === $bracket[0] && \preg_match($this->regexes['interpolation_end'], $this->code, $match, 0, $this->cursor)) {
338
- \array_pop($this->brackets);
339
- $this->pushToken(\WCML\Twig\Token::INTERPOLATION_END_TYPE);
340
- $this->moveCursor($match[0]);
341
- $this->popState();
342
- } else {
343
- $this->lexExpression();
344
- }
345
- }
346
- protected function pushToken($type, $value = '')
347
- {
348
- // do not push empty text tokens
349
- if (\WCML\Twig\Token::TEXT_TYPE === $type && '' === $value) {
350
- return;
351
- }
352
- $this->tokens[] = new \WCML\Twig\Token($type, $value, $this->lineno);
353
- }
354
- protected function moveCursor($text)
355
- {
356
- $this->cursor += \strlen($text);
357
- $this->lineno += \substr_count($text, "\n");
358
- }
359
- protected function getOperatorRegex()
360
- {
361
- $operators = \array_merge(['='], \array_keys($this->env->getUnaryOperators()), \array_keys($this->env->getBinaryOperators()));
362
- $operators = \array_combine($operators, \array_map('strlen', $operators));
363
- \arsort($operators);
364
- $regex = [];
365
- foreach ($operators as $operator => $length) {
366
- // an operator that ends with a character must be followed by
367
- // a whitespace or a parenthesis
368
- if (\ctype_alpha($operator[$length - 1])) {
369
- $r = \preg_quote($operator, '/') . '(?=[\\s()])';
370
- } else {
371
- $r = \preg_quote($operator, '/');
372
- }
373
- // an operator with a space can be any amount of whitespaces
374
- $r = \preg_replace('/\\s+/', '\\s+', $r);
375
- $regex[] = $r;
376
- }
377
- return '/' . \implode('|', $regex) . '/A';
378
- }
379
- protected function pushState($state)
380
- {
381
- $this->states[] = $this->state;
382
- $this->state = $state;
383
- }
384
- protected function popState()
385
- {
386
- if (0 === \count($this->states)) {
387
- throw new \LogicException('Cannot pop state without a previous state.');
388
- }
389
- $this->state = \array_pop($this->states);
390
- }
391
- }
392
- \class_alias('WCML\\Twig\\Lexer', 'WCML\\Twig_Lexer');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/twig/src/Loader/ArrayLoader.php DELETED
@@ -1,87 +0,0 @@
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
- namespace WCML\Twig\Loader;
12
-
13
- use WCML\Twig\Error\LoaderError;
14
- use WCML\Twig\Source;
15
- /**
16
- * Loads a template from an array.
17
- *
18
- * When using this loader with a cache mechanism, you should know that a new cache
19
- * key is generated each time a template content "changes" (the cache key being the
20
- * source code of the template). If you don't want to see your cache grows out of
21
- * control, you need to take care of clearing the old cache file by yourself.
22
- *
23
- * This loader should only be used for unit testing.
24
- *
25
- * @final
26
- *
27
- * @author Fabien Potencier <fabien@symfony.com>
28
- */
29
- class ArrayLoader implements \WCML\Twig\Loader\LoaderInterface, \WCML\Twig\Loader\ExistsLoaderInterface, \WCML\Twig\Loader\SourceContextLoaderInterface
30
- {
31
- protected $templates = [];
32
- /**
33
- * @param array $templates An array of templates (keys are the names, and values are the source code)
34
- */
35
- public function __construct(array $templates = [])
36
- {
37
- $this->templates = $templates;
38
- }
39
- /**
40
- * Adds or overrides a template.
41
- *
42
- * @param string $name The template name
43
- * @param string $template The template source
44
- */
45
- public function setTemplate($name, $template)
46
- {
47
- $this->templates[(string) $name] = $template;
48
- }
49
- public function getSource($name)
50
- {
51
- @\trigger_error(\sprintf('Calling "getSource" on "%s" is deprecated since 1.27. Use getSourceContext() instead.', \get_class($this)), \E_USER_DEPRECATED);
52
- $name = (string) $name;
53
- if (!isset($this->templates[$name])) {
54
- throw new \WCML\Twig\Error\LoaderError(\sprintf('Template "%s" is not defined.', $name));
55
- }
56
- return $this->templates[$name];
57
- }
58
- public function getSourceContext($name)
59
- {
60
- $name = (string) $name;
61
- if (!isset($this->templates[$name])) {
62
- throw new \WCML\Twig\Error\LoaderError(\sprintf('Template "%s" is not defined.', $name));
63
- }
64
- return new \WCML\Twig\Source($this->templates[$name], $name);
65
- }
66
- public function exists($name)
67
- {
68
- return isset($this->templates[(string) $name]);
69
- }
70
- public function getCacheKey($name)
71
- {
72
- $name = (string) $name;
73
- if (!isset($this->templates[$name])) {
74
- throw new \WCML\Twig\Error\LoaderError(\sprintf('Template "%s" is not defined.', $name));
75
- }
76
- return $name . ':' . $this->templates[$name];
77
- }
78
- public function isFresh($name, $time)
79
- {
80
- $name = (string) $name;
81
- if (!isset($this->templates[$name])) {
82
- throw new \WCML\Twig\Error\LoaderError(\sprintf('Template "%s" is not defined.', $name));
83
- }
84
- return \true;
85
- }
86
- }
87
- \class_alias('WCML\\Twig\\Loader\\ArrayLoader', 'WCML\\Twig_Loader_Array');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/twig/src/Loader/ChainLoader.php DELETED
@@ -1,137 +0,0 @@
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
- namespace WCML\Twig\Loader;
12
-
13
- use WCML\Twig\Error\LoaderError;
14
- use WCML\Twig\Source;
15
- /**
16
- * Loads templates from other loaders.
17
- *
18
- * @final
19
- *
20
- * @author Fabien Potencier <fabien@symfony.com>
21
- */
22
- class ChainLoader implements \WCML\Twig\Loader\LoaderInterface, \WCML\Twig\Loader\ExistsLoaderInterface, \WCML\Twig\Loader\SourceContextLoaderInterface
23
- {
24
- private $hasSourceCache = [];
25
- protected $loaders = [];
26
- /**
27
- * @param LoaderInterface[] $loaders
28
- */
29
- public function __construct(array $loaders = [])
30
- {
31
- foreach ($loaders as $loader) {
32
- $this->addLoader($loader);
33
- }
34
- }
35
- public function addLoader(\WCML\Twig\Loader\LoaderInterface $loader)
36
- {
37
- $this->loaders[] = $loader;
38
- $this->hasSourceCache = [];
39
- }
40
- /**
41
- * @return LoaderInterface[]
42
- */
43
- public function getLoaders()
44
- {
45
- return $this->loaders;
46
- }
47
- public function getSource($name)
48
- {
49
- @\trigger_error(\sprintf('Calling "getSource" on "%s" is deprecated since 1.27. Use getSourceContext() instead.', \get_class($this)), \E_USER_DEPRECATED);
50
- $exceptions = [];
51
- foreach ($this->loaders as $loader) {
52
- if ($loader instanceof \WCML\Twig\Loader\ExistsLoaderInterface && !$loader->exists($name)) {
53
- continue;
54
- }
55
- try {
56
- return $loader->getSource($name);
57
- } catch (\WCML\Twig\Error\LoaderError $e) {
58
- $exceptions[] = $e->getMessage();
59
- }
60
- }
61
- throw new \WCML\Twig\Error\LoaderError(\sprintf('Template "%s" is not defined%s.', $name, $exceptions ? ' (' . \implode(', ', $exceptions) . ')' : ''));
62
- }
63
- public function getSourceContext($name)
64
- {
65
- $exceptions = [];
66
- foreach ($this->loaders as $loader) {
67
- if ($loader instanceof \WCML\Twig\Loader\ExistsLoaderInterface && !$loader->exists($name)) {
68
- continue;
69
- }
70
- try {
71
- if ($loader instanceof \WCML\Twig\Loader\SourceContextLoaderInterface) {
72
- return $loader->getSourceContext($name);
73
- }
74
- return new \WCML\Twig\Source($loader->getSource($name), $name);
75
- } catch (\WCML\Twig\Error\LoaderError $e) {
76
- $exceptions[] = $e->getMessage();
77
- }
78
- }
79
- throw new \WCML\Twig\Error\LoaderError(\sprintf('Template "%s" is not defined%s.', $name, $exceptions ? ' (' . \implode(', ', $exceptions) . ')' : ''));
80
- }
81
- public function exists($name)
82
- {
83
- $name = (string) $name;
84
- if (isset($this->hasSourceCache[$name])) {
85
- return $this->hasSourceCache[$name];
86
- }
87
- foreach ($this->loaders as $loader) {
88
- if ($loader instanceof \WCML\Twig\Loader\ExistsLoaderInterface) {
89
- if ($loader->exists($name)) {
90
- return $this->hasSourceCache[$name] = \true;
91
- }
92
- continue;
93
- }
94
- try {
95
- if ($loader instanceof \WCML\Twig\Loader\SourceContextLoaderInterface) {
96
- $loader->getSourceContext($name);
97
- } else {
98
- $loader->getSource($name);
99
- }
100
- return $this->hasSourceCache[$name] = \true;
101
- } catch (\WCML\Twig\Error\LoaderError $e) {
102
- }
103
- }
104
- return $this->hasSourceCache[$name] = \false;
105
- }
106
- public function getCacheKey($name)
107
- {
108
- $exceptions = [];
109
- foreach ($this->loaders as $loader) {
110
- if ($loader instanceof \WCML\Twig\Loader\ExistsLoaderInterface && !$loader->exists($name)) {
111
- continue;
112
- }
113
- try {
114
- return $loader->getCacheKey($name);
115
- } catch (\WCML\Twig\Error\LoaderError $e) {
116
- $exceptions[] = \get_class($loader) . ': ' . $e->getMessage();
117
- }
118
- }
119
- throw new \WCML\Twig\Error\LoaderError(\sprintf('Template "%s" is not defined%s.', $name, $exceptions ? ' (' . \implode(', ', $exceptions) . ')' : ''));
120
- }
121
- public function isFresh($name, $time)
122
- {
123
- $exceptions = [];
124
- foreach ($this->loaders as $loader) {
125
- if ($loader instanceof \WCML\Twig\Loader\ExistsLoaderInterface && !$loader->exists($name)) {
126
- continue;
127
- }
128
- try {
129
- return $loader->isFresh($name, $time);
130
- } catch (\WCML\Twig\Error\LoaderError $e) {
131
- $exceptions[] = \get_class($loader) . ': ' . $e->getMessage();
132
- }
133
- }
134
- throw new \WCML\Twig\Error\LoaderError(\sprintf('Template "%s" is not defined%s.', $name, $exceptions ? ' (' . \implode(', ', $exceptions) . ')' : ''));
135
- }
136
- }
137
- \class_alias('WCML\\Twig\\Loader\\ChainLoader', 'WCML\\Twig_Loader_Chain');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/twig/src/Loader/ExistsLoaderInterface.php DELETED
@@ -1,31 +0,0 @@
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
- namespace WCML\Twig\Loader;
12
-
13
- /**
14
- * Adds an exists() method for loaders.
15
- *
16
- * @author Florin Patan <florinpatan@gmail.com>
17
- *
18
- * @deprecated since 1.12 (to be removed in 3.0)
19
- */
20
- interface ExistsLoaderInterface
21
- {
22
- /**
23
- * Check if we have the source code of a template, given its name.
24
- *
25
- * @param string $name The name of the template to check if we can load
26
- *
27
- * @return bool If the template source code is handled by this loader or not
28
- */
29
- public function exists($name);
30
- }
31
- \class_alias('WCML\\Twig\\Loader\\ExistsLoaderInterface', 'WCML\\Twig_ExistsLoaderInterface');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/twig/src/Loader/FilesystemLoader.php DELETED
@@ -1,261 +0,0 @@
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
- namespace WCML\Twig\Loader;
12
-
13
- use WCML\Twig\Error\LoaderError;
14
- use WCML\Twig\Source;
15
- /**
16
- * Loads template from the filesystem.
17
- *
18
- * @author Fabien Potencier <fabien@symfony.com>
19
- */
20
- class FilesystemLoader implements \WCML\Twig\Loader\LoaderInterface, \WCML\Twig\Loader\ExistsLoaderInterface, \WCML\Twig\Loader\SourceContextLoaderInterface
21
- {
22
- /** Identifier of the main namespace. */
23
- const MAIN_NAMESPACE = '__main__';
24
- protected $paths = [];
25
- protected $cache = [];
26
- protected $errorCache = [];
27
- private $rootPath;
28
- /**
29
- * @param string|array $paths A path or an array of paths where to look for templates
30
- * @param string|null $rootPath The root path common to all relative paths (null for getcwd())
31
- */
32
- public function __construct($paths = [], $rootPath = null)
33
- {
34
- $this->rootPath = (null === $rootPath ? \getcwd() : $rootPath) . \DIRECTORY_SEPARATOR;
35
- if (\false !== ($realPath = \realpath($rootPath))) {
36
- $this->rootPath = $realPath . \DIRECTORY_SEPARATOR;
37
- }
38
- if ($paths) {
39
- $this->setPaths($paths);
40
- }
41
- }
42
- /**
43
- * Returns the paths to the templates.
44
- *
45
- * @param string $namespace A path namespace
46
- *
47
- * @return array The array of paths where to look for templates
48
- */
49
- public function getPaths($namespace = self::MAIN_NAMESPACE)
50
- {
51
- return isset($this->paths[$namespace]) ? $this->paths[$namespace] : [];
52
- }
53
- /**
54
- * Returns the path namespaces.
55
- *
56
- * The main namespace is always defined.
57
- *
58
- * @return array The array of defined namespaces
59
- */
60
- public function getNamespaces()
61
- {
62
- return \array_keys($this->paths);
63
- }
64
- /**
65
- * Sets the paths where templates are stored.
66
- *
67
- * @param string|array $paths A path or an array of paths where to look for templates
68
- * @param string $namespace A path namespace
69
- */
70
- public function setPaths($paths, $namespace = self::MAIN_NAMESPACE)
71
- {
72
- if (!\is_array($paths)) {
73
- $paths = [$paths];
74
- }
75
- $this->paths[$namespace] = [];
76
- foreach ($paths as $path) {
77
- $this->addPath($path, $namespace);
78
- }
79
- }
80
- /**
81
- * Adds a path where templates are stored.
82
- *
83
- * @param string $path A path where to look for templates
84
- * @param string $namespace A path namespace
85
- *
86
- * @throws LoaderError
87
- */
88
- public function addPath($path, $namespace = self::MAIN_NAMESPACE)
89
- {
90
- // invalidate the cache
91
- $this->cache = $this->errorCache = [];
92
- $checkPath = $this->isAbsolutePath($path) ? $path : $this->rootPath . $path;
93
- if (!\is_dir($checkPath)) {
94
- throw new \WCML\Twig\Error\LoaderError(\sprintf('The "%s" directory does not exist ("%s").', $path, $checkPath));
95
- }
96
- $this->paths[$namespace][] = \rtrim($path, '/\\');
97
- }
98
- /**
99
- * Prepends a path where templates are stored.
100
- *
101
- * @param string $path A path where to look for templates
102
- * @param string $namespace A path namespace
103
- *
104
- * @throws LoaderError
105
- */
106
- public function prependPath($path, $namespace = self::MAIN_NAMESPACE)
107
- {
108
- // invalidate the cache
109
- $this->cache = $this->errorCache = [];
110
- $checkPath = $this->isAbsolutePath($path) ? $path : $this->rootPath . $path;
111
- if (!\is_dir($checkPath)) {
112
- throw new \WCML\Twig\Error\LoaderError(\sprintf('The "%s" directory does not exist ("%s").', $path, $checkPath));
113
- }
114
- $path = \rtrim($path, '/\\');
115
- if (!isset($this->paths[$namespace])) {
116
- $this->paths[$namespace][] = $path;
117
- } else {
118
- \array_unshift($this->paths[$namespace], $path);
119
- }
120
- }
121
- public function getSource($name)
122
- {
123
- @\trigger_error(\sprintf('Calling "getSource" on "%s" is deprecated since 1.27. Use getSourceContext() instead.', \get_class($this)), \E_USER_DEPRECATED);
124
- if (null === ($path = $this->findTemplate($name)) || \false === $path) {
125
- return '';
126
- }
127
- return \file_get_contents($path);
128
- }
129
- public function getSourceContext($name)
130
- {
131
- if (null === ($path = $this->findTemplate($name)) || \false === $path) {
132
- return new \WCML\Twig\Source('', $name, '');
133
- }
134
- return new \WCML\Twig\Source(\file_get_contents($path), $name, $path);
135
- }
136
- public function getCacheKey($name)
137
- {
138
- if (null === ($path = $this->findTemplate($name)) || \false === $path) {
139
- return '';
140
- }
141
- $len = \strlen($this->rootPath);
142
- if (0 === \strncmp($this->rootPath, $path, $len)) {
143
- return \substr($path, $len);
144
- }
145
- return $path;
146
- }
147
- public function exists($name)
148
- {
149
- $name = $this->normalizeName($name);
150
- if (isset($this->cache[$name])) {
151
- return \true;
152
- }
153
- try {
154
- return null !== ($path = $this->findTemplate($name, \false)) && \false !== $path;
155
- } catch (\WCML\Twig\Error\LoaderError $e) {
156
- @\trigger_error(\sprintf('In %s::findTemplate(), you must accept a second argument that when set to "false" returns "false" instead of throwing an exception. Not supporting this argument is deprecated since version 1.27.', \get_class($this)), \E_USER_DEPRECATED);
157
- return \false;
158
- }
159
- }
160
- public function isFresh($name, $time)
161
- {
162
- // false support to be removed in 3.0
163
- if (null === ($path = $this->findTemplate($name)) || \false === $path) {
164
- return \false;
165
- }
166
- return \filemtime($path) < $time;
167
- }
168
- /**
169
- * Checks if the template can be found.
170
- *
171
- * @param string $name The template name
172
- *
173
- * @return string|false|null The template name or false/null
174
- */
175
- protected function findTemplate($name)
176
- {
177
- $throw = \func_num_args() > 1 ? \func_get_arg(1) : \true;
178
- $name = $this->normalizeName($name);
179
- if (isset($this->cache[$name])) {
180
- return $this->cache[$name];
181
- }
182
- if (isset($this->errorCache[$name])) {
183
- if (!$throw) {
184
- return \false;
185
- }
186
- throw new \WCML\Twig\Error\LoaderError($this->errorCache[$name]);
187
- }
188
- try {
189
- $this->validateName($name);
190
- list($namespace, $shortname) = $this->parseName($name);
191
- } catch (\WCML\Twig\Error\LoaderError $e) {
192
- if (!$throw) {
193
- return \false;
194
- }
195
- throw $e;
196
- }
197
- if (!isset($this->paths[$namespace])) {
198
- $this->errorCache[$name] = \sprintf('There are no registered paths for namespace "%s".', $namespace);
199
- if (!$throw) {
200
- return \false;
201
- }
202
- throw new \WCML\Twig\Error\LoaderError($this->errorCache[$name]);
203
- }
204
- foreach ($this->paths[$namespace] as $path) {
205
- if (!$this->isAbsolutePath($path)) {
206
- $path = $this->rootPath . $path;
207
- }
208
- if (\is_file($path . '/' . $shortname)) {
209
- if (\false !== ($realpath = \realpath($path . '/' . $shortname))) {
210
- return $this->cache[$name] = $realpath;
211
- }
212
- return $this->cache[$name] = $path . '/' . $shortname;
213
- }
214
- }
215
- $this->errorCache[$name] = \sprintf('Unable to find template "%s" (looked into: %s).', $name, \implode(', ', $this->paths[$namespace]));
216
- if (!$throw) {
217
- return \false;
218
- }
219
- throw new \WCML\Twig\Error\LoaderError($this->errorCache[$name]);
220
- }
221
- protected function parseName($name, $default = self::MAIN_NAMESPACE)
222
- {
223
- if (isset($name[0]) && '@' == $name[0]) {
224
- if (\false === ($pos = \strpos($name, '/'))) {
225
- throw new \WCML\Twig\Error\LoaderError(\sprintf('Malformed namespaced template name "%s" (expecting "@namespace/template_name").', $name));
226
- }
227
- $namespace = \substr($name, 1, $pos - 1);
228
- $shortname = \substr($name, $pos + 1);
229
- return [$namespace, $shortname];
230
- }
231
- return [$default, $name];
232
- }
233
- protected function normalizeName($name)
234
- {
235
- return \preg_replace('#/{2,}#', '/', \str_replace('\\', '/', (string) $name));
236
- }
237
- protected function validateName($name)
238
- {
239
- if (\false !== \strpos($name, "\0")) {
240
- throw new \WCML\Twig\Error\LoaderError('A template name cannot contain NUL bytes.');
241
- }
242
- $name = \ltrim($name, '/');
243
- $parts = \explode('/', $name);
244
- $level = 0;
245
- foreach ($parts as $part) {
246
- if ('..' === $part) {
247
- --$level;
248
- } elseif ('.' !== $part) {
249
- ++$level;
250
- }
251
- if ($level < 0) {
252
- throw new \WCML\Twig\Error\LoaderError(\sprintf('Looks like you try to load a template outside configured directories (%s).', $name));
253
- }
254
- }
255
- }
256
- private function isAbsolutePath($file)
257
- {
258
- return \strspn($file, '/\\', 0, 1) || \strlen($file) > 3 && \ctype_alpha($file[0]) && ':' === \substr($file, 1, 1) && \strspn($file, '/\\', 2, 1) || null !== \parse_url($file, \PHP_URL_SCHEME);
259
- }
260
- }
261
- \class_alias('WCML\\Twig\\Loader\\FilesystemLoader', 'WCML\\Twig_Loader_Filesystem');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/twig/src/Loader/LoaderInterface.php DELETED
@@ -1,56 +0,0 @@
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
- namespace WCML\Twig\Loader;
12
-
13
- use WCML\Twig\Error\LoaderError;
14
- /**
15
- * Interface all loaders must implement.
16
- *
17
- * @author Fabien Potencier <fabien@symfony.com>
18
- */
19
- interface LoaderInterface
20
- {
21
- /**
22
- * Gets the source code of a template, given its name.
23
- *
24
- * @param string $name The name of the template to load
25
- *
26
- * @return string The template source code
27
- *
28
- * @throws LoaderError When $name is not found
29
- *
30
- * @deprecated since 1.27 (to be removed in 2.0), implement Twig\Loader\SourceContextLoaderInterface
31
- */
32
- public function getSource($name);
33
- /**
34
- * Gets the cache key to use for the cache for a given template name.
35
- *
36
- * @param string $name The name of the template to load
37
- *
38
- * @return string The cache key
39
- *
40
- * @throws LoaderError When $name is not found
41
- */
42
- public function getCacheKey($name);
43
- /**
44
- * Returns true if the template is still fresh.
45
- *
46
- * @param string $name The template name
47
- * @param int $time Timestamp of the last modification time of the
48
- * cached template
49
- *
50
- * @return bool true if the template is fresh, false otherwise
51
- *
52
- * @throws LoaderError When $name is not found
53
- */
54
- public function isFresh($name, $time);
55
- }
56
- \class_alias('WCML\\Twig\\Loader\\LoaderInterface', 'WCML\\Twig_LoaderInterface');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/twig/src/Loader/SourceContextLoaderInterface.php DELETED
@@ -1,35 +0,0 @@
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
- namespace WCML\Twig\Loader;
12
-
13
- use WCML\Twig\Error\LoaderError;
14
- use WCML\Twig\Source;
15
- /**
16
- * Adds a getSourceContext() method for loaders.
17
- *
18
- * @author Fabien Potencier <fabien@symfony.com>
19
- *
20
- * @deprecated since 1.27 (to be removed in 3.0)
21
- */
22
- interface SourceContextLoaderInterface
23
- {
24
- /**
25
- * Returns the source context for a given template logical name.
26
- *
27
- * @param string $name The template logical name
28
- *
29
- * @return Source
30
- *
31
- * @throws LoaderError When $name is not found
32
- */
33
- public function getSourceContext($name);
34
- }
35
- \class_alias('WCML\\Twig\\Loader\\SourceContextLoaderInterface', 'WCML\\Twig_SourceContextLoaderInterface');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/twig/src/Markup.php DELETED
@@ -1,36 +0,0 @@
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
- namespace WCML\Twig;
12
-
13
- /**
14
- * Marks a content as safe.
15
- *
16
- * @author Fabien Potencier <fabien@symfony.com>
17
- */
18
- class Markup implements \Countable
19
- {
20
- protected $content;
21
- protected $charset;
22
- public function __construct($content, $charset)
23
- {
24
- $this->content = (string) $content;
25
- $this->charset = $charset;
26
- }
27
- public function __toString()
28
- {
29
- return $this->content;
30
- }
31
- public function count()
32
- {
33
- return \function_exists('mb_get_info') ? \mb_strlen($this->content, $this->charset) : \strlen($this->content);
34
- }
35
- }
36
- \class_alias('WCML\\Twig\\Markup', 'WCML\\Twig_Markup');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/twig/src/Node/AutoEscapeNode.php DELETED
@@ -1,36 +0,0 @@
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
- namespace WCML\Twig\Node;
12
-
13
- use WCML\Twig\Compiler;
14
- /**
15
- * Represents an autoescape node.
16
- *
17
- * The value is the escaping strategy (can be html, js, ...)
18
- *
19
- * The true value is equivalent to html.
20
- *
21
- * If autoescaping is disabled, then the value is false.
22
- *
23
- * @author Fabien Potencier <fabien@symfony.com>
24
- */
25
- class AutoEscapeNode extends \WCML\Twig\Node\Node
26
- {
27
- public function __construct($value, \WCML\Twig_NodeInterface $body, $lineno, $tag = 'autoescape')
28
- {
29
- parent::__construct(['body' => $body], ['value' => $value], $lineno, $tag);
30
- }
31
- public function compile(\WCML\Twig\Compiler $compiler)
32
- {
33
- $compiler->subcompile($this->getNode('body'));
34
- }
35
- }
36
- \class_alias('WCML\\Twig\\Node\\AutoEscapeNode', 'WCML\\Twig_Node_AutoEscape');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/twig/src/Node/BlockNode.php DELETED
@@ -1,32 +0,0 @@
1
- <?php
2
-
3
- /*
4
- * This file is part of Twig.
5
- *
6
- * (c) Fabien Potencier
7
- * (c) Armin Ronacher
8
- *
9
- * For the full copyright and license information, please view the LICENSE
10
- * file that was distributed with this source code.
11
- */
12
- namespace WCML\Twig\Node;
13
-
14
- use WCML\Twig\Compiler;
15
- /**
16
- * Represents a block node.
17
- *
18
- * @author Fabien Potencier <fabien@symfony.com>
19
- */
20
- class BlockNode extends \WCML\Twig\Node\Node
21
- {
22
- public function __construct($name, \WCML\Twig_NodeInterface $body, $lineno, $tag = null)
23
- {
24
- parent::__construct(['body' => $body], ['name' => $name], $lineno, $tag);
25
- }
26
- public function compile(\WCML\Twig\Compiler $compiler)
27
- {
28
- $compiler->addDebugInfo($this)->write(\sprintf("public function block_%s(\$context, array \$blocks = [])\n", $this->getAttribute('name')), "{\n")->indent();
29
- $compiler->subcompile($this->getNode('body'))->outdent()->write("}\n\n");
30
- }
31
- }
32
- \class_alias('WCML\\Twig\\Node\\BlockNode', 'WCML\\Twig_Node_Block');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/twig/src/Node/BlockReferenceNode.php DELETED
@@ -1,31 +0,0 @@
1
- <?php
2
-
3
- /*
4
- * This file is part of Twig.
5
- *
6
- * (c) Fabien Potencier
7
- * (c) Armin Ronacher
8
- *
9
- * For the full copyright and license information, please view the LICENSE
10
- * file that was distributed with this source code.
11
- */
12
- namespace WCML\Twig\Node;
13
-
14
- use WCML\Twig\Compiler;
15
- /**
16
- * Represents a block call node.
17
- *
18
- * @author Fabien Potencier <fabien@symfony.com>
19
- */
20
- class BlockReferenceNode extends \WCML\Twig\Node\Node implements \WCML\Twig\Node\NodeOutputInterface
21
- {
22
- public function __construct($name, $lineno, $tag = null)
23
- {
24
- parent::__construct([], ['name' => $name], $lineno, $tag);
25
- }
26
- public function compile(\WCML\Twig\Compiler $compiler)
27
- {
28
- $compiler->addDebugInfo($this)->write(\sprintf("\$this->displayBlock('%s', \$context, \$blocks);\n", $this->getAttribute('name')));
29
- }
30
- }
31
- \class_alias('WCML\\Twig\\Node\\BlockReferenceNode', 'WCML\\Twig_Node_BlockReference');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/twig/src/Node/BodyNode.php DELETED
@@ -1,21 +0,0 @@
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
- namespace WCML\Twig\Node;
12
-
13
- /**
14
- * Represents a body node.
15
- *
16
- * @author Fabien Potencier <fabien@symfony.com>
17
- */
18
- class BodyNode extends \WCML\Twig\Node\Node
19
- {
20
- }
21
- \class_alias('WCML\\Twig\\Node\\BodyNode', 'WCML\\Twig_Node_Body');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/twig/src/Node/CheckSecurityNode.php DELETED
@@ -1,44 +0,0 @@
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
- namespace WCML\Twig\Node;
12
-
13
- use WCML\Twig\Compiler;
14
- /**
15
- * @author Fabien Potencier <fabien@symfony.com>
16
- */
17
- class CheckSecurityNode extends \WCML\Twig\Node\Node
18
- {
19
- protected $usedFilters;
20
- protected $usedTags;
21
- protected $usedFunctions;
22
- public function __construct(array $usedFilters, array $usedTags, array $usedFunctions)
23
- {
24
- $this->usedFilters = $usedFilters;
25
- $this->usedTags = $usedTags;
26
- $this->usedFunctions = $usedFunctions;
27
- parent::__construct();
28
- }
29
- public function compile(\WCML\Twig\Compiler $compiler)
30
- {
31
- $tags = $filters = $functions = [];
32
- foreach (['tags', 'filters', 'functions'] as $type) {
33
- foreach ($this->{'used' . \ucfirst($type)} as $name => $node) {
34
- if ($node instanceof \WCML\Twig\Node\Node) {
35
- ${$type}[$name] = $node->getTemplateLine();
36
- } else {
37
- ${$type}[$node] = null;
38
- }
39
- }
40
- }
41
- $compiler->write("\$this->sandbox = \$this->env->getExtension('\\WCML\\Twig\\Extension\\SandboxExtension');\n")->write('$tags = ')->repr(\array_filter($tags))->raw(";\n")->write('$filters = ')->repr(\array_filter($filters))->raw(";\n")->write('$functions = ')->repr(\array_filter($functions))->raw(";\n\n")->write("try {\n")->indent()->write("\$this->sandbox->checkSecurity(\n")->indent()->write(!$tags ? "[],\n" : "['" . \implode("', '", \array_keys($tags)) . "'],\n")->write(!$filters ? "[],\n" : "['" . \implode("', '", \array_keys($filters)) . "'],\n")->write(!$functions ? "[]\n" : "['" . \implode("', '", \array_keys($functions)) . "']\n")->outdent()->write(");\n")->outdent()->write("} catch (SecurityError \$e) {\n")->indent()->write("\$e->setSourceContext(\$this->getSourceContext());\n\n")->write("if (\$e instanceof SecurityNotAllowedTagError && isset(\$tags[\$e->getTagName()])) {\n")->indent()->write("\$e->setTemplateLine(\$tags[\$e->getTagName()]);\n")->outdent()->write("} elseif (\$e instanceof SecurityNotAllowedFilterError && isset(\$filters[\$e->getFilterName()])) {\n")->indent()->write("\$e->setTemplateLine(\$filters[\$e->getFilterName()]);\n")->outdent()->write("} elseif (\$e instanceof SecurityNotAllowedFunctionError && isset(\$functions[\$e->getFunctionName()])) {\n")->indent()->write("\$e->setTemplateLine(\$functions[\$e->getFunctionName()]);\n")->outdent()->write("}\n\n")->write("throw \$e;\n")->outdent()->write("}\n\n");
42
- }
43
- }
44
- \class_alias('WCML\\Twig\\Node\\CheckSecurityNode', 'WCML\\Twig_Node_CheckSecurity');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/twig/src/Node/CheckToStringNode.php DELETED
@@ -1,35 +0,0 @@
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
- namespace WCML\Twig\Node;
12
-
13
- use WCML\Twig\Compiler;
14
- use WCML\Twig\Node\Expression\AbstractExpression;
15
- /**
16
- * Checks if casting an expression to __toString() is allowed by the sandbox.
17
- *
18
- * For instance, when there is a simple Print statement, like {{ article }},
19
- * and if the sandbox is enabled, we need to check that the __toString()
20
- * method is allowed if 'article' is an object. The same goes for {{ article|upper }}
21
- * or {{ random(article) }}
22
- *
23
- * @author Fabien Potencier <fabien@symfony.com>
24
- */
25
- class CheckToStringNode extends \WCML\Twig\Node\Expression\AbstractExpression
26
- {
27
- public function __construct(\WCML\Twig\Node\Expression\AbstractExpression $expr)
28
- {
29
- parent::__construct(['expr' => $expr], [], $expr->getTemplateLine(), $expr->getNodeTag());
30
- }
31
- public function compile(\WCML\Twig\Compiler $compiler)
32
- {
33
- $compiler->raw('$this->sandbox->ensureToStringAllowed(')->subcompile($this->getNode('expr'))->raw(')');
34
- }
35
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/twig/src/Node/DeprecatedNode.php DELETED
@@ -1,40 +0,0 @@
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
- namespace WCML\Twig\Node;
12
-
13
- use WCML\Twig\Compiler;
14
- use WCML\Twig\Node\Expression\AbstractExpression;
15
- use WCML\Twig\Node\Expression\ConstantExpression;
16
- /**
17
- * Represents a deprecated node.
18
- *
19
- * @author Yonel Ceruto <yonelceruto@gmail.com>
20
- */
21
- class DeprecatedNode extends \WCML\Twig\Node\Node
22
- {
23
- public function __construct(\WCML\Twig\Node\Expression\AbstractExpression $expr, $lineno, $tag = null)
24
- {
25
- parent::__construct(['expr' => $expr], [], $lineno, $tag);
26
- }
27
- public function compile(\WCML\Twig\Compiler $compiler)
28
- {
29
- $compiler->addDebugInfo($this);
30
- $expr = $this->getNode('expr');
31
- if ($expr instanceof \WCML\Twig\Node\Expression\ConstantExpression) {
32
- $compiler->write('@trigger_error(')->subcompile($expr);
33
- } else {
34
- $varName = $compiler->getVarName();
35
- $compiler->write(\sprintf('$%s = ', $varName))->subcompile($expr)->raw(";\n")->write(\sprintf('@trigger_error($%s', $varName));
36
- }
37
- $compiler->raw('.')->string(\sprintf(' ("%s" at line %d).', $this->getTemplateName(), $this->getTemplateLine()))->raw(", E_USER_DEPRECATED);\n");
38
- }
39
- }
40
- \class_alias('WCML\\Twig\\Node\\DeprecatedNode', 'WCML\\Twig_Node_Deprecated');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/twig/src/Node/DoNode.php DELETED
@@ -1,31 +0,0 @@
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
- namespace WCML\Twig\Node;
12
-
13
- use WCML\Twig\Compiler;
14
- use WCML\Twig\Node\Expression\AbstractExpression;
15
- /**
16
- * Represents a do node.
17
- *
18
- * @author Fabien Potencier <fabien@symfony.com>
19
- */
20
- class DoNode extends \WCML\Twig\Node\Node
21
- {
22
- public function __construct(\WCML\Twig\Node\Expression\AbstractExpression $expr, $lineno, $tag = null)
23
- {
24
- parent::__construct(['expr' => $expr], [], $lineno, $tag);
25
- }
26
- public function compile(\WCML\Twig\Compiler $compiler)
27
- {
28
- $compiler->addDebugInfo($this)->write('')->subcompile($this->getNode('expr'))->raw(";\n");
29
- }
30
- }
31
- \class_alias('WCML\\Twig\\Node\\DoNode', 'WCML\\Twig_Node_Do');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/twig/src/Node/EmbedNode.php DELETED
@@ -1,37 +0,0 @@
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
- namespace WCML\Twig\Node;
12
-
13
- use WCML\Twig\Compiler;
14
- use WCML\Twig\Node\Expression\AbstractExpression;
15
- use WCML\Twig\Node\Expression\ConstantExpression;
16
- /**
17
- * Represents an embed node.
18
- *
19
- * @author Fabien Potencier <fabien@symfony.com>
20
- */
21
- class EmbedNode extends \WCML\Twig\Node\IncludeNode
22
- {
23
- // we don't inject the module to avoid node visitors to traverse it twice (as it will be already visited in the main module)
24
- public function __construct($name, $index, \WCML\Twig\Node\Expression\AbstractExpression $variables = null, $only = \false, $ignoreMissing = \false, $lineno, $tag = null)
25
- {
26
- parent::__construct(new \WCML\Twig\Node\Expression\ConstantExpression('not_used', $lineno), $variables, $only, $ignoreMissing, $lineno, $tag);
27
- $this->setAttribute('name', $name);
28
- // to be removed in 2.0, used name instead
29
- $this->setAttribute('filename', $name);
30
- $this->setAttribute('index', $index);
31
- }
32
- protected function addGetTemplate(\WCML\Twig\Compiler $compiler)
33
- {
34
- $compiler->write('$this->loadTemplate(')->string($this->getAttribute('name'))->raw(', ')->repr($this->getTemplateName())->raw(', ')->repr($this->getTemplateLine())->raw(', ')->string($this->getAttribute('index'))->raw(')');
35
- }
36
- }
37
- \class_alias('WCML\\Twig\\Node\\EmbedNode', 'WCML\\Twig_Node_Embed');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/twig/src/Node/Expression/AbstractExpression.php DELETED
@@ -1,23 +0,0 @@
1
- <?php
2
-
3
- /*
4
- * This file is part of Twig.
5
- *
6
- * (c) Fabien Potencier
7
- * (c) Armin Ronacher
8
- *
9
- * For the full copyright and license information, please view the LICENSE
10
- * file that was distributed with this source code.
11
- */
12
- namespace WCML\Twig\Node\Expression;
13
-
14
- use WCML\Twig\Node\Node;
15
- /**
16
- * Abstract class for all nodes that represents an expression.
17
- *
18
- * @author Fabien Potencier <fabien@symfony.com>
19
- */
20
- abstract class AbstractExpression extends \WCML\Twig\Node\Node
21
- {
22
- }
23
- \class_alias('WCML\\Twig\\Node\\Expression\\AbstractExpression', 'WCML\\Twig_Node_Expression');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/twig/src/Node/Expression/ArrayExpression.php DELETED
@@ -1,67 +0,0 @@
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
- namespace WCML\Twig\Node\Expression;
12
-
13
- use WCML\Twig\Compiler;
14
- class ArrayExpression extends \WCML\Twig\Node\Expression\AbstractExpression
15
- {
16
- protected $index;
17
- public function __construct(array $elements, $lineno)
18
- {
19
- parent::__construct($elements, [], $lineno);
20
- $this->index = -1;
21
- foreach ($this->getKeyValuePairs() as $pair) {
22
- if ($pair['key'] instanceof \WCML\Twig\Node\Expression\ConstantExpression && \ctype_digit((string) $pair['key']->getAttribute('value')) && $pair['key']->getAttribute('value') > $this->index) {
23
- $this->index = $pair['key']->getAttribute('value');
24
- }
25
- }
26
- }
27
- public function getKeyValuePairs()
28
- {
29
- $pairs = [];
30
- foreach (\array_chunk($this->nodes, 2) as $pair) {
31
- $pairs[] = ['key' => $pair[0], 'value' => $pair[1]];
32
- }
33
- return $pairs;
34
- }
35
- public function hasElement(\WCML\Twig\Node\Expression\AbstractExpression $key)
36
- {
37
- foreach ($this->getKeyValuePairs() as $pair) {
38
- // we compare the string representation of the keys
39
- // to avoid comparing the line numbers which are not relevant here.
40
- if ((string) $key === (string) $pair['key']) {
41
- return \true;
42
- }
43
- }
44
- return \false;
45
- }
46
- public function addElement(\WCML\Twig\Node\Expression\AbstractExpression $value, \WCML\Twig\Node\Expression\AbstractExpression $key = null)
47
- {
48
- if (null === $key) {
49
- $key = new \WCML\Twig\Node\Expression\ConstantExpression(++$this->index, $value->getTemplateLine());
50
- }
51
- \array_push($this->nodes, $key, $value);
52
- }
53
- public function compile(\WCML\Twig\Compiler $compiler)
54
- {
55
- $compiler->raw('[');
56
- $first = \true;
57
- foreach ($this->getKeyValuePairs() as $pair) {
58
- if (!$first) {
59
- $compiler->raw(', ');
60
- }
61
- $first = \false;
62
- $compiler->subcompile($pair['key'])->raw(' => ')->subcompile($pair['value']);
63
- }
64
- $compiler->raw(']');
65
- }
66
- }
67
- \class_alias('WCML\\Twig\\Node\\Expression\\ArrayExpression', 'WCML\\Twig_Node_Expression_Array');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/twig/src/Node/Expression/ArrowFunctionExpression.php DELETED
@@ -1,41 +0,0 @@
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
- namespace WCML\Twig\Node\Expression;
12
-
13
- use WCML\Twig\Compiler;
14
- use WCML\Twig\Node\Node;
15
- /**
16
- * Represents an arrow function.
17
- *
18
- * @author Fabien Potencier <fabien@symfony.com>
19
- */
20
- class ArrowFunctionExpression extends \WCML\Twig\Node\Expression\AbstractExpression
21
- {
22
- public function __construct(\WCML\Twig\Node\Expression\AbstractExpression $expr, \WCML\Twig\Node\Node $names, $lineno, $tag = null)
23
- {
24
- parent::__construct(['expr' => $expr, 'names' => $names], [], $lineno, $tag);
25
- }
26
- public function compile(\WCML\Twig\Compiler $compiler)
27
- {
28
- $compiler->addDebugInfo($this)->raw('function (');
29
- foreach ($this->getNode('names') as $i => $name) {
30
- if ($i) {
31
- $compiler->raw(', ');
32
- }
33
- $compiler->raw('$__')->raw($name->getAttribute('name'))->raw('__');
34
- }
35
- $compiler->raw(') use ($context) { ');
36
- foreach ($this->getNode('names') as $name) {
37
- $compiler->raw('$context["')->raw($name->getAttribute('name'))->raw('"] = $__')->raw($name->getAttribute('name'))->raw('__; ');
38
- }
39
- $compiler->raw('return ')->subcompile($this->getNode('expr'))->raw('; }');
40
- }
41
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/twig/src/Node/Expression/AssignNameExpression.php DELETED
@@ -1,22 +0,0 @@
1
- <?php
2
-
3
- /*
4
- * This file is part of Twig.
5
- *
6
- * (c) Fabien Potencier
7
- * (c) Armin Ronacher
8
- *
9
- * For the full copyright and license information, please view the LICENSE
10
- * file that was distributed with this source code.
11
- */
12
- namespace WCML\Twig\Node\Expression;
13
-
14
- use WCML\Twig\Compiler;
15
- class AssignNameExpression extends \WCML\Twig\Node\Expression\NameExpression
16
- {
17
- public function compile(\WCML\Twig\Compiler $compiler)
18
- {
19
- $compiler->raw('$context[')->string($this->getAttribute('name'))->raw(']');
20
- }
21
- }
22
- \class_alias('WCML\\Twig\\Node\\Expression\\AssignNameExpression', 'WCML\\Twig_Node_Expression_AssignName');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/twig/src/Node/Expression/Binary/AbstractBinary.php DELETED
@@ -1,30 +0,0 @@
1
- <?php
2
-
3
- /*
4
- * This file is part of Twig.
5
- *
6
- * (c) Fabien Potencier
7
- * (c) Armin Ronacher
8
- *
9
- * For the full copyright and license information, please view the LICENSE
10
- * file that was distributed with this source code.
11
- */
12
- namespace WCML\Twig\Node\Expression\Binary;
13
-
14
- use WCML\Twig\Compiler;
15
- use WCML\Twig\Node\Expression\AbstractExpression;
16
- abstract class AbstractBinary extends \WCML\Twig\Node\Expression\AbstractExpression
17
- {
18
- public function __construct(\WCML\Twig_NodeInterface $left, \WCML\Twig_NodeInterface $right, $lineno)
19
- {
20
- parent::__construct(['left' => $left, 'right' => $right], [], $lineno);
21
- }
22
- public function compile(\WCML\Twig\Compiler $compiler)
23
- {
24
- $compiler->raw('(')->subcompile($this->getNode('left'))->raw(' ');
25
- $this->operator($compiler);
26
- $compiler->raw(' ')->subcompile($this->getNode('right'))->raw(')');
27
- }
28
- public abstract function operator(\WCML\Twig\Compiler $compiler);
29
- }
30
- \class_alias('WCML\\Twig\\Node\\Expression\\Binary\\AbstractBinary', 'WCML\\Twig_Node_Expression_Binary');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/twig/src/Node/Expression/Binary/AddBinary.php DELETED
@@ -1,22 +0,0 @@
1
- <?php
2
-
3
- /*
4
- * This file is part of Twig.
5
- *
6
- * (c) Fabien Potencier
7
- * (c) Armin Ronacher
8
- *
9
- * For the full copyright and license information, please view the LICENSE
10
- * file that was distributed with this source code.
11
- */
12
- namespace WCML\Twig\Node\Expression\Binary;
13
-
14
- use WCML\Twig\Compiler;
15
- class AddBinary extends \WCML\Twig\Node\Expression\Binary\AbstractBinary
16
- {
17
- public function operator(\WCML\Twig\Compiler $compiler)
18
- {
19
- return $compiler->raw('+');
20
- }
21
- }
22
- \class_alias('WCML\\Twig\\Node\\Expression\\Binary\\AddBinary', 'WCML\\Twig_Node_Expression_Binary_Add');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/twig/src/Node/Expression/Binary/AndBinary.php DELETED
@@ -1,22 +0,0 @@
1
- <?php
2
-
3
- /*
4
- * This file is part of Twig.
5
- *
6
- * (c) Fabien Potencier
7
- * (c) Armin Ronacher
8
- *
9
- * For the full copyright and license information, please view the LICENSE
10
- * file that was distributed with this source code.
11
- */
12
- namespace WCML\Twig\Node\Expression\Binary;
13
-
14
- use WCML\Twig\Compiler;
15
- class AndBinary extends \WCML\Twig\Node\Expression\Binary\AbstractBinary
16
- {
17
- public function operator(\WCML\Twig\Compiler $compiler)
18
- {
19
- return $compiler->raw('&&');
20
- }
21
- }
22
- \class_alias('WCML\\Twig\\Node\\Expression\\Binary\\AndBinary', 'WCML\\Twig_Node_Expression_Binary_And');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/twig/src/Node/Expression/Binary/BitwiseAndBinary.php DELETED
@@ -1,22 +0,0 @@
1
- <?php
2
-
3
- /*
4
- * This file is part of Twig.
5
- *
6
- * (c) Fabien Potencier
7
- * (c) Armin Ronacher
8
- *
9
- * For the full copyright and license information, please view the LICENSE
10
- * file that was distributed with this source code.
11
- */
12
- namespace WCML\Twig\Node\Expression\Binary;
13
-
14
- use WCML\Twig\Compiler;
15
- class BitwiseAndBinary extends \WCML\Twig\Node\Expression\Binary\AbstractBinary
16
- {
17
- public function operator(\WCML\Twig\Compiler $compiler)
18
- {
19
- return $compiler->raw('&');
20
- }
21
- }
22
- \class_alias('WCML\\Twig\\Node\\Expression\\Binary\\BitwiseAndBinary', 'WCML\\Twig_Node_Expression_Binary_BitwiseAnd');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/twig/src/Node/Expression/Binary/BitwiseOrBinary.php DELETED
@@ -1,22 +0,0 @@
1
- <?php
2
-
3
- /*
4
- * This file is part of Twig.
5
- *
6
- * (c) Fabien Potencier
7
- * (c) Armin Ronacher
8
- *
9
- * For the full copyright and license information, please view the LICENSE
10
- * file that was distributed with this source code.
11
- */
12
- namespace WCML\Twig\Node\Expression\Binary;
13
-
14
- use WCML\Twig\Compiler;
15
- class BitwiseOrBinary extends \WCML\Twig\Node\Expression\Binary\AbstractBinary
16
- {
17
- public function operator(\WCML\Twig\Compiler $compiler)
18
- {
19
- return $compiler->raw('|');
20
- }
21
- }
22
- \class_alias('WCML\\Twig\\Node\\Expression\\Binary\\BitwiseOrBinary', 'WCML\\Twig_Node_Expression_Binary_BitwiseOr');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/twig/src/Node/Expression/Binary/BitwiseXorBinary.php DELETED
@@ -1,22 +0,0 @@
1
- <?php
2
-
3
- /*
4
- * This file is part of Twig.
5
- *
6
- * (c) Fabien Potencier
7
- * (c) Armin Ronacher
8
- *
9
- * For the full copyright and license information, please view the LICENSE
10
- * file that was distributed with this source code.
11
- */
12
- namespace WCML\Twig\Node\Expression\Binary;
13
-
14
- use WCML\Twig\Compiler;
15
- class BitwiseXorBinary extends \WCML\Twig\Node\Expression\Binary\AbstractBinary
16
- {
17
- public function operator(\WCML\Twig\Compiler $compiler)
18
- {
19
- return $compiler->raw('^');
20
- }
21
- }
22
- \class_alias('WCML\\Twig\\Node\\Expression\\Binary\\BitwiseXorBinary', 'WCML\\Twig_Node_Expression_Binary_BitwiseXor');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/twig/src/Node/Expression/Binary/ConcatBinary.php DELETED
@@ -1,22 +0,0 @@
1
- <?php
2
-
3
- /*
4
- * This file is part of Twig.
5
- *
6
- * (c) Fabien Potencier
7
- * (c) Armin Ronacher
8
- *
9
- * For the full copyright and license information, please view the LICENSE
10
- * file that was distributed with this source code.
11
- */
12
- namespace WCML\Twig\Node\Expression\Binary;
13
-
14
- use WCML\Twig\Compiler;
15
- class ConcatBinary extends \WCML\Twig\Node\Expression\Binary\AbstractBinary
16
- {
17
- public function operator(\WCML\Twig\Compiler $compiler)
18
- {
19
- return $compiler->raw('.');
20
- }
21
- }
22
- \class_alias('WCML\\Twig\\Node\\Expression\\Binary\\ConcatBinary', 'WCML\\Twig_Node_Expression_Binary_Concat');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/twig/src/Node/Expression/Binary/DivBinary.php DELETED
@@ -1,22 +0,0 @@
1
- <?php
2
-
3
- /*
4
- * This file is part of Twig.
5
- *
6
- * (c) Fabien Potencier
7
- * (c) Armin Ronacher
8
- *
9
- * For the full copyright and license information, please view the LICENSE
10
- * file that was distributed with this source code.
11
- */
12
- namespace WCML\Twig\Node\Expression\Binary;
13
-
14
- use WCML\Twig\Compiler;
15
- class DivBinary extends \WCML\Twig\Node\Expression\Binary\AbstractBinary
16
- {
17
- public function operator(\WCML\Twig\Compiler $compiler)
18
- {
19
- return $compiler->raw('/');
20
- }
21
- }
22
- \class_alias('WCML\\Twig\\Node\\Expression\\Binary\\DivBinary', 'WCML\\Twig_Node_Expression_Binary_Div');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/twig/src/Node/Expression/Binary/EndsWithBinary.php DELETED
@@ -1,27 +0,0 @@
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
- namespace WCML\Twig\Node\Expression\Binary;
12
-
13
- use WCML\Twig\Compiler;
14
- class EndsWithBinary extends \WCML\Twig\Node\Expression\Binary\AbstractBinary
15
- {
16
- public function compile(\WCML\Twig\Compiler $compiler)
17
- {
18
- $left = $compiler->getVarName();
19
- $right = $compiler->getVarName();
20
- $compiler->raw(\sprintf('(is_string($%s = ', $left))->subcompile($this->getNode('left'))->raw(\sprintf(') && is_string($%s = ', $right))->subcompile($this->getNode('right'))->raw(\sprintf(') && (\'\' === $%2$s || $%2$s === substr($%1$s, -strlen($%2$s))))', $left, $right));
21
- }
22
- public function operator(\WCML\Twig\Compiler $compiler)
23
- {
24
- return $compiler->raw('');
25
- }
26
- }
27
- \class_alias('WCML\\Twig\\Node\\Expression\\Binary\\EndsWithBinary', 'WCML\\Twig_Node_Expression_Binary_EndsWith');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/twig/src/Node/Expression/Binary/EqualBinary.php DELETED
@@ -1,21 +0,0 @@
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
- namespace WCML\Twig\Node\Expression\Binary;
12
-
13
- use WCML\Twig\Compiler;
14
- class EqualBinary extends \WCML\Twig\Node\Expression\Binary\AbstractBinary
15
- {
16
- public function operator(\WCML\Twig\Compiler $compiler)
17
- {
18
- return $compiler->raw('==');
19
- }
20
- }
21
- \class_alias('WCML\\Twig\\Node\\Expression\\Binary\\EqualBinary', 'WCML\\Twig_Node_Expression_Binary_Equal');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/twig/src/Node/Expression/Binary/FloorDivBinary.php DELETED
@@ -1,27 +0,0 @@
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
- namespace WCML\Twig\Node\Expression\Binary;
12
-
13
- use WCML\Twig\Compiler;
14
- class FloorDivBinary extends \WCML\Twig\Node\Expression\Binary\AbstractBinary
15
- {
16
- public function compile(\WCML\Twig\Compiler $compiler)
17
- {
18
- $compiler->raw('(int) floor(');
19
- parent::compile($compiler);
20
- $compiler->raw(')');
21
- }
22
- public function operator(\WCML\Twig\Compiler $compiler)
23
- {
24
- return $compiler->raw('/');
25
- }
26
- }
27
- \class_alias('WCML\\Twig\\Node\\Expression\\Binary\\FloorDivBinary', 'WCML\\Twig_Node_Expression_Binary_FloorDiv');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/twig/src/Node/Expression/Binary/GreaterBinary.php DELETED
@@ -1,21 +0,0 @@
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
- namespace WCML\Twig\Node\Expression\Binary;
12
-
13
- use WCML\Twig\Compiler;
14
- class GreaterBinary extends \WCML\Twig\Node\Expression\Binary\AbstractBinary
15
- {
16
- public function operator(\WCML\Twig\Compiler $compiler)
17
- {
18
- return $compiler->raw('>');
19
- }
20
- }
21
- \class_alias('WCML\\Twig\\Node\\Expression\\Binary\\GreaterBinary', 'WCML\\Twig_Node_Expression_Binary_Greater');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/twig/src/Node/Expression/Binary/GreaterEqualBinary.php DELETED
@@ -1,21 +0,0 @@
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
- namespace WCML\Twig\Node\Expression\Binary;
12
-
13
- use WCML\Twig\Compiler;
14
- class GreaterEqualBinary extends \WCML\Twig\Node\Expression\Binary\AbstractBinary
15
- {
16
- public function operator(\WCML\Twig\Compiler $compiler)
17
- {
18
- return $compiler->raw('>=');
19
- }
20
- }
21
- \class_alias('WCML\\Twig\\Node\\Expression\\Binary\\GreaterEqualBinary', 'WCML\\Twig_Node_Expression_Binary_GreaterEqual');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/twig/src/Node/Expression/Binary/InBinary.php DELETED
@@ -1,25 +0,0 @@
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
- namespace WCML\Twig\Node\Expression\Binary;
12
-
13
- use WCML\Twig\Compiler;
14
- class InBinary extends \WCML\Twig\Node\Expression\Binary\AbstractBinary
15
- {
16
- public function compile(\WCML\Twig\Compiler $compiler)
17
- {
18
- $compiler->raw('twig_in_filter(')->subcompile($this->getNode('left'))->raw(', ')->subcompile($this->getNode('right'))->raw(')');
19
- }
20
- public function operator(\WCML\Twig\Compiler $compiler)
21
- {
22
- return $compiler->raw('in');
23
- }
24
- }
25
- \class_alias('WCML\\Twig\\Node\\Expression\\Binary\\InBinary', 'WCML\\Twig_Node_Expression_Binary_In');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/twig/src/Node/Expression/Binary/LessBinary.php DELETED
@@ -1,21 +0,0 @@
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
- namespace WCML\Twig\Node\Expression\Binary;
12
-
13
- use WCML\Twig\Compiler;
14
- class LessBinary extends \WCML\Twig\Node\Expression\Binary\AbstractBinary
15
- {
16
- public function operator(\WCML\Twig\Compiler $compiler)
17
- {
18
- return $compiler->raw('<');
19
- }
20
- }
21
- \class_alias('WCML\\Twig\\Node\\Expression\\Binary\\LessBinary', 'WCML\\Twig_Node_Expression_Binary_Less');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/twig/src/Node/Expression/Binary/LessEqualBinary.php DELETED
@@ -1,21 +0,0 @@
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
- namespace WCML\Twig\Node\Expression\Binary;
12
-
13
- use WCML\Twig\Compiler;
14
- class LessEqualBinary extends \WCML\Twig\Node\Expression\Binary\AbstractBinary
15
- {
16
- public function operator(\WCML\Twig\Compiler $compiler)
17
- {
18
- return $compiler->raw('<=');
19
- }
20
- }
21
- \class_alias('WCML\\Twig\\Node\\Expression\\Binary\\LessEqualBinary', 'WCML\\Twig_Node_Expression_Binary_LessEqual');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/twig/src/Node/Expression/Binary/MatchesBinary.php DELETED
@@ -1,25 +0,0 @@
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
- namespace WCML\Twig\Node\Expression\Binary;
12
-
13
- use WCML\Twig\Compiler;
14
- class MatchesBinary extends \WCML\Twig\Node\Expression\Binary\AbstractBinary
15
- {
16
- public function compile(\WCML\Twig\Compiler $compiler)
17
- {
18
- $compiler->raw('preg_match(')->subcompile($this->getNode('right'))->raw(', ')->subcompile($this->getNode('left'))->raw(')');
19
- }
20
- public function operator(\WCML\Twig\Compiler $compiler)
21
- {
22
- return $compiler->raw('');
23
- }
24
- }
25
- \class_alias('WCML\\Twig\\Node\\Expression\\Binary\\MatchesBinary', 'WCML\\Twig_Node_Expression_Binary_Matches');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/twig/src/Node/Expression/Binary/ModBinary.php DELETED
@@ -1,22 +0,0 @@
1
- <?php
2
-
3
- /*
4
- * This file is part of Twig.
5
- *
6
- * (c) Fabien Potencier
7
- * (c) Armin Ronacher
8
- *
9
- * For the full copyright and license information, please view the LICENSE
10
- * file that was distributed with this source code.
11
- */
12
- namespace WCML\Twig\Node\Expression\Binary;
13
-
14
- use WCML\Twig\Compiler;
15
- class ModBinary extends \WCML\Twig\Node\Expression\Binary\AbstractBinary
16
- {
17
- public function operator(\WCML\Twig\Compiler $compiler)
18
- {
19
- return $compiler->raw('%');
20
- }
21
- }
22
- \class_alias('WCML\\Twig\\Node\\Expression\\Binary\\ModBinary', 'WCML\\Twig_Node_Expression_Binary_Mod');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/twig/src/Node/Expression/Binary/MulBinary.php DELETED
@@ -1,22 +0,0 @@
1
- <?php
2
-
3
- /*
4
- * This file is part of Twig.
5
- *
6
- * (c) Fabien Potencier
7
- * (c) Armin Ronacher
8
- *
9
- * For the full copyright and license information, please view the LICENSE
10
- * file that was distributed with this source code.
11
- */
12
- namespace WCML\Twig\Node\Expression\Binary;
13
-
14
- use WCML\Twig\Compiler;
15
- class MulBinary extends \WCML\Twig\Node\Expression\Binary\AbstractBinary
16
- {
17
- public function operator(\WCML\Twig\Compiler $compiler)
18
- {
19
- return $compiler->raw('*');
20
- }
21
- }
22
- \class_alias('WCML\\Twig\\Node\\Expression\\Binary\\MulBinary', 'WCML\\Twig_Node_Expression_Binary_Mul');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/twig/src/Node/Expression/Binary/NotEqualBinary.php DELETED
@@ -1,21 +0,0 @@
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
- namespace WCML\Twig\Node\Expression\Binary;
12
-
13
- use WCML\Twig\Compiler;
14
- class NotEqualBinary extends \WCML\Twig\Node\Expression\Binary\AbstractBinary
15
- {
16
- public function operator(\WCML\Twig\Compiler $compiler)
17
- {
18
- return $compiler->raw('!=');
19
- }
20
- }
21
- \class_alias('WCML\\Twig\\Node\\Expression\\Binary\\NotEqualBinary', 'WCML\\Twig_Node_Expression_Binary_NotEqual');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/twig/src/Node/Expression/Binary/NotInBinary.php DELETED
@@ -1,25 +0,0 @@
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
- namespace WCML\Twig\Node\Expression\Binary;
12
-
13
- use WCML\Twig\Compiler;
14
- class NotInBinary extends \WCML\Twig\Node\Expression\Binary\AbstractBinary
15
- {
16
- public function compile(\WCML\Twig\Compiler $compiler)
17
- {
18
- $compiler->raw('!twig_in_filter(')->subcompile($this->getNode('left'))->raw(', ')->subcompile($this->getNode('right'))->raw(')');
19
- }
20
- public function operator(\WCML\Twig\Compiler $compiler)
21
- {
22
- return $compiler->raw('not in');
23
- }
24
- }
25
- \class_alias('WCML\\Twig\\Node\\Expression\\Binary\\NotInBinary', 'WCML\\Twig_Node_Expression_Binary_NotIn');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/twig/src/Node/Expression/Binary/OrBinary.php DELETED
@@ -1,22 +0,0 @@
1
- <?php
2
-
3
- /*
4
- * This file is part of Twig.
5
- *
6
- * (c) Fabien Potencier
7
- * (c) Armin Ronacher
8
- *
9
- * For the full copyright and license information, please view the LICENSE
10
- * file that was distributed with this source code.
11
- */
12
- namespace WCML\Twig\Node\Expression\Binary;
13
-
14
- use WCML\Twig\Compiler;
15
- class OrBinary extends \WCML\Twig\Node\Expression\Binary\AbstractBinary
16
- {
17
- public function operator(\WCML\Twig\Compiler $compiler)
18
- {
19
- return $compiler->raw('||');
20
- }
21
- }
22
- \class_alias('WCML\\Twig\\Node\\Expression\\Binary\\OrBinary', 'WCML\\Twig_Node_Expression_Binary_Or');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/twig/src/Node/Expression/Binary/PowerBinary.php DELETED
@@ -1,28 +0,0 @@
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
- namespace WCML\Twig\Node\Expression\Binary;
12
-
13
- use WCML\Twig\Compiler;
14
- class PowerBinary extends \WCML\Twig\Node\Expression\Binary\AbstractBinary
15
- {
16
- public function compile(\WCML\Twig\Compiler $compiler)
17
- {
18
- if (\PHP_VERSION_ID >= 50600) {
19
- return parent::compile($compiler);
20
- }
21
- $compiler->raw('pow(')->subcompile($this->getNode('left'))->raw(', ')->subcompile($this->getNode('right'))->raw(')');
22
- }
23
- public function operator(\WCML\Twig\Compiler $compiler)
24
- {
25
- return $compiler->raw('**');
26
- }
27
- }
28
- \class_alias('WCML\\Twig\\Node\\Expression\\Binary\\PowerBinary', 'WCML\\Twig_Node_Expression_Binary_Power');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/twig/src/Node/Expression/Binary/RangeBinary.php DELETED
@@ -1,25 +0,0 @@
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
- namespace WCML\Twig\Node\Expression\Binary;
12
-
13
- use WCML\Twig\Compiler;
14
- class RangeBinary extends \WCML\Twig\Node\Expression\Binary\AbstractBinary
15
- {
16
- public function compile(\WCML\Twig\Compiler $compiler)
17
- {
18
- $compiler->raw('range(')->subcompile($this->getNode('left'))->raw(', ')->subcompile($this->getNode('right'))->raw(')');
19
- }
20
- public function operator(\WCML\Twig\Compiler $compiler)
21
- {
22
- return $compiler->raw('..');
23
- }
24
- }
25
- \class_alias('WCML\\Twig\\Node\\Expression\\Binary\\RangeBinary', 'WCML\\Twig_Node_Expression_Binary_Range');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/twig/src/Node/Expression/Binary/StartsWithBinary.php DELETED
@@ -1,27 +0,0 @@
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
- namespace WCML\Twig\Node\Expression\Binary;
12
-
13
- use WCML\Twig\Compiler;
14
- class StartsWithBinary extends \WCML\Twig\Node\Expression\Binary\AbstractBinary
15
- {
16
- public function compile(\WCML\Twig\Compiler $compiler)
17
- {
18
- $left = $compiler->getVarName();
19
- $right = $compiler->getVarName();
20
- $compiler->raw(\sprintf('(is_string($%s = ', $left))->subcompile($this->getNode('left'))->raw(\sprintf(') && is_string($%s = ', $right))->subcompile($this->getNode('right'))->raw(\sprintf(') && (\'\' === $%2$s || 0 === strpos($%1$s, $%2$s)))', $left, $right));
21
- }
22
- public function operator(\WCML\Twig\Compiler $compiler)
23
- {
24
- return $compiler->raw('');
25
- }
26
- }
27
- \class_alias('WCML\\Twig\\Node\\Expression\\Binary\\StartsWithBinary', 'WCML\\Twig_Node_Expression_Binary_StartsWith');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/twig/src/Node/Expression/Binary/SubBinary.php DELETED
@@ -1,22 +0,0 @@
1
- <?php
2
-
3
- /*
4
- * This file is part of Twig.
5
- *
6
- * (c) Fabien Potencier
7
- * (c) Armin Ronacher
8
- *
9
- * For the full copyright and license information, please view the LICENSE
10
- * file that was distributed with this source code.
11
- */
12
- namespace WCML\Twig\Node\Expression\Binary;
13
-
14
- use WCML\Twig\Compiler;
15
- class SubBinary extends \WCML\Twig\Node\Expression\Binary\AbstractBinary
16
- {
17
- public function operator(\WCML\Twig\Compiler $compiler)
18
- {
19
- return $compiler->raw('-');
20
- }
21
- }
22
- \class_alias('WCML\\Twig\\Node\\Expression\\Binary\\SubBinary', 'WCML\\Twig_Node_Expression_Binary_Sub');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/twig/src/Node/Expression/BlockReferenceExpression.php DELETED
@@ -1,71 +0,0 @@
1
- <?php
2
-
3
- /*
4
- * This file is part of Twig.
5
- *
6
- * (c) Fabien Potencier
7
- * (c) Armin Ronacher
8
- *
9
- * For the full copyright and license information, please view the LICENSE
10
- * file that was distributed with this source code.
11
- */
12
- namespace WCML\Twig\Node\Expression;
13
-
14
- use WCML\Twig\Compiler;
15
- use WCML\Twig\Node\Node;
16
- /**
17
- * Represents a block call node.
18
- *
19
- * @author Fabien Potencier <fabien@symfony.com>
20
- */
21
- class BlockReferenceExpression extends \WCML\Twig\Node\Expression\AbstractExpression
22
- {
23
- /**
24
- * @param Node|null $template
25
- */
26
- public function __construct(\WCML\Twig_NodeInterface $name, $template = null, $lineno, $tag = null)
27
- {
28
- if (\is_bool($template)) {
29
- @\trigger_error(\sprintf('The %s method "$asString" argument is deprecated since version 1.28 and will be removed in 2.0.', __METHOD__), \E_USER_DEPRECATED);
30
- $template = null;
31
- }
32
- $nodes = ['name' => $name];
33
- if (null !== $template) {
34
- $nodes['template'] = $template;
35
- }
36
- parent::__construct($nodes, ['is_defined_test' => \false, 'output' => \false], $lineno, $tag);
37
- }
38
- public function compile(\WCML\Twig\Compiler $compiler)
39
- {
40
- if ($this->getAttribute('is_defined_test')) {
41
- $this->compileTemplateCall($compiler, 'hasBlock');
42
- } else {
43
- if ($this->getAttribute('output')) {
44
- $compiler->addDebugInfo($this);
45
- $this->compileTemplateCall($compiler, 'displayBlock')->raw(";\n");
46
- } else {
47
- $this->compileTemplateCall($compiler, 'renderBlock');
48
- }
49
- }
50
- }
51
- private function compileTemplateCall(\WCML\Twig\Compiler $compiler, $method)
52
- {
53
- if (!$this->hasNode('template')) {
54
- $compiler->write('$this');
55
- } else {
56
- $compiler->write('$this->loadTemplate(')->subcompile($this->getNode('template'))->raw(', ')->repr($this->getTemplateName())->raw(', ')->repr($this->getTemplateLine())->raw(')');
57
- }
58
- $compiler->raw(\sprintf('->%s', $method));
59
- $this->compileBlockArguments($compiler);
60
- return $compiler;
61
- }
62
- private function compileBlockArguments(\WCML\Twig\Compiler $compiler)
63
- {
64
- $compiler->raw('(')->subcompile($this->getNode('name'))->raw(', $context');
65
- if (!$this->hasNode('template')) {
66
- $compiler->raw(', $blocks');
67
- }
68
- return $compiler->raw(')');
69
- }
70
- }
71
- \class_alias('WCML\\Twig\\Node\\Expression\\BlockReferenceExpression', 'WCML\\Twig_Node_Expression_BlockReference');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/twig/src/Node/Expression/CallExpression.php DELETED
@@ -1,256 +0,0 @@
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
- namespace WCML\Twig\Node\Expression;
12
-
13
- use WCML\Twig\Compiler;
14
- use WCML\Twig\Error\SyntaxError;
15
- use WCML\Twig\Extension\ExtensionInterface;
16
- use WCML\Twig\Node\Node;
17
- abstract class CallExpression extends \WCML\Twig\Node\Expression\AbstractExpression
18
- {
19
- private $reflector;
20
- protected function compileCallable(\WCML\Twig\Compiler $compiler)
21
- {
22
- $closingParenthesis = \false;
23
- $isArray = \false;
24
- if ($this->hasAttribute('callable') && ($callable = $this->getAttribute('callable'))) {
25
- if (\is_string($callable) && \false === \strpos($callable, '::')) {
26
- $compiler->raw($callable);
27
- } else {
28
- list($r, $callable) = $this->reflectCallable($callable);
29
- if ($r instanceof \ReflectionMethod && \is_string($callable[0])) {
30
- if ($r->isStatic()) {
31
- $compiler->raw(\sprintf('%s::%s', $callable[0], $callable[1]));
32
- } else {
33
- $compiler->raw(\sprintf('$this->env->getRuntime(\'%s\')->%s', $callable[0], $callable[1]));
34
- }
35
- } elseif ($r instanceof \ReflectionMethod && $callable[0] instanceof \WCML\Twig\Extension\ExtensionInterface) {
36
- $compiler->raw(\sprintf('$this->env->getExtension(\'%s\')->%s', \get_class($callable[0]), $callable[1]));
37
- } else {
38
- $type = \ucfirst($this->getAttribute('type'));
39
- $compiler->raw(\sprintf('call_user_func_array($this->env->get%s(\'%s\')->getCallable(), ', $type, $this->getAttribute('name')));
40
- $closingParenthesis = \true;
41
- $isArray = \true;
42
- }
43
- }
44
- } else {
45
- $compiler->raw($this->getAttribute('thing')->compile());
46
- }
47
- $this->compileArguments($compiler, $isArray);
48
- if ($closingParenthesis) {
49
- $compiler->raw(')');
50
- }
51
- }
52
- protected function compileArguments(\WCML\Twig\Compiler $compiler, $isArray = \false)
53
- {
54
- $compiler->raw($isArray ? '[' : '(');
55
- $first = \true;
56
- if ($this->hasAttribute('needs_environment') && $this->getAttribute('needs_environment')) {
57
- $compiler->raw('$this->env');
58
- $first = \false;
59
- }
60
- if ($this->hasAttribute('needs_context') && $this->getAttribute('needs_context')) {
61
- if (!$first) {
62
- $compiler->raw(', ');
63
- }
64
- $compiler->raw('$context');
65
- $first = \false;
66
- }
67
- if ($this->hasAttribute('arguments')) {
68
- foreach ($this->getAttribute('arguments') as $argument) {
69
- if (!$first) {
70
- $compiler->raw(', ');
71
- }
72
- $compiler->string($argument);
73
- $first = \false;
74
- }
75
- }
76
- if ($this->hasNode('node')) {
77
- if (!$first) {
78
- $compiler->raw(', ');
79
- }
80
- $compiler->subcompile($this->getNode('node'));
81
- $first = \false;
82
- }
83
- if ($this->hasNode('arguments')) {
84
- $callable = $this->hasAttribute('callable') ? $this->getAttribute('callable') : null;
85
- $arguments = $this->getArguments($callable, $this->getNode('arguments'));
86
- foreach ($arguments as $node) {
87
- if (!$first) {
88
- $compiler->raw(', ');
89
- }
90
- $compiler->subcompile($node);
91
- $first = \false;
92
- }
93
- }
94
- $compiler->raw($isArray ? ']' : ')');
95
- }
96
- protected function getArguments($callable, $arguments)
97
- {
98
- $callType = $this->getAttribute('type');
99
- $callName = $this->getAttribute('name');
100
- $parameters = [];
101
- $named = \false;
102
- foreach ($arguments as $name => $node) {
103
- if (!\is_int($name)) {
104
- $named = \true;
105
- $name = $this->normalizeName($name);
106
- } elseif ($named) {
107
- throw new \WCML\Twig\Error\SyntaxError(\sprintf('Positional arguments cannot be used after named arguments for %s "%s".', $callType, $callName), $this->getTemplateLine(), $this->getSourceContext());
108
- }
109
- $parameters[$name] = $node;
110
- }
111
- $isVariadic = $this->hasAttribute('is_variadic') && $this->getAttribute('is_variadic');
112
- if (!$named && !$isVariadic) {
113
- return $parameters;
114
- }
115
- if (!$callable) {
116
- if ($named) {
117
- $message = \sprintf('Named arguments are not supported for %s "%s".', $callType, $callName);
118
- } else {
119
- $message = \sprintf('Arbitrary positional arguments are not supported for %s "%s".', $callType, $callName);
120
- }
121
- throw new \LogicException($message);
122
- }
123
- $callableParameters = $this->getCallableParameters($callable, $isVariadic);
124
- $arguments = [];
125
- $names = [];
126
- $missingArguments = [];
127
- $optionalArguments = [];
128
- $pos = 0;
129
- foreach ($callableParameters as $callableParameter) {
130
- $names[] = $name = $this->normalizeName($callableParameter->name);
131
- if (\array_key_exists($name, $parameters)) {
132
- if (\array_key_exists($pos, $parameters)) {
133
- throw new \WCML\Twig\Error\SyntaxError(\sprintf('Argument "%s" is defined twice for %s "%s".', $name, $callType, $callName), $this->getTemplateLine(), $this->getSourceContext());
134
- }
135
- if (\count($missingArguments)) {
136
- throw new \WCML\Twig\Error\SyntaxError(\sprintf('Argument "%s" could not be assigned for %s "%s(%s)" because it is mapped to an internal PHP function which cannot determine default value for optional argument%s "%s".', $name, $callType, $callName, \implode(', ', $names), \count($missingArguments) > 1 ? 's' : '', \implode('", "', $missingArguments)), $this->getTemplateLine(), $this->getSourceContext());
137
- }
138
- $arguments = \array_merge($arguments, $optionalArguments);
139
- $arguments[] = $parameters[$name];
140
- unset($parameters[$name]);
141
- $optionalArguments = [];
142
- } elseif (\array_key_exists($pos, $parameters)) {
143
- $arguments = \array_merge($arguments, $optionalArguments);
144
- $arguments[] = $parameters[$pos];
145
- unset($parameters[$pos]);
146
- $optionalArguments = [];
147
- ++$pos;
148
- } elseif ($callableParameter->isDefaultValueAvailable()) {
149
- $optionalArguments[] = new \WCML\Twig\Node\Expression\ConstantExpression($callableParameter->getDefaultValue(), -1);
150
- } elseif ($callableParameter->isOptional()) {
151
- if (empty($parameters)) {
152
- break;
153
- } else {
154
- $missingArguments[] = $name;
155
- }
156
- } else {
157
- throw new \WCML\Twig\Error\SyntaxError(\sprintf('Value for argument "%s" is required for %s "%s".', $name, $callType, $callName), $this->getTemplateLine(), $this->getSourceContext());
158
- }
159
- }
160
- if ($isVariadic) {
161
- $arbitraryArguments = new \WCML\Twig\Node\Expression\ArrayExpression([], -1);
162
- foreach ($parameters as $key => $value) {
163
- if (\is_int($key)) {
164
- $arbitraryArguments->addElement($value);
165
- } else {
166
- $arbitraryArguments->addElement($value, new \WCML\Twig\Node\Expression\ConstantExpression($key, -1));
167
- }
168
- unset($parameters[$key]);
169
- }
170
- if ($arbitraryArguments->count()) {
171
- $arguments = \array_merge($arguments, $optionalArguments);
172
- $arguments[] = $arbitraryArguments;
173
- }
174
- }
175
- if (!empty($parameters)) {
176
- $unknownParameter = null;
177
- foreach ($parameters as $parameter) {
178
- if ($parameter instanceof \WCML\Twig\Node\Node) {
179
- $unknownParameter = $parameter;
180
- break;
181
- }
182
- }
183
- throw new \WCML\Twig\Error\SyntaxError(\sprintf('Unknown argument%s "%s" for %s "%s(%s)".', \count($parameters) > 1 ? 's' : '', \implode('", "', \array_keys($parameters)), $callType, $callName, \implode(', ', $names)), $unknownParameter ? $unknownParameter->getTemplateLine() : $this->getTemplateLine(), $unknownParameter ? $unknownParameter->getSourceContext() : $this->getSourceContext());
184
- }
185
- return $arguments;
186
- }
187
- protected function normalizeName($name)
188
- {
189
- return \strtolower(\preg_replace(['/([A-Z]+)([A-Z][a-z])/', '/([a-z\\d])([A-Z])/'], ['\\1_\\2', '\\1_\\2'], $name));
190
- }
191
- private function getCallableParameters($callable, $isVariadic)
192
- {
193
- list($r) = $this->reflectCallable($callable);
194
- if (null === $r) {
195
- return [];
196
- }
197
- $parameters = $r->getParameters();
198
- if ($this->hasNode('node')) {
199
- \array_shift($parameters);
200
- }
201
- if ($this->hasAttribute('needs_environment') && $this->getAttribute('needs_environment')) {
202
- \array_shift($parameters);
203
- }
204
- if ($this->hasAttribute('needs_context') && $this->getAttribute('needs_context')) {
205
- \array_shift($parameters);
206
- }
207
- if ($this->hasAttribute('arguments') && null !== $this->getAttribute('arguments')) {
208
- foreach ($this->getAttribute('arguments') as $argument) {
209
- \array_shift($parameters);
210
- }
211
- }
212
- if ($isVariadic) {
213
- $argument = \end($parameters);
214
- if ($argument && $argument->isArray() && $argument->isDefaultValueAvailable() && [] === $argument->getDefaultValue()) {
215
- \array_pop($parameters);
216
- } else {
217
- $callableName = $r->name;
218
- if ($r instanceof \ReflectionMethod) {
219
- $callableName = $r->getDeclaringClass()->name . '::' . $callableName;
220
- }
221
- throw new \LogicException(\sprintf('The last parameter of "%s" for %s "%s" must be an array with default value, eg. "array $arg = []".', $callableName, $this->getAttribute('type'), $this->getAttribute('name')));
222
- }
223
- }
224
- return $parameters;
225
- }
226
- private function reflectCallable($callable)
227
- {
228
- if (null !== $this->reflector) {
229
- return $this->reflector;
230
- }
231
- if (\is_array($callable)) {
232
- if (!\method_exists($callable[0], $callable[1])) {
233
- // __call()
234
- return [null, []];
235
- }
236
- $r = new \ReflectionMethod($callable[0], $callable[1]);
237
- } elseif (\is_object($callable) && !$callable instanceof \Closure) {
238
- $r = new \ReflectionObject($callable);
239
- $r = $r->getMethod('__invoke');
240
- $callable = [$callable, '__invoke'];
241
- } elseif (\is_string($callable) && \false !== ($pos = \strpos($callable, '::'))) {
242
- $class = \substr($callable, 0, $pos);
243
- $method = \substr($callable, $pos + 2);
244
- if (!\method_exists($class, $method)) {
245
- // __staticCall()
246
- return [null, []];
247
- }
248
- $r = new \ReflectionMethod($callable);
249
- $callable = [$class, $method];
250
- } else {
251
- $r = new \ReflectionFunction($callable);
252
- }
253
- return $this->reflector = [$r, $callable];
254
- }
255
- }
256
- \class_alias('WCML\\Twig\\Node\\Expression\\CallExpression', 'WCML\\Twig_Node_Expression_Call');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/twig/src/Node/Expression/ConditionalExpression.php DELETED
@@ -1,26 +0,0 @@
1
- <?php
2
-
3
- /*
4
- * This file is part of Twig.
5
- *
6
- * (c) Fabien Potencier
7
- * (c) Armin Ronacher
8
- *
9
- * For the full copyright and license information, please view the LICENSE
10
- * file that was distributed with this source code.
11
- */
12
- namespace WCML\Twig\Node\Expression;
13
-
14
- use WCML\Twig\Compiler;
15
- class ConditionalExpression extends \WCML\Twig\Node\Expression\AbstractExpression
16
- {
17
- public function __construct(\WCML\Twig\Node\Expression\AbstractExpression $expr1, \WCML\Twig\Node\Expression\AbstractExpression $expr2, \WCML\Twig\Node\Expression\AbstractExpression $expr3, $lineno)
18
- {
19
- parent::__construct(['expr1' => $expr1, 'expr2' => $expr2, 'expr3' => $expr3], [], $lineno);
20
- }
21
- public function compile(\WCML\Twig\Compiler $compiler)
22
- {
23
- $compiler->raw('((')->subcompile($this->getNode('expr1'))->raw(') ? (')->subcompile($this->getNode('expr2'))->raw(') : (')->subcompile($this->getNode('expr3'))->raw('))');
24
- }
25
- }
26
- \class_alias('WCML\\Twig\\Node\\Expression\\ConditionalExpression', 'WCML\\Twig_Node_Expression_Conditional');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/twig/src/Node/Expression/ConstantExpression.php DELETED
@@ -1,26 +0,0 @@
1
- <?php
2
-
3
- /*
4
- * This file is part of Twig.
5
- *
6
- * (c) Fabien Potencier
7
- * (c) Armin Ronacher
8
- *
9
- * For the full copyright and license information, please view the LICENSE
10
- * file that was distributed with this source code.
11
- */
12
- namespace WCML\Twig\Node\Expression;
13
-
14
- use WCML\Twig\Compiler;
15
- class ConstantExpression extends \WCML\Twig\Node\Expression\AbstractExpression
16
- {
17
- public function __construct($value, $lineno)
18
- {
19
- parent::__construct([], ['value' => $value], $lineno);
20
- }
21
- public function compile(\WCML\Twig\Compiler $compiler)
22
- {
23
- $compiler->repr($this->getAttribute('value'));
24
- }
25
- }
26
- \class_alias('WCML\\Twig\\Node\\Expression\\ConstantExpression', 'WCML\\Twig_Node_Expression_Constant');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/twig/src/Node/Expression/Filter/DefaultFilter.php DELETED
@@ -1,47 +0,0 @@
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
- namespace WCML\Twig\Node\Expression\Filter;
12
-
13
- use WCML\Twig\Compiler;
14
- use WCML\Twig\Node\Expression\ConditionalExpression;
15
- use WCML\Twig\Node\Expression\ConstantExpression;
16
- use WCML\Twig\Node\Expression\FilterExpression;
17
- use WCML\Twig\Node\Expression\GetAttrExpression;
18
- use WCML\Twig\Node\Expression\NameExpression;
19
- use WCML\Twig\Node\Expression\Test\DefinedTest;
20
- use WCML\Twig\Node\Node;
21
- /**
22
- * Returns the value or the default value when it is undefined or empty.
23
- *
24
- * {{ var.foo|default('foo item on var is not defined') }}
25
- *
26
- * @author Fabien Potencier <fabien@symfony.com>
27
- */
28
- class DefaultFilter extends \WCML\Twig\Node\Expression\FilterExpression
29
- {
30
- public function __construct(\WCML\Twig_NodeInterface $node, \WCML\Twig\Node\Expression\ConstantExpression $filterName, \WCML\Twig_NodeInterface $arguments, $lineno, $tag = null)
31
- {
32
- $default = new \WCML\Twig\Node\Expression\FilterExpression($node, new \WCML\Twig\Node\Expression\ConstantExpression('default', $node->getTemplateLine()), $arguments, $node->getTemplateLine());
33
- if ('default' === $filterName->getAttribute('value') && ($node instanceof \WCML\Twig\Node\Expression\NameExpression || $node instanceof \WCML\Twig\Node\Expression\GetAttrExpression)) {
34
- $test = new \WCML\Twig\Node\Expression\Test\DefinedTest(clone $node, 'defined', new \WCML\Twig\Node\Node(), $node->getTemplateLine());
35
- $false = \count($arguments) ? $arguments->getNode(0) : new \WCML\Twig\Node\Expression\ConstantExpression('', $node->getTemplateLine());
36
- $node = new \WCML\Twig\Node\Expression\ConditionalExpression($test, $default, $false, $node->getTemplateLine());
37
- } else {
38
- $node = $default;
39
- }
40
- parent::__construct($node, $filterName, $arguments, $lineno, $tag);
41
- }
42
- public function compile(\WCML\Twig\Compiler $compiler)
43
- {
44
- $compiler->subcompile($this->getNode('node'));
45
- }
46
- }
47
- \class_alias('WCML\\Twig\\Node\\Expression\\Filter\\DefaultFilter', 'WCML\\Twig_Node_Expression_Filter_Default');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/twig/src/Node/Expression/FilterExpression.php DELETED
@@ -1,41 +0,0 @@
1
- <?php
2
-
3
- /*
4
- * This file is part of Twig.
5
- *
6
- * (c) Fabien Potencier
7
- * (c) Armin Ronacher
8
- *
9
- * For the full copyright and license information, please view the LICENSE
10
- * file that was distributed with this source code.
11
- */
12
- namespace WCML\Twig\Node\Expression;
13
-
14
- use WCML\Twig\Compiler;
15
- use WCML\Twig\TwigFilter;
16
- class FilterExpression extends \WCML\Twig\Node\Expression\CallExpression
17
- {
18
- public function __construct(\WCML\Twig_NodeInterface $node, \WCML\Twig\Node\Expression\ConstantExpression $filterName, \WCML\Twig_NodeInterface $arguments, $lineno, $tag = null)
19
- {
20
- parent::__construct(['node' => $node, 'filter' => $filterName, 'arguments' => $arguments], [], $lineno, $tag);
21
- }
22
- public function compile(\WCML\Twig\Compiler $compiler)
23
- {
24
- $name = $this->getNode('filter')->getAttribute('value');
25
- $filter = $compiler->getEnvironment()->getFilter($name);
26
- $this->setAttribute('name', $name);
27
- $this->setAttribute('type', 'filter');
28
- $this->setAttribute('thing', $filter);
29
- $this->setAttribute('needs_environment', $filter->needsEnvironment());
30
- $this->setAttribute('needs_context', $filter->needsContext());
31
- $this->setAttribute('arguments', $filter->getArguments());
32
- if ($filter instanceof \WCML\Twig_FilterCallableInterface || $filter instanceof \WCML\Twig\TwigFilter) {
33
- $this->setAttribute('callable', $filter->getCallable());
34
- }
35
- if ($filter instanceof \WCML\Twig\TwigFilter) {
36
- $this->setAttribute('is_variadic', $filter->isVariadic());
37
- }
38
- $this->compileCallable($compiler);
39
- }
40
- }
41
- \class_alias('WCML\\Twig\\Node\\Expression\\FilterExpression', 'WCML\\Twig_Node_Expression_Filter');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/twig/src/Node/Expression/FunctionExpression.php DELETED
@@ -1,44 +0,0 @@
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
- namespace WCML\Twig\Node\Expression;
12
-
13
- use WCML\Twig\Compiler;
14
- use WCML\Twig\TwigFunction;
15
- class FunctionExpression extends \WCML\Twig\Node\Expression\CallExpression
16
- {
17
- public function __construct($name, \WCML\Twig_NodeInterface $arguments, $lineno)
18
- {
19
- parent::__construct(['arguments' => $arguments], ['name' => $name, 'is_defined_test' => \false], $lineno);
20
- }
21
- public function compile(\WCML\Twig\Compiler $compiler)
22
- {
23
- $name = $this->getAttribute('name');
24
- $function = $compiler->getEnvironment()->getFunction($name);
25
- $this->setAttribute('name', $name);
26
- $this->setAttribute('type', 'function');
27
- $this->setAttribute('thing', $function);
28
- $this->setAttribute('needs_environment', $function->needsEnvironment());
29
- $this->setAttribute('needs_context', $function->needsContext());
30
- $this->setAttribute('arguments', $function->getArguments());
31
- if ($function instanceof \WCML\Twig_FunctionCallableInterface || $function instanceof \WCML\Twig\TwigFunction) {
32
- $callable = $function->getCallable();
33
- if ('constant' === $name && $this->getAttribute('is_defined_test')) {
34
- $callable = 'twig_constant_is_defined';
35
- }
36
- $this->setAttribute('callable', $callable);
37
- }
38
- if ($function instanceof \WCML\Twig\TwigFunction) {
39
- $this->setAttribute('is_variadic', $function->isVariadic());
40
- }
41
- $this->compileCallable($compiler);
42
- }
43
- }
44
- \class_alias('WCML\\Twig\\Node\\Expression\\FunctionExpression', 'WCML\\Twig_Node_Expression_Function');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/twig/src/Node/Expression/GetAttrExpression.php DELETED
@@ -1,65 +0,0 @@
1
- <?php
2
-
3
- /*
4
- * This file is part of Twig.
5
- *
6
- * (c) Fabien Potencier
7
- * (c) Armin Ronacher
8
- *
9
- * For the full copyright and license information, please view the LICENSE
10
- * file that was distributed with this source code.
11
- */
12
- namespace WCML\Twig\Node\Expression;
13
-
14
- use WCML\Twig\Compiler;
15
- use WCML\Twig\Template;
16
- class GetAttrExpression extends \WCML\Twig\Node\Expression\AbstractExpression
17
- {
18
- public function __construct(\WCML\Twig\Node\Expression\AbstractExpression $node, \WCML\Twig\Node\Expression\AbstractExpression $attribute, \WCML\Twig\Node\Expression\AbstractExpression $arguments = null, $type, $lineno)
19
- {
20
- $nodes = ['node' => $node, 'attribute' => $attribute];
21
- if (null !== $arguments) {
22
- $nodes['arguments'] = $arguments;
23
- }
24
- parent::__construct($nodes, ['type' => $type, 'is_defined_test' => \false, 'ignore_strict_check' => \false, 'disable_c_ext' => \false], $lineno);
25
- }
26
- public function compile(\WCML\Twig\Compiler $compiler)
27
- {
28
- if ($this->getAttribute('disable_c_ext')) {
29
- @\trigger_error(\sprintf('Using the "disable_c_ext" attribute on %s is deprecated since version 1.30 and will be removed in 2.0.', __CLASS__), \E_USER_DEPRECATED);
30
- }
31
- if (\function_exists('WCML\\twig_template_get_attributes') && !$this->getAttribute('disable_c_ext')) {
32
- $compiler->raw('twig_template_get_attributes($this, ');
33
- } else {
34
- $compiler->raw('$this->getAttribute(');
35
- }
36
- if ($this->getAttribute('ignore_strict_check')) {
37
- $this->getNode('node')->setAttribute('ignore_strict_check', \true);
38
- }
39
- $compiler->subcompile($this->getNode('node'));
40
- $compiler->raw(', ')->subcompile($this->getNode('attribute'));
41
- // only generate optional arguments when needed (to make generated code more readable)
42
- $needFourth = $this->getAttribute('ignore_strict_check');
43
- $needThird = $needFourth || $this->getAttribute('is_defined_test');
44
- $needSecond = $needThird || \WCML\Twig\Template::ANY_CALL !== $this->getAttribute('type');
45
- $needFirst = $needSecond || $this->hasNode('arguments');
46
- if ($needFirst) {
47
- if ($this->hasNode('arguments')) {
48
- $compiler->raw(', ')->subcompile($this->getNode('arguments'));
49
- } else {
50
- $compiler->raw(', []');
51
- }
52
- }
53
- if ($needSecond) {
54
- $compiler->raw(', ')->repr($this->getAttribute('type'));
55
- }
56
- if ($needThird) {
57
- $compiler->raw(', ')->repr($this->getAttribute('is_defined_test'));
58
- }
59
- if ($needFourth) {
60
- $compiler->raw(', ')->repr($this->getAttribute('ignore_strict_check'));
61
- }
62
- $compiler->raw(')');
63
- }
64
- }
65
- \class_alias('WCML\\Twig\\Node\\Expression\\GetAttrExpression', 'WCML\\Twig_Node_Expression_GetAttr');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/twig/src/Node/Expression/InlinePrint.php DELETED
@@ -1,28 +0,0 @@
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
- namespace WCML\Twig\Node\Expression;
12
-
13
- use WCML\Twig\Compiler;
14
- use WCML\Twig\Node\Node;
15
- /**
16
- * @internal
17
- */
18
- final class InlinePrint extends \WCML\Twig\Node\Expression\AbstractExpression
19
- {
20
- public function __construct(\WCML\Twig\Node\Node $node, $lineno)
21
- {
22
- parent::__construct(['node' => $node], [], $lineno);
23
- }
24
- public function compile(\WCML\Twig\Compiler $compiler)
25
- {
26
- $compiler->raw('print (')->subcompile($this->getNode('node'))->raw(')');
27
- }
28
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/twig/src/Node/Expression/MethodCallExpression.php DELETED
@@ -1,37 +0,0 @@
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
- namespace WCML\Twig\Node\Expression;
12
-
13
- use WCML\Twig\Compiler;
14
- class MethodCallExpression extends \WCML\Twig\Node\Expression\AbstractExpression
15
- {
16
- public function __construct(\WCML\Twig\Node\Expression\AbstractExpression $node, $method, \WCML\Twig\Node\Expression\ArrayExpression $arguments, $lineno)
17
- {
18
- parent::__construct(['node' => $node, 'arguments' => $arguments], ['method' => $method, 'safe' => \false], $lineno);
19
- if ($node instanceof \WCML\Twig\Node\Expression\NameExpression) {
20
- $node->setAttribute('always_defined', \true);
21
- }
22
- }
23
- public function compile(\WCML\Twig\Compiler $compiler)
24
- {
25
- $compiler->subcompile($this->getNode('node'))->raw('->')->raw($this->getAttribute('method'))->raw('(');
26
- $first = \true;
27
- foreach ($this->getNode('arguments')->getKeyValuePairs() as $pair) {
28
- if (!$first) {
29
- $compiler->raw(', ');
30
- }
31
- $first = \false;
32
- $compiler->subcompile($pair['value']);
33
- }
34
- $compiler->raw(')');
35
- }
36
- }
37
- \class_alias('WCML\\Twig\\Node\\Expression\\MethodCallExpression', 'WCML\\Twig_Node_Expression_MethodCall');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/twig/src/Node/Expression/NameExpression.php DELETED
@@ -1,73 +0,0 @@
1
- <?php
2
-
3
- /*
4
- * This file is part of Twig.
5
- *
6
- * (c) Fabien Potencier
7
- * (c) Armin Ronacher
8
- *
9
- * For the full copyright and license information, please view the LICENSE
10
- * file that was distributed with this source code.
11
- */
12
- namespace WCML\Twig\Node\Expression;
13
-
14
- use WCML\Twig\Compiler;
15
- class NameExpression extends \WCML\Twig\Node\Expression\AbstractExpression
16
- {
17
- protected $specialVars = ['_self' => '$this', '_context' => '$context', '_charset' => '$this->env->getCharset()'];
18
- public function __construct($name, $lineno)
19
- {
20
- parent::__construct([], ['name' => $name, 'is_defined_test' => \false, 'ignore_strict_check' => \false, 'always_defined' => \false], $lineno);
21
- }
22
- public function compile(\WCML\Twig\Compiler $compiler)
23
- {
24
- $name = $this->getAttribute('name');
25
- $compiler->addDebugInfo($this);
26
- if ($this->getAttribute('is_defined_test')) {
27
- if ($this->isSpecial()) {
28
- $compiler->repr(\true);
29
- } elseif (\PHP_VERSION_ID >= 700400) {
30
- $compiler->raw('array_key_exists(')->string($name)->raw(', $context)');
31
- } else {
32
- $compiler->raw('(isset($context[')->string($name)->raw(']) || array_key_exists(')->string($name)->raw(', $context))');
33
- }
34
- } elseif ($this->isSpecial()) {
35
- $compiler->raw($this->specialVars[$name]);
36
- } elseif ($this->getAttribute('always_defined')) {
37
- $compiler->raw('$context[')->string($name)->raw(']');
38
- } else {
39
- if (\PHP_VERSION_ID >= 70000) {
40
- // use PHP 7 null coalescing operator
41
- $compiler->raw('($context[')->string($name)->raw('] ?? ');
42
- if ($this->getAttribute('ignore_strict_check') || !$compiler->getEnvironment()->isStrictVariables()) {
43
- $compiler->raw('null)');
44
- } else {
45
- $compiler->raw('$this->getContext($context, ')->string($name)->raw('))');
46
- }
47
- } elseif (\PHP_VERSION_ID >= 50400) {
48
- // PHP 5.4 ternary operator performance was optimized
49
- $compiler->raw('(isset($context[')->string($name)->raw(']) ? $context[')->string($name)->raw('] : ');
50
- if ($this->getAttribute('ignore_strict_check') || !$compiler->getEnvironment()->isStrictVariables()) {
51
- $compiler->raw('null)');
52
- } else {
53
- $compiler->raw('$this->getContext($context, ')->string($name)->raw('))');
54
- }
55
- } else {
56
- $compiler->raw('$this->getContext($context, ')->string($name);
57
- if ($this->getAttribute('ignore_strict_check')) {
58
- $compiler->raw(', true');
59
- }
60
- $compiler->raw(')');
61
- }
62
- }
63
- }
64
- public function isSpecial()
65
- {
66
- return isset($this->specialVars[$this->getAttribute('name')]);
67
- }
68
- public function isSimple()
69
- {
70
- return !$this->isSpecial() && !$this->getAttribute('is_defined_test');
71
- }
72
- }
73
- \class_alias('WCML\\Twig\\Node\\Expression\\NameExpression', 'WCML\\Twig_Node_Expression_Name');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/twig/src/Node/Expression/NullCoalesceExpression.php DELETED
@@ -1,43 +0,0 @@
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
- namespace WCML\Twig\Node\Expression;
12
-
13
- use WCML\Twig\Compiler;
14
- use WCML\Twig\Node\Expression\Binary\AndBinary;
15
- use WCML\Twig\Node\Expression\Test\DefinedTest;
16
- use WCML\Twig\Node\Expression\Test\NullTest;
17
- use WCML\Twig\Node\Expression\Unary\NotUnary;
18
- use WCML\Twig\Node\Node;
19
- class NullCoalesceExpression extends \WCML\Twig\Node\Expression\ConditionalExpression
20
- {
21
- public function __construct(\WCML\Twig_NodeInterface $left, \WCML\Twig_NodeInterface $right, $lineno)
22
- {
23
- $test = new \WCML\Twig\Node\Expression\Binary\AndBinary(new \WCML\Twig\Node\Expression\Test\DefinedTest(clone $left, 'defined', new \WCML\Twig\Node\Node(), $left->getTemplateLine()), new \WCML\Twig\Node\Expression\Unary\NotUnary(new \WCML\Twig\Node\Expression\Test\NullTest($left, 'null', new \WCML\Twig\Node\Node(), $left->getTemplateLine()), $left->getTemplateLine()), $left->getTemplateLine());
24
- parent::__construct($test, $left, $right, $lineno);
25
- }
26
- public function compile(\WCML\Twig\Compiler $compiler)
27
- {
28
- /*
29
- * This optimizes only one case. PHP 7 also supports more complex expressions
30
- * that can return null. So, for instance, if log is defined, log("foo") ?? "..." works,
31
- * but log($a["foo"]) ?? "..." does not if $a["foo"] is not defined. More advanced
32
- * cases might be implemented as an optimizer node visitor, but has not been done
33
- * as benefits are probably not worth the added complexity.
34
- */
35
- if (\PHP_VERSION_ID >= 70000 && $this->getNode('expr2') instanceof \WCML\Twig\Node\Expression\NameExpression) {
36
- $this->getNode('expr2')->setAttribute('always_defined', \true);
37
- $compiler->raw('((')->subcompile($this->getNode('expr2'))->raw(') ?? (')->subcompile($this->getNode('expr3'))->raw('))');
38
- } else {
39
- parent::compile($compiler);
40
- }
41
- }
42
- }
43
- \class_alias('WCML\\Twig\\Node\\Expression\\NullCoalesceExpression', 'WCML\\Twig_Node_Expression_NullCoalesce');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/twig/src/Node/Expression/ParentExpression.php DELETED
@@ -1,35 +0,0 @@
1
- <?php
2
-
3
- /*
4
- * This file is part of Twig.
5
- *
6
- * (c) Fabien Potencier
7
- * (c) Armin Ronacher
8
- *
9
- * For the full copyright and license information, please view the LICENSE
10
- * file that was distributed with this source code.
11
- */
12
- namespace WCML\Twig\Node\Expression;
13
-
14
- use WCML\Twig\Compiler;
15
- /**
16
- * Represents a parent node.
17
- *
18
- * @author Fabien Potencier <fabien@symfony.com>
19
- */
20
- class ParentExpression extends \WCML\Twig\Node\Expression\AbstractExpression
21
- {
22
- public function __construct($name, $lineno, $tag = null)
23
- {
24
- parent::__construct([], ['output' => \false, 'name' => $name], $lineno, $tag);
25
- }
26
- public function compile(\WCML\Twig\Compiler $compiler)
27
- {
28
- if ($this->getAttribute('output')) {
29
- $compiler->addDebugInfo($this)->write('$this->displayParentBlock(')->string($this->getAttribute('name'))->raw(", \$context, \$blocks);\n");
30
- } else {
31
- $compiler->raw('$this->renderParentBlock(')->string($this->getAttribute('name'))->raw(', $context, $blocks)');
32
- }
33
- }
34
- }
35
- \class_alias('WCML\\Twig\\Node\\Expression\\ParentExpression', 'WCML\\Twig_Node_Expression_Parent');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/twig/src/Node/Expression/TempNameExpression.php DELETED
@@ -1,25 +0,0 @@
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
- namespace WCML\Twig\Node\Expression;
12
-
13
- use WCML\Twig\Compiler;
14
- class TempNameExpression extends \WCML\Twig\Node\Expression\AbstractExpression
15
- {
16
- public function __construct($name, $lineno)
17
- {
18
- parent::__construct([], ['name' => $name], $lineno);
19
- }
20
- public function compile(\WCML\Twig\Compiler $compiler)
21
- {
22
- $compiler->raw('$_')->raw($this->getAttribute('name'))->raw('_');
23
- }
24
- }
25
- \class_alias('WCML\\Twig\\Node\\Expression\\TempNameExpression', 'WCML\\Twig_Node_Expression_TempName');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/twig/src/Node/Expression/Test/ConstantTest.php DELETED
@@ -1,35 +0,0 @@
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
- namespace WCML\Twig\Node\Expression\Test;
12
-
13
- use WCML\Twig\Compiler;
14
- use WCML\Twig\Node\Expression\TestExpression;
15
- /**
16
- * Checks if a variable is the exact same value as a constant.
17
- *
18
- * {% if post.status is constant('Post::PUBLISHED') %}
19
- * the status attribute is exactly the same as Post::PUBLISHED
20
- * {% endif %}
21
- *
22
- * @author Fabien Potencier <fabien@symfony.com>
23
- */
24
- class ConstantTest extends \WCML\Twig\Node\Expression\TestExpression
25
- {
26
- public function compile(\WCML\Twig\Compiler $compiler)
27
- {
28
- $compiler->raw('(')->subcompile($this->getNode('node'))->raw(' === constant(');
29
- if ($this->getNode('arguments')->hasNode(1)) {
30
- $compiler->raw('get_class(')->subcompile($this->getNode('arguments')->getNode(1))->raw(')."::".');
31
- }
32
- $compiler->subcompile($this->getNode('arguments')->getNode(0))->raw('))');
33
- }
34
- }
35
- \class_alias('WCML\\Twig\\Node\\Expression\\Test\\ConstantTest', 'WCML\\Twig_Node_Expression_Test_Constant');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/twig/src/Node/Expression/Test/DefinedTest.php DELETED
@@ -1,64 +0,0 @@
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
- namespace WCML\Twig\Node\Expression\Test;
12
-
13
- use WCML\Twig\Compiler;
14
- use WCML\Twig\Error\SyntaxError;
15
- use WCML\Twig\Node\Expression\ArrayExpression;
16
- use WCML\Twig\Node\Expression\BlockReferenceExpression;
17
- use WCML\Twig\Node\Expression\ConstantExpression;
18
- use WCML\Twig\Node\Expression\FunctionExpression;
19
- use WCML\Twig\Node\Expression\GetAttrExpression;
20
- use WCML\Twig\Node\Expression\NameExpression;
21
- use WCML\Twig\Node\Expression\TestExpression;
22
- /**
23
- * Checks if a variable is defined in the current context.
24
- *
25
- * {# defined works with variable names and variable attributes #}
26
- * {% if foo is defined %}
27
- * {# ... #}
28
- * {% endif %}
29
- *
30
- * @author Fabien Potencier <fabien@symfony.com>
31
- */
32
- class DefinedTest extends \WCML\Twig\Node\Expression\TestExpression
33
- {
34
- public function __construct(\WCML\Twig_NodeInterface $node, $name, \WCML\Twig_NodeInterface $arguments = null, $lineno)
35
- {
36
- if ($node instanceof \WCML\Twig\Node\Expression\NameExpression) {
37
- $node->setAttribute('is_defined_test', \true);
38
- } elseif ($node instanceof \WCML\Twig\Node\Expression\GetAttrExpression) {
39
- $node->setAttribute('is_defined_test', \true);
40
- $this->changeIgnoreStrictCheck($node);
41
- } elseif ($node instanceof \WCML\Twig\Node\Expression\BlockReferenceExpression) {
42
- $node->setAttribute('is_defined_test', \true);
43
- } elseif ($node instanceof \WCML\Twig\Node\Expression\FunctionExpression && 'constant' === $node->getAttribute('name')) {
44
- $node->setAttribute('is_defined_test', \true);
45
- } elseif ($node instanceof \WCML\Twig\Node\Expression\ConstantExpression || $node instanceof \WCML\Twig\Node\Expression\ArrayExpression) {
46
- $node = new \WCML\Twig\Node\Expression\ConstantExpression(\true, $node->getTemplateLine());
47
- } else {
48
- throw new \WCML\Twig\Error\SyntaxError('The "defined" test only works with simple variables.', $lineno);
49
- }
50
- parent::__construct($node, $name, $arguments, $lineno);
51
- }
52
- protected function changeIgnoreStrictCheck(\WCML\Twig\Node\Expression\GetAttrExpression $node)
53
- {
54
- $node->setAttribute('ignore_strict_check', \true);
55
- if ($node->getNode('node') instanceof \WCML\Twig\Node\Expression\GetAttrExpression) {
56
- $this->changeIgnoreStrictCheck($node->getNode('node'));
57
- }
58
- }
59
- public function compile(\WCML\Twig\Compiler $compiler)
60
- {
61
- $compiler->subcompile($this->getNode('node'));
62
- }
63
- }
64
- \class_alias('WCML\\Twig\\Node\\Expression\\Test\\DefinedTest', 'WCML\\Twig_Node_Expression_Test_Defined');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/twig/src/Node/Expression/Test/DivisiblebyTest.php DELETED
@@ -1,29 +0,0 @@
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
- namespace WCML\Twig\Node\Expression\Test;
12
-
13
- use WCML\Twig\Compiler;
14
- use WCML\Twig\Node\Expression\TestExpression;
15
- /**
16
- * Checks if a variable is divisible by a number.
17
- *
18
- * {% if loop.index is divisible by(3) %}
19
- *
20
- * @author Fabien Potencier <fabien@symfony.com>
21
- */
22
- class DivisiblebyTest extends \WCML\Twig\Node\Expression\TestExpression
23
- {
24
- public function compile(\WCML\Twig\Compiler $compiler)
25
- {
26
- $compiler->raw('(0 == ')->subcompile($this->getNode('node'))->raw(' % ')->subcompile($this->getNode('arguments')->getNode(0))->raw(')');
27
- }
28
- }
29
- \class_alias('WCML\\Twig\\Node\\Expression\\Test\\DivisiblebyTest', 'WCML\\Twig_Node_Expression_Test_Divisibleby');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/twig/src/Node/Expression/Test/EvenTest.php DELETED
@@ -1,29 +0,0 @@
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
- namespace WCML\Twig\Node\Expression\Test;
12
-
13
- use WCML\Twig\Compiler;
14
- use WCML\Twig\Node\Expression\TestExpression;
15
- /**
16
- * Checks if a number is even.
17
- *
18
- * {{ var is even }}
19
- *
20
- * @author Fabien Potencier <fabien@symfony.com>
21
- */
22
- class EvenTest extends \WCML\Twig\Node\Expression\TestExpression
23
- {
24
- public function compile(\WCML\Twig\Compiler $compiler)
25
- {
26
- $compiler->raw('(')->subcompile($this->getNode('node'))->raw(' % 2 == 0')->raw(')');
27
- }
28
- }
29
- \class_alias('WCML\\Twig\\Node\\Expression\\Test\\EvenTest', 'WCML\\Twig_Node_Expression_Test_Even');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/twig/src/Node/Expression/Test/NullTest.php DELETED
@@ -1,29 +0,0 @@
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
- namespace WCML\Twig\Node\Expression\Test;
12
-
13
- use WCML\Twig\Compiler;
14
- use WCML\Twig\Node\Expression\TestExpression;
15
- /**
16
- * Checks that a variable is null.
17
- *
18
- * {{ var is none }}
19
- *
20
- * @author Fabien Potencier <fabien@symfony.com>
21
- */
22
- class NullTest extends \WCML\Twig\Node\Expression\TestExpression
23
- {
24
- public function compile(\WCML\Twig\Compiler $compiler)
25
- {
26
- $compiler->raw('(null === ')->subcompile($this->getNode('node'))->raw(')');
27
- }
28
- }
29
- \class_alias('WCML\\Twig\\Node\\Expression\\Test\\NullTest', 'WCML\\Twig_Node_Expression_Test_Null');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/twig/src/Node/Expression/Test/OddTest.php DELETED
@@ -1,29 +0,0 @@
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
- namespace WCML\Twig\Node\Expression\Test;
12
-
13
- use WCML\Twig\Compiler;
14
- use WCML\Twig\Node\Expression\TestExpression;
15
- /**
16
- * Checks if a number is odd.
17
- *
18
- * {{ var is odd }}
19
- *
20
- * @author Fabien Potencier <fabien@symfony.com>
21
- */
22
- class OddTest extends \WCML\Twig\Node\Expression\TestExpression
23
- {
24
- public function compile(\WCML\Twig\Compiler $compiler)
25
- {
26
- $compiler->raw('(')->subcompile($this->getNode('node'))->raw(' % 2 == 1')->raw(')');
27
- }
28
- }
29
- \class_alias('WCML\\Twig\\Node\\Expression\\Test\\OddTest', 'WCML\\Twig_Node_Expression_Test_Odd');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/twig/src/Node/Expression/Test/SameasTest.php DELETED
@@ -1,27 +0,0 @@
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
- namespace WCML\Twig\Node\Expression\Test;
12
-
13
- use WCML\Twig\Compiler;
14
- use WCML\Twig\Node\Expression\TestExpression;
15
- /**
16
- * Checks if a variable is the same as another one (=== in PHP).
17
- *
18
- * @author Fabien Potencier <fabien@symfony.com>
19
- */
20
- class SameasTest extends \WCML\Twig\Node\Expression\TestExpression
21
- {
22
- public function compile(\WCML\Twig\Compiler $compiler)
23
- {
24
- $compiler->raw('(')->subcompile($this->getNode('node'))->raw(' === ')->subcompile($this->getNode('arguments')->getNode(0))->raw(')');
25
- }
26
- }
27
- \class_alias('WCML\\Twig\\Node\\Expression\\Test\\SameasTest', 'WCML\\Twig_Node_Expression_Test_Sameas');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/twig/src/Node/Expression/TestExpression.php DELETED
@@ -1,44 +0,0 @@
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
- namespace WCML\Twig\Node\Expression;
12
-
13
- use WCML\Twig\Compiler;
14
- use WCML\Twig\TwigTest;
15
- class TestExpression extends \WCML\Twig\Node\Expression\CallExpression
16
- {
17
- public function __construct(\WCML\Twig_NodeInterface $node, $name, \WCML\Twig_NodeInterface $arguments = null, $lineno)
18
- {
19
- $nodes = ['node' => $node];
20
- if (null !== $arguments) {
21
- $nodes['arguments'] = $arguments;
22
- }
23
- parent::__construct($nodes, ['name' => $name], $lineno);
24
- }
25
- public function compile(\WCML\Twig\Compiler $compiler)
26
- {
27
- $name = $this->getAttribute('name');
28
- $test = $compiler->getEnvironment()->getTest($name);
29
- $this->setAttribute('name', $name);
30
- $this->setAttribute('type', 'test');
31
- $this->setAttribute('thing', $test);
32
- if ($test instanceof \WCML\Twig\TwigTest) {
33
- $this->setAttribute('arguments', $test->getArguments());
34
- }
35
- if ($test instanceof \WCML\Twig_TestCallableInterface || $test instanceof \WCML\Twig\TwigTest) {
36
- $this->setAttribute('callable', $test->getCallable());
37
- }
38
- if ($test instanceof \WCML\Twig\TwigTest) {
39
- $this->setAttribute('is_variadic', $test->isVariadic());
40
- }
41
- $this->compileCallable($compiler);
42
- }
43
- }
44
- \class_alias('WCML\\Twig\\Node\\Expression\\TestExpression', 'WCML\\Twig_Node_Expression_Test');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/twig/src/Node/Expression/Unary/AbstractUnary.php DELETED
@@ -1,30 +0,0 @@
1
- <?php
2
-
3
- /*
4
- * This file is part of Twig.
5
- *
6
- * (c) Fabien Potencier
7
- * (c) Armin Ronacher
8
- *
9
- * For the full copyright and license information, please view the LICENSE
10
- * file that was distributed with this source code.
11
- */
12
- namespace WCML\Twig\Node\Expression\Unary;
13
-
14
- use WCML\Twig\Compiler;
15
- use WCML\Twig\Node\Expression\AbstractExpression;
16
- abstract class AbstractUnary extends \WCML\Twig\Node\Expression\AbstractExpression
17
- {
18
- public function __construct(\WCML\Twig_NodeInterface $node, $lineno)
19
- {
20
- parent::__construct(['node' => $node], [], $lineno);
21
- }
22
- public function compile(\WCML\Twig\Compiler $compiler)
23
- {
24
- $compiler->raw(' ');
25
- $this->operator($compiler);
26
- $compiler->subcompile($this->getNode('node'));
27
- }
28
- public abstract function operator(\WCML\Twig\Compiler $compiler);
29
- }
30
- \class_alias('WCML\\Twig\\Node\\Expression\\Unary\\AbstractUnary', 'WCML\\Twig_Node_Expression_Unary');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/twig/src/Node/Expression/Unary/NegUnary.php DELETED
@@ -1,22 +0,0 @@
1
- <?php
2
-
3
- /*
4
- * This file is part of Twig.
5
- *
6
- * (c) Fabien Potencier
7
- * (c) Armin Ronacher
8
- *
9
- * For the full copyright and license information, please view the LICENSE
10
- * file that was distributed with this source code.
11
- */
12
- namespace WCML\Twig\Node\Expression\Unary;
13
-
14
- use WCML\Twig\Compiler;
15
- class NegUnary extends \WCML\Twig\Node\Expression\Unary\AbstractUnary
16
- {
17
- public function operator(\WCML\Twig\Compiler $compiler)
18
- {
19
- $compiler->raw('-');
20
- }
21
- }
22
- \class_alias('WCML\\Twig\\Node\\Expression\\Unary\\NegUnary', 'WCML\\Twig_Node_Expression_Unary_Neg');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/twig/src/Node/Expression/Unary/NotUnary.php DELETED
@@ -1,22 +0,0 @@
1
- <?php
2
-
3
- /*
4
- * This file is part of Twig.
5
- *
6
- * (c) Fabien Potencier
7
- * (c) Armin Ronacher
8
- *
9
- * For the full copyright and license information, please view the LICENSE
10
- * file that was distributed with this source code.
11
- */
12
- namespace WCML\Twig\Node\Expression\Unary;
13
-
14
- use WCML\Twig\Compiler;
15
- class NotUnary extends \WCML\Twig\Node\Expression\Unary\AbstractUnary
16
- {
17
- public function operator(\WCML\Twig\Compiler $compiler)
18
- {
19
- $compiler->raw('!');
20
- }
21
- }
22
- \class_alias('WCML\\Twig\\Node\\Expression\\Unary\\NotUnary', 'WCML\\Twig_Node_Expression_Unary_Not');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/twig/src/Node/Expression/Unary/PosUnary.php DELETED
@@ -1,22 +0,0 @@
1
- <?php
2
-
3
- /*
4
- * This file is part of Twig.
5
- *
6
- * (c) Fabien Potencier
7
- * (c) Armin Ronacher
8
- *
9
- * For the full copyright and license information, please view the LICENSE
10
- * file that was distributed with this source code.
11
- */
12
- namespace WCML\Twig\Node\Expression\Unary;
13
-
14
- use WCML\Twig\Compiler;
15
- class PosUnary extends \WCML\Twig\Node\Expression\Unary\AbstractUnary
16
- {
17
- public function operator(\WCML\Twig\Compiler $compiler)
18
- {
19
- $compiler->raw('+');
20
- }
21
- }
22
- \class_alias('WCML\\Twig\\Node\\Expression\\Unary\\PosUnary', 'WCML\\Twig_Node_Expression_Unary_Pos');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/twig/src/Node/FlushNode.php DELETED
@@ -1,30 +0,0 @@
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
- namespace WCML\Twig\Node;
12
-
13
- use WCML\Twig\Compiler;
14
- /**
15
- * Represents a flush node.
16
- *
17
- * @author Fabien Potencier <fabien@symfony.com>
18
- */
19
- class FlushNode extends \WCML\Twig\Node\Node
20
- {
21
- public function __construct($lineno, $tag)
22
- {
23
- parent::__construct([], [], $lineno, $tag);
24
- }
25
- public function compile(\WCML\Twig\Compiler $compiler)
26
- {
27
- $compiler->addDebugInfo($this)->write("flush();\n");
28
- }
29
- }
30
- \class_alias('WCML\\Twig\\Node\\FlushNode', 'WCML\\Twig_Node_Flush');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/twig/src/Node/ForLoopNode.php DELETED
@@ -1,38 +0,0 @@
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
- namespace WCML\Twig\Node;
12
-
13
- use WCML\Twig\Compiler;
14
- /**
15
- * Internal node used by the for node.
16
- *
17
- * @author Fabien Potencier <fabien@symfony.com>
18
- */
19
- class ForLoopNode extends \WCML\Twig\Node\Node
20
- {
21
- public function __construct($lineno, $tag = null)
22
- {
23
- parent::__construct([], ['with_loop' => \false, 'ifexpr' => \false, 'else' => \false], $lineno, $tag);
24
- }
25
- public function compile(\WCML\Twig\Compiler $compiler)
26
- {
27
- if ($this->getAttribute('else')) {
28
- $compiler->write("\$context['_iterated'] = true;\n");
29
- }
30
- if ($this->getAttribute('with_loop')) {
31
- $compiler->write("++\$context['loop']['index0'];\n")->write("++\$context['loop']['index'];\n")->write("\$context['loop']['first'] = false;\n");
32
- if (!$this->getAttribute('ifexpr')) {
33
- $compiler->write("if (isset(\$context['loop']['length'])) {\n")->indent()->write("--\$context['loop']['revindex0'];\n")->write("--\$context['loop']['revindex'];\n")->write("\$context['loop']['last'] = 0 === \$context['loop']['revindex0'];\n")->outdent()->write("}\n");
34
- }
35
- }
36
- }
37
- }
38
- \class_alias('WCML\\Twig\\Node\\ForLoopNode', 'WCML\\Twig_Node_ForLoop');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/twig/src/Node/ForNode.php DELETED
@@ -1,63 +0,0 @@
1
- <?php
2
-
3
- /*
4
- * This file is part of Twig.
5
- *
6
- * (c) Fabien Potencier
7
- * (c) Armin Ronacher
8
- *
9
- * For the full copyright and license information, please view the LICENSE
10
- * file that was distributed with this source code.
11
- */
12
- namespace WCML\Twig\Node;
13
-
14
- use WCML\Twig\Compiler;
15
- use WCML\Twig\Node\Expression\AbstractExpression;
16
- use WCML\Twig\Node\Expression\AssignNameExpression;
17
- /**
18
- * Represents a for node.
19
- *
20
- * @author Fabien Potencier <fabien@symfony.com>
21
- */
22
- class ForNode extends \WCML\Twig\Node\Node
23
- {
24
- protected $loop;
25
- public function __construct(\WCML\Twig\Node\Expression\AssignNameExpression $keyTarget, \WCML\Twig\Node\Expression\AssignNameExpression $valueTarget, \WCML\Twig\Node\Expression\AbstractExpression $seq, \WCML\Twig\Node\Expression\AbstractExpression $ifexpr = null, \WCML\Twig_NodeInterface $body, \WCML\Twig_NodeInterface $else = null, $lineno, $tag = null)
26
- {
27
- $body = new \WCML\Twig\Node\Node([$body, $this->loop = new \WCML\Twig\Node\ForLoopNode($lineno, $tag)]);
28
- if (null !== $ifexpr) {
29
- $body = new \WCML\Twig\Node\IfNode(new \WCML\Twig\Node\Node([$ifexpr, $body]), null, $lineno, $tag);
30
- }
31
- $nodes = ['key_target' => $keyTarget, 'value_target' => $valueTarget, 'seq' => $seq, 'body' => $body];
32
- if (null !== $else) {
33
- $nodes['else'] = $else;
34
- }
35
- parent::__construct($nodes, ['with_loop' => \true, 'ifexpr' => null !== $ifexpr], $lineno, $tag);
36
- }
37
- public function compile(\WCML\Twig\Compiler $compiler)
38
- {
39
- $compiler->addDebugInfo($this)->write("\$context['_parent'] = \$context;\n")->write("\$context['_seq'] = twig_ensure_traversable(")->subcompile($this->getNode('seq'))->raw(");\n");
40
- if ($this->hasNode('else')) {
41
- $compiler->write("\$context['_iterated'] = false;\n");
42
- }
43
- if ($this->getAttribute('with_loop')) {
44
- $compiler->write("\$context['loop'] = [\n")->write(" 'parent' => \$context['_parent'],\n")->write(" 'index0' => 0,\n")->write(" 'index' => 1,\n")->write(" 'first' => true,\n")->write("];\n");
45
- if (!$this->getAttribute('ifexpr')) {
46
- $compiler->write("if (is_array(\$context['_seq']) || (is_object(\$context['_seq']) && \$context['_seq'] instanceof \\Countable)) {\n")->indent()->write("\$length = count(\$context['_seq']);\n")->write("\$context['loop']['revindex0'] = \$length - 1;\n")->write("\$context['loop']['revindex'] = \$length;\n")->write("\$context['loop']['length'] = \$length;\n")->write("\$context['loop']['last'] = 1 === \$length;\n")->outdent()->write("}\n");
47
- }
48
- }
49
- $this->loop->setAttribute('else', $this->hasNode('else'));
50
- $this->loop->setAttribute('with_loop', $this->getAttribute('with_loop'));
51
- $this->loop->setAttribute('ifexpr', $this->getAttribute('ifexpr'));
52
- $compiler->write("foreach (\$context['_seq'] as ")->subcompile($this->getNode('key_target'))->raw(' => ')->subcompile($this->getNode('value_target'))->raw(") {\n")->indent()->subcompile($this->getNode('body'))->outdent()->write("}\n");
53
- if ($this->hasNode('else')) {
54
- $compiler->write("if (!\$context['_iterated']) {\n")->indent()->subcompile($this->getNode('else'))->outdent()->write("}\n");
55
- }
56
- $compiler->write("\$_parent = \$context['_parent'];\n");
57
- // remove some "private" loop variables (needed for nested loops)
58
- $compiler->write('unset($context[\'_seq\'], $context[\'_iterated\'], $context[\'' . $this->getNode('key_target')->getAttribute('name') . '\'], $context[\'' . $this->getNode('value_target')->getAttribute('name') . '\'], $context[\'_parent\'], $context[\'loop\']);' . "\n");
59
- // keep the values set in the inner context for variables defined in the outer context
60
- $compiler->write("\$context = array_intersect_key(\$context, \$_parent) + \$_parent;\n");
61
- }
62
- }
63
- \class_alias('WCML\\Twig\\Node\\ForNode', 'WCML\\Twig_Node_For');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/twig/src/Node/IfNode.php DELETED
@@ -1,47 +0,0 @@
1
- <?php
2
-
3
- /*
4
- * This file is part of Twig.
5
- *
6
- * (c) Fabien Potencier
7
- * (c) Armin Ronacher
8
- *
9
- * For the full copyright and license information, please view the LICENSE
10
- * file that was distributed with this source code.
11
- */
12
- namespace WCML\Twig\Node;
13
-
14
- use WCML\Twig\Compiler;
15
- /**
16
- * Represents an if node.
17
- *
18
- * @author Fabien Potencier <fabien@symfony.com>
19
- */
20
- class IfNode extends \WCML\Twig\Node\Node
21
- {
22
- public function __construct(\WCML\Twig_NodeInterface $tests, \WCML\Twig_NodeInterface $else = null, $lineno, $tag = null)
23
- {
24
- $nodes = ['tests' => $tests];
25
- if (null !== $else) {
26
- $nodes['else'] = $else;
27
- }
28
- parent::__construct($nodes, [], $lineno, $tag);
29
- }
30
- public function compile(\WCML\Twig\Compiler $compiler)
31
- {
32
- $compiler->addDebugInfo($this);
33
- for ($i = 0, $count = \count($this->getNode('tests')); $i < $count; $i += 2) {
34
- if ($i > 0) {
35
- $compiler->outdent()->write('} elseif (');
36
- } else {
37
- $compiler->write('if (');
38
- }
39
- $compiler->subcompile($this->getNode('tests')->getNode($i))->raw(") {\n")->indent()->subcompile($this->getNode('tests')->getNode($i + 1));
40
- }
41
- if ($this->hasNode('else')) {
42
- $compiler->outdent()->write("} else {\n")->indent()->subcompile($this->getNode('else'));
43
- }
44
- $compiler->outdent()->write("}\n");
45
- }
46
- }
47
- \class_alias('WCML\\Twig\\Node\\IfNode', 'WCML\\Twig_Node_If');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/twig/src/Node/ImportNode.php DELETED
@@ -1,38 +0,0 @@
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
- namespace WCML\Twig\Node;
12
-
13
- use WCML\Twig\Compiler;
14
- use WCML\Twig\Node\Expression\AbstractExpression;
15
- use WCML\Twig\Node\Expression\NameExpression;
16
- /**
17
- * Represents an import node.
18
- *
19
- * @author Fabien Potencier <fabien@symfony.com>
20
- */
21
- class ImportNode extends \WCML\Twig\Node\Node
22
- {
23
- public function __construct(\WCML\Twig\Node\Expression\AbstractExpression $expr, \WCML\Twig\Node\Expression\AbstractExpression $var, $lineno, $tag = null)
24
- {
25
- parent::__construct(['expr' => $expr, 'var' => $var], [], $lineno, $tag);
26
- }
27
- public function compile(\WCML\Twig\Compiler $compiler)
28
- {
29
- $compiler->addDebugInfo($this)->write('')->subcompile($this->getNode('var'))->raw(' = ');
30
- if ($this->getNode('expr') instanceof \WCML\Twig\Node\Expression\NameExpression && '_self' === $this->getNode('expr')->getAttribute('name')) {
31
- $compiler->raw('$this');
32
- } else {
33
- $compiler->raw('$this->loadTemplate(')->subcompile($this->getNode('expr'))->raw(', ')->repr($this->getTemplateName())->raw(', ')->repr($this->getTemplateLine())->raw(')->unwrap()');
34
- }
35
- $compiler->raw(";\n");
36
- }
37
- }
38
- \class_alias('WCML\\Twig\\Node\\ImportNode', 'WCML\\Twig_Node_Import');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/twig/src/Node/IncludeNode.php DELETED
@@ -1,65 +0,0 @@
1
- <?php
2
-
3
- /*
4
- * This file is part of Twig.
5
- *
6
- * (c) Fabien Potencier
7
- * (c) Armin Ronacher
8
- *
9
- * For the full copyright and license information, please view the LICENSE
10
- * file that was distributed with this source code.
11
- */
12
- namespace WCML\Twig\Node;
13
-
14
- use WCML\Twig\Compiler;
15
- use WCML\Twig\Node\Expression\AbstractExpression;
16
- /**
17
- * Represents an include node.
18
- *
19
- * @author Fabien Potencier <fabien@symfony.com>
20
- */
21
- class IncludeNode extends \WCML\Twig\Node\Node implements \WCML\Twig\Node\NodeOutputInterface
22
- {
23
- public function __construct(\WCML\Twig\Node\Expression\AbstractExpression $expr, \WCML\Twig\Node\Expression\AbstractExpression $variables = null, $only = \false, $ignoreMissing = \false, $lineno, $tag = null)
24
- {
25
- $nodes = ['expr' => $expr];
26
- if (null !== $variables) {
27
- $nodes['variables'] = $variables;
28
- }
29
- parent::__construct($nodes, ['only' => (bool) $only, 'ignore_missing' => (bool) $ignoreMissing], $lineno, $tag);
30
- }
31
- public function compile(\WCML\Twig\Compiler $compiler)
32
- {
33
- $compiler->addDebugInfo($this);
34
- if ($this->getAttribute('ignore_missing')) {
35
- $template = $compiler->getVarName();
36
- $compiler->write(\sprintf("\$%s = null;\n", $template))->write("try {\n")->indent()->write(\sprintf('$%s = ', $template));
37
- $this->addGetTemplate($compiler);
38
- $compiler->raw(";\n")->outdent()->write("} catch (LoaderError \$e) {\n")->indent()->write("// ignore missing template\n")->outdent()->write("}\n")->write(\sprintf("if (\$%s) {\n", $template))->indent()->write(\sprintf('$%s->display(', $template));
39
- $this->addTemplateArguments($compiler);
40
- $compiler->raw(");\n")->outdent()->write("}\n");
41
- } else {
42
- $this->addGetTemplate($compiler);
43
- $compiler->raw('->display(');
44
- $this->addTemplateArguments($compiler);
45
- $compiler->raw(");\n");
46
- }
47
- }
48
- protected function addGetTemplate(\WCML\Twig\Compiler $compiler)
49
- {
50
- $compiler->write('$this->loadTemplate(')->subcompile($this->getNode('expr'))->raw(', ')->repr($this->getTemplateName())->raw(', ')->repr($this->getTemplateLine())->raw(')');
51
- }
52
- protected function addTemplateArguments(\WCML\Twig\Compiler $compiler)
53
- {
54
- if (!$this->hasNode('variables')) {
55
- $compiler->raw(\false === $this->getAttribute('only') ? '$context' : '[]');
56
- } elseif (\false === $this->getAttribute('only')) {
57
- $compiler->raw('twig_array_merge($context, ')->subcompile($this->getNode('variables'))->raw(')');
58
- } else {
59
- $compiler->raw('twig_to_array(');
60
- $compiler->subcompile($this->getNode('variables'));
61
- $compiler->raw(')');
62
- }
63
- }
64
- }
65
- \class_alias('WCML\\Twig\\Node\\IncludeNode', 'WCML\\Twig_Node_Include');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/twig/src/Node/MacroNode.php DELETED
@@ -1,69 +0,0 @@
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
- namespace WCML\Twig\Node;
12
-
13
- use WCML\Twig\Compiler;
14
- use WCML\Twig\Error\SyntaxError;
15
- /**
16
- * Represents a macro node.
17
- *
18
- * @author Fabien Potencier <fabien@symfony.com>
19
- */
20
- class MacroNode extends \WCML\Twig\Node\Node
21
- {
22
- const VARARGS_NAME = 'varargs';
23
- public function __construct($name, \WCML\Twig_NodeInterface $body, \WCML\Twig_NodeInterface $arguments, $lineno, $tag = null)
24
- {
25
- foreach ($arguments as $argumentName => $argument) {
26
- if (self::VARARGS_NAME === $argumentName) {
27
- throw new \WCML\Twig\Error\SyntaxError(\sprintf('The argument "%s" in macro "%s" cannot be defined because the variable "%s" is reserved for arbitrary arguments.', self::VARARGS_NAME, $name, self::VARARGS_NAME), $argument->getTemplateLine(), $argument->getSourceContext());
28
- }
29
- }
30
- parent::__construct(['body' => $body, 'arguments' => $arguments], ['name' => $name], $lineno, $tag);
31
- }
32
- public function compile(\WCML\Twig\Compiler $compiler)
33
- {
34
- $compiler->addDebugInfo($this)->write(\sprintf('public function get%s(', $this->getAttribute('name')));
35
- $count = \count($this->getNode('arguments'));
36
- $pos = 0;
37
- foreach ($this->getNode('arguments') as $name => $default) {
38
- $compiler->raw('$__' . $name . '__ = ')->subcompile($default);
39
- if (++$pos < $count) {
40
- $compiler->raw(', ');
41
- }
42
- }
43
- if (\PHP_VERSION_ID >= 50600) {
44
- if ($count) {
45
- $compiler->raw(', ');
46
- }
47
- $compiler->raw('...$__varargs__');
48
- }
49
- $compiler->raw(")\n")->write("{\n")->indent();
50
- $compiler->write("\$context = \$this->env->mergeGlobals([\n")->indent();
51
- foreach ($this->getNode('arguments') as $name => $default) {
52
- $compiler->write('')->string($name)->raw(' => $__' . $name . '__')->raw(",\n");
53
- }
54
- $compiler->write('')->string(self::VARARGS_NAME)->raw(' => ');
55
- if (\PHP_VERSION_ID >= 50600) {
56
- $compiler->raw("\$__varargs__,\n");
57
- } else {
58
- $compiler->raw('func_num_args() > ')->repr($count)->raw(' ? array_slice(func_get_args(), ')->repr($count)->raw(") : [],\n");
59
- }
60
- $compiler->outdent()->write("]);\n\n")->write("\$blocks = [];\n\n");
61
- if ($compiler->getEnvironment()->isDebug()) {
62
- $compiler->write("ob_start();\n");
63
- } else {
64
- $compiler->write("ob_start(function () { return ''; });\n");
65
- }
66
- $compiler->write("try {\n")->indent()->subcompile($this->getNode('body'))->outdent()->write("} catch (\\Exception \$e) {\n")->indent()->write("ob_end_clean();\n\n")->write("throw \$e;\n")->outdent()->write("} catch (\\Throwable \$e) {\n")->indent()->write("ob_end_clean();\n\n")->write("throw \$e;\n")->outdent()->write("}\n\n")->write("return ('' === \$tmp = ob_get_clean()) ? '' : new Markup(\$tmp, \$this->env->getCharset());\n")->outdent()->write("}\n\n");
67
- }
68
- }
69
- \class_alias('WCML\\Twig\\Node\\MacroNode', 'WCML\\Twig_Node_Macro');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/twig/src/Node/ModuleNode.php DELETED
@@ -1,237 +0,0 @@
1
- <?php
2
-
3
- /*
4
- * This file is part of Twig.
5
- *
6
- * (c) Fabien Potencier
7
- * (c) Armin Ronacher
8
- *
9
- * For the full copyright and license information, please view the LICENSE
10
- * file that was distributed with this source code.
11
- */
12
- namespace WCML\Twig\Node;
13
-
14
- use WCML\Twig\Compiler;
15
- use WCML\Twig\Node\Expression\AbstractExpression;
16
- use WCML\Twig\Node\Expression\ConstantExpression;
17
- use WCML\Twig\Source;
18
- /**
19
- * Represents a module node.
20
- *
21
- * Consider this class as being final. If you need to customize the behavior of
22
- * the generated class, consider adding nodes to the following nodes: display_start,
23
- * display_end, constructor_start, constructor_end, and class_end.
24
- *
25
- * @author Fabien Potencier <fabien@symfony.com>
26
- */
27
- class ModuleNode extends \WCML\Twig\Node\Node
28
- {
29
- public function __construct(\WCML\Twig_NodeInterface $body, \WCML\Twig\Node\Expression\AbstractExpression $parent = null, \WCML\Twig_NodeInterface $blocks, \WCML\Twig_NodeInterface $macros, \WCML\Twig_NodeInterface $traits, $embeddedTemplates, $name, $source = '')
30
- {
31
- if (!$name instanceof \WCML\Twig\Source) {
32
- @\trigger_error(\sprintf('Passing a string as the $name argument of %s() is deprecated since version 1.27. Pass a \\Twig\\Source instance instead.', __METHOD__), \E_USER_DEPRECATED);
33
- $source = new \WCML\Twig\Source($source, $name);
34
- } else {
35
- $source = $name;
36
- }
37
- $nodes = ['body' => $body, 'blocks' => $blocks, 'macros' => $macros, 'traits' => $traits, 'display_start' => new \WCML\Twig\Node\Node(), 'display_end' => new \WCML\Twig\Node\Node(), 'constructor_start' => new \WCML\Twig\Node\Node(), 'constructor_end' => new \WCML\Twig\Node\Node(), 'class_end' => new \WCML\Twig\Node\Node()];
38
- if (null !== $parent) {
39
- $nodes['parent'] = $parent;
40
- }
41
- // embedded templates are set as attributes so that they are only visited once by the visitors
42
- parent::__construct($nodes, [
43
- // source to be remove in 2.0
44
- 'source' => $source->getCode(),
45
- // filename to be remove in 2.0 (use getTemplateName() instead)
46
- 'filename' => $source->getName(),
47
- 'index' => null,
48
- 'embedded_templates' => $embeddedTemplates,
49
- ], 1);
50
- // populate the template name of all node children
51
- $this->setTemplateName($source->getName());
52
- $this->setSourceContext($source);
53
- }
54
- public function setIndex($index)
55
- {
56
- $this->setAttribute('index', $index);
57
- }
58
- public function compile(\WCML\Twig\Compiler $compiler)
59
- {
60
- $this->compileTemplate($compiler);
61
- foreach ($this->getAttribute('embedded_templates') as $template) {
62
- $compiler->subcompile($template);
63
- }
64
- }
65
- protected function compileTemplate(\WCML\Twig\Compiler $compiler)
66
- {
67
- if (!$this->getAttribute('index')) {
68
- $compiler->write('<?php');
69
- }
70
- $this->compileClassHeader($compiler);
71
- if (\count($this->getNode('blocks')) || \count($this->getNode('traits')) || !$this->hasNode('parent') || $this->getNode('parent') instanceof \WCML\Twig\Node\Expression\ConstantExpression || \count($this->getNode('constructor_start')) || \count($this->getNode('constructor_end'))) {
72
- $this->compileConstructor($compiler);
73
- }
74
- $this->compileGetParent($compiler);
75
- $this->compileDisplay($compiler);
76
- $compiler->subcompile($this->getNode('blocks'));
77
- $this->compileMacros($compiler);
78
- $this->compileGetTemplateName($compiler);
79
- $this->compileIsTraitable($compiler);
80
- $this->compileDebugInfo($compiler);
81
- $this->compileGetSource($compiler);
82
- $this->compileGetSourceContext($compiler);
83
- $this->compileClassFooter($compiler);
84
- }
85
- protected function compileGetParent(\WCML\Twig\Compiler $compiler)
86
- {
87
- if (!$this->hasNode('parent')) {
88
- return;
89
- }
90
- $parent = $this->getNode('parent');
91
- $compiler->write("protected function doGetParent(array \$context)\n", "{\n")->indent()->addDebugInfo($parent)->write('return ');
92
- if ($parent instanceof \WCML\Twig\Node\Expression\ConstantExpression) {
93
- $compiler->subcompile($parent);
94
- } else {
95
- $compiler->raw('$this->loadTemplate(')->subcompile($parent)->raw(', ')->repr($this->getSourceContext()->getName())->raw(', ')->repr($parent->getTemplateLine())->raw(')');
96
- }
97
- $compiler->raw(";\n")->outdent()->write("}\n\n");
98
- }
99
- protected function compileClassHeader(\WCML\Twig\Compiler $compiler)
100
- {
101
- $compiler->write("\n\nnamespace WCML;\n\n");
102
- if (!$this->getAttribute('index')) {
103
- $compiler->write("use \\WCML\\Twig\\Environment;\n")->write("use \\WCML\\Twig\\Error\\LoaderError;\n")->write("use \\WCML\\Twig\\Error\\RuntimeError;\n")->write("use \\WCML\\Twig\\Markup;\n")->write("use \\WCML\\Twig\\Sandbox\\SecurityError;\n")->write("use \\WCML\\Twig\\Sandbox\\SecurityNotAllowedTagError;\n")->write("use \\WCML\\Twig\\Sandbox\\SecurityNotAllowedFilterError;\n")->write("use \\WCML\\Twig\\Sandbox\\SecurityNotAllowedFunctionError;\n")->write("use \\WCML\\Twig\\Source;\n")->write("use \\WCML\\Twig\\Template;\n\n");
104
- }
105
- $compiler->write('/* ' . \str_replace('*/', '* /', $this->getSourceContext()->getName()) . " */\n")->write('class ' . \substr( $compiler->getEnvironment()->getTemplateClass($this->getSourceContext()->getName(), $this->getAttribute('index')), 6 ) )->raw(\sprintf(" extends %s\n", $compiler->getEnvironment()->getBaseTemplateClass()))->write("{\n")->indent();
106
- }
107
- protected function compileConstructor(\WCML\Twig\Compiler $compiler)
108
- {
109
- $compiler->write("public function __construct(Environment \$env)\n", "{\n")->indent()->subcompile($this->getNode('constructor_start'))->write("parent::__construct(\$env);\n\n");
110
- // parent
111
- if (!$this->hasNode('parent')) {
112
- $compiler->write("\$this->parent = false;\n\n");
113
- }
114
- $countTraits = \count($this->getNode('traits'));
115
- if ($countTraits) {
116
- // traits
117
- foreach ($this->getNode('traits') as $i => $trait) {
118
- $this->compileLoadTemplate($compiler, $trait->getNode('template'), \sprintf('$_trait_%s', $i));
119
- $node = $trait->getNode('template');
120
- $compiler->addDebugInfo($node)->write(\sprintf("if (!\$_trait_%s->isTraitable()) {\n", $i))->indent()->write("throw new RuntimeError('Template \"'.")->subcompile($trait->getNode('template'))->raw(".'\" cannot be used as a trait.', ")->repr($node->getTemplateLine())->raw(", \$this->getSourceContext());\n")->outdent()->write("}\n")->write(\sprintf("\$_trait_%s_blocks = \$_trait_%s->getBlocks();\n\n", $i, $i));
121
- foreach ($trait->getNode('targets') as $key => $value) {
122
- $compiler->write(\sprintf('if (!isset($_trait_%s_blocks[', $i))->string($key)->raw("])) {\n")->indent()->write("throw new RuntimeError(sprintf('Block ")->string($key)->raw(' is not defined in trait ')->subcompile($trait->getNode('template'))->raw(".'), ")->repr($node->getTemplateLine())->raw(", \$this->getSourceContext());\n")->outdent()->write("}\n\n")->write(\sprintf('$_trait_%s_blocks[', $i))->subcompile($value)->raw(\sprintf('] = $_trait_%s_blocks[', $i))->string($key)->raw(\sprintf(']; unset($_trait_%s_blocks[', $i))->string($key)->raw("]);\n\n");
123
- }
124
- }
125
- if ($countTraits > 1) {
126
- $compiler->write("\$this->traits = array_merge(\n")->indent();
127
- for ($i = 0; $i < $countTraits; ++$i) {
128
- $compiler->write(\sprintf('$_trait_%s_blocks' . ($i == $countTraits - 1 ? '' : ',') . "\n", $i));
129
- }
130
- $compiler->outdent()->write(");\n\n");
131
- } else {
132
- $compiler->write("\$this->traits = \$_trait_0_blocks;\n\n");
133
- }
134
- $compiler->write("\$this->blocks = array_merge(\n")->indent()->write("\$this->traits,\n")->write("[\n");
135
- } else {
136
- $compiler->write("\$this->blocks = [\n");
137
- }
138
- // blocks
139
- $compiler->indent();
140
- foreach ($this->getNode('blocks') as $name => $node) {
141
- $compiler->write(\sprintf("'%s' => [\$this, 'block_%s'],\n", $name, $name));
142
- }
143
- if ($countTraits) {
144
- $compiler->outdent()->write("]\n")->outdent()->write(");\n");
145
- } else {
146
- $compiler->outdent()->write("];\n");
147
- }
148
- $compiler->subcompile($this->getNode('constructor_end'))->outdent()->write("}\n\n");
149
- }
150
- protected function compileDisplay(\WCML\Twig\Compiler $compiler)
151
- {
152
- $compiler->write("protected function doDisplay(array \$context, array \$blocks = [])\n", "{\n")->indent()->subcompile($this->getNode('display_start'))->subcompile($this->getNode('body'));
153
- if ($this->hasNode('parent')) {
154
- $parent = $this->getNode('parent');
155
- $compiler->addDebugInfo($parent);
156
- if ($parent instanceof \WCML\Twig\Node\Expression\ConstantExpression) {
157
- $compiler->write('$this->parent = $this->loadTemplate(')->subcompile($parent)->raw(', ')->repr($this->getSourceContext()->getName())->raw(', ')->repr($parent->getTemplateLine())->raw(");\n");
158
- $compiler->write('$this->parent');
159
- } else {
160
- $compiler->write('$this->getParent($context)');
161
- }
162
- $compiler->raw("->display(\$context, array_merge(\$this->blocks, \$blocks));\n");
163
- }
164
- $compiler->subcompile($this->getNode('display_end'))->outdent()->write("}\n\n");
165
- }
166
- protected function compileClassFooter(\WCML\Twig\Compiler $compiler)
167
- {
168
- $compiler->subcompile($this->getNode('class_end'))->outdent()->write("}\n");
169
- }
170
- protected function compileMacros(\WCML\Twig\Compiler $compiler)
171
- {
172
- $compiler->subcompile($this->getNode('macros'));
173
- }
174
- protected function compileGetTemplateName(\WCML\Twig\Compiler $compiler)
175
- {
176
- $compiler->write("public function getTemplateName()\n", "{\n")->indent()->write('return ')->repr($this->getSourceContext()->getName())->raw(";\n")->outdent()->write("}\n\n");
177
- }
178
- protected function compileIsTraitable(\WCML\Twig\Compiler $compiler)
179
- {
180
- // A template can be used as a trait if:
181
- // * it has no parent
182
- // * it has no macros
183
- // * it has no body
184
- //
185
- // Put another way, a template can be used as a trait if it
186
- // only contains blocks and use statements.
187
- $traitable = !$this->hasNode('parent') && 0 === \count($this->getNode('macros'));
188
- if ($traitable) {
189
- if ($this->getNode('body') instanceof \WCML\Twig\Node\BodyNode) {
190
- $nodes = $this->getNode('body')->getNode(0);
191
- } else {
192
- $nodes = $this->getNode('body');
193
- }
194
- if (!\count($nodes)) {
195
- $nodes = new \WCML\Twig\Node\Node([$nodes]);
196
- }
197
- foreach ($nodes as $node) {
198
- if (!\count($node)) {
199
- continue;
200
- }
201
- if ($node instanceof \WCML\Twig\Node\TextNode && \ctype_space($node->getAttribute('data'))) {
202
- continue;
203
- }
204
- if ($node instanceof \WCML\Twig\Node\BlockReferenceNode) {
205
- continue;
206
- }
207
- $traitable = \false;
208
- break;
209
- }
210
- }
211
- if ($traitable) {
212
- return;
213
- }
214
- $compiler->write("public function isTraitable()\n", "{\n")->indent()->write(\sprintf("return %s;\n", $traitable ? 'true' : 'false'))->outdent()->write("}\n\n");
215
- }
216
- protected function compileDebugInfo(\WCML\Twig\Compiler $compiler)
217
- {
218
- $compiler->write("public function getDebugInfo()\n", "{\n")->indent()->write(\sprintf("return %s;\n", \str_replace("\n", '', \var_export(\array_reverse($compiler->getDebugInfo(), \true), \true))))->outdent()->write("}\n\n");
219
- }
220
- protected function compileGetSource(\WCML\Twig\Compiler $compiler)
221
- {
222
- $compiler->write("/** @deprecated since 1.27 (to be removed in 2.0). Use getSourceContext() instead */\n")->write("public function getSource()\n", "{\n")->indent()->write("@trigger_error('The '.__METHOD__.' method is deprecated since version 1.27 and will be removed in 2.0. Use getSourceContext() instead.', E_USER_DEPRECATED);\n\n")->write('return $this->getSourceContext()->getCode();')->raw("\n")->outdent()->write("}\n\n");
223
- }
224
- protected function compileGetSourceContext(\WCML\Twig\Compiler $compiler)
225
- {
226
- $compiler->write("public function getSourceContext()\n", "{\n")->indent()->write('return new Source(')->string($compiler->getEnvironment()->isDebug() ? $this->getSourceContext()->getCode() : '')->raw(', ')->string($this->getSourceContext()->getName())->raw(', ')->string($this->getSourceContext()->getPath())->raw(");\n")->outdent()->write("}\n");
227
- }
228
- protected function compileLoadTemplate(\WCML\Twig\Compiler $compiler, $node, $var)
229
- {
230
- if ($node instanceof \WCML\Twig\Node\Expression\ConstantExpression) {
231
- $compiler->write(\sprintf('%s = $this->loadTemplate(', $var))->subcompile($node)->raw(', ')->repr($node->getTemplateName())->raw(', ')->repr($node->getTemplateLine())->raw(");\n");
232
- } else {
233
- throw new \LogicException('Trait templates can only be constant nodes.');
234
- }
235
- }
236
- }
237
- \class_alias('WCML\\Twig\\Node\\ModuleNode', 'WCML\\Twig_Node_Module');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/twig/src/Node/Node.php DELETED
@@ -1,228 +0,0 @@
1
- <?php
2
-
3
- /*
4
- * This file is part of Twig.
5
- *
6
- * (c) Fabien Potencier
7
- * (c) Armin Ronacher
8
- *
9
- * For the full copyright and license information, please view the LICENSE
10
- * file that was distributed with this source code.
11
- */
12
- namespace WCML\Twig\Node;
13
-
14
- use WCML\Twig\Compiler;
15
- use WCML\Twig\Source;
16
- /**
17
- * Represents a node in the AST.
18
- *
19
- * @author Fabien Potencier <fabien@symfony.com>
20
- */
21
- class Node implements \WCML\Twig_NodeInterface
22
- {
23
- protected $nodes;
24
- protected $attributes;
25
- protected $lineno;
26
- protected $tag;
27
- private $name;
28
- private $sourceContext;
29
- /**
30
- * @param array $nodes An array of named nodes
31
- * @param array $attributes An array of attributes (should not be nodes)
32
- * @param int $lineno The line number
33
- * @param string $tag The tag name associated with the Node
34
- */
35
- public function __construct(array $nodes = [], array $attributes = [], $lineno = 0, $tag = null)
36
- {
37
- foreach ($nodes as $name => $node) {
38
- if (!$node instanceof \WCML\Twig_NodeInterface) {
39
- @\trigger_error(\sprintf('Using "%s" for the value of node "%s" of "%s" is deprecated since version 1.25 and will be removed in 2.0.', \is_object($node) ? \get_class($node) : (null === $node ? 'null' : \gettype($node)), $name, \get_class($this)), \E_USER_DEPRECATED);
40
- }
41
- }
42
- $this->nodes = $nodes;
43
- $this->attributes = $attributes;
44
- $this->lineno = $lineno;
45
- $this->tag = $tag;
46
- }
47
- public function __toString()
48
- {
49
- $attributes = [];
50
- foreach ($this->attributes as $name => $value) {
51
- $attributes[] = \sprintf('%s: %s', $name, \str_replace("\n", '', \var_export($value, \true)));
52
- }
53
- $repr = [\get_class($this) . '(' . \implode(', ', $attributes)];
54
- if (\count($this->nodes)) {
55
- foreach ($this->nodes as $name => $node) {
56
- $len = \strlen($name) + 4;
57
- $noderepr = [];
58
- foreach (\explode("\n", (string) $node) as $line) {
59
- $noderepr[] = \str_repeat(' ', $len) . $line;
60
- }
61
- $repr[] = \sprintf(' %s: %s', $name, \ltrim(\implode("\n", $noderepr)));
62
- }
63
- $repr[] = ')';
64
- } else {
65
- $repr[0] .= ')';
66
- }
67
- return \implode("\n", $repr);
68
- }
69
- /**
70
- * @deprecated since 1.16.1 (to be removed in 2.0)
71
- */
72
- public function toXml($asDom = \false)
73
- {
74
- @\trigger_error(\sprintf('%s is deprecated since version 1.16.1 and will be removed in 2.0.', __METHOD__), \E_USER_DEPRECATED);
75
- $dom = new \DOMDocument('1.0', 'UTF-8');
76
- $dom->formatOutput = \true;
77
- $dom->appendChild($xml = $dom->createElement('twig'));
78
- $xml->appendChild($node = $dom->createElement('node'));
79
- $node->setAttribute('class', \get_class($this));
80
- foreach ($this->attributes as $name => $value) {
81
- $node->appendChild($attribute = $dom->createElement('attribute'));
82
- $attribute->setAttribute('name', $name);
83
- $attribute->appendChild($dom->createTextNode($value));
84
- }
85
- foreach ($this->nodes as $name => $n) {
86
- if (null === $n) {
87
- continue;
88
- }
89
- $child = $n->toXml(\true)->getElementsByTagName('node')->item(0);
90
- $child = $dom->importNode($child, \true);
91
- $child->setAttribute('name', $name);
92
- $node->appendChild($child);
93
- }
94
- return $asDom ? $dom : $dom->saveXML();
95
- }
96
- public function compile(\WCML\Twig\Compiler $compiler)
97
- {
98
- foreach ($this->nodes as $node) {
99
- $node->compile($compiler);
100
- }
101
- }
102
- public function getTemplateLine()
103
- {
104
- return $this->lineno;
105
- }
106
- /**
107
- * @deprecated since 1.27 (to be removed in 2.0)
108
- */
109
- public function getLine()
110
- {
111
- @\trigger_error('The ' . __METHOD__ . ' method is deprecated since version 1.27 and will be removed in 2.0. Use getTemplateLine() instead.', \E_USER_DEPRECATED);
112
- return $this->lineno;
113
- }
114
- public function getNodeTag()
115
- {
116
- return $this->tag;
117
- }
118
- /**
119
- * @return bool
120
- */
121
- public function hasAttribute($name)
122
- {
123
- return \array_key_exists($name, $this->attributes);
124
- }
125
- /**
126
- * @return mixed
127
- */
128
- public function getAttribute($name)
129
- {
130
- if (!\array_key_exists($name, $this->attributes)) {
131
- throw new \LogicException(\sprintf('Attribute "%s" does not exist for Node "%s".', $name, \get_class($this)));
132
- }
133
- return $this->attributes[$name];
134
- }
135
- /**
136
- * @param string $name
137
- * @param mixed $value
138
- */
139
- public function setAttribute($name, $value)
140
- {
141
- $this->attributes[$name] = $value;
142
- }
143
- public function removeAttribute($name)
144
- {
145
- unset($this->attributes[$name]);
146
- }
147
- /**
148
- * @return bool
149
- */
150
- public function hasNode($name)
151
- {
152
- return \array_key_exists($name, $this->nodes);
153
- }
154
- /**
155
- * @return Node
156
- */
157
- public function getNode($name)
158
- {
159
- if (!\array_key_exists($name, $this->nodes)) {
160
- throw new \LogicException(\sprintf('Node "%s" does not exist for Node "%s".', $name, \get_class($this)));
161
- }
162
- return $this->nodes[$name];
163
- }
164
- public function setNode($name, $node = null)
165
- {
166
- if (!$node instanceof \WCML\Twig_NodeInterface) {
167
- @\trigger_error(\sprintf('Using "%s" for the value of node "%s" of "%s" is deprecated since version 1.25 and will be removed in 2.0.', \is_object($node) ? \get_class($node) : (null === $node ? 'null' : \gettype($node)), $name, \get_class($this)), \E_USER_DEPRECATED);
168
- }
169
- $this->nodes[$name] = $node;
170
- }
171
- public function removeNode($name)
172
- {
173
- unset($this->nodes[$name]);
174
- }
175
- public function count()
176
- {
177
- return \count($this->nodes);
178
- }
179
- public function getIterator()
180
- {
181
- return new \ArrayIterator($this->nodes);
182
- }
183
- public function setTemplateName($name)
184
- {
185
- $this->name = $name;
186
- foreach ($this->nodes as $node) {
187
- if (null !== $node) {
188
- $node->setTemplateName($name);
189
- }
190
- }
191
- }
192
- public function getTemplateName()
193
- {
194
- return $this->name;
195
- }
196
- public function setSourceContext(\WCML\Twig\Source $source)
197
- {
198
- $this->sourceContext = $source;
199
- foreach ($this->nodes as $node) {
200
- if ($node instanceof \WCML\Twig\Node\Node) {
201
- $node->setSourceContext($source);
202
- }
203
- }
204
- }
205
- public function getSourceContext()
206
- {
207
- return $this->sourceContext;
208
- }
209
- /**
210
- * @deprecated since 1.27 (to be removed in 2.0)
211
- */
212
- public function setFilename($name)
213
- {
214
- @\trigger_error('The ' . __METHOD__ . ' method is deprecated since version 1.27 and will be removed in 2.0. Use setTemplateName() instead.', \E_USER_DEPRECATED);
215
- $this->setTemplateName($name);
216
- }
217
- /**
218
- * @deprecated since 1.27 (to be removed in 2.0)
219
- */
220
- public function getFilename()
221
- {
222
- @\trigger_error('The ' . __METHOD__ . ' method is deprecated since version 1.27 and will be removed in 2.0. Use getTemplateName() instead.', \E_USER_DEPRECATED);
223
- return $this->name;
224
- }
225
- }
226
- \class_alias('WCML\\Twig\\Node\\Node', 'WCML\\Twig_Node');
227
- // Ensure that the aliased name is loaded to keep BC for classes implementing the typehint with the old aliased name.
228
- \class_exists('WCML\\Twig\\Compiler');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/twig/src/Node/NodeCaptureInterface.php DELETED
@@ -1,21 +0,0 @@
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
- namespace WCML\Twig\Node;
12
-
13
- /**
14
- * Represents a node that captures any nested displayable nodes.
15
- *
16
- * @author Fabien Potencier <fabien@symfony.com>
17
- */
18
- interface NodeCaptureInterface
19
- {
20
- }
21
- \class_alias('WCML\\Twig\\Node\\NodeCaptureInterface', 'WCML\\Twig_NodeCaptureInterface');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/twig/src/Node/NodeOutputInterface.php DELETED
@@ -1,21 +0,0 @@
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
- namespace WCML\Twig\Node;
12
-
13
- /**
14
- * Represents a displayable node in the AST.
15
- *
16
- * @author Fabien Potencier <fabien@symfony.com>
17
- */
18
- interface NodeOutputInterface
19
- {
20
- }
21
- \class_alias('WCML\\Twig\\Node\\NodeOutputInterface', 'WCML\\Twig_NodeOutputInterface');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/twig/src/Node/PrintNode.php DELETED
@@ -1,32 +0,0 @@
1
- <?php
2
-
3
- /*
4
- * This file is part of Twig.
5
- *
6
- * (c) Fabien Potencier
7
- * (c) Armin Ronacher
8
- *
9
- * For the full copyright and license information, please view the LICENSE
10
- * file that was distributed with this source code.
11
- */
12
- namespace WCML\Twig\Node;
13
-
14
- use WCML\Twig\Compiler;
15
- use WCML\Twig\Node\Expression\AbstractExpression;
16
- /**
17
- * Represents a node that outputs an expression.
18
- *
19
- * @author Fabien Potencier <fabien@symfony.com>
20
- */
21
- class PrintNode extends \WCML\Twig\Node\Node implements \WCML\Twig\Node\NodeOutputInterface
22
- {
23
- public function __construct(\WCML\Twig\Node\Expression\AbstractExpression $expr, $lineno, $tag = null)
24
- {
25
- parent::__construct(['expr' => $expr], [], $lineno, $tag);
26
- }
27
- public function compile(\WCML\Twig\Compiler $compiler)
28
- {
29
- $compiler->addDebugInfo($this)->write('echo ')->subcompile($this->getNode('expr'))->raw(";\n");
30
- }
31
- }
32
- \class_alias('WCML\\Twig\\Node\\PrintNode', 'WCML\\Twig_Node_Print');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/twig/src/Node/SandboxNode.php DELETED
@@ -1,30 +0,0 @@
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
- namespace WCML\Twig\Node;
12
-
13
- use WCML\Twig\Compiler;
14
- /**
15
- * Represents a sandbox node.
16
- *
17
- * @author Fabien Potencier <fabien@symfony.com>
18
- */
19
- class SandboxNode extends \WCML\Twig\Node\Node
20
- {
21
- public function __construct(\WCML\Twig_NodeInterface $body, $lineno, $tag = null)
22
- {
23
- parent::__construct(['body' => $body], [], $lineno, $tag);
24
- }
25
- public function compile(\WCML\Twig\Compiler $compiler)
26
- {
27
- $compiler->addDebugInfo($this)->write("if (!\$alreadySandboxed = \$this->sandbox->isSandboxed()) {\n")->indent()->write("\$this->sandbox->enableSandbox();\n")->outdent()->write("}\n")->subcompile($this->getNode('body'))->write("if (!\$alreadySandboxed) {\n")->indent()->write("\$this->sandbox->disableSandbox();\n")->outdent()->write("}\n");
28
- }
29
- }
30
- \class_alias('WCML\\Twig\\Node\\SandboxNode', 'WCML\\Twig_Node_Sandbox');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/twig/src/Node/SandboxedPrintNode.php DELETED
@@ -1,54 +0,0 @@
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
- namespace WCML\Twig\Node;
12
-
13
- use WCML\Twig\Compiler;
14
- use WCML\Twig\Node\Expression\ConstantExpression;
15
- use WCML\Twig\Node\Expression\FilterExpression;
16
- /**
17
- * Adds a check for the __toString() method when the variable is an object and the sandbox is activated.
18
- *
19
- * When there is a simple Print statement, like {{ article }},
20
- * and if the sandbox is enabled, we need to check that the __toString()
21
- * method is allowed if 'article' is an object.
22
- *
23
- * Not used anymore, to be deprecated in 2.x and removed in 3.0
24
- *
25
- * @author Fabien Potencier <fabien@symfony.com>
26
- */
27
- class SandboxedPrintNode extends \WCML\Twig\Node\PrintNode
28
- {
29
- public function compile(\WCML\Twig\Compiler $compiler)
30
- {
31
- $compiler->addDebugInfo($this)->write('echo ');
32
- $expr = $this->getNode('expr');
33
- if ($expr instanceof \WCML\Twig\Node\Expression\ConstantExpression) {
34
- $compiler->subcompile($expr)->raw(";\n");
35
- } else {
36
- $compiler->write('$this->env->getExtension(\'\\WCML\\Twig\\Extension\\SandboxExtension\')->ensureToStringAllowed(')->subcompile($expr)->raw(");\n");
37
- }
38
- }
39
- /**
40
- * Removes node filters.
41
- *
42
- * This is mostly needed when another visitor adds filters (like the escaper one).
43
- *
44
- * @return Node
45
- */
46
- protected function removeNodeFilter(\WCML\Twig\Node\Node $node)
47
- {
48
- if ($node instanceof \WCML\Twig\Node\Expression\FilterExpression) {
49
- return $this->removeNodeFilter($node->getNode('node'));
50
- }
51
- return $node;
52
- }
53
- }
54
- \class_alias('WCML\\Twig\\Node\\SandboxedPrintNode', 'WCML\\Twig_Node_SandboxedPrint');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/twig/src/Node/SetNode.php DELETED
@@ -1,87 +0,0 @@
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
- namespace WCML\Twig\Node;
12
-
13
- use WCML\Twig\Compiler;
14
- use WCML\Twig\Node\Expression\ConstantExpression;
15
- /**
16
- * Represents a set node.
17
- *
18
- * @author Fabien Potencier <fabien@symfony.com>
19
- */
20
- class SetNode extends \WCML\Twig\Node\Node implements \WCML\Twig\Node\NodeCaptureInterface
21
- {
22
- public function __construct($capture, \WCML\Twig_NodeInterface $names, \WCML\Twig_NodeInterface $values, $lineno, $tag = null)
23
- {
24
- parent::__construct(['names' => $names, 'values' => $values], ['capture' => $capture, 'safe' => \false], $lineno, $tag);
25
- /*
26
- * Optimizes the node when capture is used for a large block of text.
27
- *
28
- * {% set foo %}foo{% endset %} is compiled to $context['foo'] = new Twig\Markup("foo");
29
- */
30
- if ($this->getAttribute('capture')) {
31
- $this->setAttribute('safe', \true);
32
- $values = $this->getNode('values');
33
- if ($values instanceof \WCML\Twig\Node\TextNode) {
34
- $this->setNode('values', new \WCML\Twig\Node\Expression\ConstantExpression($values->getAttribute('data'), $values->getTemplateLine()));
35
- $this->setAttribute('capture', \false);
36
- }
37
- }
38
- }
39
- public function compile(\WCML\Twig\Compiler $compiler)
40
- {
41
- $compiler->addDebugInfo($this);
42
- if (\count($this->getNode('names')) > 1) {
43
- $compiler->write('list(');
44
- foreach ($this->getNode('names') as $idx => $node) {
45
- if ($idx) {
46
- $compiler->raw(', ');
47
- }
48
- $compiler->subcompile($node);
49
- }
50
- $compiler->raw(')');
51
- } else {
52
- if ($this->getAttribute('capture')) {
53
- if ($compiler->getEnvironment()->isDebug()) {
54
- $compiler->write("ob_start();\n");
55
- } else {
56
- $compiler->write("ob_start(function () { return ''; });\n");
57
- }
58
- $compiler->subcompile($this->getNode('values'));
59
- }
60
- $compiler->subcompile($this->getNode('names'), \false);
61
- if ($this->getAttribute('capture')) {
62
- $compiler->raw(" = ('' === \$tmp = ob_get_clean()) ? '' : new Markup(\$tmp, \$this->env->getCharset())");
63
- }
64
- }
65
- if (!$this->getAttribute('capture')) {
66
- $compiler->raw(' = ');
67
- if (\count($this->getNode('names')) > 1) {
68
- $compiler->write('[');
69
- foreach ($this->getNode('values') as $idx => $value) {
70
- if ($idx) {
71
- $compiler->raw(', ');
72
- }
73
- $compiler->subcompile($value);
74
- }
75
- $compiler->raw(']');
76
- } else {
77
- if ($this->getAttribute('safe')) {
78
- $compiler->raw("('' === \$tmp = ")->subcompile($this->getNode('values'))->raw(") ? '' : new Markup(\$tmp, \$this->env->getCharset())");
79
- } else {
80
- $compiler->subcompile($this->getNode('values'));
81
- }
82
- }
83
- }
84
- $compiler->raw(";\n");
85
- }
86
- }
87
- \class_alias('WCML\\Twig\\Node\\SetNode', 'WCML\\Twig_Node_Set');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/twig/src/Node/SetTempNode.php DELETED
@@ -1,29 +0,0 @@
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
- namespace WCML\Twig\Node;
12
-
13
- use WCML\Twig\Compiler;
14
- /**
15
- * @internal
16
- */
17
- class SetTempNode extends \WCML\Twig\Node\Node
18
- {
19
- public function __construct($name, $lineno)
20
- {
21
- parent::__construct([], ['name' => $name], $lineno);
22
- }
23
- public function compile(\WCML\Twig\Compiler $compiler)
24
- {
25
- $name = $this->getAttribute('name');
26
- $compiler->addDebugInfo($this)->write('if (isset($context[')->string($name)->raw('])) { $_')->raw($name)->raw('_ = $context[')->repr($name)->raw(']; } else { $_')->raw($name)->raw("_ = null; }\n");
27
- }
28
- }
29
- \class_alias('WCML\\Twig\\Node\\SetTempNode', 'WCML\\Twig_Node_SetTemp');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/twig/src/Node/SpacelessNode.php DELETED
@@ -1,38 +0,0 @@
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
- namespace WCML\Twig\Node;
12
-
13
- use WCML\Twig\Compiler;
14
- /**
15
- * Represents a spaceless node.
16
- *
17
- * It removes spaces between HTML tags.
18
- *
19
- * @author Fabien Potencier <fabien@symfony.com>
20
- */
21
- class SpacelessNode extends \WCML\Twig\Node\Node
22
- {
23
- public function __construct(\WCML\Twig_NodeInterface $body, $lineno, $tag = 'spaceless')
24
- {
25
- parent::__construct(['body' => $body], [], $lineno, $tag);
26
- }
27
- public function compile(\WCML\Twig\Compiler $compiler)
28
- {
29
- $compiler->addDebugInfo($this);
30
- if ($compiler->getEnvironment()->isDebug()) {
31
- $compiler->write("ob_start();\n");
32
- } else {
33
- $compiler->write("ob_start(function () { return ''; });\n");
34
- }
35
- $compiler->subcompile($this->getNode('body'))->write("echo trim(preg_replace('/>\\s+</', '><', ob_get_clean()));\n");
36
- }
37
- }
38
- \class_alias('WCML\\Twig\\Node\\SpacelessNode', 'WCML\\Twig_Node_Spaceless');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/twig/src/Node/TextNode.php DELETED
@@ -1,31 +0,0 @@
1
- <?php
2
-
3
- /*
4
- * This file is part of Twig.
5
- *
6
- * (c) Fabien Potencier
7
- * (c) Armin Ronacher
8
- *
9
- * For the full copyright and license information, please view the LICENSE
10
- * file that was distributed with this source code.
11
- */
12
- namespace WCML\Twig\Node;
13
-
14
- use WCML\Twig\Compiler;
15
- /**
16
- * Represents a text node.
17
- *
18
- * @author Fabien Potencier <fabien@symfony.com>
19
- */
20
- class TextNode extends \WCML\Twig\Node\Node implements \WCML\Twig\Node\NodeOutputInterface
21
- {
22
- public function __construct($data, $lineno)
23
- {
24
- parent::__construct([], ['data' => $data], $lineno);
25
- }
26
- public function compile(\WCML\Twig\Compiler $compiler)
27
- {
28
- $compiler->addDebugInfo($this)->write('echo ')->string($this->getAttribute('data'))->raw(";\n");
29
- }
30
- }
31
- \class_alias('WCML\\Twig\\Node\\TextNode', 'WCML\\Twig_Node_Text');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/twig/src/Node/WithNode.php DELETED
@@ -1,48 +0,0 @@
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
- namespace WCML\Twig\Node;
12
-
13
- use WCML\Twig\Compiler;
14
- /**
15
- * Represents a nested "with" scope.
16
- *
17
- * @author Fabien Potencier <fabien@symfony.com>
18
- */
19
- class WithNode extends \WCML\Twig\Node\Node
20
- {
21
- public function __construct(\WCML\Twig\Node\Node $body, \WCML\Twig\Node\Node $variables = null, $only = \false, $lineno, $tag = null)
22
- {
23
- $nodes = ['body' => $body];
24
- if (null !== $variables) {
25
- $nodes['variables'] = $variables;
26
- }
27
- parent::__construct($nodes, ['only' => (bool) $only], $lineno, $tag);
28
- }
29
- public function compile(\WCML\Twig\Compiler $compiler)
30
- {
31
- $compiler->addDebugInfo($this);
32
- if ($this->hasNode('variables')) {
33
- $node = $this->getNode('variables');
34
- $varsName = $compiler->getVarName();
35
- $compiler->write(\sprintf('$%s = ', $varsName))->subcompile($node)->raw(";\n")->write(\sprintf("if (!twig_test_iterable(\$%s)) {\n", $varsName))->indent()->write("throw new RuntimeError('Variables passed to the \"with\" tag must be a hash.', ")->repr($node->getTemplateLine())->raw(", \$this->getSourceContext());\n")->outdent()->write("}\n")->write(\sprintf("\$%s = twig_to_array(\$%s);\n", $varsName, $varsName));
36
- if ($this->getAttribute('only')) {
37
- $compiler->write("\$context = ['_parent' => \$context];\n");
38
- } else {
39
- $compiler->write("\$context['_parent'] = \$context;\n");
40
- }
41
- $compiler->write(\sprintf("\$context = \$this->env->mergeGlobals(array_merge(\$context, \$%s));\n", $varsName));
42
- } else {
43
- $compiler->write("\$context['_parent'] = \$context;\n");
44
- }
45
- $compiler->subcompile($this->getNode('body'))->write("\$context = \$context['_parent'];\n");
46
- }
47
- }
48
- \class_alias('WCML\\Twig\\Node\\WithNode', 'WCML\\Twig_Node_With');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/twig/src/NodeTraverser.php DELETED
@@ -1,77 +0,0 @@
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
- namespace WCML\Twig;
12
-
13
- use WCML\Twig\NodeVisitor\NodeVisitorInterface;
14
- /**
15
- * A node traverser.
16
- *
17
- * It visits all nodes and their children and calls the given visitor for each.
18
- *
19
- * @final
20
- *
21
- * @author Fabien Potencier <fabien@symfony.com>
22
- */
23
- class NodeTraverser
24
- {
25
- protected $env;
26
- protected $visitors = [];
27
- /**
28
- * @param NodeVisitorInterface[] $visitors
29
- */
30
- public function __construct(\WCML\Twig\Environment $env, array $visitors = [])
31
- {
32
- $this->env = $env;
33
- foreach ($visitors as $visitor) {
34
- $this->addVisitor($visitor);
35
- }
36
- }
37
- public function addVisitor(\WCML\Twig\NodeVisitor\NodeVisitorInterface $visitor)
38
- {
39
- $this->visitors[$visitor->getPriority()][] = $visitor;
40
- }
41
- /**
42
- * Traverses a node and calls the registered visitors.
43
- *
44
- * @return \Twig_NodeInterface
45
- */
46
- public function traverse(\WCML\Twig_NodeInterface $node)
47
- {
48
- \ksort($this->visitors);
49
- foreach ($this->visitors as $visitors) {
50
- foreach ($visitors as $visitor) {
51
- $node = $this->traverseForVisitor($visitor, $node);
52
- }
53
- }
54
- return $node;
55
- }
56
- protected function traverseForVisitor(\WCML\Twig\NodeVisitor\NodeVisitorInterface $visitor, \WCML\Twig_NodeInterface $node = null)
57
- {
58
- if (null === $node) {
59
- return;
60
- }
61
- $node = $visitor->enterNode($node, $this->env);
62
- foreach ($node as $k => $n) {
63
- if (null === $n) {
64
- continue;
65
- }
66
- if (\false !== ($m = $this->traverseForVisitor($visitor, $n)) && null !== $m) {
67
- if ($m !== $n) {
68
- $node->setNode($k, $m);
69
- }
70
- } else {
71
- $node->removeNode($k);
72
- }
73
- }
74
- return $visitor->leaveNode($node, $this->env);
75
- }
76
- }
77
- \class_alias('WCML\\Twig\\NodeTraverser', 'WCML\\Twig_NodeTraverser');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/twig/src/NodeVisitor/AbstractNodeVisitor.php DELETED
@@ -1,51 +0,0 @@
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
- namespace WCML\Twig\NodeVisitor;
12
-
13
- use WCML\Twig\Environment;
14
- use WCML\Twig\Node\Node;
15
- /**
16
- * Used to make node visitors compatible with Twig 1.x and 2.x.
17
- *
18
- * To be removed in Twig 3.1.
19
- *
20
- * @author Fabien Potencier <fabien@symfony.com>
21
- */
22
- abstract class AbstractNodeVisitor implements \WCML\Twig\NodeVisitor\NodeVisitorInterface
23
- {
24
- public final function enterNode(\WCML\Twig_NodeInterface $node, \WCML\Twig\Environment $env)
25
- {
26
- if (!$node instanceof \WCML\Twig\Node\Node) {
27
- throw new \LogicException(\sprintf('%s only supports \\Twig\\Node\\Node instances.', __CLASS__));
28
- }
29
- return $this->doEnterNode($node, $env);
30
- }
31
- public final function leaveNode(\WCML\Twig_NodeInterface $node, \WCML\Twig\Environment $env)
32
- {
33
- if (!$node instanceof \WCML\Twig\Node\Node) {
34
- throw new \LogicException(\sprintf('%s only supports \\Twig\\Node\\Node instances.', __CLASS__));
35
- }
36
- return $this->doLeaveNode($node, $env);
37
- }
38
- /**
39
- * Called before child nodes are visited.
40
- *
41
- * @return Node The modified node
42
- */
43
- protected abstract function doEnterNode(\WCML\Twig\Node\Node $node, \WCML\Twig\Environment $env);
44
- /**
45
- * Called after child nodes are visited.
46
- *
47
- * @return Node|false|null The modified node or null if the node must be removed
48
- */
49
- protected abstract function doLeaveNode(\WCML\Twig\Node\Node $node, \WCML\Twig\Environment $env);
50
- }
51
- \class_alias('WCML\\Twig\\NodeVisitor\\AbstractNodeVisitor', 'WCML\\Twig_BaseNodeVisitor');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/twig/src/NodeVisitor/EscaperNodeVisitor.php DELETED
@@ -1,172 +0,0 @@
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
- namespace WCML\Twig\NodeVisitor;
12
-
13
- use WCML\Twig\Environment;
14
- use WCML\Twig\Node\AutoEscapeNode;
15
- use WCML\Twig\Node\BlockNode;
16
- use WCML\Twig\Node\BlockReferenceNode;
17
- use WCML\Twig\Node\DoNode;
18
- use WCML\Twig\Node\Expression\ConditionalExpression;
19
- use WCML\Twig\Node\Expression\ConstantExpression;
20
- use WCML\Twig\Node\Expression\FilterExpression;
21
- use WCML\Twig\Node\Expression\InlinePrint;
22
- use WCML\Twig\Node\ImportNode;
23
- use WCML\Twig\Node\ModuleNode;
24
- use WCML\Twig\Node\Node;
25
- use WCML\Twig\Node\PrintNode;
26
- use WCML\Twig\NodeTraverser;
27
- /**
28
- * @final
29
- *
30
- * @author Fabien Potencier <fabien@symfony.com>
31
- */
32
- class EscaperNodeVisitor extends \WCML\Twig\NodeVisitor\AbstractNodeVisitor
33
- {
34
- protected $statusStack = [];
35
- protected $blocks = [];
36
- protected $safeAnalysis;
37
- protected $traverser;
38
- protected $defaultStrategy = \false;
39
- protected $safeVars = [];
40
- public function __construct()
41
- {
42
- $this->safeAnalysis = new \WCML\Twig\NodeVisitor\SafeAnalysisNodeVisitor();
43
- }
44
- protected function doEnterNode(\WCML\Twig\Node\Node $node, \WCML\Twig\Environment $env)
45
- {
46
- if ($node instanceof \WCML\Twig\Node\ModuleNode) {
47
- if ($env->hasExtension('WCML\\Twig\\Extension\\EscaperExtension') && ($defaultStrategy = $env->getExtension('WCML\\Twig\\Extension\\EscaperExtension')->getDefaultStrategy($node->getTemplateName()))) {
48
- $this->defaultStrategy = $defaultStrategy;
49
- }
50
- $this->safeVars = [];
51
- $this->blocks = [];
52
- } elseif ($node instanceof \WCML\Twig\Node\AutoEscapeNode) {
53
- $this->statusStack[] = $node->getAttribute('value');
54
- } elseif ($node instanceof \WCML\Twig\Node\BlockNode) {
55
- $this->statusStack[] = isset($this->blocks[$node->getAttribute('name')]) ? $this->blocks[$node->getAttribute('name')] : $this->needEscaping($env);
56
- } elseif ($node instanceof \WCML\Twig\Node\ImportNode) {
57
- $this->safeVars[] = $node->getNode('var')->getAttribute('name');
58
- }
59
- return $node;
60
- }
61
- protected function doLeaveNode(\WCML\Twig\Node\Node $node, \WCML\Twig\Environment $env)
62
- {
63
- if ($node instanceof \WCML\Twig\Node\ModuleNode) {
64
- $this->defaultStrategy = \false;
65
- $this->safeVars = [];
66
- $this->blocks = [];
67
- } elseif ($node instanceof \WCML\Twig\Node\Expression\FilterExpression) {
68
- return $this->preEscapeFilterNode($node, $env);
69
- } elseif ($node instanceof \WCML\Twig\Node\PrintNode && \false !== ($type = $this->needEscaping($env))) {
70
- $expression = $node->getNode('expr');
71
- if ($expression instanceof \WCML\Twig\Node\Expression\ConditionalExpression && $this->shouldUnwrapConditional($expression, $env, $type)) {
72
- return new \WCML\Twig\Node\DoNode($this->unwrapConditional($expression, $env, $type), $expression->getTemplateLine());
73
- }
74
- return $this->escapePrintNode($node, $env, $type);
75
- }
76
- if ($node instanceof \WCML\Twig\Node\AutoEscapeNode || $node instanceof \WCML\Twig\Node\BlockNode) {
77
- \array_pop($this->statusStack);
78
- } elseif ($node instanceof \WCML\Twig\Node\BlockReferenceNode) {
79
- $this->blocks[$node->getAttribute('name')] = $this->needEscaping($env);
80
- }
81
- return $node;
82
- }
83
- private function shouldUnwrapConditional(\WCML\Twig\Node\Expression\ConditionalExpression $expression, \WCML\Twig\Environment $env, $type)
84
- {
85
- $expr2Safe = $this->isSafeFor($type, $expression->getNode('expr2'), $env);
86
- $expr3Safe = $this->isSafeFor($type, $expression->getNode('expr3'), $env);
87
- return $expr2Safe !== $expr3Safe;
88
- }
89
- private function unwrapConditional(\WCML\Twig\Node\Expression\ConditionalExpression $expression, \WCML\Twig\Environment $env, $type)
90
- {
91
- // convert "echo a ? b : c" to "a ? echo b : echo c" recursively
92
- $expr2 = $expression->getNode('expr2');
93
- if ($expr2 instanceof \WCML\Twig\Node\Expression\ConditionalExpression && $this->shouldUnwrapConditional($expr2, $env, $type)) {
94
- $expr2 = $this->unwrapConditional($expr2, $env, $type);
95
- } else {
96
- $expr2 = $this->escapeInlinePrintNode(new \WCML\Twig\Node\Expression\InlinePrint($expr2, $expr2->getTemplateLine()), $env, $type);
97
- }
98
- $expr3 = $expression->getNode('expr3');
99
- if ($expr3 instanceof \WCML\Twig\Node\Expression\ConditionalExpression && $this->shouldUnwrapConditional($expr3, $env, $type)) {
100
- $expr3 = $this->unwrapConditional($expr3, $env, $type);
101
- } else {
102
- $expr3 = $this->escapeInlinePrintNode(new \WCML\Twig\Node\Expression\InlinePrint($expr3, $expr3->getTemplateLine()), $env, $type);
103
- }
104
- return new \WCML\Twig\Node\Expression\ConditionalExpression($expression->getNode('expr1'), $expr2, $expr3, $expression->getTemplateLine());
105
- }
106
- private function escapeInlinePrintNode(\WCML\Twig\Node\Expression\InlinePrint $node, \WCML\Twig\Environment $env, $type)
107
- {
108
- $expression = $node->getNode('node');
109
- if ($this->isSafeFor($type, $expression, $env)) {
110
- return $node;
111
- }
112
- return new \WCML\Twig\Node\Expression\InlinePrint($this->getEscaperFilter($type, $expression), $node->getTemplateLine());
113
- }
114
- protected function escapePrintNode(\WCML\Twig\Node\PrintNode $node, \WCML\Twig\Environment $env, $type)
115
- {
116
- if (\false === $type) {
117
- return $node;
118
- }
119
- $expression = $node->getNode('expr');
120
- if ($this->isSafeFor($type, $expression, $env)) {
121
- return $node;
122
- }
123
- $class = \get_class($node);
124
- return new $class($this->getEscaperFilter($type, $expression), $node->getTemplateLine());
125
- }
126
- protected function preEscapeFilterNode(\WCML\Twig\Node\Expression\FilterExpression $filter, \WCML\Twig\Environment $env)
127
- {
128
- $name = $filter->getNode('filter')->getAttribute('value');
129
- $type = $env->getFilter($name)->getPreEscape();
130
- if (null === $type) {
131
- return $filter;
132
- }
133
- $node = $filter->getNode('node');
134
- if ($this->isSafeFor($type, $node, $env)) {
135
- return $filter;
136
- }
137
- $filter->setNode('node', $this->getEscaperFilter($type, $node));
138
- return $filter;
139
- }
140
- protected function isSafeFor($type, \WCML\Twig_NodeInterface $expression, $env)
141
- {
142
- $safe = $this->safeAnalysis->getSafe($expression);
143
- if (null === $safe) {
144
- if (null === $this->traverser) {
145
- $this->traverser = new \WCML\Twig\NodeTraverser($env, [$this->safeAnalysis]);
146
- }
147
- $this->safeAnalysis->setSafeVars($this->safeVars);
148
- $this->traverser->traverse($expression);
149
- $safe = $this->safeAnalysis->getSafe($expression);
150
- }
151
- return \in_array($type, $safe) || \in_array('all', $safe);
152
- }
153
- protected function needEscaping(\WCML\Twig\Environment $env)
154
- {
155
- if (\count($this->statusStack)) {
156
- return $this->statusStack[\count($this->statusStack) - 1];
157
- }
158
- return $this->defaultStrategy ? $this->defaultStrategy : \false;
159
- }
160
- protected function getEscaperFilter($type, \WCML\Twig_NodeInterface $node)
161
- {
162
- $line = $node->getTemplateLine();
163
- $name = new \WCML\Twig\Node\Expression\ConstantExpression('escape', $line);
164
- $args = new \WCML\Twig\Node\Node([new \WCML\Twig\Node\Expression\ConstantExpression((string) $type, $line), new \WCML\Twig\Node\Expression\ConstantExpression(null, $line), new \WCML\Twig\Node\Expression\ConstantExpression(\true, $line)]);
165
- return new \WCML\Twig\Node\Expression\FilterExpression($node, $name, $args, $line);
166
- }
167
- public function getPriority()
168
- {
169
- return 0;
170
- }
171
- }
172
- \class_alias('WCML\\Twig\\NodeVisitor\\EscaperNodeVisitor', 'WCML\\Twig_NodeVisitor_Escaper');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/twig/src/NodeVisitor/NodeVisitorInterface.php DELETED
@@ -1,44 +0,0 @@
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
- namespace WCML\Twig\NodeVisitor;
12
-
13
- use WCML\Twig\Environment;
14
- /**
15
- * Interface for node visitor classes.
16
- *
17
- * @author Fabien Potencier <fabien@symfony.com>
18
- */
19
- interface NodeVisitorInterface
20
- {
21
- /**
22
- * Called before child nodes are visited.
23
- *
24
- * @return \Twig_NodeInterface The modified node
25
- */
26
- public function enterNode(\WCML\Twig_NodeInterface $node, \WCML\Twig\Environment $env);
27
- /**
28
- * Called after child nodes are visited.
29
- *
30
- * @return \Twig_NodeInterface|false|null The modified node or null if the node must be removed
31
- */
32
- public function leaveNode(\WCML\Twig_NodeInterface $node, \WCML\Twig\Environment $env);
33
- /**
34
- * Returns the priority for this visitor.
35
- *
36
- * Priority should be between -10 and 10 (0 is the default).
37
- *
38
- * @return int The priority level
39
- */
40
- public function getPriority();
41
- }
42
- \class_alias('WCML\\Twig\\NodeVisitor\\NodeVisitorInterface', 'WCML\\Twig_NodeVisitorInterface');
43
- // Ensure that the aliased name is loaded to keep BC for classes implementing the typehint with the old aliased name.
44
- \class_exists('WCML\\Twig\\Environment');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/twig/src/NodeVisitor/OptimizerNodeVisitor.php DELETED
@@ -1,206 +0,0 @@
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
- namespace WCML\Twig\NodeVisitor;
12
-
13
- use WCML\Twig\Environment;
14
- use WCML\Twig\Node\BlockReferenceNode;
15
- use WCML\Twig\Node\BodyNode;
16
- use WCML\Twig\Node\Expression\AbstractExpression;
17
- use WCML\Twig\Node\Expression\BlockReferenceExpression;
18
- use WCML\Twig\Node\Expression\ConstantExpression;
19
- use WCML\Twig\Node\Expression\FilterExpression;
20
- use WCML\Twig\Node\Expression\FunctionExpression;
21
- use WCML\Twig\Node\Expression\GetAttrExpression;
22
- use WCML\Twig\Node\Expression\NameExpression;
23
- use WCML\Twig\Node\Expression\ParentExpression;
24
- use WCML\Twig\Node\Expression\TempNameExpression;
25
- use WCML\Twig\Node\ForNode;
26
- use WCML\Twig\Node\IncludeNode;
27
- use WCML\Twig\Node\Node;
28
- use WCML\Twig\Node\PrintNode;
29
- use WCML\Twig\Node\SetTempNode;
30
- /**
31
- * Tries to optimize the AST.
32
- *
33
- * This visitor is always the last registered one.
34
- *
35
- * You can configure which optimizations you want to activate via the
36
- * optimizer mode.
37
- *
38
- * @final
39
- *
40
- * @author Fabien Potencier <fabien@symfony.com>
41
- */
42
- class OptimizerNodeVisitor extends \WCML\Twig\NodeVisitor\AbstractNodeVisitor
43
- {
44
- const OPTIMIZE_ALL = -1;
45
- const OPTIMIZE_NONE = 0;
46
- const OPTIMIZE_FOR = 2;
47
- const OPTIMIZE_RAW_FILTER = 4;
48
- const OPTIMIZE_VAR_ACCESS = 8;
49
- protected $loops = [];
50
- protected $loopsTargets = [];
51
- protected $optimizers;
52
- protected $prependedNodes = [];
53
- protected $inABody = \false;
54
- /**
55
- * @param int $optimizers The optimizer mode
56
- */
57
- public function __construct($optimizers = -1)
58
- {
59
- if (!\is_int($optimizers) || $optimizers > (self::OPTIMIZE_FOR | self::OPTIMIZE_RAW_FILTER | self::OPTIMIZE_VAR_ACCESS)) {
60
- throw new \InvalidArgumentException(\sprintf('Optimizer mode "%s" is not valid.', $optimizers));
61
- }
62
- $this->optimizers = $optimizers;
63
- }
64
- protected function doEnterNode(\WCML\Twig\Node\Node $node, \WCML\Twig\Environment $env)
65
- {
66
- if (self::OPTIMIZE_FOR === (self::OPTIMIZE_FOR & $this->optimizers)) {
67
- $this->enterOptimizeFor($node, $env);
68
- }
69
- if (\PHP_VERSION_ID < 50400 && self::OPTIMIZE_VAR_ACCESS === (self::OPTIMIZE_VAR_ACCESS & $this->optimizers) && !$env->isStrictVariables() && !$env->hasExtension('WCML\\Twig\\Extension\\SandboxExtension')) {
70
- if ($this->inABody) {
71
- if (!$node instanceof \WCML\Twig\Node\Expression\AbstractExpression) {
72
- if ('Twig_Node' !== \get_class($node)) {
73
- \array_unshift($this->prependedNodes, []);
74
- }
75
- } else {
76
- $node = $this->optimizeVariables($node, $env);
77
- }
78
- } elseif ($node instanceof \WCML\Twig\Node\BodyNode) {
79
- $this->inABody = \true;
80
- }
81
- }
82
- return $node;
83
- }
84
- protected function doLeaveNode(\WCML\Twig\Node\Node $node, \WCML\Twig\Environment $env)
85
- {
86
- $expression = $node instanceof \WCML\Twig\Node\Expression\AbstractExpression;
87
- if (self::OPTIMIZE_FOR === (self::OPTIMIZE_FOR & $this->optimizers)) {
88
- $this->leaveOptimizeFor($node, $env);
89
- }
90
- if (self::OPTIMIZE_RAW_FILTER === (self::OPTIMIZE_RAW_FILTER & $this->optimizers)) {
91
- $node = $this->optimizeRawFilter($node, $env);
92
- }
93
- $node = $this->optimizePrintNode($node, $env);
94
- if (self::OPTIMIZE_VAR_ACCESS === (self::OPTIMIZE_VAR_ACCESS & $this->optimizers) && !$env->isStrictVariables() && !$env->hasExtension('WCML\\Twig\\Extension\\SandboxExtension')) {
95
- if ($node instanceof \WCML\Twig\Node\BodyNode) {
96
- $this->inABody = \false;
97
- } elseif ($this->inABody) {
98
- if (!$expression && 'Twig_Node' !== \get_class($node) && ($prependedNodes = \array_shift($this->prependedNodes))) {
99
- $nodes = [];
100
- foreach (\array_unique($prependedNodes) as $name) {
101
- $nodes[] = new \WCML\Twig\Node\SetTempNode($name, $node->getTemplateLine());
102
- }
103
- $nodes[] = $node;
104
- $node = new \WCML\Twig\Node\Node($nodes);
105
- }
106
- }
107
- }
108
- return $node;
109
- }
110
- protected function optimizeVariables(\WCML\Twig_NodeInterface $node, \WCML\Twig\Environment $env)
111
- {
112
- if ('Twig_Node_Expression_Name' === \get_class($node) && $node->isSimple()) {
113
- $this->prependedNodes[0][] = $node->getAttribute('name');
114
- return new \WCML\Twig\Node\Expression\TempNameExpression($node->getAttribute('name'), $node->getTemplateLine());
115
- }
116
- return $node;
117
- }
118
- /**
119
- * Optimizes print nodes.
120
- *
121
- * It replaces:
122
- *
123
- * * "echo $this->render(Parent)Block()" with "$this->display(Parent)Block()"
124
- *
125
- * @return \Twig_NodeInterface
126
- */
127
- protected function optimizePrintNode(\WCML\Twig_NodeInterface $node, \WCML\Twig\Environment $env)
128
- {
129
- if (!$node instanceof \WCML\Twig\Node\PrintNode) {
130
- return $node;
131
- }
132
- $exprNode = $node->getNode('expr');
133
- if ($exprNode instanceof \WCML\Twig\Node\Expression\BlockReferenceExpression || $exprNode instanceof \WCML\Twig\Node\Expression\ParentExpression) {
134
- $exprNode->setAttribute('output', \true);
135
- return $exprNode;
136
- }
137
- return $node;
138
- }
139
- /**
140
- * Removes "raw" filters.
141
- *
142
- * @return \Twig_NodeInterface
143
- */
144
- protected function optimizeRawFilter(\WCML\Twig_NodeInterface $node, \WCML\Twig\Environment $env)
145
- {
146
- if ($node instanceof \WCML\Twig\Node\Expression\FilterExpression && 'raw' == $node->getNode('filter')->getAttribute('value')) {
147
- return $node->getNode('node');
148
- }
149
- return $node;
150
- }
151
- /**
152
- * Optimizes "for" tag by removing the "loop" variable creation whenever possible.
153
- */
154
- protected function enterOptimizeFor(\WCML\Twig_NodeInterface $node, \WCML\Twig\Environment $env)
155
- {
156
- if ($node instanceof \WCML\Twig\Node\ForNode) {
157
- // disable the loop variable by default
158
- $node->setAttribute('with_loop', \false);
159
- \array_unshift($this->loops, $node);
160
- \array_unshift($this->loopsTargets, $node->getNode('value_target')->getAttribute('name'));
161
- \array_unshift($this->loopsTargets, $node->getNode('key_target')->getAttribute('name'));
162
- } elseif (!$this->loops) {
163
- // we are outside a loop
164
- return;
165
- } elseif ($node instanceof \WCML\Twig\Node\Expression\NameExpression && 'loop' === $node->getAttribute('name')) {
166
- $node->setAttribute('always_defined', \true);
167
- $this->addLoopToCurrent();
168
- } elseif ($node instanceof \WCML\Twig\Node\Expression\NameExpression && \in_array($node->getAttribute('name'), $this->loopsTargets)) {
169
- $node->setAttribute('always_defined', \true);
170
- } elseif ($node instanceof \WCML\Twig\Node\BlockReferenceNode || $node instanceof \WCML\Twig\Node\Expression\BlockReferenceExpression) {
171
- $this->addLoopToCurrent();
172
- } elseif ($node instanceof \WCML\Twig\Node\IncludeNode && !$node->getAttribute('only')) {
173
- $this->addLoopToAll();
174
- } elseif ($node instanceof \WCML\Twig\Node\Expression\FunctionExpression && 'include' === $node->getAttribute('name') && (!$node->getNode('arguments')->hasNode('with_context') || \false !== $node->getNode('arguments')->getNode('with_context')->getAttribute('value'))) {
175
- $this->addLoopToAll();
176
- } elseif ($node instanceof \WCML\Twig\Node\Expression\GetAttrExpression && (!$node->getNode('attribute') instanceof \WCML\Twig\Node\Expression\ConstantExpression || 'parent' === $node->getNode('attribute')->getAttribute('value')) && (\true === $this->loops[0]->getAttribute('with_loop') || $node->getNode('node') instanceof \WCML\Twig\Node\Expression\NameExpression && 'loop' === $node->getNode('node')->getAttribute('name'))) {
177
- $this->addLoopToAll();
178
- }
179
- }
180
- /**
181
- * Optimizes "for" tag by removing the "loop" variable creation whenever possible.
182
- */
183
- protected function leaveOptimizeFor(\WCML\Twig_NodeInterface $node, \WCML\Twig\Environment $env)
184
- {
185
- if ($node instanceof \WCML\Twig\Node\ForNode) {
186
- \array_shift($this->loops);
187
- \array_shift($this->loopsTargets);
188
- \array_shift($this->loopsTargets);
189
- }
190
- }
191
- protected function addLoopToCurrent()
192
- {
193
- $this->loops[0]->setAttribute('with_loop', \true);
194
- }
195
- protected function addLoopToAll()
196
- {
197
- foreach ($this->loops as $loop) {
198
- $loop->setAttribute('with_loop', \true);
199
- }
200
- }
201
- public function getPriority()
202
- {
203
- return 255;
204
- }
205
- }
206
- \class_alias('WCML\\Twig\\NodeVisitor\\OptimizerNodeVisitor', 'WCML\\Twig_NodeVisitor_Optimizer');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/twig/src/NodeVisitor/SafeAnalysisNodeVisitor.php DELETED
@@ -1,143 +0,0 @@
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
- namespace WCML\Twig\NodeVisitor;
12
-
13
- use WCML\Twig\Environment;
14
- use WCML\Twig\Node\Expression\BlockReferenceExpression;
15
- use WCML\Twig\Node\Expression\ConditionalExpression;
16
- use WCML\Twig\Node\Expression\ConstantExpression;
17
- use WCML\Twig\Node\Expression\FilterExpression;
18
- use WCML\Twig\Node\Expression\FunctionExpression;
19
- use WCML\Twig\Node\Expression\GetAttrExpression;
20
- use WCML\Twig\Node\Expression\MethodCallExpression;
21
- use WCML\Twig\Node\Expression\NameExpression;
22
- use WCML\Twig\Node\Expression\ParentExpression;
23
- use WCML\Twig\Node\Node;
24
- /**
25
- * @final
26
- */
27
- class SafeAnalysisNodeVisitor extends \WCML\Twig\NodeVisitor\AbstractNodeVisitor
28
- {
29
- protected $data = [];
30
- protected $safeVars = [];
31
- public function setSafeVars($safeVars)
32
- {
33
- $this->safeVars = $safeVars;
34
- }
35
- public function getSafe(\WCML\Twig_NodeInterface $node)
36
- {
37
- $hash = \spl_object_hash($node);
38
- if (!isset($this->data[$hash])) {
39
- return;
40
- }
41
- foreach ($this->data[$hash] as $bucket) {
42
- if ($bucket['key'] !== $node) {
43
- continue;
44
- }
45
- if (\in_array('html_attr', $bucket['value'])) {
46
- $bucket['value'][] = 'html';
47
- }
48
- return $bucket['value'];
49
- }
50
- }
51
- protected function setSafe(\WCML\Twig_NodeInterface $node, array $safe)
52
- {
53
- $hash = \spl_object_hash($node);
54
- if (isset($this->data[$hash])) {
55
- foreach ($this->data[$hash] as &$bucket) {
56
- if ($bucket['key'] === $node) {
57
- $bucket['value'] = $safe;
58
- return;
59
- }
60
- }
61
- }
62
- $this->data[$hash][] = ['key' => $node, 'value' => $safe];
63
- }
64
- protected function doEnterNode(\WCML\Twig\Node\Node $node, \WCML\Twig\Environment $env)
65
- {
66
- return $node;
67
- }
68
- protected function doLeaveNode(\WCML\Twig\Node\Node $node, \WCML\Twig\Environment $env)
69
- {
70
- if ($node instanceof \WCML\Twig\Node\Expression\ConstantExpression) {
71
- // constants are marked safe for all
72
- $this->setSafe($node, ['all']);
73
- } elseif ($node instanceof \WCML\Twig\Node\Expression\BlockReferenceExpression) {
74
- // blocks are safe by definition
75
- $this->setSafe($node, ['all']);
76
- } elseif ($node instanceof \WCML\Twig\Node\Expression\ParentExpression) {
77
- // parent block is safe by definition
78
- $this->setSafe($node, ['all']);
79
- } elseif ($node instanceof \WCML\Twig\Node\Expression\ConditionalExpression) {
80
- // intersect safeness of both operands
81
- $safe = $this->intersectSafe($this->getSafe($node->getNode('expr2')), $this->getSafe($node->getNode('expr3')));
82
- $this->setSafe($node, $safe);
83
- } elseif ($node instanceof \WCML\Twig\Node\Expression\FilterExpression) {
84
- // filter expression is safe when the filter is safe
85
- $name = $node->getNode('filter')->getAttribute('value');
86
- $args = $node->getNode('arguments');
87
- if (\false !== ($filter = $env->getFilter($name))) {
88
- $safe = $filter->getSafe($args);
89
- if (null === $safe) {
90
- $safe = $this->intersectSafe($this->getSafe($node->getNode('node')), $filter->getPreservesSafety());
91
- }
92
- $this->setSafe($node, $safe);
93
- } else {
94
- $this->setSafe($node, []);
95
- }
96
- } elseif ($node instanceof \WCML\Twig\Node\Expression\FunctionExpression) {
97
- // function expression is safe when the function is safe
98
- $name = $node->getAttribute('name');
99
- $args = $node->getNode('arguments');
100
- $function = $env->getFunction($name);
101
- if (\false !== $function) {
102
- $this->setSafe($node, $function->getSafe($args));
103
- } else {
104
- $this->setSafe($node, []);
105
- }
106
- } elseif ($node instanceof \WCML\Twig\Node\Expression\MethodCallExpression) {
107
- if ($node->getAttribute('safe')) {
108
- $this->setSafe($node, ['all']);
109
- } else {
110
- $this->setSafe($node, []);
111
- }
112
- } elseif ($node instanceof \WCML\Twig\Node\Expression\GetAttrExpression && $node->getNode('node') instanceof \WCML\Twig\Node\Expression\NameExpression) {
113
- $name = $node->getNode('node')->getAttribute('name');
114
- // attributes on template instances are safe
115
- if ('_self' == $name || \in_array($name, $this->safeVars)) {
116
- $this->setSafe($node, ['all']);
117
- } else {
118
- $this->setSafe($node, []);
119
- }
120
- } else {
121
- $this->setSafe($node, []);
122
- }
123
- return $node;
124
- }
125
- protected function intersectSafe(array $a = null, array $b = null)
126
- {
127
- if (null === $a || null === $b) {
128
- return [];
129
- }
130
- if (\in_array('all', $a)) {
131
- return $b;
132
- }
133
- if (\in_array('all', $b)) {
134
- return $a;
135
- }
136
- return \array_intersect($a, $b);
137
- }
138
- public function getPriority()
139
- {
140
- return 0;
141
- }
142
- }
143
- \class_alias('WCML\\Twig\\NodeVisitor\\SafeAnalysisNodeVisitor', 'WCML\\Twig_NodeVisitor_SafeAnalysis');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/twig/src/NodeVisitor/SandboxNodeVisitor.php DELETED
@@ -1,118 +0,0 @@
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
- namespace WCML\Twig\NodeVisitor;
12
-
13
- use WCML\Twig\Environment;
14
- use WCML\Twig\Node\CheckSecurityNode;
15
- use WCML\Twig\Node\CheckToStringNode;
16
- use WCML\Twig\Node\Expression\Binary\ConcatBinary;
17
- use WCML\Twig\Node\Expression\Binary\RangeBinary;
18
- use WCML\Twig\Node\Expression\FilterExpression;
19
- use WCML\Twig\Node\Expression\FunctionExpression;
20
- use WCML\Twig\Node\Expression\GetAttrExpression;
21
- use WCML\Twig\Node\Expression\NameExpression;
22
- use WCML\Twig\Node\ModuleNode;
23
- use WCML\Twig\Node\Node;
24
- use WCML\Twig\Node\PrintNode;
25
- use WCML\Twig\Node\SetNode;
26
- /**
27
- * @final
28
- *
29
- * @author Fabien Potencier <fabien@symfony.com>
30
- */
31
- class SandboxNodeVisitor extends \WCML\Twig\NodeVisitor\AbstractNodeVisitor
32
- {
33
- protected $inAModule = \false;
34
- protected $tags;
35
- protected $filters;
36
- protected $functions;
37
- private $needsToStringWrap = \false;
38
- protected function doEnterNode(\WCML\Twig\Node\Node $node, \WCML\Twig\Environment $env)
39
- {
40
- if ($node instanceof \WCML\Twig\Node\ModuleNode) {
41
- $this->inAModule = \true;
42
- $this->tags = [];
43
- $this->filters = [];
44
- $this->functions = [];
45
- return $node;
46
- } elseif ($this->inAModule) {
47
- // look for tags
48
- if ($node->getNodeTag() && !isset($this->tags[$node->getNodeTag()])) {
49
- $this->tags[$node->getNodeTag()] = $node;
50
- }
51
- // look for filters
52
- if ($node instanceof \WCML\Twig\Node\Expression\FilterExpression && !isset($this->filters[$node->getNode('filter')->getAttribute('value')])) {
53
- $this->filters[$node->getNode('filter')->getAttribute('value')] = $node;
54
- }
55
- // look for functions
56
- if ($node instanceof \WCML\Twig\Node\Expression\FunctionExpression && !isset($this->functions[$node->getAttribute('name')])) {
57
- $this->functions[$node->getAttribute('name')] = $node;
58
- }
59
- // the .. operator is equivalent to the range() function
60
- if ($node instanceof \WCML\Twig\Node\Expression\Binary\RangeBinary && !isset($this->functions['range'])) {
61
- $this->functions['range'] = $node;
62
- }
63
- if ($node instanceof \WCML\Twig\Node\PrintNode) {
64
- $this->needsToStringWrap = \true;
65
- $this->wrapNode($node, 'expr');
66
- }
67
- if ($node instanceof \WCML\Twig\Node\SetNode && !$node->getAttribute('capture')) {
68
- $this->needsToStringWrap = \true;
69
- }
70
- // wrap outer nodes that can implicitly call __toString()
71
- if ($this->needsToStringWrap) {
72
- if ($node instanceof \WCML\Twig\Node\Expression\Binary\ConcatBinary) {
73
- $this->wrapNode($node, 'left');
74
- $this->wrapNode($node, 'right');
75
- }
76
- if ($node instanceof \WCML\Twig\Node\Expression\FilterExpression) {
77
- $this->wrapNode($node, 'node');
78
- $this->wrapArrayNode($node, 'arguments');
79
- }
80
- if ($node instanceof \WCML\Twig\Node\Expression\FunctionExpression) {
81
- $this->wrapArrayNode($node, 'arguments');
82
- }
83
- }
84
- }
85
- return $node;
86
- }
87
- protected function doLeaveNode(\WCML\Twig\Node\Node $node, \WCML\Twig\Environment $env)
88
- {
89
- if ($node instanceof \WCML\Twig\Node\ModuleNode) {
90
- $this->inAModule = \false;
91
- $node->getNode('constructor_end')->setNode('_security_check', new \WCML\Twig\Node\Node([new \WCML\Twig\Node\CheckSecurityNode($this->filters, $this->tags, $this->functions), $node->getNode('display_start')]));
92
- } elseif ($this->inAModule) {
93
- if ($node instanceof \WCML\Twig\Node\PrintNode || $node instanceof \WCML\Twig\Node\SetNode) {
94
- $this->needsToStringWrap = \false;
95
- }
96
- }
97
- return $node;
98
- }
99
- private function wrapNode(\WCML\Twig\Node\Node $node, $name)
100
- {
101
- $expr = $node->getNode($name);
102
- if ($expr instanceof \WCML\Twig\Node\Expression\NameExpression || $expr instanceof \WCML\Twig\Node\Expression\GetAttrExpression) {
103
- $node->setNode($name, new \WCML\Twig\Node\CheckToStringNode($expr));
104
- }
105
- }
106
- private function wrapArrayNode(\WCML\Twig\Node\Node $node, $name)
107
- {
108
- $args = $node->getNode($name);
109
- foreach ($args as $name => $_) {
110
- $this->wrapNode($args, $name);
111
- }
112
- }
113
- public function getPriority()
114
- {
115
- return 0;
116
- }
117
- }
118
- \class_alias('WCML\\Twig\\NodeVisitor\\SandboxNodeVisitor', 'WCML\\Twig_NodeVisitor_Sandbox');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/twig/src/Parser.php DELETED
@@ -1,358 +0,0 @@
1
- <?php
2
-
3
- /*
4
- * This file is part of Twig.
5
- *
6
- * (c) Fabien Potencier
7
- * (c) Armin Ronacher
8
- *
9
- * For the full copyright and license information, please view the LICENSE
10
- * file that was distributed with this source code.
11
- */
12
- namespace WCML\Twig;
13
-
14
- use WCML\Twig\Error\SyntaxError;
15
- use WCML\Twig\Node\BlockNode;
16
- use WCML\Twig\Node\BlockReferenceNode;
17
- use WCML\Twig\Node\BodyNode;
18
- use WCML\Twig\Node\Expression\AbstractExpression;
19
- use WCML\Twig\Node\MacroNode;
20
- use WCML\Twig\Node\ModuleNode;
21
- use WCML\Twig\Node\Node;
22
- use WCML\Twig\Node\NodeCaptureInterface;
23
- use WCML\Twig\Node\NodeOutputInterface;
24
- use WCML\Twig\Node\PrintNode;
25
- use WCML\Twig\Node\TextNode;
26
- use WCML\Twig\NodeVisitor\NodeVisitorInterface;
27
- use WCML\Twig\TokenParser\TokenParserInterface;
28
- /**
29
- * Default parser implementation.
30
- *
31
- * @author Fabien Potencier <fabien@symfony.com>
32
- */
33
- class Parser implements \WCML\Twig_ParserInterface
34
- {
35
- protected $stack = [];
36
- protected $stream;
37
- protected $parent;
38
- protected $handlers;
39
- protected $visitors;
40
- protected $expressionParser;
41
- protected $blocks;
42
- protected $blockStack;
43
- protected $macros;
44
- protected $env;
45
- protected $reservedMacroNames;
46
- protected $importedSymbols;
47
- protected $traits;
48
- protected $embeddedTemplates = [];
49
- private $varNameSalt = 0;
50
- public function __construct(\WCML\Twig\Environment $env)
51
- {
52
- $this->env = $env;
53
- }
54
- /**
55
- * @deprecated since 1.27 (to be removed in 2.0)
56
- */
57
- public function getEnvironment()
58
- {
59
- @\trigger_error('The ' . __METHOD__ . ' method is deprecated since version 1.27 and will be removed in 2.0.', \E_USER_DEPRECATED);
60
- return $this->env;
61
- }
62
- public function getVarName()
63
- {
64
- return \sprintf('__internal_%s', \hash('sha256', __METHOD__ . $this->stream->getSourceContext()->getCode() . $this->varNameSalt++));
65
- }
66
- /**
67
- * @deprecated since 1.27 (to be removed in 2.0). Use $parser->getStream()->getSourceContext()->getPath() instead.
68
- */
69
- public function getFilename()
70
- {
71
- @\trigger_error(\sprintf('The "%s" method is deprecated since version 1.27 and will be removed in 2.0. Use $parser->getStream()->getSourceContext()->getPath() instead.', __METHOD__), \E_USER_DEPRECATED);
72
- return $this->stream->getSourceContext()->getName();
73
- }
74
- public function parse(\WCML\Twig\TokenStream $stream, $test = null, $dropNeedle = \false)
75
- {
76
- // push all variables into the stack to keep the current state of the parser
77
- // using get_object_vars() instead of foreach would lead to https://bugs.php.net/71336
78
- // This hack can be removed when min version if PHP 7.0
79
- $vars = [];
80
- foreach ($this as $k => $v) {
81
- $vars[$k] = $v;
82
- }
83
- unset($vars['stack'], $vars['env'], $vars['handlers'], $vars['visitors'], $vars['expressionParser'], $vars['reservedMacroNames']);
84
- $this->stack[] = $vars;
85
- // tag handlers
86
- if (null === $this->handlers) {
87
- $this->handlers = $this->env->getTokenParsers();
88
- $this->handlers->setParser($this);
89
- }
90
- // node visitors
91
- if (null === $this->visitors) {
92
- $this->visitors = $this->env->getNodeVisitors();
93
- }
94
- if (null === $this->expressionParser) {
95
- $this->expressionParser = new \WCML\Twig\ExpressionParser($this, $this->env);
96
- }
97
- $this->stream = $stream;
98
- $this->parent = null;
99
- $this->blocks = [];
100
- $this->macros = [];
101
- $this->traits = [];
102
- $this->blockStack = [];
103
- $this->importedSymbols = [[]];
104
- $this->embeddedTemplates = [];
105
- $this->varNameSalt = 0;
106
- try {
107
- $body = $this->subparse($test, $dropNeedle);
108
- if (null !== $this->parent && null === ($body = $this->filterBodyNodes($body))) {
109
- $body = new \WCML\Twig\Node\Node();
110
- }
111
- } catch (\WCML\Twig\Error\SyntaxError $e) {
112
- if (!$e->getSourceContext()) {
113
- $e->setSourceContext($this->stream->getSourceContext());
114
- }
115
- if (!$e->getTemplateLine()) {
116
- $e->setTemplateLine($this->stream->getCurrent()->getLine());
117
- }
118
- throw $e;
119
- }
120
- $node = new \WCML\Twig\Node\ModuleNode(new \WCML\Twig\Node\BodyNode([$body]), $this->parent, new \WCML\Twig\Node\Node($this->blocks), new \WCML\Twig\Node\Node($this->macros), new \WCML\Twig\Node\Node($this->traits), $this->embeddedTemplates, $stream->getSourceContext());
121
- $traverser = new \WCML\Twig\NodeTraverser($this->env, $this->visitors);
122
- $node = $traverser->traverse($node);
123
- // restore previous stack so previous parse() call can resume working
124
- foreach (\array_pop($this->stack) as $key => $val) {
125
- $this->{$key} = $val;
126
- }
127
- return $node;
128
- }
129
- public function subparse($test, $dropNeedle = \false)
130
- {
131
- $lineno = $this->getCurrentToken()->getLine();
132
- $rv = [];
133
- while (!$this->stream->isEOF()) {
134
- switch ($this->getCurrentToken()->getType()) {
135
- case \WCML\Twig\Token::TEXT_TYPE:
136
- $token = $this->stream->next();
137
- $rv[] = new \WCML\Twig\Node\TextNode($token->getValue(), $token->getLine());
138
- break;
139
- case \WCML\Twig\Token::VAR_START_TYPE:
140
- $token = $this->stream->next();
141
- $expr = $this->expressionParser->parseExpression();
142
- $this->stream->expect(\WCML\Twig\Token::VAR_END_TYPE);
143
- $rv[] = new \WCML\Twig\Node\PrintNode($expr, $token->getLine());
144
- break;
145
- case \WCML\Twig\Token::BLOCK_START_TYPE:
146
- $this->stream->next();
147
- $token = $this->getCurrentToken();
148
- if (\WCML\Twig\Token::NAME_TYPE !== $token->getType()) {
149
- throw new \WCML\Twig\Error\SyntaxError('A block must start with a tag name.', $token->getLine(), $this->stream->getSourceContext());
150
- }
151
- if (null !== $test && \call_user_func($test, $token)) {
152
- if ($dropNeedle) {
153
- $this->stream->next();
154
- }
155
- if (1 === \count($rv)) {
156
- return $rv[0];
157
- }
158
- return new \WCML\Twig\Node\Node($rv, [], $lineno);
159
- }
160
- $subparser = $this->handlers->getTokenParser($token->getValue());
161
- if (null === $subparser) {
162
- if (null !== $test) {
163
- $e = new \WCML\Twig\Error\SyntaxError(\sprintf('Unexpected "%s" tag', $token->getValue()), $token->getLine(), $this->stream->getSourceContext());
164
- if (\is_array($test) && isset($test[0]) && $test[0] instanceof \WCML\Twig\TokenParser\TokenParserInterface) {
165
- $e->appendMessage(\sprintf(' (expecting closing tag for the "%s" tag defined near line %s).', $test[0]->getTag(), $lineno));
166
- }
167
- } else {
168
- $e = new \WCML\Twig\Error\SyntaxError(\sprintf('Unknown "%s" tag.', $token->getValue()), $token->getLine(), $this->stream->getSourceContext());
169
- $e->addSuggestions($token->getValue(), \array_keys($this->env->getTags()));
170
- }
171
- throw $e;
172
- }
173
- $this->stream->next();
174
- $node = $subparser->parse($token);
175
- if (null !== $node) {
176
- $rv[] = $node;
177
- }
178
- break;
179
- default:
180
- throw new \WCML\Twig\Error\SyntaxError('Lexer or parser ended up in unsupported state.', $this->getCurrentToken()->getLine(), $this->stream->getSourceContext());
181
- }
182
- }
183
- if (1 === \count($rv)) {
184
- return $rv[0];
185
- }
186
- return new \WCML\Twig\Node\Node($rv, [], $lineno);
187
- }
188
- /**
189
- * @deprecated since 1.27 (to be removed in 2.0)
190
- */
191
- public function addHandler($name, $class)
192
- {
193
- @\trigger_error('The ' . __METHOD__ . ' method is deprecated since version 1.27 and will be removed in 2.0.', \E_USER_DEPRECATED);
194
- $this->handlers[$name] = $class;
195
- }
196
- /**
197
- * @deprecated since 1.27 (to be removed in 2.0)
198
- */
199
- public function addNodeVisitor(\WCML\Twig\NodeVisitor\NodeVisitorInterface $visitor)
200
- {
201
- @\trigger_error('The ' . __METHOD__ . ' method is deprecated since version 1.27 and will be removed in 2.0.', \E_USER_DEPRECATED);
202
- $this->visitors[] = $visitor;
203
- }
204
- public function getBlockStack()
205
- {
206
- return $this->blockStack;
207
- }
208
- public function peekBlockStack()
209
- {
210
- return isset($this->blockStack[\count($this->blockStack) - 1]) ? $this->blockStack[\count($this->blockStack) - 1] : null;
211
- }
212
- public function popBlockStack()
213
- {
214
- \array_pop($this->blockStack);
215
- }
216
- public function pushBlockStack($name)
217
- {
218
- $this->blockStack[] = $name;
219
- }
220
- public function hasBlock($name)
221
- {
222
- return isset($this->blocks[$name]);
223
- }
224
- public function getBlock($name)
225
- {
226
- return $this->blocks[$name];
227
- }
228
- public function setBlock($name, \WCML\Twig\Node\BlockNode $value)
229
- {
230
- $this->blocks[$name] = new \WCML\Twig\Node\BodyNode([$value], [], $value->getTemplateLine());
231
- }
232
- public function hasMacro($name)
233
- {
234
- return isset($this->macros[$name]);
235
- }
236
- public function setMacro($name, \WCML\Twig\Node\MacroNode $node)
237
- {
238
- if ($this->isReservedMacroName($name)) {
239
- throw new \WCML\Twig\Error\SyntaxError(\sprintf('"%s" cannot be used as a macro name as it is a reserved keyword.', $name), $node->getTemplateLine(), $this->stream->getSourceContext());
240
- }
241
- $this->macros[$name] = $node;
242
- }
243
- public function isReservedMacroName($name)
244
- {
245
- if (null === $this->reservedMacroNames) {
246
- $this->reservedMacroNames = [];
247
- $r = new \ReflectionClass($this->env->getBaseTemplateClass());
248
- foreach ($r->getMethods() as $method) {
249
- $methodName = \strtolower($method->getName());
250
- if ('get' === \substr($methodName, 0, 3) && isset($methodName[3])) {
251
- $this->reservedMacroNames[] = \substr($methodName, 3);
252
- }
253
- }
254
- }
255
- return \in_array(\strtolower($name), $this->reservedMacroNames);
256
- }
257
- public function addTrait($trait)
258
- {
259
- $this->traits[] = $trait;
260
- }
261
- public function hasTraits()
262
- {
263
- return \count($this->traits) > 0;
264
- }
265
- public function embedTemplate(\WCML\Twig\Node\ModuleNode $template)
266
- {
267
- $template->setIndex(\mt_rand());
268
- $this->embeddedTemplates[] = $template;
269
- }
270
- public function addImportedSymbol($type, $alias, $name = null, \WCML\Twig\Node\Expression\AbstractExpression $node = null)
271
- {
272
- $this->importedSymbols[0][$type][$alias] = ['name' => $name, 'node' => $node];
273
- }
274
- public function getImportedSymbol($type, $alias)
275
- {
276
- if (null !== $this->peekBlockStack()) {
277
- foreach ($this->importedSymbols as $functions) {
278
- if (isset($functions[$type][$alias])) {
279
- if (\count($this->blockStack) > 1) {
280
- return null;
281
- }
282
- return $functions[$type][$alias];
283
- }
284
- }
285
- } else {
286
- return isset($this->importedSymbols[0][$type][$alias]) ? $this->importedSymbols[0][$type][$alias] : null;
287
- }
288
- }
289
- public function isMainScope()
290
- {
291
- return 1 === \count($this->importedSymbols);
292
- }
293
- public function pushLocalScope()
294
- {
295
- \array_unshift($this->importedSymbols, []);
296
- }
297
- public function popLocalScope()
298
- {
299
- \array_shift($this->importedSymbols);
300
- }
301
- /**
302
- * @return ExpressionParser
303
- */
304
- public function getExpressionParser()
305
- {
306
- return $this->expressionParser;
307
- }
308
- public function getParent()
309
- {
310
- return $this->parent;
311
- }
312
- public function setParent($parent)
313
- {
314
- $this->parent = $parent;
315
- }
316
- /**
317
- * @return TokenStream
318
- */
319
- public function getStream()
320
- {
321
- return $this->stream;
322
- }
323
- /**
324
- * @return Token
325
- */
326
- public function getCurrentToken()
327
- {
328
- return $this->stream->getCurrent();
329
- }
330
- protected function filterBodyNodes(\WCML\Twig_NodeInterface $node)
331
- {
332
- // check that the body does not contain non-empty output nodes
333
- if ($node instanceof \WCML\Twig\Node\TextNode && !\ctype_space($node->getAttribute('data')) || !$node instanceof \WCML\Twig\Node\TextNode && !$node instanceof \WCML\Twig\Node\BlockReferenceNode && $node instanceof \WCML\Twig\Node\NodeOutputInterface) {
334
- if (\false !== \strpos((string) $node, \chr(0xef) . \chr(0xbb) . \chr(0xbf))) {
335
- $t = \substr($node->getAttribute('data'), 3);
336
- if ('' === $t || \ctype_space($t)) {
337
- // bypass empty nodes starting with a BOM
338
- return;
339
- }
340
- }
341
- throw new \WCML\Twig\Error\SyntaxError('A template that extends another one cannot include content outside Twig blocks. Did you forget to put the content inside a {% block %} tag?', $node->getTemplateLine(), $this->stream->getSourceContext());
342
- }
343
- // bypass nodes that will "capture" the output
344
- if ($node instanceof \WCML\Twig\Node\NodeCaptureInterface) {
345
- return $node;
346
- }
347
- if ($node instanceof \WCML\Twig\Node\NodeOutputInterface) {
348
- return;
349
- }
350
- foreach ($node as $k => $n) {
351
- if (null !== $n && null === $this->filterBodyNodes($n)) {
352
- $node->removeNode($k);
353
- }
354
- }
355
- return $node;
356
- }
357
- }
358
- \class_alias('WCML\\Twig\\Parser', 'WCML\\Twig_Parser');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/twig/src/Profiler/Dumper/BaseDumper.php DELETED
@@ -1,53 +0,0 @@
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
- namespace WCML\Twig\Profiler\Dumper;
12
-
13
- use WCML\Twig\Profiler\Profile;
14
- /**
15
- * @author Fabien Potencier <fabien@symfony.com>
16
- */
17
- abstract class BaseDumper
18
- {
19
- private $root;
20
- public function dump(\WCML\Twig\Profiler\Profile $profile)
21
- {
22
- return $this->dumpProfile($profile);
23
- }
24
- protected abstract function formatTemplate(\WCML\Twig\Profiler\Profile $profile, $prefix);
25
- protected abstract function formatNonTemplate(\WCML\Twig\Profiler\Profile $profile, $prefix);
26
- protected abstract function formatTime(\WCML\Twig\Profiler\Profile $profile, $percent);
27
- private function dumpProfile(\WCML\Twig\Profiler\Profile $profile, $prefix = '', $sibling = \false)
28
- {
29
- if ($profile->isRoot()) {
30
- $this->root = $profile->getDuration();
31
- $start = $profile->getName();
32
- } else {
33
- if ($profile->isTemplate()) {
34
- $start = $this->formatTemplate($profile, $prefix);
35
- } else {
36
- $start = $this->formatNonTemplate($profile, $prefix);
37
- }
38
- $prefix .= $sibling ? '│ ' : ' ';
39
- }
40
- $percent = $this->root ? $profile->getDuration() / $this->root * 100 : 0;
41
- if ($profile->getDuration() * 1000 < 1) {
42
- $str = $start . "\n";
43
- } else {
44
- $str = \sprintf("%s %s\n", $start, $this->formatTime($profile, $percent));
45
- }
46
- $nCount = \count($profile->getProfiles());
47
- foreach ($profile as $i => $p) {
48
- $str .= $this->dumpProfile($p, $prefix, $i + 1 !== $nCount);
49
- }
50
- return $str;
51
- }
52
- }
53
- \class_alias('WCML\\Twig\\Profiler\\Dumper\\BaseDumper', 'WCML\\Twig_Profiler_Dumper_Base');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/twig/src/Profiler/Dumper/BlackfireDumper.php DELETED
@@ -1,63 +0,0 @@
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
- namespace WCML\Twig\Profiler\Dumper;
12
-
13
- use WCML\Twig\Profiler\Profile;
14
- /**
15
- * @author Fabien Potencier <fabien@symfony.com>
16
- *
17
- * @final
18
- */
19
- class BlackfireDumper
20
- {
21
- public function dump(\WCML\Twig\Profiler\Profile $profile)
22
- {
23
- $data = [];
24
- $this->dumpProfile('main()', $profile, $data);
25
- $this->dumpChildren('main()', $profile, $data);
26
- $start = \sprintf('%f', \microtime(\true));
27
- $str = <<<EOF
28
- file-format: BlackfireProbe
29
- cost-dimensions: wt mu pmu
30
- request-start: {$start}
31
-
32
-
33
- EOF;
34
- foreach ($data as $name => $values) {
35
- $str .= "{$name}//{$values['ct']} {$values['wt']} {$values['mu']} {$values['pmu']}\n";
36
- }
37
- return $str;
38
- }
39
- private function dumpChildren($parent, \WCML\Twig\Profiler\Profile $profile, &$data)
40
- {
41
- foreach ($profile as $p) {
42
- if ($p->isTemplate()) {
43
- $name = $p->getTemplate();
44
- } else {
45
- $name = \sprintf('%s::%s(%s)', $p->getTemplate(), $p->getType(), $p->getName());
46
- }
47
- $this->dumpProfile(\sprintf('%s==>%s', $parent, $name), $p, $data);
48
- $this->dumpChildren($name, $p, $data);
49
- }
50
- }
51
- private function dumpProfile($edge, \WCML\Twig\Profiler\Profile $profile, &$data)
52
- {
53
- if (isset($data[$edge])) {
54
- ++$data[$edge]['ct'];
55
- $data[$edge]['wt'] += \floor($profile->getDuration() * 1000000);
56
- $data[$edge]['mu'] += $profile->getMemoryUsage();
57
- $data[$edge]['pmu'] += $profile->getPeakMemoryUsage();
58
- } else {
59
- $data[$edge] = ['ct' => 1, 'wt' => \floor($profile->getDuration() * 1000000), 'mu' => $profile->getMemoryUsage(), 'pmu' => $profile->getPeakMemoryUsage()];
60
- }
61
- }
62
- }
63
- \class_alias('WCML\\Twig\\Profiler\\Dumper\\BlackfireDumper', 'WCML\\Twig_Profiler_Dumper_Blackfire');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/twig/src/Profiler/Dumper/HtmlDumper.php DELETED
@@ -1,39 +0,0 @@
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
- namespace WCML\Twig\Profiler\Dumper;
12
-
13
- use WCML\Twig\Profiler\Profile;
14
- /**
15
- * @author Fabien Potencier <fabien@symfony.com>
16
- *
17
- * @final
18
- */
19
- class HtmlDumper extends \WCML\Twig\Profiler\Dumper\BaseDumper
20
- {
21
- private static $colors = ['block' => '#dfd', 'macro' => '#ddf', 'template' => '#ffd', 'big' => '#d44'];
22
- public function dump(\WCML\Twig\Profiler\Profile $profile)
23
- {
24
- return '<pre>' . parent::dump($profile) . '</pre>';
25
- }
26
- protected function formatTemplate(\WCML\Twig\Profiler\Profile $profile, $prefix)
27
- {
28
- return \sprintf('%s└ <span style="background-color: %s">%s</span>', $prefix, self::$colors['template'], $profile->getTemplate());
29
- }
30
- protected function formatNonTemplate(\WCML\Twig\Profiler\Profile $profile, $prefix)
31
- {
32
- return \sprintf('%s└ %s::%s(<span style="background-color: %s">%s</span>)', $prefix, $profile->getTemplate(), $profile->getType(), isset(self::$colors[$profile->getType()]) ? self::$colors[$profile->getType()] : 'auto', $profile->getName());
33
- }
34
- protected function formatTime(\WCML\Twig\Profiler\Profile $profile, $percent)
35
- {
36
- return \sprintf('<span style="color: %s">%.2fms/%.0f%%</span>', $percent > 20 ? self::$colors['big'] : 'auto', $profile->getDuration() * 1000, $percent);
37
- }
38
- }
39
- \class_alias('WCML\\Twig\\Profiler\\Dumper\\HtmlDumper', 'WCML\\Twig_Profiler_Dumper_Html');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/twig/src/Profiler/Dumper/TextDumper.php DELETED
@@ -1,34 +0,0 @@
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
- namespace WCML\Twig\Profiler\Dumper;
12
-
13
- use WCML\Twig\Profiler\Profile;
14
- /**
15
- * @author Fabien Potencier <fabien@symfony.com>
16
- *
17
- * @final
18
- */
19
- class TextDumper extends \WCML\Twig\Profiler\Dumper\BaseDumper
20
- {
21
- protected function formatTemplate(\WCML\Twig\Profiler\Profile $profile, $prefix)
22
- {
23
- return \sprintf('%s└ %s', $prefix, $profile->getTemplate());
24
- }
25
- protected function formatNonTemplate(\WCML\Twig\Profiler\Profile $profile, $prefix)
26
- {
27
- return \sprintf('%s└ %s::%s(%s)', $prefix, $profile->getTemplate(), $profile->getType(), $profile->getName());
28
- }
29
- protected function formatTime(\WCML\Twig\Profiler\Profile $profile, $percent)
30
- {
31
- return \sprintf('%.2fms/%.0f%%', $profile->getDuration() * 1000, $percent);
32
- }
33
- }
34
- \class_alias('WCML\\Twig\\Profiler\\Dumper\\TextDumper', 'WCML\\Twig_Profiler_Dumper_Text');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/twig/src/Profiler/Node/EnterProfileNode.php DELETED
@@ -1,31 +0,0 @@
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
- namespace WCML\Twig\Profiler\Node;
12
-
13
- use WCML\Twig\Compiler;
14
- use WCML\Twig\Node\Node;
15
- /**
16
- * Represents a profile enter node.
17
- *
18
- * @author Fabien Potencier <fabien@symfony.com>
19
- */
20
- class EnterProfileNode extends \WCML\Twig\Node\Node
21
- {
22
- public function __construct($extensionName, $type, $name, $varName)
23
- {
24
- parent::__construct([], ['extension_name' => $extensionName, 'name' => $name, 'type' => $type, 'var_name' => $varName]);
25
- }
26
- public function compile(\WCML\Twig\Compiler $compiler)
27
- {
28
- $compiler->write(\sprintf('$%s = $this->env->getExtension(', $this->getAttribute('var_name')))->repr($this->getAttribute('extension_name'))->raw(");\n")->write(\sprintf('$%s->enter($%s = new \\Twig\\Profiler\\Profile($this->getTemplateName(), ', $this->getAttribute('var_name'), $this->getAttribute('var_name') . '_prof'))->repr($this->getAttribute('type'))->raw(', ')->repr($this->getAttribute('name'))->raw("));\n\n");
29
- }
30
- }
31
- \class_alias('WCML\\Twig\\Profiler\\Node\\EnterProfileNode', 'WCML\\Twig_Profiler_Node_EnterProfile');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/twig/src/Profiler/Node/LeaveProfileNode.php DELETED
@@ -1,31 +0,0 @@
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
- namespace WCML\Twig\Profiler\Node;
12
-
13
- use WCML\Twig\Compiler;
14
- use WCML\Twig\Node\Node;
15
- /**
16
- * Represents a profile leave node.
17
- *
18
- * @author Fabien Potencier <fabien@symfony.com>
19
- */
20
- class LeaveProfileNode extends \WCML\Twig\Node\Node
21
- {
22
- public function __construct($varName)
23
- {
24
- parent::__construct([], ['var_name' => $varName]);
25
- }
26
- public function compile(\WCML\Twig\Compiler $compiler)
27
- {
28
- $compiler->write("\n")->write(\sprintf("\$%s->leave(\$%s);\n\n", $this->getAttribute('var_name'), $this->getAttribute('var_name') . '_prof'));
29
- }
30
- }
31
- \class_alias('WCML\\Twig\\Profiler\\Node\\LeaveProfileNode', 'WCML\\Twig_Profiler_Node_LeaveProfile');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/twig/src/Profiler/NodeVisitor/ProfilerNodeVisitor.php DELETED
@@ -1,63 +0,0 @@
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
- namespace WCML\Twig\Profiler\NodeVisitor;
12
-
13
- use WCML\Twig\Environment;
14
- use WCML\Twig\Node\BlockNode;
15
- use WCML\Twig\Node\BodyNode;
16
- use WCML\Twig\Node\MacroNode;
17
- use WCML\Twig\Node\ModuleNode;
18
- use WCML\Twig\Node\Node;
19
- use WCML\Twig\NodeVisitor\AbstractNodeVisitor;
20
- use WCML\Twig\Profiler\Node\EnterProfileNode;
21
- use WCML\Twig\Profiler\Node\LeaveProfileNode;
22
- use WCML\Twig\Profiler\Profile;
23
- /**
24
- * @author Fabien Potencier <fabien@symfony.com>
25
- *
26
- * @final
27
- */
28
- class ProfilerNodeVisitor extends \WCML\Twig\NodeVisitor\AbstractNodeVisitor
29
- {
30
- private $extensionName;
31
- public function __construct($extensionName)
32
- {
33
- $this->extensionName = $extensionName;
34
- }
35
- protected function doEnterNode(\WCML\Twig\Node\Node $node, \WCML\Twig\Environment $env)
36
- {
37
- return $node;
38
- }
39
- protected function doLeaveNode(\WCML\Twig\Node\Node $node, \WCML\Twig\Environment $env)
40
- {
41
- if ($node instanceof \WCML\Twig\Node\ModuleNode) {
42
- $varName = $this->getVarName();
43
- $node->setNode('display_start', new \WCML\Twig\Node\Node([new \WCML\Twig\Profiler\Node\EnterProfileNode($this->extensionName, \WCML\Twig\Profiler\Profile::TEMPLATE, $node->getTemplateName(), $varName), $node->getNode('display_start')]));
44
- $node->setNode('display_end', new \WCML\Twig\Node\Node([new \WCML\Twig\Profiler\Node\LeaveProfileNode($varName), $node->getNode('display_end')]));
45
- } elseif ($node instanceof \WCML\Twig\Node\BlockNode) {
46
- $varName = $this->getVarName();
47
- $node->setNode('body', new \WCML\Twig\Node\BodyNode([new \WCML\Twig\Profiler\Node\EnterProfileNode($this->extensionName, \WCML\Twig\Profiler\Profile::BLOCK, $node->getAttribute('name'), $varName), $node->getNode('body'), new \WCML\Twig\Profiler\Node\LeaveProfileNode($varName)]));
48
- } elseif ($node instanceof \WCML\Twig\Node\MacroNode) {
49
- $varName = $this->getVarName();
50
- $node->setNode('body', new \WCML\Twig\Node\BodyNode([new \WCML\Twig\Profiler\Node\EnterProfileNode($this->extensionName, \WCML\Twig\Profiler\Profile::MACRO, $node->getAttribute('name'), $varName), $node->getNode('body'), new \WCML\Twig\Profiler\Node\LeaveProfileNode($varName)]));
51
- }
52
- return $node;
53
- }
54
- private function getVarName()
55
- {
56
- return \sprintf('__internal_%s', \hash('sha256', $this->extensionName));
57
- }
58
- public function getPriority()
59
- {
60
- return 0;
61
- }
62
- }
63
- \class_alias('WCML\\Twig\\Profiler\\NodeVisitor\\ProfilerNodeVisitor', 'WCML\\Twig_Profiler_NodeVisitor_Profiler');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/twig/src/Profiler/Profile.php DELETED
@@ -1,154 +0,0 @@
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
- namespace WCML\Twig\Profiler;
12
-
13
- /**
14
- * @author Fabien Potencier <fabien@symfony.com>
15
- *
16
- * @final
17
- */
18
- class Profile implements \IteratorAggregate, \Serializable
19
- {
20
- const ROOT = 'ROOT';
21
- const BLOCK = 'block';
22
- const TEMPLATE = 'template';
23
- const MACRO = 'macro';
24
- private $template;
25
- private $name;
26
- private $type;
27
- private $starts = [];
28
- private $ends = [];
29
- private $profiles = [];
30
- public function __construct($template = 'main', $type = self::ROOT, $name = 'main')
31
- {
32
- $this->template = $template;
33
- $this->type = $type;
34
- $this->name = 0 === \strpos($name, '__internal_') ? 'INTERNAL' : $name;
35
- $this->enter();
36
- }
37
- public function getTemplate()
38
- {
39
- return $this->template;
40
- }
41
- public function getType()
42
- {
43
- return $this->type;
44
- }
45
- public function getName()
46
- {
47
- return $this->name;
48
- }
49
- public function isRoot()
50
- {
51
- return self::ROOT === $this->type;
52
- }
53
- public function isTemplate()
54
- {
55
- return self::TEMPLATE === $this->type;
56
- }
57
- public function isBlock()
58
- {
59
- return self::BLOCK === $this->type;
60
- }
61
- public function isMacro()
62
- {
63
- return self::MACRO === $this->type;
64
- }
65
- public function getProfiles()
66
- {
67
- return $this->profiles;
68
- }
69
- public function addProfile(self $profile)
70
- {
71
- $this->profiles[] = $profile;
72
- }
73
- /**
74
- * Returns the duration in microseconds.
75
- *
76
- * @return float
77
- */
78
- public function getDuration()
79
- {
80
- if ($this->isRoot() && $this->profiles) {
81
- // for the root node with children, duration is the sum of all child durations
82
- $duration = 0;
83
- foreach ($this->profiles as $profile) {
84
- $duration += $profile->getDuration();
85
- }
86
- return $duration;
87
- }
88
- return isset($this->ends['wt']) && isset($this->starts['wt']) ? $this->ends['wt'] - $this->starts['wt'] : 0;
89
- }
90
- /**
91
- * Returns the memory usage in bytes.
92
- *
93
- * @return int
94
- */
95
- public function getMemoryUsage()
96
- {
97
- return isset($this->ends['mu']) && isset($this->starts['mu']) ? $this->ends['mu'] - $this->starts['mu'] : 0;
98
- }
99
- /**
100
- * Returns the peak memory usage in bytes.
101
- *
102
- * @return int
103
- */
104
- public function getPeakMemoryUsage()
105
- {
106
- return isset($this->ends['pmu']) && isset($this->starts['pmu']) ? $this->ends['pmu'] - $this->starts['pmu'] : 0;
107
- }
108
- /**
109
- * Starts the profiling.
110
- */
111
- public function enter()
112
- {
113
- $this->starts = ['wt' => \microtime(\true), 'mu' => \memory_get_usage(), 'pmu' => \memory_get_peak_usage()];
114
- }
115
- /**
116
- * Stops the profiling.
117
- */
118
- public function leave()
119
- {
120
- $this->ends = ['wt' => \microtime(\true), 'mu' => \memory_get_usage(), 'pmu' => \memory_get_peak_usage()];
121
- }
122
- public function reset()
123
- {
124
- $this->starts = $this->ends = $this->profiles = [];
125
- $this->enter();
126
- }
127
- public function getIterator()
128
- {
129
- return new \ArrayIterator($this->profiles);
130
- }
131
- public function serialize()
132
- {
133
- return \serialize($this->__serialize());
134
- }
135
- public function unserialize($data)
136
- {
137
- $this->__unserialize(\unserialize($data));
138
- }
139
- /**
140
- * @internal
141
- */
142
- public function __serialize()
143
- {
144
- return [$this->template, $this->name, $this->type, $this->starts, $this->ends, $this->profiles];
145
- }
146
- /**
147
- * @internal
148
- */
149
- public function __unserialize(array $data)
150
- {
151
- list($this->template, $this->name, $this->type, $this->starts, $this->ends, $this->profiles) = $data;
152
- }
153
- }
154
- \class_alias('WCML\\Twig\\Profiler\\Profile', 'WCML\\Twig_Profiler_Profile');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/twig/src/RuntimeLoader/ContainerRuntimeLoader.php DELETED
@@ -1,36 +0,0 @@
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
- namespace WCML\Twig\RuntimeLoader;
12
-
13
- use WCML\Psr\Container\ContainerInterface;
14
- /**
15
- * Lazily loads Twig runtime implementations from a PSR-11 container.
16
- *
17
- * Note that the runtime services MUST use their class names as identifiers.
18
- *
19
- * @author Fabien Potencier <fabien@symfony.com>
20
- * @author Robin Chalas <robin.chalas@gmail.com>
21
- */
22
- class ContainerRuntimeLoader implements \WCML\Twig\RuntimeLoader\RuntimeLoaderInterface
23
- {
24
- private $container;
25
- public function __construct(\WCML\Psr\Container\ContainerInterface $container)
26
- {
27
- $this->container = $container;
28
- }
29
- public function load($class)
30
- {
31
- if ($this->container->has($class)) {
32
- return $this->container->get($class);
33
- }
34
- }
35
- }
36
- \class_alias('WCML\\Twig\\RuntimeLoader\\ContainerRuntimeLoader', 'WCML\\Twig_ContainerRuntimeLoader');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/twig/src/RuntimeLoader/FactoryRuntimeLoader.php DELETED
@@ -1,36 +0,0 @@
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
- namespace WCML\Twig\RuntimeLoader;
12
-
13
- /**
14
- * Lazy loads the runtime implementations for a Twig element.
15
- *
16
- * @author Robin Chalas <robin.chalas@gmail.com>
17
- */
18
- class FactoryRuntimeLoader implements \WCML\Twig\RuntimeLoader\RuntimeLoaderInterface
19
- {
20
- private $map;
21
- /**
22
- * @param array $map An array where keys are class names and values factory callables
23
- */
24
- public function __construct($map = [])
25
- {
26
- $this->map = $map;
27
- }
28
- public function load($class)
29
- {
30
- if (isset($this->map[$class])) {
31
- $runtimeFactory = $this->map[$class];
32
- return $runtimeFactory();
33
- }
34
- }
35
- }
36
- \class_alias('WCML\\Twig\\RuntimeLoader\\FactoryRuntimeLoader', 'WCML\\Twig_FactoryRuntimeLoader');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/twig/src/RuntimeLoader/RuntimeLoaderInterface.php DELETED
@@ -1,29 +0,0 @@
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
- namespace WCML\Twig\RuntimeLoader;
12
-
13
- /**
14
- * Creates runtime implementations for Twig elements (filters/functions/tests).
15
- *
16
- * @author Fabien Potencier <fabien@symfony.com>
17
- */
18
- interface RuntimeLoaderInterface
19
- {
20
- /**
21
- * Creates the runtime implementation of a Twig element (filter/function/test).
22
- *
23
- * @param string $class A runtime class
24
- *
25
- * @return object|null The runtime instance or null if the loader does not know how to create the runtime for this class
26
- */
27
- public function load($class);
28
- }
29
- \class_alias('WCML\\Twig\\RuntimeLoader\\RuntimeLoaderInterface', 'WCML\\Twig_RuntimeLoaderInterface');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/twig/src/Sandbox/SecurityError.php DELETED
@@ -1,22 +0,0 @@
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
- namespace WCML\Twig\Sandbox;
12
-
13
- use WCML\Twig\Error\Error;
14
- /**
15
- * Exception thrown when a security error occurs at runtime.
16
- *
17
- * @author Fabien Potencier <fabien@symfony.com>
18
- */
19
- class SecurityError extends \WCML\Twig\Error\Error
20
- {
21
- }
22
- \class_alias('WCML\\Twig\\Sandbox\\SecurityError', 'WCML\\Twig_Sandbox_SecurityError');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/twig/src/Sandbox/SecurityNotAllowedFilterError.php DELETED
@@ -1,31 +0,0 @@
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
- namespace WCML\Twig\Sandbox;
12
-
13
- /**
14
- * Exception thrown when a not allowed filter is used in a template.
15
- *
16
- * @author Martin Hasoň <martin.hason@gmail.com>
17
- */
18
- class SecurityNotAllowedFilterError extends \WCML\Twig\Sandbox\SecurityError
19
- {
20
- private $filterName;
21
- public function __construct($message, $functionName, $lineno = -1, $filename = null, \Exception $previous = null)
22
- {
23
- parent::__construct($message, $lineno, $filename, $previous);
24
- $this->filterName = $functionName;
25
- }
26
- public function getFilterName()
27
- {
28
- return $this->filterName;
29
- }
30
- }
31
- \class_alias('WCML\\Twig\\Sandbox\\SecurityNotAllowedFilterError', 'WCML\\Twig_Sandbox_SecurityNotAllowedFilterError');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/twig/src/Sandbox/SecurityNotAllowedFunctionError.php DELETED
@@ -1,31 +0,0 @@
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
- namespace WCML\Twig\Sandbox;
12
-
13
- /**
14
- * Exception thrown when a not allowed function is used in a template.
15
- *
16
- * @author Martin Hasoň <martin.hason@gmail.com>
17
- */
18
- class SecurityNotAllowedFunctionError extends \WCML\Twig\Sandbox\SecurityError
19
- {
20
- private $functionName;
21
- public function __construct($message, $functionName, $lineno = -1, $filename = null, \Exception $previous = null)
22
- {
23
- parent::__construct($message, $lineno, $filename, $previous);
24
- $this->functionName = $functionName;
25
- }
26
- public function getFunctionName()
27
- {
28
- return $this->functionName;
29
- }
30
- }
31
- \class_alias('WCML\\Twig\\Sandbox\\SecurityNotAllowedFunctionError', 'WCML\\Twig_Sandbox_SecurityNotAllowedFunctionError');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/twig/src/Sandbox/SecurityNotAllowedMethodError.php DELETED
@@ -1,37 +0,0 @@
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
- namespace WCML\Twig\Sandbox;
12
-
13
- /**
14
- * Exception thrown when a not allowed class method is used in a template.
15
- *
16
- * @author Kit Burton-Senior <mail@kitbs.com>
17
- */
18
- class SecurityNotAllowedMethodError extends \WCML\Twig\Sandbox\SecurityError
19
- {
20
- private $className;
21
- private $methodName;
22
- public function __construct($message, $className, $methodName, $lineno = -1, $filename = null, \Exception $previous = null)
23
- {
24
- parent::__construct($message, $lineno, $filename, $previous);
25
- $this->className = $className;
26
- $this->methodName = $methodName;
27
- }
28
- public function getClassName()
29
- {
30
- return $this->className;
31
- }
32
- public function getMethodName()
33
- {
34
- return $this->methodName;
35
- }
36
- }
37
- \class_alias('WCML\\Twig\\Sandbox\\SecurityNotAllowedMethodError', 'WCML\\Twig_Sandbox_SecurityNotAllowedMethodError');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/twig/src/Sandbox/SecurityNotAllowedPropertyError.php DELETED
@@ -1,37 +0,0 @@
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
- namespace WCML\Twig\Sandbox;
12
-
13
- /**
14
- * Exception thrown when a not allowed class property is used in a template.
15
- *
16
- * @author Kit Burton-Senior <mail@kitbs.com>
17
- */
18
- class SecurityNotAllowedPropertyError extends \WCML\Twig\Sandbox\SecurityError
19
- {
20
- private $className;
21
- private $propertyName;
22
- public function __construct($message, $className, $propertyName, $lineno = -1, $filename = null, \Exception $previous = null)
23
- {
24
- parent::__construct($message, $lineno, $filename, $previous);
25
- $this->className = $className;
26
- $this->propertyName = $propertyName;
27
- }
28
- public function getClassName()
29
- {
30
- return $this->className;
31
- }
32
- public function getPropertyName()
33
- {
34
- return $this->propertyName;
35
- }
36
- }
37
- \class_alias('WCML\\Twig\\Sandbox\\SecurityNotAllowedPropertyError', 'WCML\\Twig_Sandbox_SecurityNotAllowedPropertyError');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/twig/src/Sandbox/SecurityNotAllowedTagError.php DELETED
@@ -1,31 +0,0 @@
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
- namespace WCML\Twig\Sandbox;
12
-
13
- /**
14
- * Exception thrown when a not allowed tag is used in a template.
15
- *
16
- * @author Martin Hasoň <martin.hason@gmail.com>
17
- */
18
- class SecurityNotAllowedTagError extends \WCML\Twig\Sandbox\SecurityError
19
- {
20
- private $tagName;
21
- public function __construct($message, $tagName, $lineno = -1, $filename = null, \Exception $previous = null)
22
- {
23
- parent::__construct($message, $lineno, $filename, $previous);
24
- $this->tagName = $tagName;
25
- }
26
- public function getTagName()
27
- {
28
- return $this->tagName;
29
- }
30
- }
31
- \class_alias('WCML\\Twig\\Sandbox\\SecurityNotAllowedTagError', 'WCML\\Twig_Sandbox_SecurityNotAllowedTagError');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/twig/src/Sandbox/SecurityPolicy.php DELETED
@@ -1,110 +0,0 @@
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
- namespace WCML\Twig\Sandbox;
12
-
13
- use WCML\Twig\Markup;
14
- /**
15
- * Represents a security policy which need to be enforced when sandbox mode is enabled.
16
- *
17
- * @final
18
- *
19
- * @author Fabien Potencier <fabien@symfony.com>
20
- */
21
- class SecurityPolicy implements \WCML\Twig\Sandbox\SecurityPolicyInterface
22
- {
23
- protected $allowedTags;
24
- protected $allowedFilters;
25
- protected $allowedMethods;
26
- protected $allowedProperties;
27
- protected $allowedFunctions;
28
- public function __construct(array $allowedTags = [], array $allowedFilters = [], array $allowedMethods = [], array $allowedProperties = [], array $allowedFunctions = [])
29
- {
30
- $this->allowedTags = $allowedTags;
31
- $this->allowedFilters = $allowedFilters;
32
- $this->setAllowedMethods($allowedMethods);
33
- $this->allowedProperties = $allowedProperties;
34
- $this->allowedFunctions = $allowedFunctions;
35
- }
36
- public function setAllowedTags(array $tags)
37
- {
38
- $this->allowedTags = $tags;
39
- }
40
- public function setAllowedFilters(array $filters)
41
- {
42
- $this->allowedFilters = $filters;
43
- }
44
- public function setAllowedMethods(array $methods)
45
- {
46
- $this->allowedMethods = [];
47
- foreach ($methods as $class => $m) {
48
- $this->allowedMethods[$class] = \array_map('strtolower', \is_array($m) ? $m : [$m]);
49
- }
50
- }
51
- public function setAllowedProperties(array $properties)
52
- {
53
- $this->allowedProperties = $properties;
54
- }
55
- public function setAllowedFunctions(array $functions)
56
- {
57
- $this->allowedFunctions = $functions;
58
- }
59
- public function checkSecurity($tags, $filters, $functions)
60
- {
61
- foreach ($tags as $tag) {
62
- if (!\in_array($tag, $this->allowedTags)) {
63
- throw new \WCML\Twig\Sandbox\SecurityNotAllowedTagError(\sprintf('Tag "%s" is not allowed.', $tag), $tag);
64
- }
65
- }
66
- foreach ($filters as $filter) {
67
- if (!\in_array($filter, $this->allowedFilters)) {
68
- throw new \WCML\Twig\Sandbox\SecurityNotAllowedFilterError(\sprintf('Filter "%s" is not allowed.', $filter), $filter);
69
- }
70
- }
71
- foreach ($functions as $function) {
72
- if (!\in_array($function, $this->allowedFunctions)) {
73
- throw new \WCML\Twig\Sandbox\SecurityNotAllowedFunctionError(\sprintf('Function "%s" is not allowed.', $function), $function);
74
- }
75
- }
76
- }
77
- public function checkMethodAllowed($obj, $method)
78
- {
79
- if ($obj instanceof \WCML\Twig_TemplateInterface || $obj instanceof \WCML\Twig\Markup) {
80
- return;
81
- }
82
- $allowed = \false;
83
- $method = \strtolower($method);
84
- foreach ($this->allowedMethods as $class => $methods) {
85
- if ($obj instanceof $class) {
86
- $allowed = \in_array($method, $methods);
87
- break;
88
- }
89
- }
90
- if (!$allowed) {
91
- $class = \get_class($obj);
92
- throw new \WCML\Twig\Sandbox\SecurityNotAllowedMethodError(\sprintf('Calling "%s" method on a "%s" object is not allowed.', $method, $class), $class, $method);
93
- }
94
- }
95
- public function checkPropertyAllowed($obj, $property)
96
- {
97
- $allowed = \false;
98
- foreach ($this->allowedProperties as $class => $properties) {
99
- if ($obj instanceof $class) {
100
- $allowed = \in_array($property, \is_array($properties) ? $properties : [$properties]);
101
- break;
102
- }
103
- }
104
- if (!$allowed) {
105
- $class = \get_class($obj);
106
- throw new \WCML\Twig\Sandbox\SecurityNotAllowedPropertyError(\sprintf('Calling "%s" property on a "%s" object is not allowed.', $property, $class), $class, $property);
107
- }
108
- }
109
- }
110
- \class_alias('WCML\\Twig\\Sandbox\\SecurityPolicy', 'WCML\\Twig_Sandbox_SecurityPolicy');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/twig/src/Sandbox/SecurityPolicyInterface.php DELETED
@@ -1,24 +0,0 @@
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
- namespace WCML\Twig\Sandbox;
12
-
13
- /**
14
- * Interface that all security policy classes must implements.
15
- *
16
- * @author Fabien Potencier <fabien@symfony.com>
17
- */
18
- interface SecurityPolicyInterface
19
- {
20
- public function checkSecurity($tags, $filters, $functions);
21
- public function checkMethodAllowed($obj, $method);
22
- public function checkPropertyAllowed($obj, $method);
23
- }
24
- \class_alias('WCML\\Twig\\Sandbox\\SecurityPolicyInterface', 'WCML\\Twig_Sandbox_SecurityPolicyInterface');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/twig/src/Source.php DELETED
@@ -1,49 +0,0 @@
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
- namespace WCML\Twig;
12
-
13
- /**
14
- * Holds information about a non-compiled Twig template.
15
- *
16
- * @final
17
- *
18
- * @author Fabien Potencier <fabien@symfony.com>
19
- */
20
- class Source
21
- {
22
- private $code;
23
- private $name;
24
- private $path;
25
- /**
26
- * @param string $code The template source code
27
- * @param string $name The template logical name
28
- * @param string $path The filesystem path of the template if any
29
- */
30
- public function __construct($code, $name, $path = '')
31
- {
32
- $this->code = $code;
33
- $this->name = $name;
34
- $this->path = $path;
35
- }
36
- public function getCode()
37
- {
38
- return $this->code;
39
- }
40
- public function getName()
41
- {
42
- return $this->name;
43
- }
44
- public function getPath()
45
- {
46
- return $this->path;
47
- }
48
- }
49
- \class_alias('WCML\\Twig\\Source', 'WCML\\Twig_Source');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/twig/src/Template.php DELETED
@@ -1,639 +0,0 @@
1
- <?php
2
-
3
- /*
4
- * This file is part of Twig.
5
- *
6
- * (c) Fabien Potencier
7
- * (c) Armin Ronacher
8
- *
9
- * For the full copyright and license information, please view the LICENSE
10
- * file that was distributed with this source code.
11
- */
12
- namespace WCML\Twig;
13
-
14
- use WCML\Twig\Error\Error;
15
- use WCML\Twig\Error\LoaderError;
16
- use WCML\Twig\Error\RuntimeError;
17
- /**
18
- * Default base class for compiled templates.
19
- *
20
- * This class is an implementation detail of how template compilation currently
21
- * works, which might change. It should never be used directly. Use $twig->load()
22
- * instead, which returns an instance of \Twig\TemplateWrapper.
23
- *
24
- * @author Fabien Potencier <fabien@symfony.com>
25
- *
26
- * @internal
27
- */
28
- abstract class Template implements \WCML\Twig_TemplateInterface
29
- {
30
- /**
31
- * @internal
32
- */
33
- protected static $cache = [];
34
- protected $parent;
35
- protected $parents = [];
36
- protected $env;
37
- protected $blocks = [];
38
- protected $traits = [];
39
- protected $sandbox;
40
- public function __construct(\WCML\Twig\Environment $env)
41
- {
42
- $this->env = $env;
43
- }
44
- /**
45
- * @internal this method will be removed in 2.0 and is only used internally to provide an upgrade path from 1.x to 2.0
46
- */
47
- public function __toString()
48
- {
49
- return $this->getTemplateName();
50
- }
51
- /**
52
- * Returns the template name.
53
- *
54
- * @return string The template name
55
- */
56
- public abstract function getTemplateName();
57
- /**
58
- * Returns debug information about the template.
59
- *
60
- * @return array Debug information
61
- */
62
- public function getDebugInfo()
63
- {
64
- return [];
65
- }
66
- /**
67
- * Returns the template source code.
68
- *
69
- * @return string The template source code
70
- *
71
- * @deprecated since 1.27 (to be removed in 2.0). Use getSourceContext() instead
72
- */
73
- public function getSource()
74
- {
75
- @\trigger_error('The ' . __METHOD__ . ' method is deprecated since version 1.27 and will be removed in 2.0. Use getSourceContext() instead.', \E_USER_DEPRECATED);
76
- return '';
77
- }
78
- /**
79
- * Returns information about the original template source code.
80
- *
81
- * @return Source
82
- */
83
- public function getSourceContext()
84
- {
85
- return new \WCML\Twig\Source('', $this->getTemplateName());
86
- }
87
- /**
88
- * @deprecated since 1.20 (to be removed in 2.0)
89
- */
90
- public function getEnvironment()
91
- {
92
- @\trigger_error('The ' . __METHOD__ . ' method is deprecated since version 1.20 and will be removed in 2.0.', \E_USER_DEPRECATED);
93
- return $this->env;
94
- }
95
- /**
96
- * Returns the parent template.
97
- *
98
- * This method is for internal use only and should never be called
99
- * directly.
100
- *
101
- * @param array $context
102
- *
103
- * @return \Twig_TemplateInterface|TemplateWrapper|false The parent template or false if there is no parent
104
- *
105
- * @internal
106
- */
107
- public function getParent(array $context)
108
- {
109
- if (null !== $this->parent) {
110
- return $this->parent;
111
- }
112
- try {
113
- $parent = $this->doGetParent($context);
114
- if (\false === $parent) {
115
- return \false;
116
- }
117
- if ($parent instanceof self || $parent instanceof \WCML\Twig\TemplateWrapper) {
118
- return $this->parents[$parent->getSourceContext()->getName()] = $parent;
119
- }
120
- if (!isset($this->parents[$parent])) {
121
- $this->parents[$parent] = $this->loadTemplate($parent);
122
- }
123
- } catch (\WCML\Twig\Error\LoaderError $e) {
124
- $e->setSourceContext(null);
125
- $e->guess();
126
- throw $e;
127
- }
128
- return $this->parents[$parent];
129
- }
130
- protected function doGetParent(array $context)
131
- {
132
- return \false;
133
- }
134
- public function isTraitable()
135
- {
136
- return \true;
137
- }
138
- /**
139
- * Displays a parent block.
140
- *
141
- * This method is for internal use only and should never be called
142
- * directly.
143
- *
144
- * @param string $name The block name to display from the parent
145
- * @param array $context The context
146
- * @param array $blocks The current set of blocks
147
- */
148
- public function displayParentBlock($name, array $context, array $blocks = [])
149
- {
150
- $name = (string) $name;
151
- if (isset($this->traits[$name])) {
152
- $this->traits[$name][0]->displayBlock($name, $context, $blocks, \false);
153
- } elseif (\false !== ($parent = $this->getParent($context))) {
154
- $parent->displayBlock($name, $context, $blocks, \false);
155
- } else {
156
- throw new \WCML\Twig\Error\RuntimeError(\sprintf('The template has no parent and no traits defining the "%s" block.', $name), -1, $this->getSourceContext());
157
- }
158
- }
159
- /**
160
- * Displays a block.
161
- *
162
- * This method is for internal use only and should never be called
163
- * directly.
164
- *
165
- * @param string $name The block name to display
166
- * @param array $context The context
167
- * @param array $blocks The current set of blocks
168
- * @param bool $useBlocks Whether to use the current set of blocks
169
- */
170
- public function displayBlock($name, array $context, array $blocks = [], $useBlocks = \true)
171
- {
172
- $name = (string) $name;
173
- if ($useBlocks && isset($blocks[$name])) {
174
- $template = $blocks[$name][0];
175
- $block = $blocks[$name][1];
176
- } elseif (isset($this->blocks[$name])) {
177
- $template = $this->blocks[$name][0];
178
- $block = $this->blocks[$name][1];
179
- } else {
180
- $template = null;
181
- $block = null;
182
- }
183
- // avoid RCEs when sandbox is enabled
184
- if (null !== $template && !$template instanceof self) {
185
- throw new \LogicException('A block must be a method on a \\Twig\\Template instance.');
186
- }
187
- if (null !== $template) {
188
- try {
189
- $template->{$block}($context, $blocks);
190
- } catch (\WCML\Twig\Error\Error $e) {
191
- if (!$e->getSourceContext()) {
192
- $e->setSourceContext($template->getSourceContext());
193
- }
194
- // this is mostly useful for \Twig\Error\LoaderError exceptions
195
- // see \Twig\Error\LoaderError
196
- if (-1 === $e->getTemplateLine()) {
197
- $e->guess();
198
- }
199
- throw $e;
200
- } catch (\Exception $e) {
201
- $e = new \WCML\Twig\Error\RuntimeError(\sprintf('An exception has been thrown during the rendering of a template ("%s").', $e->getMessage()), -1, $template->getSourceContext(), $e);
202
- $e->guess();
203
- throw $e;
204
- }
205
- } elseif (\false !== ($parent = $this->getParent($context))) {
206
- $parent->displayBlock($name, $context, \array_merge($this->blocks, $blocks), \false);
207
- } else {
208
- @\trigger_error(\sprintf('Silent display of undefined block "%s" in template "%s" is deprecated since version 1.29 and will throw an exception in 2.0. Use the "block(\'%s\') is defined" expression to test for block existence.', $name, $this->getTemplateName(), $name), \E_USER_DEPRECATED);
209
- }
210
- }
211
- /**
212
- * Renders a parent block.
213
- *
214
- * This method is for internal use only and should never be called
215
- * directly.
216
- *
217
- * @param string $name The block name to render from the parent
218
- * @param array $context The context
219
- * @param array $blocks The current set of blocks
220
- *
221
- * @return string The rendered block
222
- */
223
- public function renderParentBlock($name, array $context, array $blocks = [])
224
- {
225
- if ($this->env->isDebug()) {
226
- \ob_start();
227
- } else {
228
- \ob_start(function () {
229
- return '';
230
- });
231
- }
232
- $this->displayParentBlock($name, $context, $blocks);
233
- return \ob_get_clean();
234
- }
235
- /**
236
- * Renders a block.
237
- *
238
- * This method is for internal use only and should never be called
239
- * directly.
240
- *
241
- * @param string $name The block name to render
242
- * @param array $context The context
243
- * @param array $blocks The current set of blocks
244
- * @param bool $useBlocks Whether to use the current set of blocks
245
- *
246
- * @return string The rendered block
247
- */
248
- public function renderBlock($name, array $context, array $blocks = [], $useBlocks = \true)
249
- {
250
- if ($this->env->isDebug()) {
251
- \ob_start();
252
- } else {
253
- \ob_start(function () {
254
- return '';
255
- });
256
- }
257
- $this->displayBlock($name, $context, $blocks, $useBlocks);
258
- return \ob_get_clean();
259
- }
260
- /**
261
- * Returns whether a block exists or not in the current context of the template.
262
- *
263
- * This method checks blocks defined in the current template
264
- * or defined in "used" traits or defined in parent templates.
265
- *
266
- * @param string $name The block name
267
- * @param array $context The context
268
- * @param array $blocks The current set of blocks
269
- *
270
- * @return bool true if the block exists, false otherwise
271
- */
272
- public function hasBlock($name, array $context = null, array $blocks = [])
273
- {
274
- if (null === $context) {
275
- @\trigger_error('The ' . __METHOD__ . ' method is internal and should never be called; calling it directly is deprecated since version 1.28 and won\'t be possible anymore in 2.0.', \E_USER_DEPRECATED);
276
- return isset($this->blocks[(string) $name]);
277
- }
278
- if (isset($blocks[$name])) {
279
- return $blocks[$name][0] instanceof self;
280
- }
281
- if (isset($this->blocks[$name])) {
282
- return \true;
283
- }
284
- if (\false !== ($parent = $this->getParent($context))) {
285
- return $parent->hasBlock($name, $context);
286
- }
287
- return \false;
288
- }
289
- /**
290
- * Returns all block names in the current context of the template.
291
- *
292
- * This method checks blocks defined in the current template
293
- * or defined in "used" traits or defined in parent templates.
294
- *
295
- * @param array $context The context
296
- * @param array $blocks The current set of blocks
297
- *
298
- * @return array An array of block names
299
- */
300
- public function getBlockNames(array $context = null, array $blocks = [])
301
- {
302
- if (null === $context) {
303
- @\trigger_error('The ' . __METHOD__ . ' method is internal and should never be called; calling it directly is deprecated since version 1.28 and won\'t be possible anymore in 2.0.', \E_USER_DEPRECATED);
304
- return \array_keys($this->blocks);
305
- }
306
- $names = \array_merge(\array_keys($blocks), \array_keys($this->blocks));
307
- if (\false !== ($parent = $this->getParent($context))) {
308
- $names = \array_merge($names, $parent->getBlockNames($context));
309
- }
310
- return \array_unique($names);
311
- }
312
- /**
313
- * @return Template|TemplateWrapper
314
- */
315
- protected function loadTemplate($template, $templateName = null, $line = null, $index = null)
316
- {
317
- try {
318
- if (\is_array($template)) {
319
- return $this->env->resolveTemplate($template);
320
- }
321
- if ($template instanceof self || $template instanceof \WCML\Twig\TemplateWrapper) {
322
- return $template;
323
- }
324
- if ($template === $this->getTemplateName()) {
325
- $class = \get_class($this);
326
- if (\false !== ($pos = \strrpos($class, '___', -1))) {
327
- $class = \substr($class, 0, $pos);
328
- }
329
- return $this->env->loadClass($class, $template, $index);
330
- }
331
- return $this->env->loadTemplate($template, $index);
332
- } catch (\WCML\Twig\Error\Error $e) {
333
- if (!$e->getSourceContext()) {
334
- $e->setSourceContext($templateName ? new \WCML\Twig\Source('', $templateName) : $this->getSourceContext());
335
- }
336
- if ($e->getTemplateLine() > 0) {
337
- throw $e;
338
- }
339
- if (!$line) {
340
- $e->guess();
341
- } else {
342
- $e->setTemplateLine($line);
343
- }
344
- throw $e;
345
- }
346
- }
347
- /**
348
- * @internal
349
- *
350
- * @return Template
351
- */
352
- protected function unwrap()
353
- {
354
- return $this;
355
- }
356
- /**
357
- * Returns all blocks.
358
- *
359
- * This method is for internal use only and should never be called
360
- * directly.
361
- *
362
- * @return array An array of blocks
363
- */
364
- public function getBlocks()
365
- {
366
- return $this->blocks;
367
- }
368
- public function display(array $context, array $blocks = [])
369
- {
370
- $this->displayWithErrorHandling($this->env->mergeGlobals($context), \array_merge($this->blocks, $blocks));
371
- }
372
- public function render(array $context)
373
- {
374
- $level = \ob_get_level();
375
- if ($this->env->isDebug()) {
376
- \ob_start();
377
- } else {
378
- \ob_start(function () {
379
- return '';
380
- });
381
- }
382
- try {
383
- $this->display($context);
384
- } catch (\Exception $e) {
385
- while (\ob_get_level() > $level) {
386
- \ob_end_clean();
387
- }
388
- throw $e;
389
- } catch (\Throwable $e) {
390
- while (\ob_get_level() > $level) {
391
- \ob_end_clean();
392
- }
393
- throw $e;
394
- }
395
- return \ob_get_clean();
396
- }
397
- protected function displayWithErrorHandling(array $context, array $blocks = [])
398
- {
399
- try {
400
- $this->doDisplay($context, $blocks);
401
- } catch (\WCML\Twig\Error\Error $e) {
402
- if (!$e->getSourceContext()) {
403
- $e->setSourceContext($this->getSourceContext());
404
- }
405
- // this is mostly useful for \Twig\Error\LoaderError exceptions
406
- // see \Twig\Error\LoaderError
407
- if (-1 === $e->getTemplateLine()) {
408
- $e->guess();
409
- }
410
- throw $e;
411
- } catch (\Exception $e) {
412
- $e = new \WCML\Twig\Error\RuntimeError(\sprintf('An exception has been thrown during the rendering of a template ("%s").', $e->getMessage()), -1, $this->getSourceContext(), $e);
413
- $e->guess();
414
- throw $e;
415
- }
416
- }
417
- /**
418
- * Auto-generated method to display the template with the given context.
419
- *
420
- * @param array $context An array of parameters to pass to the template
421
- * @param array $blocks An array of blocks to pass to the template
422
- */
423
- protected abstract function doDisplay(array $context, array $blocks = []);
424
- /**
425
- * Returns a variable from the context.
426
- *
427
- * This method is for internal use only and should never be called
428
- * directly.
429
- *
430
- * This method should not be overridden in a sub-class as this is an
431
- * implementation detail that has been introduced to optimize variable
432
- * access for versions of PHP before 5.4. This is not a way to override
433
- * the way to get a variable value.
434
- *
435
- * @param array $context The context
436
- * @param string $item The variable to return from the context
437
- * @param bool $ignoreStrictCheck Whether to ignore the strict variable check or not
438
- *
439
- * @return mixed The content of the context variable
440
- *
441
- * @throws RuntimeError if the variable does not exist and Twig is running in strict mode
442
- *
443
- * @internal
444
- */
445
- protected final function getContext($context, $item, $ignoreStrictCheck = \false)
446
- {
447
- if (!\array_key_exists($item, $context)) {
448
- if ($ignoreStrictCheck || !$this->env->isStrictVariables()) {
449
- return;
450
- }
451
- throw new \WCML\Twig\Error\RuntimeError(\sprintf('Variable "%s" does not exist.', $item), -1, $this->getSourceContext());
452
- }
453
- return $context[$item];
454
- }
455
- /**
456
- * Returns the attribute value for a given array/object.
457
- *
458
- * @param mixed $object The object or array from where to get the item
459
- * @param mixed $item The item to get from the array or object
460
- * @param array $arguments An array of arguments to pass if the item is an object method
461
- * @param string $type The type of attribute (@see \Twig\Template constants)
462
- * @param bool $isDefinedTest Whether this is only a defined check
463
- * @param bool $ignoreStrictCheck Whether to ignore the strict attribute check or not
464
- *
465
- * @return mixed The attribute value, or a Boolean when $isDefinedTest is true, or null when the attribute is not set and $ignoreStrictCheck is true
466
- *
467
- * @throws RuntimeError if the attribute does not exist and Twig is running in strict mode and $isDefinedTest is false
468
- *
469
- * @internal
470
- */
471
- protected function getAttribute($object, $item, array $arguments = [], $type = self::ANY_CALL, $isDefinedTest = \false, $ignoreStrictCheck = \false)
472
- {
473
- // array
474
- if (self::METHOD_CALL !== $type) {
475
- $arrayItem = \is_bool($item) || \is_float($item) ? (int) $item : $item;
476
- if ((\is_array($object) || $object instanceof \ArrayObject) && (isset($object[$arrayItem]) || \array_key_exists($arrayItem, $object)) || $object instanceof \ArrayAccess && isset($object[$arrayItem])) {
477
- if ($isDefinedTest) {
478
- return \true;
479
- }
480
- return $object[$arrayItem];
481
- }
482
- if (self::ARRAY_CALL === $type || !\is_object($object)) {
483
- if ($isDefinedTest) {
484
- return \false;
485
- }
486
- if ($ignoreStrictCheck || !$this->env->isStrictVariables()) {
487
- return;
488
- }
489
- if ($object instanceof \ArrayAccess) {
490
- $message = \sprintf('Key "%s" in object with ArrayAccess of class "%s" does not exist.', $arrayItem, \get_class($object));
491
- } elseif (\is_object($object)) {
492
- $message = \sprintf('Impossible to access a key "%s" on an object of class "%s" that does not implement ArrayAccess interface.', $item, \get_class($object));
493
- } elseif (\is_array($object)) {
494
- if (empty($object)) {
495
- $message = \sprintf('Key "%s" does not exist as the array is empty.', $arrayItem);
496
- } else {
497
- $message = \sprintf('Key "%s" for array with keys "%s" does not exist.', $arrayItem, \implode(', ', \array_keys($object)));
498
- }
499
- } elseif (self::ARRAY_CALL === $type) {
500
- if (null === $object) {
501
- $message = \sprintf('Impossible to access a key ("%s") on a null variable.', $item);
502
- } else {
503
- $message = \sprintf('Impossible to access a key ("%s") on a %s variable ("%s").', $item, \gettype($object), $object);
504
- }
505
- } elseif (null === $object) {
506
- $message = \sprintf('Impossible to access an attribute ("%s") on a null variable.', $item);
507
- } else {
508
- $message = \sprintf('Impossible to access an attribute ("%s") on a %s variable ("%s").', $item, \gettype($object), $object);
509
- }
510
- throw new \WCML\Twig\Error\RuntimeError($message, -1, $this->getSourceContext());
511
- }
512
- }
513
- if (!\is_object($object)) {
514
- if ($isDefinedTest) {
515
- return \false;
516
- }
517
- if ($ignoreStrictCheck || !$this->env->isStrictVariables()) {
518
- return;
519
- }
520
- if (null === $object) {
521
- $message = \sprintf('Impossible to invoke a method ("%s") on a null variable.', $item);
522
- } elseif (\is_array($object)) {
523
- $message = \sprintf('Impossible to invoke a method ("%s") on an array.', $item);
524
- } else {
525
- $message = \sprintf('Impossible to invoke a method ("%s") on a %s variable ("%s").', $item, \gettype($object), $object);
526
- }
527
- throw new \WCML\Twig\Error\RuntimeError($message, -1, $this->getSourceContext());
528
- }
529
- // object property
530
- if (self::METHOD_CALL !== $type && !$object instanceof self) {
531
- // \Twig\Template does not have public properties, and we don't want to allow access to internal ones
532
- if (isset($object->{$item}) || \array_key_exists((string) $item, $object)) {
533
- if ($isDefinedTest) {
534
- return \true;
535
- }
536
- if ($this->env->hasExtension('WCML\\Twig\\Extension\\SandboxExtension')) {
537
- $this->env->getExtension('WCML\\Twig\\Extension\\SandboxExtension')->checkPropertyAllowed($object, $item);
538
- }
539
- return $object->{$item};
540
- }
541
- }
542
- $class = \get_class($object);
543
- // object method
544
- if (!isset(self::$cache[$class])) {
545
- // get_class_methods returns all methods accessible in the scope, but we only want public ones to be accessible in templates
546
- if ($object instanceof self) {
547
- $ref = new \ReflectionClass($class);
548
- $methods = [];
549
- foreach ($ref->getMethods(\ReflectionMethod::IS_PUBLIC) as $refMethod) {
550
- // Accessing the environment from templates is forbidden to prevent untrusted changes to the environment
551
- if ('getenvironment' !== \strtolower($refMethod->name)) {
552
- $methods[] = $refMethod->name;
553
- }
554
- }
555
- } else {
556
- $methods = \get_class_methods($object);
557
- }
558
- // sort values to have consistent behavior, so that "get" methods win precedence over "is" methods
559
- \sort($methods);
560
- $cache = [];
561
- foreach ($methods as $method) {
562
- $cache[$method] = $method;
563
- $cache[$lcName = \strtolower($method)] = $method;
564
- if ('g' === $lcName[0] && 0 === \strpos($lcName, 'get')) {
565
- $name = \substr($method, 3);
566
- $lcName = \substr($lcName, 3);
567
- } elseif ('i' === $lcName[0] && 0 === \strpos($lcName, 'is')) {
568
- $name = \substr($method, 2);
569
- $lcName = \substr($lcName, 2);
570
- } else {
571
- continue;
572
- }
573
- // skip get() and is() methods (in which case, $name is empty)
574
- if ($name) {
575
- if (!isset($cache[$name])) {
576
- $cache[$name] = $method;
577
- }
578
- if (!isset($cache[$lcName])) {
579
- $cache[$lcName] = $method;
580
- }
581
- }
582
- }
583
- self::$cache[$class] = $cache;
584
- }
585
- $call = \false;
586
- if (isset(self::$cache[$class][$item])) {
587
- $method = self::$cache[$class][$item];
588
- } elseif (isset(self::$cache[$class][$lcItem = \strtolower($item)])) {
589
- $method = self::$cache[$class][$lcItem];
590
- } elseif (isset(self::$cache[$class]['__call'])) {
591
- $method = $item;
592
- $call = \true;
593
- } else {
594
- if ($isDefinedTest) {
595
- return \false;
596
- }
597
- if ($ignoreStrictCheck || !$this->env->isStrictVariables()) {
598
- return;
599
- }
600
- throw new \WCML\Twig\Error\RuntimeError(\sprintf('Neither the property "%1$s" nor one of the methods "%1$s()", "get%1$s()"/"is%1$s()" or "__call()" exist and have public access in class "%2$s".', $item, $class), -1, $this->getSourceContext());
601
- }
602
- if ($isDefinedTest) {
603
- return \true;
604
- }
605
- if ($this->env->hasExtension('WCML\\Twig\\Extension\\SandboxExtension')) {
606
- $this->env->getExtension('WCML\\Twig\\Extension\\SandboxExtension')->checkMethodAllowed($object, $method);
607
- }
608
- // Some objects throw exceptions when they have __call, and the method we try
609
- // to call is not supported. If ignoreStrictCheck is true, we should return null.
610
- try {
611
- if (!$arguments) {
612
- $ret = $object->{$method}();
613
- } else {
614
- $ret = \call_user_func_array([$object, $method], $arguments);
615
- }
616
- } catch (\BadMethodCallException $e) {
617
- if ($call && ($ignoreStrictCheck || !$this->env->isStrictVariables())) {
618
- return;
619
- }
620
- throw $e;
621
- }
622
- // @deprecated in 1.28
623
- if ($object instanceof \WCML\Twig_TemplateInterface) {
624
- $self = $object->getTemplateName() === $this->getTemplateName();
625
- $message = \sprintf('Calling "%s" on template "%s" from template "%s" is deprecated since version 1.28 and won\'t be supported anymore in 2.0.', $item, $object->getTemplateName(), $this->getTemplateName());
626
- if ('renderBlock' === $method || 'displayBlock' === $method) {
627
- $message .= \sprintf(' Use block("%s"%s) instead).', $arguments[0], $self ? '' : ', template');
628
- } elseif ('hasBlock' === $method) {
629
- $message .= \sprintf(' Use "block("%s"%s) is defined" instead).', $arguments[0], $self ? '' : ', template');
630
- } elseif ('render' === $method || 'display' === $method) {
631
- $message .= \sprintf(' Use include("%s") instead).', $object->getTemplateName());
632
- }
633
- @\trigger_error($message, \E_USER_DEPRECATED);
634
- return '' === $ret ? '' : new \WCML\Twig\Markup($ret, $this->env->getCharset());
635
- }
636
- return $ret;
637
- }
638
- }
639
- \class_alias('WCML\\Twig\\Template', 'WCML\\Twig_Template');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/twig/src/TemplateWrapper.php DELETED
@@ -1,148 +0,0 @@
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
- namespace WCML\Twig;
12
-
13
- /**
14
- * Exposes a template to userland.
15
- *
16
- * @author Fabien Potencier <fabien@symfony.com>
17
- */
18
- final class TemplateWrapper
19
- {
20
- private $env;
21
- private $template;
22
- /**
23
- * This method is for internal use only and should never be called
24
- * directly (use \\WCML\\Twig\\Environment::load() instead).
25
- *
26
- * @internal
27
- */
28
- public function __construct(\WCML\Twig\Environment $env, \WCML\Twig\Template $template)
29
- {
30
- $this->env = $env;
31
- $this->template = $template;
32
- }
33
- /**
34
- * Renders the template.
35
- *
36
- * @param array $context An array of parameters to pass to the template
37
- *
38
- * @return string The rendered template
39
- */
40
- public function render($context = [])
41
- {
42
- // using func_get_args() allows to not expose the blocks argument
43
- // as it should only be used by internal code
44
- return $this->template->render($context, \func_num_args() > 1 ? \func_get_arg(1) : []);
45
- }
46
- /**
47
- * Displays the template.
48
- *
49
- * @param array $context An array of parameters to pass to the template
50
- */
51
- public function display($context = [])
52
- {
53
- // using func_get_args() allows to not expose the blocks argument
54
- // as it should only be used by internal code
55
- $this->template->display($context, \func_num_args() > 1 ? \func_get_arg(1) : []);
56
- }
57
- /**
58
- * Checks if a block is defined.
59
- *
60
- * @param string $name The block name
61
- * @param array $context An array of parameters to pass to the template
62
- *
63
- * @return bool
64
- */
65
- public function hasBlock($name, $context = [])
66
- {
67
- return $this->template->hasBlock($name, $context);
68
- }
69
- /**
70
- * Returns defined block names in the template.
71
- *
72
- * @param array $context An array of parameters to pass to the template
73
- *
74
- * @return string[] An array of defined template block names
75
- */
76
- public function getBlockNames($context = [])
77
- {
78
- return $this->template->getBlockNames($context);
79
- }
80
- /**
81
- * Renders a template block.
82
- *
83
- * @param string $name The block name to render
84
- * @param array $context An array of parameters to pass to the template
85
- *
86
- * @return string The rendered block
87
- */
88
- public function renderBlock($name, $context = [])
89
- {
90
- $context = $this->env->mergeGlobals($context);
91
- $level = \ob_get_level();
92
- if ($this->env->isDebug()) {
93
- \ob_start();
94
- } else {
95
- \ob_start(function () {
96
- return '';
97
- });
98
- }
99
- try {
100
- $this->template->displayBlock($name, $context);
101
- } catch (\Exception $e) {
102
- while (\ob_get_level() > $level) {
103
- \ob_end_clean();
104
- }
105
- throw $e;
106
- } catch (\Throwable $e) {
107
- while (\ob_get_level() > $level) {
108
- \ob_end_clean();
109
- }
110
- throw $e;
111
- }
112
- return \ob_get_clean();
113
- }
114
- /**
115
- * Displays a template block.
116
- *
117
- * @param string $name The block name to render
118
- * @param array $context An array of parameters to pass to the template
119
- */
120
- public function displayBlock($name, $context = [])
121
- {
122
- $this->template->displayBlock($name, $this->env->mergeGlobals($context));
123
- }
124
- /**
125
- * @return Source
126
- */
127
- public function getSourceContext()
128
- {
129
- return $this->template->getSourceContext();
130
- }
131
- /**
132
- * @return string
133
- */
134
- public function getTemplateName()
135
- {
136
- return $this->template->getTemplateName();
137
- }
138
- /**
139
- * @internal
140
- *
141
- * @return Template
142
- */
143
- public function unwrap()
144
- {
145
- return $this->template;
146
- }
147
- }
148
- \class_alias('WCML\\Twig\\TemplateWrapper', 'WCML\\Twig_TemplateWrapper');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/twig/src/Test/IntegrationTestCase.php DELETED
@@ -1,213 +0,0 @@
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
- namespace WCML\Twig\Test;
12
-
13
- use WCML\PHPUnit\Framework\TestCase;
14
- use WCML\Twig\Environment;
15
- use WCML\Twig\Error\Error;
16
- use WCML\Twig\Extension\ExtensionInterface;
17
- use WCML\Twig\Loader\ArrayLoader;
18
- use WCML\Twig\Loader\SourceContextLoaderInterface;
19
- use WCML\Twig\RuntimeLoader\RuntimeLoaderInterface;
20
- use WCML\Twig\Source;
21
- use WCML\Twig\TwigFilter;
22
- use WCML\Twig\TwigFunction;
23
- use WCML\Twig\TwigTest;
24
- /**
25
- * Integration test helper.
26
- *
27
- * @author Fabien Potencier <fabien@symfony.com>
28
- * @author Karma Dordrak <drak@zikula.org>
29
- */
30
- abstract class IntegrationTestCase extends \WCML\PHPUnit\Framework\TestCase
31
- {
32
- /**
33
- * @return string
34
- */
35
- protected abstract function getFixturesDir();
36
- /**
37
- * @return RuntimeLoaderInterface[]
38
- */
39
- protected function getRuntimeLoaders()
40
- {
41
- return [];
42
- }
43
- /**
44
- * @return ExtensionInterface[]
45
- */
46
- protected function getExtensions()
47
- {
48
- return [];
49
- }
50
- /**
51
- * @return TwigFilter[]
52
- */
53
- protected function getTwigFilters()
54
- {
55
- return [];
56
- }
57
- /**
58
- * @return TwigFunction[]
59
- */
60
- protected function getTwigFunctions()
61
- {
62
- return [];
63
- }
64
- /**
65
- * @return TwigTest[]
66
- */
67
- protected function getTwigTests()
68
- {
69
- return [];
70
- }
71
- /**
72
- * @dataProvider getTests
73
- */
74
- public function testIntegration($file, $message, $condition, $templates, $exception, $outputs)
75
- {
76
- $this->doIntegrationTest($file, $message, $condition, $templates, $exception, $outputs);
77
- }
78
- /**
79
- * @dataProvider getLegacyTests
80
- * @group legacy
81
- */
82
- public function testLegacyIntegration($file, $message, $condition, $templates, $exception, $outputs)
83
- {
84
- $this->doIntegrationTest($file, $message, $condition, $templates, $exception, $outputs);
85
- }
86
- public function getTests($name, $legacyTests = \false)
87
- {
88
- $fixturesDir = \realpath($this->getFixturesDir());
89
- $tests = [];
90
- foreach (new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($fixturesDir), \RecursiveIteratorIterator::LEAVES_ONLY) as $file) {
91
- if (!\preg_match('/\\.test$/', $file)) {
92
- continue;
93
- }
94
- if ($legacyTests xor \false !== \strpos($file->getRealpath(), '.legacy.test')) {
95
- continue;
96
- }
97
- $test = \file_get_contents($file->getRealpath());
98
- if (\preg_match('/--TEST--\\s*(.*?)\\s*(?:--CONDITION--\\s*(.*))?\\s*((?:--TEMPLATE(?:\\(.*?\\))?--(?:.*?))+)\\s*(?:--DATA--\\s*(.*))?\\s*--EXCEPTION--\\s*(.*)/sx', $test, $match)) {
99
- $message = $match[1];
100
- $condition = $match[2];
101
- $templates = self::parseTemplates($match[3]);
102
- $exception = $match[5];
103
- $outputs = [[null, $match[4], null, '']];
104
- } elseif (\preg_match('/--TEST--\\s*(.*?)\\s*(?:--CONDITION--\\s*(.*))?\\s*((?:--TEMPLATE(?:\\(.*?\\))?--(?:.*?))+)--DATA--.*?--EXPECT--.*/s', $test, $match)) {
105
- $message = $match[1];
106
- $condition = $match[2];
107
- $templates = self::parseTemplates($match[3]);
108
- $exception = \false;
109
- \preg_match_all('/--DATA--(.*?)(?:--CONFIG--(.*?))?--EXPECT--(.*?)(?=\\-\\-DATA\\-\\-|$)/s', $test, $outputs, \PREG_SET_ORDER);
110
- } else {
111
- throw new \InvalidArgumentException(\sprintf('Test "%s" is not valid.', \str_replace($fixturesDir . '/', '', $file)));
112
- }
113
- $tests[] = [\str_replace($fixturesDir . '/', '', $file), $message, $condition, $templates, $exception, $outputs];
114
- }
115
- if ($legacyTests && empty($tests)) {
116
- // add a dummy test to avoid a PHPUnit message
117
- return [['not', '-', '', [], '', []]];
118
- }
119
- return $tests;
120
- }
121
- public function getLegacyTests()
122
- {
123
- return $this->getTests('testLegacyIntegration', \true);
124
- }
125
- protected function doIntegrationTest($file, $message, $condition, $templates, $exception, $outputs)
126
- {
127
- if (!$outputs) {
128
- $this->markTestSkipped('no tests to run');
129
- }
130
- if ($condition) {
131
- eval('$ret = ' . $condition . ';');
132
- if (!$ret) {
133
- $this->markTestSkipped($condition);
134
- }
135
- }
136
- $loader = new \WCML\Twig\Loader\ArrayLoader($templates);
137
- foreach ($outputs as $i => $match) {
138
- $config = \array_merge(['cache' => \false, 'strict_variables' => \true], $match[2] ? eval($match[2] . ';') : []);
139
- $twig = new \WCML\Twig\Environment($loader, $config);
140
- $twig->addGlobal('global', 'global');
141
- foreach ($this->getRuntimeLoaders() as $runtimeLoader) {
142
- $twig->addRuntimeLoader($runtimeLoader);
143
- }
144
- foreach ($this->getExtensions() as $extension) {
145
- $twig->addExtension($extension);
146
- }
147
- foreach ($this->getTwigFilters() as $filter) {
148
- $twig->addFilter($filter);
149
- }
150
- foreach ($this->getTwigTests() as $test) {
151
- $twig->addTest($test);
152
- }
153
- foreach ($this->getTwigFunctions() as $function) {
154
- $twig->addFunction($function);
155
- }
156
- $p = new \ReflectionProperty($twig, 'templateClassPrefix');
157
- $p->setAccessible(\true);
158
- $p->setValue($twig, '\\WCML\\__TwigTemplate_' . \hash('sha256', \uniqid(\mt_rand(), \true), \false) . '_');
159
- try {
160
- $template = $twig->load('index.twig');
161
- } catch (\Exception $e) {
162
- if (\false !== $exception) {
163
- $message = $e->getMessage();
164
- $this->assertSame(\trim($exception), \trim(\sprintf('%s: %s', \get_class($e), $message)));
165
- $last = \substr($message, \strlen($message) - 1);
166
- $this->assertTrue('.' === $last || '?' === $last, 'Exception message must end with a dot or a question mark.');
167
- return;
168
- }
169
- throw new \WCML\Twig\Error\Error(\sprintf('%s: %s', \get_class($e), $e->getMessage()), -1, null, $e);
170
- }
171
- try {
172
- $output = \trim($template->render(eval($match[1] . ';')), "\n ");
173
- } catch (\Exception $e) {
174
- if (\false !== $exception) {
175
- $this->assertSame(\trim($exception), \trim(\sprintf('%s: %s', \get_class($e), $e->getMessage())));
176
- return;
177
- }
178
- $e = new \WCML\Twig\Error\Error(\sprintf('%s: %s', \get_class($e), $e->getMessage()), -1, null, $e);
179
- $output = \trim(\sprintf('%s: %s', \get_class($e), $e->getMessage()));
180
- }
181
- if (\false !== $exception) {
182
- list($class) = \explode(':', $exception);
183
- $constraintClass = \class_exists('WCML\\PHPUnit\\Framework\\Constraint\\Exception') ? 'PHPUnit\\Framework\\Constraint\\Exception' : 'PHPUnit_Framework_Constraint_Exception';
184
- $this->assertThat(null, new $constraintClass($class));
185
- }
186
- $expected = \trim($match[3], "\n ");
187
- if ($expected !== $output) {
188
- \printf("Compiled templates that failed on case %d:\n", $i + 1);
189
- foreach (\array_keys($templates) as $name) {
190
- echo "Template: {$name}\n";
191
- $loader = $twig->getLoader();
192
- if (!$loader instanceof \WCML\Twig\Loader\SourceContextLoaderInterface) {
193
- $source = new \WCML\Twig\Source($loader->getSource($name), $name);
194
- } else {
195
- $source = $loader->getSourceContext($name);
196
- }
197
- echo $twig->compile($twig->parse($twig->tokenize($source)));
198
- }
199
- }
200
- $this->assertEquals($expected, $output, $message . ' (in ' . $file . ')');
201
- }
202
- }
203
- protected static function parseTemplates($test)
204
- {
205
- $templates = [];
206
- \preg_match_all('/--TEMPLATE(?:\\((.*?)\\))?--(.*?)(?=\\-\\-TEMPLATE|$)/s', $test, $matches, \PREG_SET_ORDER);
207
- foreach ($matches as $match) {
208
- $templates[$match[1] ? $match[1] : 'index.twig'] = $match[2];
209
- }
210
- return $templates;
211
- }
212
- }
213
- \class_alias('WCML\\Twig\\Test\\IntegrationTestCase', 'WCML\\Twig_Test_IntegrationTestCase');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/twig/src/Test/NodeTestCase.php DELETED
@@ -1,65 +0,0 @@
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
- namespace WCML\Twig\Test;
12
-
13
- use WCML\PHPUnit\Framework\TestCase;
14
- use WCML\Twig\Compiler;
15
- use WCML\Twig\Environment;
16
- use WCML\Twig\Loader\ArrayLoader;
17
- use WCML\Twig\Node\Node;
18
- abstract class NodeTestCase extends \WCML\PHPUnit\Framework\TestCase
19
- {
20
- public abstract function getTests();
21
- /**
22
- * @dataProvider getTests
23
- */
24
- public function testCompile($node, $source, $environment = null, $isPattern = \false)
25
- {
26
- $this->assertNodeCompilation($source, $node, $environment, $isPattern);
27
- }
28
- public function assertNodeCompilation($source, \WCML\Twig\Node\Node $node, \WCML\Twig\Environment $environment = null, $isPattern = \false)
29
- {
30
- $compiler = $this->getCompiler($environment);
31
- $compiler->compile($node);
32
- if ($isPattern) {
33
- $this->assertStringMatchesFormat($source, \trim($compiler->getSource()));
34
- } else {
35
- $this->assertEquals($source, \trim($compiler->getSource()));
36
- }
37
- }
38
- protected function getCompiler(\WCML\Twig\Environment $environment = null)
39
- {
40
- return new \WCML\Twig\Compiler(null === $environment ? $this->getEnvironment() : $environment);
41
- }
42
- protected function getEnvironment()
43
- {
44
- return new \WCML\Twig\Environment(new \WCML\Twig\Loader\ArrayLoader([]));
45
- }
46
- protected function getVariableGetter($name, $line = \false)
47
- {
48
- $line = $line > 0 ? "// line {$line}\n" : '';
49
- if (\PHP_VERSION_ID >= 70000) {
50
- return \sprintf('%s($context["%s"] ?? null)', $line, $name);
51
- }
52
- if (\PHP_VERSION_ID >= 50400) {
53
- return \sprintf('%s(isset($context["%s"]) ? $context["%s"] : null)', $line, $name, $name);
54
- }
55
- return \sprintf('%s$this->getContext($context, "%s")', $line, $name);
56
- }
57
- protected function getAttributeGetter()
58
- {
59
- if (\function_exists('WCML\\twig_template_get_attributes')) {
60
- return 'twig_template_get_attributes($this, ';
61
- }
62
- return '$this->getAttribute(';
63
- }
64
- }
65
- \class_alias('WCML\\Twig\\Test\\NodeTestCase', 'WCML\\Twig_Test_NodeTestCase');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/twig/src/Token.php DELETED
@@ -1,198 +0,0 @@
1
- <?php
2
-
3
- /*
4
- * This file is part of Twig.
5
- *
6
- * (c) Fabien Potencier
7
- * (c) Armin Ronacher
8
- *
9
- * For the full copyright and license information, please view the LICENSE
10
- * file that was distributed with this source code.
11
- */
12
- namespace WCML\Twig;
13
-
14
- /**
15
- * Represents a Token.
16
- *
17
- * @author Fabien Potencier <fabien@symfony.com>
18
- *
19
- * @final
20
- */
21
- class Token
22
- {
23
- protected $value;
24
- protected $type;
25
- protected $lineno;
26
- const EOF_TYPE = -1;
27
- const TEXT_TYPE = 0;
28
- const BLOCK_START_TYPE = 1;
29
- const VAR_START_TYPE = 2;
30
- const BLOCK_END_TYPE = 3;
31
- const VAR_END_TYPE = 4;
32
- const NAME_TYPE = 5;
33
- const NUMBER_TYPE = 6;
34
- const STRING_TYPE = 7;
35
- const OPERATOR_TYPE = 8;
36
- const PUNCTUATION_TYPE = 9;
37
- const INTERPOLATION_START_TYPE = 10;
38
- const INTERPOLATION_END_TYPE = 11;
39
- const ARROW_TYPE = 12;
40
- /**
41
- * @param int $type The type of the token
42
- * @param string $value The token value
43
- * @param int $lineno The line position in the source
44
- */
45
- public function __construct($type, $value, $lineno)
46
- {
47
- $this->type = $type;
48
- $this->value = $value;
49
- $this->lineno = $lineno;
50
- }
51
- public function __toString()
52
- {
53
- return \sprintf('%s(%s)', self::typeToString($this->type, \true), $this->value);
54
- }
55
- /**
56
- * Tests the current token for a type and/or a value.
57
- *
58
- * Parameters may be:
59
- * * just type
60
- * * type and value (or array of possible values)
61
- * * just value (or array of possible values) (NAME_TYPE is used as type)
62
- *
63
- * @param array|string|int $type The type to test
64
- * @param array|string|null $values The token value
65
- *
66
- * @return bool
67
- */
68
- public function test($type, $values = null)
69
- {
70
- if (null === $values && !\is_int($type)) {
71
- $values = $type;
72
- $type = self::NAME_TYPE;
73
- }
74
- return $this->type === $type && (null === $values || \is_array($values) && \in_array($this->value, $values) || $this->value == $values);
75
- }
76
- /**
77
- * @return int
78
- */
79
- public function getLine()
80
- {
81
- return $this->lineno;
82
- }
83
- /**
84
- * @return int
85
- */
86
- public function getType()
87
- {
88
- return $this->type;
89
- }
90
- /**
91
- * @return string
92
- */
93
- public function getValue()
94
- {
95
- return $this->value;
96
- }
97
- /**
98
- * Returns the constant representation (internal) of a given type.
99
- *
100
- * @param int $type The type as an integer
101
- * @param bool $short Whether to return a short representation or not
102
- *
103
- * @return string The string representation
104
- */
105
- public static function typeToString($type, $short = \false)
106
- {
107
- switch ($type) {
108
- case self::EOF_TYPE:
109
- $name = 'EOF_TYPE';
110
- break;
111
- case self::TEXT_TYPE:
112
- $name = 'TEXT_TYPE';
113
- break;
114
- case self::BLOCK_START_TYPE:
115
- $name = 'BLOCK_START_TYPE';
116
- break;
117
- case self::VAR_START_TYPE:
118
- $name = 'VAR_START_TYPE';
119
- break;
120
- case self::BLOCK_END_TYPE:
121
- $name = 'BLOCK_END_TYPE';
122
- break;
123
- case self::VAR_END_TYPE:
124
- $name = 'VAR_END_TYPE';
125
- break;
126
- case self::NAME_TYPE:
127
- $name = 'NAME_TYPE';
128
- break;
129
- case self::NUMBER_TYPE:
130
- $name = 'NUMBER_TYPE';
131
- break;
132
- case self::STRING_TYPE:
133
- $name = 'STRING_TYPE';
134
- break;
135
- case self::OPERATOR_TYPE:
136
- $name = 'OPERATOR_TYPE';
137
- break;
138
- case self::PUNCTUATION_TYPE:
139
- $name = 'PUNCTUATION_TYPE';
140
- break;
141
- case self::INTERPOLATION_START_TYPE:
142
- $name = 'INTERPOLATION_START_TYPE';
143
- break;
144
- case self::INTERPOLATION_END_TYPE:
145
- $name = 'INTERPOLATION_END_TYPE';
146
- break;
147
- case self::ARROW_TYPE:
148
- $name = 'ARROW_TYPE';
149
- break;
150
- default:
151
- throw new \LogicException(\sprintf('Token of type "%s" does not exist.', $type));
152
- }
153
- return $short ? $name : 'Twig\\Token::' . $name;
154
- }
155
- /**
156
- * Returns the English representation of a given type.
157
- *
158
- * @param int $type The type as an integer
159
- *
160
- * @return string The string representation
161
- */
162
- public static function typeToEnglish($type)
163
- {
164
- switch ($type) {
165
- case self::EOF_TYPE:
166
- return 'end of template';
167
- case self::TEXT_TYPE:
168
- return 'text';
169
- case self::BLOCK_START_TYPE:
170
- return 'begin of statement block';
171
- case self::VAR_START_TYPE:
172
- return 'begin of print statement';
173
- case self::BLOCK_END_TYPE:
174
- return 'end of statement block';
175
- case self::VAR_END_TYPE:
176
- return 'end of print statement';
177
- case self::NAME_TYPE:
178
- return 'name';
179
- case self::NUMBER_TYPE:
180
- return 'number';
181
- case self::STRING_TYPE:
182
- return 'string';
183
- case self::OPERATOR_TYPE:
184
- return 'operator';
185
- case self::PUNCTUATION_TYPE:
186
- return 'punctuation';
187
- case self::INTERPOLATION_START_TYPE:
188
- return 'begin of string interpolation';
189
- case self::INTERPOLATION_END_TYPE:
190
- return 'end of string interpolation';
191
- case self::ARROW_TYPE:
192
- return 'arrow function';
193
- default:
194
- throw new \LogicException(\sprintf('Token of type "%s" does not exist.', $type));
195
- }
196
- }
197
- }
198
- \class_alias('WCML\\Twig\\Token', 'WCML\\Twig_Token');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/twig/src/TokenParser/AbstractTokenParser.php DELETED
@@ -1,30 +0,0 @@
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
- namespace WCML\Twig\TokenParser;
12
-
13
- use WCML\Twig\Parser;
14
- /**
15
- * Base class for all token parsers.
16
- *
17
- * @author Fabien Potencier <fabien@symfony.com>
18
- */
19
- abstract class AbstractTokenParser implements \WCML\Twig\TokenParser\TokenParserInterface
20
- {
21
- /**
22
- * @var Parser
23
- */
24
- protected $parser;
25
- public function setParser(\WCML\Twig\Parser $parser)
26
- {
27
- $this->parser = $parser;
28
- }
29
- }
30
- \class_alias('WCML\\Twig\\TokenParser\\AbstractTokenParser', 'WCML\\Twig_TokenParser');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/twig/src/TokenParser/ApplyTokenParser.php DELETED
@@ -1,47 +0,0 @@
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
- namespace WCML\Twig\TokenParser;
12
-
13
- use WCML\Twig\Node\Expression\TempNameExpression;
14
- use WCML\Twig\Node\Node;
15
- use WCML\Twig\Node\PrintNode;
16
- use WCML\Twig\Node\SetNode;
17
- use WCML\Twig\Token;
18
- /**
19
- * Applies filters on a section of a template.
20
- *
21
- * {% apply upper %}
22
- * This text becomes uppercase
23
- * {% endapplys %}
24
- */
25
- final class ApplyTokenParser extends \WCML\Twig\TokenParser\AbstractTokenParser
26
- {
27
- public function parse(\WCML\Twig\Token $token)
28
- {
29
- $lineno = $token->getLine();
30
- $name = $this->parser->getVarName();
31
- $ref = new \WCML\Twig\Node\Expression\TempNameExpression($name, $lineno);
32
- $ref->setAttribute('always_defined', \true);
33
- $filter = $this->parser->getExpressionParser()->parseFilterExpressionRaw($ref, $this->getTag());
34
- $this->parser->getStream()->expect(\WCML\Twig\Token::BLOCK_END_TYPE);
35
- $body = $this->parser->subparse([$this, 'decideApplyEnd'], \true);
36
- $this->parser->getStream()->expect(\WCML\Twig\Token::BLOCK_END_TYPE);
37
- return new \WCML\Twig\Node\Node([new \WCML\Twig\Node\SetNode(\true, $ref, $body, $lineno, $this->getTag()), new \WCML\Twig\Node\PrintNode($filter, $lineno, $this->getTag())]);
38
- }
39
- public function decideApplyEnd(\WCML\Twig\Token $token)
40
- {
41
- return $token->test('endapply');
42
- }
43
- public function getTag()
44
- {
45
- return 'apply';
46
- }
47
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/twig/src/TokenParser/AutoEscapeTokenParser.php DELETED
@@ -1,75 +0,0 @@
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
- namespace WCML\Twig\TokenParser;
12
-
13
- use WCML\Twig\Error\SyntaxError;
14
- use WCML\Twig\Node\AutoEscapeNode;
15
- use WCML\Twig\Node\Expression\ConstantExpression;
16
- use WCML\Twig\Token;
17
- /**
18
- * Marks a section of a template to be escaped or not.
19
- *
20
- * {% autoescape true %}
21
- * Everything will be automatically escaped in this block
22
- * {% endautoescape %}
23
- *
24
- * {% autoescape false %}
25
- * Everything will be outputed as is in this block
26
- * {% endautoescape %}
27
- *
28
- * {% autoescape true js %}
29
- * Everything will be automatically escaped in this block
30
- * using the js escaping strategy
31
- * {% endautoescape %}
32
- *
33
- * @final
34
- */
35
- class AutoEscapeTokenParser extends \WCML\Twig\TokenParser\AbstractTokenParser
36
- {
37
- public function parse(\WCML\Twig\Token $token)
38
- {
39
- $lineno = $token->getLine();
40
- $stream = $this->parser->getStream();
41
- if ($stream->test(\WCML\Twig\Token::BLOCK_END_TYPE)) {
42
- $value = 'html';
43
- } else {
44
- $expr = $this->parser->getExpressionParser()->parseExpression();
45
- if (!$expr instanceof \WCML\Twig\Node\Expression\ConstantExpression) {
46
- throw new \WCML\Twig\Error\SyntaxError('An escaping strategy must be a string or a bool.', $stream->getCurrent()->getLine(), $stream->getSourceContext());
47
- }
48
- $value = $expr->getAttribute('value');
49
- $compat = \true === $value || \false === $value;
50
- if (\true === $value) {
51
- $value = 'html';
52
- }
53
- if ($compat && $stream->test(\WCML\Twig\Token::NAME_TYPE)) {
54
- @\trigger_error('Using the autoescape tag with "true" or "false" before the strategy name is deprecated since version 1.21.', \E_USER_DEPRECATED);
55
- if (\false === $value) {
56
- throw new \WCML\Twig\Error\SyntaxError('Unexpected escaping strategy as you set autoescaping to false.', $stream->getCurrent()->getLine(), $stream->getSourceContext());
57
- }
58
- $value = $stream->next()->getValue();
59
- }
60
- }
61
- $stream->expect(\WCML\Twig\Token::BLOCK_END_TYPE);
62
- $body = $this->parser->subparse([$this, 'decideBlockEnd'], \true);
63
- $stream->expect(\WCML\Twig\Token::BLOCK_END_TYPE);
64
- return new \WCML\Twig\Node\AutoEscapeNode($value, $body, $lineno, $this->getTag());
65
- }
66
- public function decideBlockEnd(\WCML\Twig\Token $token)
67
- {
68
- return $token->test('endautoescape');
69
- }
70
- public function getTag()
71
- {
72
- return 'autoescape';
73
- }
74
- }
75
- \class_alias('WCML\\Twig\\TokenParser\\AutoEscapeTokenParser', 'WCML\\Twig_TokenParser_AutoEscape');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/twig/src/TokenParser/BlockTokenParser.php DELETED
@@ -1,69 +0,0 @@
1
- <?php
2
-
3
- /*
4
- * This file is part of Twig.
5
- *
6
- * (c) Fabien Potencier
7
- * (c) Armin Ronacher
8
- *
9
- * For the full copyright and license information, please view the LICENSE
10
- * file that was distributed with this source code.
11
- */
12
- namespace WCML\Twig\TokenParser;
13
-
14
- use WCML\Twig\Error\SyntaxError;
15
- use WCML\Twig\Node\BlockNode;
16
- use WCML\Twig\Node\BlockReferenceNode;
17
- use WCML\Twig\Node\Node;
18
- use WCML\Twig\Node\PrintNode;
19
- use WCML\Twig\Token;
20
- /**
21
- * Marks a section of a template as being reusable.
22
- *
23
- * {% block head %}
24
- * <link rel="stylesheet" href="style.css" />
25
- * <title>{% block title %}{% endblock %} - My Webpage</title>
26
- * {% endblock %}
27
- *
28
- * @final
29
- */
30
- class BlockTokenParser extends \WCML\Twig\TokenParser\AbstractTokenParser
31
- {
32
- public function parse(\WCML\Twig\Token $token)
33
- {
34
- $lineno = $token->getLine();
35
- $stream = $this->parser->getStream();
36
- $name = $stream->expect(\WCML\Twig\Token::NAME_TYPE)->getValue();
37
- if ($this->parser->hasBlock($name)) {
38
- throw new \WCML\Twig\Error\SyntaxError(\sprintf("The block '%s' has already been defined line %d.", $name, $this->parser->getBlock($name)->getTemplateLine()), $stream->getCurrent()->getLine(), $stream->getSourceContext());
39
- }
40
- $this->parser->setBlock($name, $block = new \WCML\Twig\Node\BlockNode($name, new \WCML\Twig\Node\Node([]), $lineno));
41
- $this->parser->pushLocalScope();
42
- $this->parser->pushBlockStack($name);
43
- if ($stream->nextIf(\WCML\Twig\Token::BLOCK_END_TYPE)) {
44
- $body = $this->parser->subparse([$this, 'decideBlockEnd'], \true);
45
- if ($token = $stream->nextIf(\WCML\Twig\Token::NAME_TYPE)) {
46
- $value = $token->getValue();
47
- if ($value != $name) {
48
- throw new \WCML\Twig\Error\SyntaxError(\sprintf('Expected endblock for block "%s" (but "%s" given).', $name, $value), $stream->getCurrent()->getLine(), $stream->getSourceContext());
49
- }
50
- }
51
- } else {
52
- $body = new \WCML\Twig\Node\Node([new \WCML\Twig\Node\PrintNode($this->parser->getExpressionParser()->parseExpression(), $lineno)]);
53
- }
54
- $stream->expect(\WCML\Twig\Token::BLOCK_END_TYPE);
55
- $block->setNode('body', $body);
56
- $this->parser->popBlockStack();
57
- $this->parser->popLocalScope();
58
- return new \WCML\Twig\Node\BlockReferenceNode($name, $lineno, $this->getTag());
59
- }
60
- public function decideBlockEnd(\WCML\Twig\Token $token)
61
- {
62
- return $token->test('endblock');
63
- }
64
- public function getTag()
65
- {
66
- return 'block';
67
- }
68
- }
69
- \class_alias('WCML\\Twig\\TokenParser\\BlockTokenParser', 'WCML\\Twig_TokenParser_Block');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/twig/src/TokenParser/DeprecatedTokenParser.php DELETED
@@ -1,38 +0,0 @@
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
- namespace WCML\Twig\TokenParser;
12
-
13
- use WCML\Twig\Node\DeprecatedNode;
14
- use WCML\Twig\Token;
15
- /**
16
- * Deprecates a section of a template.
17
- *
18
- * {% deprecated 'The "base.twig" template is deprecated, use "layout.twig" instead.' %}
19
- * {% extends 'layout.html.twig' %}
20
- *
21
- * @author Yonel Ceruto <yonelceruto@gmail.com>
22
- *
23
- * @final
24
- */
25
- class DeprecatedTokenParser extends \WCML\Twig\TokenParser\AbstractTokenParser
26
- {
27
- public function parse(\WCML\Twig\Token $token)
28
- {
29
- $expr = $this->parser->getExpressionParser()->parseExpression();
30
- $this->parser->getStream()->expect(\WCML\Twig\Token::BLOCK_END_TYPE);
31
- return new \WCML\Twig\Node\DeprecatedNode($expr, $token->getLine(), $this->getTag());
32
- }
33
- public function getTag()
34
- {
35
- return 'deprecated';
36
- }
37
- }
38
- \class_alias('WCML\\Twig\\TokenParser\\DeprecatedTokenParser', 'WCML\\Twig_TokenParser_Deprecated');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/twig/src/TokenParser/DoTokenParser.php DELETED
@@ -1,33 +0,0 @@
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
- namespace WCML\Twig\TokenParser;
12
-
13
- use WCML\Twig\Node\DoNode;
14
- use WCML\Twig\Token;
15
- /**
16
- * Evaluates an expression, discarding the returned value.
17
- *
18
- * @final
19
- */
20
- class DoTokenParser extends \WCML\Twig\TokenParser\AbstractTokenParser
21
- {
22
- public function parse(\WCML\Twig\Token $token)
23
- {
24
- $expr = $this->parser->getExpressionParser()->parseExpression();
25
- $this->parser->getStream()->expect(\WCML\Twig\Token::BLOCK_END_TYPE);
26
- return new \WCML\Twig\Node\DoNode($expr, $token->getLine(), $this->getTag());
27
- }
28
- public function getTag()
29
- {
30
- return 'do';
31
- }
32
- }
33
- \class_alias('WCML\\Twig\\TokenParser\\DoTokenParser', 'WCML\\Twig_TokenParser_Do');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/twig/src/TokenParser/EmbedTokenParser.php DELETED
@@ -1,55 +0,0 @@
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
- namespace WCML\Twig\TokenParser;
12
-
13
- use WCML\Twig\Node\EmbedNode;
14
- use WCML\Twig\Node\Expression\ConstantExpression;
15
- use WCML\Twig\Node\Expression\NameExpression;
16
- use WCML\Twig\Token;
17
- /**
18
- * Embeds a template.
19
- *
20
- * @final
21
- */
22
- class EmbedTokenParser extends \WCML\Twig\TokenParser\IncludeTokenParser
23
- {
24
- public function parse(\WCML\Twig\Token $token)
25
- {
26
- $stream = $this->parser->getStream();
27
- $parent = $this->parser->getExpressionParser()->parseExpression();
28
- list($variables, $only, $ignoreMissing) = $this->parseArguments();
29
- $parentToken = $fakeParentToken = new \WCML\Twig\Token(\WCML\Twig\Token::STRING_TYPE, '__parent__', $token->getLine());
30
- if ($parent instanceof \WCML\Twig\Node\Expression\ConstantExpression) {
31
- $parentToken = new \WCML\Twig\Token(\WCML\Twig\Token::STRING_TYPE, $parent->getAttribute('value'), $token->getLine());
32
- } elseif ($parent instanceof \WCML\Twig\Node\Expression\NameExpression) {
33
- $parentToken = new \WCML\Twig\Token(\WCML\Twig\Token::NAME_TYPE, $parent->getAttribute('name'), $token->getLine());
34
- }
35
- // inject a fake parent to make the parent() function work
36
- $stream->injectTokens([new \WCML\Twig\Token(\WCML\Twig\Token::BLOCK_START_TYPE, '', $token->getLine()), new \WCML\Twig\Token(\WCML\Twig\Token::NAME_TYPE, 'extends', $token->getLine()), $parentToken, new \WCML\Twig\Token(\WCML\Twig\Token::BLOCK_END_TYPE, '', $token->getLine())]);
37
- $module = $this->parser->parse($stream, [$this, 'decideBlockEnd'], \true);
38
- // override the parent with the correct one
39
- if ($fakeParentToken === $parentToken) {
40
- $module->setNode('parent', $parent);
41
- }
42
- $this->parser->embedTemplate($module);
43
- $stream->expect(\WCML\Twig\Token::BLOCK_END_TYPE);
44
- return new \WCML\Twig\Node\EmbedNode($module->getTemplateName(), $module->getAttribute('index'), $variables, $only, $ignoreMissing, $token->getLine(), $this->getTag());
45
- }
46
- public function decideBlockEnd(\WCML\Twig\Token $token)
47
- {
48
- return $token->test('endembed');
49
- }
50
- public function getTag()
51
- {
52
- return 'embed';
53
- }
54
- }
55
- \class_alias('WCML\\Twig\\TokenParser\\EmbedTokenParser', 'WCML\\Twig_TokenParser_Embed');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/twig/src/TokenParser/ExtendsTokenParser.php DELETED
@@ -1,46 +0,0 @@
1
- <?php
2
-
3
- /*
4
- * This file is part of Twig.
5
- *
6
- * (c) Fabien Potencier
7
- * (c) Armin Ronacher
8
- *
9
- * For the full copyright and license information, please view the LICENSE
10
- * file that was distributed with this source code.
11
- */
12
- namespace WCML\Twig\TokenParser;
13
-
14
- use WCML\Twig\Error\SyntaxError;
15
- use WCML\Twig\Node\Node;
16
- use WCML\Twig\Token;
17
- /**
18
- * Extends a template by another one.
19
- *
20
- * {% extends "base.html" %}
21
- *
22
- * @final
23
- */
24
- class ExtendsTokenParser extends \WCML\Twig\TokenParser\AbstractTokenParser
25
- {
26
- public function parse(\WCML\Twig\Token $token)
27
- {
28
- $stream = $this->parser->getStream();
29
- if ($this->parser->peekBlockStack()) {
30
- throw new \WCML\Twig\Error\SyntaxError('Cannot use "extend" in a block.', $token->getLine(), $stream->getSourceContext());
31
- } elseif (!$this->parser->isMainScope()) {
32
- throw new \WCML\Twig\Error\SyntaxError('Cannot use "extend" in a macro.', $token->getLine(), $stream->getSourceContext());
33
- }
34
- if (null !== $this->parser->getParent()) {
35
- throw new \WCML\Twig\Error\SyntaxError('Multiple extends tags are forbidden.', $token->getLine(), $stream->getSourceContext());
36
- }
37
- $this->parser->setParent($this->parser->getExpressionParser()->parseExpression());
38
- $stream->expect(\WCML\Twig\Token::BLOCK_END_TYPE);
39
- return new \WCML\Twig\Node\Node();
40
- }
41
- public function getTag()
42
- {
43
- return 'extends';
44
- }
45
- }
46
- \class_alias('WCML\\Twig\\TokenParser\\ExtendsTokenParser', 'WCML\\Twig_TokenParser_Extends');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/twig/src/TokenParser/FilterTokenParser.php DELETED
@@ -1,50 +0,0 @@
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
- namespace WCML\Twig\TokenParser;
12
-
13
- use WCML\Twig\Node\BlockNode;
14
- use WCML\Twig\Node\Expression\BlockReferenceExpression;
15
- use WCML\Twig\Node\Expression\ConstantExpression;
16
- use WCML\Twig\Node\PrintNode;
17
- use WCML\Twig\Token;
18
- /**
19
- * Filters a section of a template by applying filters.
20
- *
21
- * {% filter upper %}
22
- * This text becomes uppercase
23
- * {% endfilter %}
24
- *
25
- * @final
26
- */
27
- class FilterTokenParser extends \WCML\Twig\TokenParser\AbstractTokenParser
28
- {
29
- public function parse(\WCML\Twig\Token $token)
30
- {
31
- $name = $this->parser->getVarName();
32
- $ref = new \WCML\Twig\Node\Expression\BlockReferenceExpression(new \WCML\Twig\Node\Expression\ConstantExpression($name, $token->getLine()), null, $token->getLine(), $this->getTag());
33
- $filter = $this->parser->getExpressionParser()->parseFilterExpressionRaw($ref, $this->getTag());
34
- $this->parser->getStream()->expect(\WCML\Twig\Token::BLOCK_END_TYPE);
35
- $body = $this->parser->subparse([$this, 'decideBlockEnd'], \true);
36
- $this->parser->getStream()->expect(\WCML\Twig\Token::BLOCK_END_TYPE);
37
- $block = new \WCML\Twig\Node\BlockNode($name, $body, $token->getLine());
38
- $this->parser->setBlock($name, $block);
39
- return new \WCML\Twig\Node\PrintNode($filter, $token->getLine(), $this->getTag());
40
- }
41
- public function decideBlockEnd(\WCML\Twig\Token $token)
42
- {
43
- return $token->test('endfilter');
44
- }
45
- public function getTag()
46
- {
47
- return 'filter';
48
- }
49
- }
50
- \class_alias('WCML\\Twig\\TokenParser\\FilterTokenParser', 'WCML\\Twig_TokenParser_Filter');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/twig/src/TokenParser/FlushTokenParser.php DELETED
@@ -1,34 +0,0 @@
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
- namespace WCML\Twig\TokenParser;
12
-
13
- use WCML\Twig\Node\FlushNode;
14
- use WCML\Twig\Token;
15
- /**
16
- * Flushes the output to the client.
17
- *
18
- * @see flush()
19
- *
20
- * @final
21
- */
22
- class FlushTokenParser extends \WCML\Twig\TokenParser\AbstractTokenParser
23
- {
24
- public function parse(\WCML\Twig\Token $token)
25
- {
26
- $this->parser->getStream()->expect(\WCML\Twig\Token::BLOCK_END_TYPE);
27
- return new \WCML\Twig\Node\FlushNode($token->getLine(), $this->getTag());
28
- }
29
- public function getTag()
30
- {
31
- return 'flush';
32
- }
33
- }
34
- \class_alias('WCML\\Twig\\TokenParser\\FlushTokenParser', 'WCML\\Twig_TokenParser_Flush');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/twig/src/TokenParser/ForTokenParser.php DELETED
@@ -1,118 +0,0 @@
1
- <?php
2
-
3
- /*
4
- * This file is part of Twig.
5
- *
6
- * (c) Fabien Potencier
7
- * (c) Armin Ronacher
8
- *
9
- * For the full copyright and license information, please view the LICENSE
10
- * file that was distributed with this source code.
11
- */
12
- namespace WCML\Twig\TokenParser;
13
-
14
- use WCML\Twig\Error\SyntaxError;
15
- use WCML\Twig\Node\Expression\AssignNameExpression;
16
- use WCML\Twig\Node\Expression\ConstantExpression;
17
- use WCML\Twig\Node\Expression\GetAttrExpression;
18
- use WCML\Twig\Node\Expression\NameExpression;
19
- use WCML\Twig\Node\ForNode;
20
- use WCML\Twig\Token;
21
- use WCML\Twig\TokenStream;
22
- /**
23
- * Loops over each item of a sequence.
24
- *
25
- * <ul>
26
- * {% for user in users %}
27
- * <li>{{ user.username|e }}</li>
28
- * {% endfor %}
29
- * </ul>
30
- *
31
- * @final
32
- */
33
- class ForTokenParser extends \WCML\Twig\TokenParser\AbstractTokenParser
34
- {
35
- public function parse(\WCML\Twig\Token $token)
36
- {
37
- $lineno = $token->getLine();
38
- $stream = $this->parser->getStream();
39
- $targets = $this->parser->getExpressionParser()->parseAssignmentExpression();
40
- $stream->expect(\WCML\Twig\Token::OPERATOR_TYPE, 'in');
41
- $seq = $this->parser->getExpressionParser()->parseExpression();
42
- $ifexpr = null;
43
- if ($stream->nextIf(\WCML\Twig\Token::NAME_TYPE, 'if')) {
44
- $ifexpr = $this->parser->getExpressionParser()->parseExpression();
45
- }
46
- $stream->expect(\WCML\Twig\Token::BLOCK_END_TYPE);
47
- $body = $this->parser->subparse([$this, 'decideForFork']);
48
- if ('else' == $stream->next()->getValue()) {
49
- $stream->expect(\WCML\Twig\Token::BLOCK_END_TYPE);
50
- $else = $this->parser->subparse([$this, 'decideForEnd'], \true);
51
- } else {
52
- $else = null;
53
- }
54
- $stream->expect(\WCML\Twig\Token::BLOCK_END_TYPE);
55
- if (\count($targets) > 1) {
56
- $keyTarget = $targets->getNode(0);
57
- $keyTarget = new \WCML\Twig\Node\Expression\AssignNameExpression($keyTarget->getAttribute('name'), $keyTarget->getTemplateLine());
58
- $valueTarget = $targets->getNode(1);
59
- $valueTarget = new \WCML\Twig\Node\Expression\AssignNameExpression($valueTarget->getAttribute('name'), $valueTarget->getTemplateLine());
60
- } else {
61
- $keyTarget = new \WCML\Twig\Node\Expression\AssignNameExpression('_key', $lineno);
62
- $valueTarget = $targets->getNode(0);
63
- $valueTarget = new \WCML\Twig\Node\Expression\AssignNameExpression($valueTarget->getAttribute('name'), $valueTarget->getTemplateLine());
64
- }
65
- if ($ifexpr) {
66
- $this->checkLoopUsageCondition($stream, $ifexpr);
67
- $this->checkLoopUsageBody($stream, $body);
68
- }
69
- return new \WCML\Twig\Node\ForNode($keyTarget, $valueTarget, $seq, $ifexpr, $body, $else, $lineno, $this->getTag());
70
- }
71
- public function decideForFork(\WCML\Twig\Token $token)
72
- {
73
- return $token->test(['else', 'endfor']);
74
- }
75
- public function decideForEnd(\WCML\Twig\Token $token)
76
- {
77
- return $token->test('endfor');
78
- }
79
- // the loop variable cannot be used in the condition
80
- protected function checkLoopUsageCondition(\WCML\Twig\TokenStream $stream, \WCML\Twig_NodeInterface $node)
81
- {
82
- if ($node instanceof \WCML\Twig\Node\Expression\GetAttrExpression && $node->getNode('node') instanceof \WCML\Twig\Node\Expression\NameExpression && 'loop' == $node->getNode('node')->getAttribute('name')) {
83
- throw new \WCML\Twig\Error\SyntaxError('The "loop" variable cannot be used in a looping condition.', $node->getTemplateLine(), $stream->getSourceContext());
84
- }
85
- foreach ($node as $n) {
86
- if (!$n) {
87
- continue;
88
- }
89
- $this->checkLoopUsageCondition($stream, $n);
90
- }
91
- }
92
- // check usage of non-defined loop-items
93
- // it does not catch all problems (for instance when a for is included into another or when the variable is used in an include)
94
- protected function checkLoopUsageBody(\WCML\Twig\TokenStream $stream, \WCML\Twig_NodeInterface $node)
95
- {
96
- if ($node instanceof \WCML\Twig\Node\Expression\GetAttrExpression && $node->getNode('node') instanceof \WCML\Twig\Node\Expression\NameExpression && 'loop' == $node->getNode('node')->getAttribute('name')) {
97
- $attribute = $node->getNode('attribute');
98
- if ($attribute instanceof \WCML\Twig\Node\Expression\ConstantExpression && \in_array($attribute->getAttribute('value'), ['length', 'revindex0', 'revindex', 'last'])) {
99
- throw new \WCML\Twig\Error\SyntaxError(\sprintf('The "loop.%s" variable is not defined when looping with a condition.', $attribute->getAttribute('value')), $node->getTemplateLine(), $stream->getSourceContext());
100
- }
101
- }
102
- // should check for parent.loop.XXX usage
103
- if ($node instanceof \WCML\Twig\Node\ForNode) {
104
- return;
105
- }
106
- foreach ($node as $n) {
107
- if (!$n) {
108
- continue;
109
- }
110
- $this->checkLoopUsageBody($stream, $n);
111
- }
112
- }
113
- public function getTag()
114
- {
115
- return 'for';
116
- }
117
- }
118
- \class_alias('WCML\\Twig\\TokenParser\\ForTokenParser', 'WCML\\Twig_TokenParser_For');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/twig/src/TokenParser/FromTokenParser.php DELETED
@@ -1,59 +0,0 @@
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
- namespace WCML\Twig\TokenParser;
12
-
13
- use WCML\Twig\Error\SyntaxError;
14
- use WCML\Twig\Node\Expression\AssignNameExpression;
15
- use WCML\Twig\Node\ImportNode;
16
- use WCML\Twig\Token;
17
- /**
18
- * Imports macros.
19
- *
20
- * {% from 'forms.html' import forms %}
21
- *
22
- * @final
23
- */
24
- class FromTokenParser extends \WCML\Twig\TokenParser\AbstractTokenParser
25
- {
26
- public function parse(\WCML\Twig\Token $token)
27
- {
28
- $macro = $this->parser->getExpressionParser()->parseExpression();
29
- $stream = $this->parser->getStream();
30
- $stream->expect(\WCML\Twig\Token::NAME_TYPE, 'import');
31
- $targets = [];
32
- do {
33
- $name = $stream->expect(\WCML\Twig\Token::NAME_TYPE)->getValue();
34
- $alias = $name;
35
- if ($stream->nextIf('as')) {
36
- $alias = $stream->expect(\WCML\Twig\Token::NAME_TYPE)->getValue();
37
- }
38
- $targets[$name] = $alias;
39
- if (!$stream->nextIf(\WCML\Twig\Token::PUNCTUATION_TYPE, ',')) {
40
- break;
41
- }
42
- } while (\true);
43
- $stream->expect(\WCML\Twig\Token::BLOCK_END_TYPE);
44
- $var = new \WCML\Twig\Node\Expression\AssignNameExpression($this->parser->getVarName(), $token->getLine());
45
- $node = new \WCML\Twig\Node\ImportNode($macro, $var, $token->getLine(), $this->getTag());
46
- foreach ($targets as $name => $alias) {
47
- if ($this->parser->isReservedMacroName($name)) {
48
- throw new \WCML\Twig\Error\SyntaxError(\sprintf('"%s" cannot be an imported macro as it is a reserved keyword.', $name), $token->getLine(), $stream->getSourceContext());
49
- }
50
- $this->parser->addImportedSymbol('function', $alias, 'get' . $name, $var);
51
- }
52
- return $node;
53
- }
54
- public function getTag()
55
- {
56
- return 'from';
57
- }
58
- }
59
- \class_alias('WCML\\Twig\\TokenParser\\FromTokenParser', 'WCML\\Twig_TokenParser_From');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/twig/src/TokenParser/IfTokenParser.php DELETED
@@ -1,79 +0,0 @@
1
- <?php
2
-
3
- /*
4
- * This file is part of Twig.
5
- *
6
- * (c) Fabien Potencier
7
- * (c) Armin Ronacher
8
- *
9
- * For the full copyright and license information, please view the LICENSE
10
- * file that was distributed with this source code.
11
- */
12
- namespace WCML\Twig\TokenParser;
13
-
14
- use WCML\Twig\Error\SyntaxError;
15
- use WCML\Twig\Node\IfNode;
16
- use WCML\Twig\Node\Node;
17
- use WCML\Twig\Token;
18
- /**
19
- * Tests a condition.
20
- *
21
- * {% if users %}
22
- * <ul>
23
- * {% for user in users %}
24
- * <li>{{ user.username|e }}</li>
25
- * {% endfor %}
26
- * </ul>
27
- * {% endif %}
28
- *
29
- * @final
30
- */
31
- class IfTokenParser extends \WCML\Twig\TokenParser\AbstractTokenParser
32
- {
33
- public function parse(\WCML\Twig\Token $token)
34
- {
35
- $lineno = $token->getLine();
36
- $expr = $this->parser->getExpressionParser()->parseExpression();
37
- $stream = $this->parser->getStream();
38
- $stream->expect(\WCML\Twig\Token::BLOCK_END_TYPE);
39
- $body = $this->parser->subparse([$this, 'decideIfFork']);
40
- $tests = [$expr, $body];
41
- $else = null;
42
- $end = \false;
43
- while (!$end) {
44
- switch ($stream->next()->getValue()) {
45
- case 'else':
46
- $stream->expect(\WCML\Twig\Token::BLOCK_END_TYPE);
47
- $else = $this->parser->subparse([$this, 'decideIfEnd']);
48
- break;
49
- case 'elseif':
50
- $expr = $this->parser->getExpressionParser()->parseExpression();
51
- $stream->expect(\WCML\Twig\Token::BLOCK_END_TYPE);
52
- $body = $this->parser->subparse([$this, 'decideIfFork']);
53
- $tests[] = $expr;
54
- $tests[] = $body;
55
- break;
56
- case 'endif':
57
- $end = \true;
58
- break;
59
- default:
60
- throw new \WCML\Twig\Error\SyntaxError(\sprintf('Unexpected end of template. Twig was looking for the following tags "else", "elseif", or "endif" to close the "if" block started at line %d).', $lineno), $stream->getCurrent()->getLine(), $stream->getSourceContext());
61
- }
62
- }
63
- $stream->expect(\WCML\Twig\Token::BLOCK_END_TYPE);
64
- return new \WCML\Twig\Node\IfNode(new \WCML\Twig\Node\Node($tests), $else, $lineno, $this->getTag());
65
- }
66
- public function decideIfFork(\WCML\Twig\Token $token)
67
- {
68
- return $token->test(['elseif', 'else', 'endif']);
69
- }
70
- public function decideIfEnd(\WCML\Twig\Token $token)
71
- {
72
- return $token->test(['endif']);
73
- }
74
- public function getTag()
75
- {
76
- return 'if';
77
- }
78
- }
79
- \class_alias('WCML\\Twig\\TokenParser\\IfTokenParser', 'WCML\\Twig_TokenParser_If');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/twig/src/TokenParser/ImportTokenParser.php DELETED
@@ -1,39 +0,0 @@
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
- namespace WCML\Twig\TokenParser;
12
-
13
- use WCML\Twig\Node\Expression\AssignNameExpression;
14
- use WCML\Twig\Node\ImportNode;
15
- use WCML\Twig\Token;
16
- /**
17
- * Imports macros.
18
- *
19
- * {% import 'forms.html' as forms %}
20
- *
21
- * @final
22
- */
23
- class ImportTokenParser extends \WCML\Twig\TokenParser\AbstractTokenParser
24
- {
25
- public function parse(\WCML\Twig\Token $token)
26
- {
27
- $macro = $this->parser->getExpressionParser()->parseExpression();
28
- $this->parser->getStream()->expect(\WCML\Twig\Token::NAME_TYPE, 'as');
29
- $var = new \WCML\Twig\Node\Expression\AssignNameExpression($this->parser->getStream()->expect(\WCML\Twig\Token::NAME_TYPE)->getValue(), $token->getLine());
30
- $this->parser->getStream()->expect(\WCML\Twig\Token::BLOCK_END_TYPE);
31
- $this->parser->addImportedSymbol('template', $var->getAttribute('name'));
32
- return new \WCML\Twig\Node\ImportNode($macro, $var, $token->getLine(), $this->getTag());
33
- }
34
- public function getTag()
35
- {
36
- return 'import';
37
- }
38
- }
39
- \class_alias('WCML\\Twig\\TokenParser\\ImportTokenParser', 'WCML\\Twig_TokenParser_Import');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/twig/src/TokenParser/IncludeTokenParser.php DELETED
@@ -1,55 +0,0 @@
1
- <?php
2
-
3
- /*
4
- * This file is part of Twig.
5
- *
6
- * (c) Fabien Potencier
7
- * (c) Armin Ronacher
8
- *
9
- * For the full copyright and license information, please view the LICENSE
10
- * file that was distributed with this source code.
11
- */
12
- namespace WCML\Twig\TokenParser;
13
-
14
- use WCML\Twig\Node\IncludeNode;
15
- use WCML\Twig\Token;
16
- /**
17
- * Includes a template.
18
- *
19
- * {% include 'header.html' %}
20
- * Body
21
- * {% include 'footer.html' %}
22
- */
23
- class IncludeTokenParser extends \WCML\Twig\TokenParser\AbstractTokenParser
24
- {
25
- public function parse(\WCML\Twig\Token $token)
26
- {
27
- $expr = $this->parser->getExpressionParser()->parseExpression();
28
- list($variables, $only, $ignoreMissing) = $this->parseArguments();
29
- return new \WCML\Twig\Node\IncludeNode($expr, $variables, $only, $ignoreMissing, $token->getLine(), $this->getTag());
30
- }
31
- protected function parseArguments()
32
- {
33
- $stream = $this->parser->getStream();
34
- $ignoreMissing = \false;
35
- if ($stream->nextIf(\WCML\Twig\Token::NAME_TYPE, 'ignore')) {
36
- $stream->expect(\WCML\Twig\Token::NAME_TYPE, 'missing');
37
- $ignoreMissing = \true;
38
- }
39
- $variables = null;
40
- if ($stream->nextIf(\WCML\Twig\Token::NAME_TYPE, 'with')) {
41
- $variables = $this->parser->getExpressionParser()->parseExpression();
42
- }
43
- $only = \false;
44
- if ($stream->nextIf(\WCML\Twig\Token::NAME_TYPE, 'only')) {
45
- $only = \true;
46
- }
47
- $stream->expect(\WCML\Twig\Token::BLOCK_END_TYPE);
48
- return [$variables, $only, $ignoreMissing];
49
- }
50
- public function getTag()
51
- {
52
- return 'include';
53
- }
54
- }
55
- \class_alias('WCML\\Twig\\TokenParser\\IncludeTokenParser', 'WCML\\Twig_TokenParser_Include');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/twig/src/TokenParser/MacroTokenParser.php DELETED
@@ -1,58 +0,0 @@
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
- namespace WCML\Twig\TokenParser;
12
-
13
- use WCML\Twig\Error\SyntaxError;
14
- use WCML\Twig\Node\BodyNode;
15
- use WCML\Twig\Node\MacroNode;
16
- use WCML\Twig\Node\Node;
17
- use WCML\Twig\Token;
18
- /**
19
- * Defines a macro.
20
- *
21
- * {% macro input(name, value, type, size) %}
22
- * <input type="{{ type|default('text') }}" name="{{ name }}" value="{{ value|e }}" size="{{ size|default(20) }}" />
23
- * {% endmacro %}
24
- *
25
- * @final
26
- */
27
- class MacroTokenParser extends \WCML\Twig\TokenParser\AbstractTokenParser
28
- {
29
- public function parse(\WCML\Twig\Token $token)
30
- {
31
- $lineno = $token->getLine();
32
- $stream = $this->parser->getStream();
33
- $name = $stream->expect(\WCML\Twig\Token::NAME_TYPE)->getValue();
34
- $arguments = $this->parser->getExpressionParser()->parseArguments(\true, \true);
35
- $stream->expect(\WCML\Twig\Token::BLOCK_END_TYPE);
36
- $this->parser->pushLocalScope();
37
- $body = $this->parser->subparse([$this, 'decideBlockEnd'], \true);
38
- if ($token = $stream->nextIf(\WCML\Twig\Token::NAME_TYPE)) {
39
- $value = $token->getValue();
40
- if ($value != $name) {
41
- throw new \WCML\Twig\Error\SyntaxError(\sprintf('Expected endmacro for macro "%s" (but "%s" given).', $name, $value), $stream->getCurrent()->getLine(), $stream->getSourceContext());
42
- }
43
- }
44
- $this->parser->popLocalScope();
45
- $stream->expect(\WCML\Twig\Token::BLOCK_END_TYPE);
46
- $this->parser->setMacro($name, new \WCML\Twig\Node\MacroNode($name, new \WCML\Twig\Node\BodyNode([$body]), $arguments, $lineno, $this->getTag()));
47
- return new \WCML\Twig\Node\Node();
48
- }
49
- public function decideBlockEnd(\WCML\Twig\Token $token)
50
- {
51
- return $token->test('endmacro');
52
- }
53
- public function getTag()
54
- {
55
- return 'macro';
56
- }
57
- }
58
- \class_alias('WCML\\Twig\\TokenParser\\MacroTokenParser', 'WCML\\Twig_TokenParser_Macro');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/twig/src/TokenParser/SandboxTokenParser.php DELETED
@@ -1,59 +0,0 @@
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
- namespace WCML\Twig\TokenParser;
12
-
13
- use WCML\Twig\Error\SyntaxError;
14
- use WCML\Twig\Node\IncludeNode;
15
- use WCML\Twig\Node\SandboxNode;
16
- use WCML\Twig\Node\TextNode;
17
- use WCML\Twig\Token;
18
- /**
19
- * Marks a section of a template as untrusted code that must be evaluated in the sandbox mode.
20
- *
21
- * {% sandbox %}
22
- * {% include 'user.html' %}
23
- * {% endsandbox %}
24
- *
25
- * @see https://twig.symfony.com/doc/api.html#sandbox-extension for details
26
- *
27
- * @final
28
- */
29
- class SandboxTokenParser extends \WCML\Twig\TokenParser\AbstractTokenParser
30
- {
31
- public function parse(\WCML\Twig\Token $token)
32
- {
33
- $stream = $this->parser->getStream();
34
- $stream->expect(\WCML\Twig\Token::BLOCK_END_TYPE);
35
- $body = $this->parser->subparse([$this, 'decideBlockEnd'], \true);
36
- $stream->expect(\WCML\Twig\Token::BLOCK_END_TYPE);
37
- // in a sandbox tag, only include tags are allowed
38
- if (!$body instanceof \WCML\Twig\Node\IncludeNode) {
39
- foreach ($body as $node) {
40
- if ($node instanceof \WCML\Twig\Node\TextNode && \ctype_space($node->getAttribute('data'))) {
41
- continue;
42
- }
43
- if (!$node instanceof \WCML\Twig\Node\IncludeNode) {
44
- throw new \WCML\Twig\Error\SyntaxError('Only "include" tags are allowed within a "sandbox" section.', $node->getTemplateLine(), $stream->getSourceContext());
45
- }
46
- }
47
- }
48
- return new \WCML\Twig\Node\SandboxNode($body, $token->getLine(), $this->getTag());
49
- }
50
- public function decideBlockEnd(\WCML\Twig\Token $token)
51
- {
52
- return $token->test('endsandbox');
53
- }
54
- public function getTag()
55
- {
56
- return 'sandbox';
57
- }
58
- }
59
- \class_alias('WCML\\Twig\\TokenParser\\SandboxTokenParser', 'WCML\\Twig_TokenParser_Sandbox');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/twig/src/TokenParser/SetTokenParser.php DELETED
@@ -1,62 +0,0 @@
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
- namespace WCML\Twig\TokenParser;
12
-
13
- use WCML\Twig\Error\SyntaxError;
14
- use WCML\Twig\Node\SetNode;
15
- use WCML\Twig\Token;
16
- /**
17
- * Defines a variable.
18
- *
19
- * {% set foo = 'foo' %}
20
- * {% set foo = [1, 2] %}
21
- * {% set foo = {'foo': 'bar'} %}
22
- * {% set foo = 'foo' ~ 'bar' %}
23
- * {% set foo, bar = 'foo', 'bar' %}
24
- * {% set foo %}Some content{% endset %}
25
- *
26
- * @final
27
- */
28
- class SetTokenParser extends \WCML\Twig\TokenParser\AbstractTokenParser
29
- {
30
- public function parse(\WCML\Twig\Token $token)
31
- {
32
- $lineno = $token->getLine();
33
- $stream = $this->parser->getStream();
34
- $names = $this->parser->getExpressionParser()->parseAssignmentExpression();
35
- $capture = \false;
36
- if ($stream->nextIf(\WCML\Twig\Token::OPERATOR_TYPE, '=')) {
37
- $values = $this->parser->getExpressionParser()->parseMultitargetExpression();
38
- $stream->expect(\WCML\Twig\Token::BLOCK_END_TYPE);
39
- if (\count($names) !== \count($values)) {
40
- throw new \WCML\Twig\Error\SyntaxError('When using set, you must have the same number of variables and assignments.', $stream->getCurrent()->getLine(), $stream->getSourceContext());
41
- }
42
- } else {
43
- $capture = \true;
44
- if (\count($names) > 1) {
45
- throw new \WCML\Twig\Error\SyntaxError('When using set with a block, you cannot have a multi-target.', $stream->getCurrent()->getLine(), $stream->getSourceContext());
46
- }
47
- $stream->expect(\WCML\Twig\Token::BLOCK_END_TYPE);
48
- $values = $this->parser->subparse([$this, 'decideBlockEnd'], \true);
49
- $stream->expect(\WCML\Twig\Token::BLOCK_END_TYPE);
50
- }
51
- return new \WCML\Twig\Node\SetNode($capture, $names, $values, $lineno, $this->getTag());
52
- }
53
- public function decideBlockEnd(\WCML\Twig\Token $token)
54
- {
55
- return $token->test('endset');
56
- }
57
- public function getTag()
58
- {
59
- return 'set';
60
- }
61
- }
62
- \class_alias('WCML\\Twig\\TokenParser\\SetTokenParser', 'WCML\\Twig_TokenParser_Set');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/twig/src/TokenParser/SpacelessTokenParser.php DELETED
@@ -1,46 +0,0 @@
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
- namespace WCML\Twig\TokenParser;
12
-
13
- use WCML\Twig\Node\SpacelessNode;
14
- use WCML\Twig\Token;
15
- /**
16
- * Remove whitespaces between HTML tags.
17
- *
18
- * {% spaceless %}
19
- * <div>
20
- * <strong>foo</strong>
21
- * </div>
22
- * {% endspaceless %}
23
- * {# output will be <div><strong>foo</strong></div> #}
24
- *
25
- * @final
26
- */
27
- class SpacelessTokenParser extends \WCML\Twig\TokenParser\AbstractTokenParser
28
- {
29
- public function parse(\WCML\Twig\Token $token)
30
- {
31
- $lineno = $token->getLine();
32
- $this->parser->getStream()->expect(\WCML\Twig\Token::BLOCK_END_TYPE);
33
- $body = $this->parser->subparse([$this, 'decideSpacelessEnd'], \true);
34
- $this->parser->getStream()->expect(\WCML\Twig\Token::BLOCK_END_TYPE);
35
- return new \WCML\Twig\Node\SpacelessNode($body, $lineno, $this->getTag());
36
- }
37
- public function decideSpacelessEnd(\WCML\Twig\Token $token)
38
- {
39
- return $token->test('endspaceless');
40
- }
41
- public function getTag()
42
- {
43
- return 'spaceless';
44
- }
45
- }
46
- \class_alias('WCML\\Twig\\TokenParser\\SpacelessTokenParser', 'WCML\\Twig_TokenParser_Spaceless');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/twig/src/TokenParser/TokenParserInterface.php DELETED
@@ -1,45 +0,0 @@
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
- namespace WCML\Twig\TokenParser;
12
-
13
- use WCML\Twig\Error\SyntaxError;
14
- use WCML\Twig\Parser;
15
- use WCML\Twig\Token;
16
- /**
17
- * Interface implemented by token parsers.
18
- *
19
- * @author Fabien Potencier <fabien@symfony.com>
20
- */
21
- interface TokenParserInterface
22
- {
23
- /**
24
- * Sets the parser associated with this token parser.
25
- */
26
- public function setParser(\WCML\Twig\Parser $parser);
27
- /**
28
- * Parses a token and returns a node.
29
- *
30
- * @return \Twig_NodeInterface
31
- *
32
- * @throws SyntaxError
33
- */
34
- public function parse(\WCML\Twig\Token $token);
35
- /**
36
- * Gets the tag name associated with this token parser.
37
- *
38
- * @return string The tag name
39
- */
40
- public function getTag();
41
- }
42
- \class_alias('WCML\\Twig\\TokenParser\\TokenParserInterface', 'WCML\\Twig_TokenParserInterface');
43
- // Ensure that the aliased name is loaded to keep BC for classes implementing the typehint with the old aliased name.
44
- \class_exists('WCML\\Twig\\Token');
45
- \class_exists('WCML\\Twig\\Parser');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/twig/src/TokenParser/UseTokenParser.php DELETED
@@ -1,63 +0,0 @@
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
- namespace WCML\Twig\TokenParser;
12
-
13
- use WCML\Twig\Error\SyntaxError;
14
- use WCML\Twig\Node\Expression\ConstantExpression;
15
- use WCML\Twig\Node\Node;
16
- use WCML\Twig\Token;
17
- /**
18
- * Imports blocks defined in another template into the current template.
19
- *
20
- * {% extends "base.html" %}
21
- *
22
- * {% use "blocks.html" %}
23
- *
24
- * {% block title %}{% endblock %}
25
- * {% block content %}{% endblock %}
26
- *
27
- * @see https://twig.symfony.com/doc/templates.html#horizontal-reuse for details.
28
- *
29
- * @final
30
- */
31
- class UseTokenParser extends \WCML\Twig\TokenParser\AbstractTokenParser
32
- {
33
- public function parse(\WCML\Twig\Token $token)
34
- {
35
- $template = $this->parser->getExpressionParser()->parseExpression();
36
- $stream = $this->parser->getStream();
37
- if (!$template instanceof \WCML\Twig\Node\Expression\ConstantExpression) {
38
- throw new \WCML\Twig\Error\SyntaxError('The template references in a "use" statement must be a string.', $stream->getCurrent()->getLine(), $stream->getSourceContext());
39
- }
40
- $targets = [];
41
- if ($stream->nextIf('with')) {
42
- do {
43
- $name = $stream->expect(\WCML\Twig\Token::NAME_TYPE)->getValue();
44
- $alias = $name;
45
- if ($stream->nextIf('as')) {
46
- $alias = $stream->expect(\WCML\Twig\Token::NAME_TYPE)->getValue();
47
- }
48
- $targets[$name] = new \WCML\Twig\Node\Expression\ConstantExpression($alias, -1);
49
- if (!$stream->nextIf(\WCML\Twig\Token::PUNCTUATION_TYPE, ',')) {
50
- break;
51
- }
52
- } while (\true);
53
- }
54
- $stream->expect(\WCML\Twig\Token::BLOCK_END_TYPE);
55
- $this->parser->addTrait(new \WCML\Twig\Node\Node(['template' => $template, 'targets' => new \WCML\Twig\Node\Node($targets)]));
56
- return new \WCML\Twig\Node\Node();
57
- }
58
- public function getTag()
59
- {
60
- return 'use';
61
- }
62
- }
63
- \class_alias('WCML\\Twig\\TokenParser\\UseTokenParser', 'WCML\\Twig_TokenParser_Use');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/twig/src/TokenParser/WithTokenParser.php DELETED
@@ -1,47 +0,0 @@
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
- namespace WCML\Twig\TokenParser;
12
-
13
- use WCML\Twig\Node\WithNode;
14
- use WCML\Twig\Token;
15
- /**
16
- * Creates a nested scope.
17
- *
18
- * @author Fabien Potencier <fabien@symfony.com>
19
- *
20
- * @final
21
- */
22
- class WithTokenParser extends \WCML\Twig\TokenParser\AbstractTokenParser
23
- {
24
- public function parse(\WCML\Twig\Token $token)
25
- {
26
- $stream = $this->parser->getStream();
27
- $variables = null;
28
- $only = \false;
29
- if (!$stream->test(\WCML\Twig\Token::BLOCK_END_TYPE)) {
30
- $variables = $this->parser->getExpressionParser()->parseExpression();
31
- $only = $stream->nextIf(\WCML\Twig\Token::NAME_TYPE, 'only');
32
- }
33
- $stream->expect(\WCML\Twig\Token::BLOCK_END_TYPE);
34
- $body = $this->parser->subparse([$this, 'decideWithEnd'], \true);
35
- $stream->expect(\WCML\Twig\Token::BLOCK_END_TYPE);
36
- return new \WCML\Twig\Node\WithNode($body, $variables, $only, $token->getLine(), $this->getTag());
37
- }
38
- public function decideWithEnd(\WCML\Twig\Token $token)
39
- {
40
- return $token->test('endwith');
41
- }
42
- public function getTag()
43
- {
44
- return 'with';
45
- }
46
- }
47
- \class_alias('WCML\\Twig\\TokenParser\\WithTokenParser', 'WCML\\Twig_TokenParser_With');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/twig/src/TokenStream.php DELETED
@@ -1,170 +0,0 @@
1
- <?php
2
-
3
- /*
4
- * This file is part of Twig.
5
- *
6
- * (c) Fabien Potencier
7
- * (c) Armin Ronacher
8
- *
9
- * For the full copyright and license information, please view the LICENSE
10
- * file that was distributed with this source code.
11
- */
12
- namespace WCML\Twig;
13
-
14
- use WCML\Twig\Error\SyntaxError;
15
- /**
16
- * Represents a token stream.
17
- *
18
- * @final
19
- *
20
- * @author Fabien Potencier <fabien@symfony.com>
21
- */
22
- class TokenStream
23
- {
24
- protected $tokens;
25
- protected $current = 0;
26
- protected $filename;
27
- private $source;
28
- /**
29
- * @param array $tokens An array of tokens
30
- * @param string|null $name The name of the template which tokens are associated with
31
- * @param string|null $source The source code associated with the tokens
32
- */
33
- public function __construct(array $tokens, $name = null, $source = null)
34
- {
35
- if (!$name instanceof \WCML\Twig\Source) {
36
- if (null !== $name || null !== $source) {
37
- @\trigger_error(\sprintf('Passing a string as the $name argument of %s() is deprecated since version 1.27. Pass a \\Twig\\Source instance instead.', __METHOD__), \E_USER_DEPRECATED);
38
- }
39
- $this->source = new \WCML\Twig\Source($source, $name);
40
- } else {
41
- $this->source = $name;
42
- }
43
- $this->tokens = $tokens;
44
- // deprecated, not used anymore, to be removed in 2.0
45
- $this->filename = $this->source->getName();
46
- }
47
- public function __toString()
48
- {
49
- return \implode("\n", $this->tokens);
50
- }
51
- public function injectTokens(array $tokens)
52
- {
53
- $this->tokens = \array_merge(\array_slice($this->tokens, 0, $this->current), $tokens, \array_slice($this->tokens, $this->current));
54
- }
55
- /**
56
- * Sets the pointer to the next token and returns the old one.
57
- *
58
- * @return Token
59
- */
60
- public function next()
61
- {
62
- if (!isset($this->tokens[++$this->current])) {
63
- throw new \WCML\Twig\Error\SyntaxError('Unexpected end of template.', $this->tokens[$this->current - 1]->getLine(), $this->source);
64
- }
65
- return $this->tokens[$this->current - 1];
66
- }
67
- /**
68
- * Tests a token, sets the pointer to the next one and returns it or throws a syntax error.
69
- *
70
- * @return Token|null The next token if the condition is true, null otherwise
71
- */
72
- public function nextIf($primary, $secondary = null)
73
- {
74
- if ($this->tokens[$this->current]->test($primary, $secondary)) {
75
- return $this->next();
76
- }
77
- }
78
- /**
79
- * Tests a token and returns it or throws a syntax error.
80
- *
81
- * @return Token
82
- */
83
- public function expect($type, $value = null, $message = null)
84
- {
85
- $token = $this->tokens[$this->current];
86
- if (!$token->test($type, $value)) {
87
- $line = $token->getLine();
88
- throw new \WCML\Twig\Error\SyntaxError(\sprintf('%sUnexpected token "%s"%s ("%s" expected%s).', $message ? $message . '. ' : '', \WCML\Twig\Token::typeToEnglish($token->getType()), $token->getValue() ? \sprintf(' of value "%s"', $token->getValue()) : '', \WCML\Twig\Token::typeToEnglish($type), $value ? \sprintf(' with value "%s"', $value) : ''), $line, $this->source);
89
- }
90
- $this->next();
91
- return $token;
92
- }
93
- /**
94
- * Looks at the next token.
95
- *
96
- * @param int $number
97
- *
98
- * @return Token
99
- */
100
- public function look($number = 1)
101
- {
102
- if (!isset($this->tokens[$this->current + $number])) {
103
- throw new \WCML\Twig\Error\SyntaxError('Unexpected end of template.', $this->tokens[$this->current + $number - 1]->getLine(), $this->source);
104
- }
105
- return $this->tokens[$this->current + $number];
106
- }
107
- /**
108
- * Tests the current token.
109
- *
110
- * @return bool
111
- */
112
- public function test($primary, $secondary = null)
113
- {
114
- return $this->tokens[$this->current]->test($primary, $secondary);
115
- }
116
- /**
117
- * Checks if end of stream was reached.
118
- *
119
- * @return bool
120
- */
121
- public function isEOF()
122
- {
123
- return \WCML\Twig\Token::EOF_TYPE === $this->tokens[$this->current]->getType();
124
- }
125
- /**
126
- * @return Token
127
- */
128
- public function getCurrent()
129
- {
130
- return $this->tokens[$this->current];
131
- }
132
- /**
133
- * Gets the name associated with this stream (null if not defined).
134
- *
135
- * @return string|null
136
- *
137
- * @deprecated since 1.27 (to be removed in 2.0)
138
- */
139
- public function getFilename()
140
- {
141
- @\trigger_error(\sprintf('The %s() method is deprecated since version 1.27 and will be removed in 2.0. Use getSourceContext() instead.', __METHOD__), \E_USER_DEPRECATED);
142
- return $this->source->getName();
143
- }
144
- /**
145
- * Gets the source code associated with this stream.
146
- *
147
- * @return string
148
- *
149
- * @internal Don't use this as it might be empty depending on the environment configuration
150
- *
151
- * @deprecated since 1.27 (to be removed in 2.0)
152
- */
153
- public function getSource()
154
- {
155
- @\trigger_error(\sprintf('The %s() method is deprecated since version 1.27 and will be removed in 2.0. Use getSourceContext() instead.', __METHOD__), \E_USER_DEPRECATED);
156
- return $this->source->getCode();
157
- }
158
- /**
159
- * Gets the source associated with this stream.
160
- *
161
- * @return Source
162
- *
163
- * @internal
164
- */
165
- public function getSourceContext()
166
- {
167
- return $this->source;
168
- }
169
- }
170
- \class_alias('WCML\\Twig\\TokenStream', 'WCML\\Twig_TokenStream');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/twig/src/TwigFilter.php DELETED
@@ -1,97 +0,0 @@
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
- namespace WCML\Twig;
12
-
13
- use WCML\Twig\Node\Node;
14
- /**
15
- * Represents a template filter.
16
- *
17
- * @final
18
- *
19
- * @author Fabien Potencier <fabien@symfony.com>
20
- */
21
- class TwigFilter
22
- {
23
- protected $name;
24
- protected $callable;
25
- protected $options;
26
- protected $arguments = [];
27
- public function __construct($name, $callable, array $options = [])
28
- {
29
- $this->name = $name;
30
- $this->callable = $callable;
31
- $this->options = \array_merge(['needs_environment' => \false, 'needs_context' => \false, 'is_variadic' => \false, 'is_safe' => null, 'is_safe_callback' => null, 'pre_escape' => null, 'preserves_safety' => null, 'node_class' => '\\WCML\\Twig\\Node\\Expression\\FilterExpression', 'deprecated' => \false, 'alternative' => null], $options);
32
- }
33
- public function getName()
34
- {
35
- return $this->name;
36
- }
37
- public function getCallable()
38
- {
39
- return $this->callable;
40
- }
41
- public function getNodeClass()
42
- {
43
- return $this->options['node_class'];
44
- }
45
- public function setArguments($arguments)
46
- {
47
- $this->arguments = $arguments;
48
- }
49
- public function getArguments()
50
- {
51
- return $this->arguments;
52
- }
53
- public function needsEnvironment()
54
- {
55
- return $this->options['needs_environment'];
56
- }
57
- public function needsContext()
58
- {
59
- return $this->options['needs_context'];
60
- }
61
- public function getSafe(\WCML\Twig\Node\Node $filterArgs)
62
- {
63
- if (null !== $this->options['is_safe']) {
64
- return $this->options['is_safe'];
65
- }
66
- if (null !== $this->options['is_safe_callback']) {
67
- return \call_user_func($this->options['is_safe_callback'], $filterArgs);
68
- }
69
- }
70
- public function getPreservesSafety()
71
- {
72
- return $this->options['preserves_safety'];
73
- }
74
- public function getPreEscape()
75
- {
76
- return $this->options['pre_escape'];
77
- }
78
- public function isVariadic()
79
- {
80
- return $this->options['is_variadic'];
81
- }
82
- public function isDeprecated()
83
- {
84
- return (bool) $this->options['deprecated'];
85
- }
86
- public function getDeprecatedVersion()
87
- {
88
- return $this->options['deprecated'];
89
- }
90
- public function getAlternative()
91
- {
92
- return $this->options['alternative'];
93
- }
94
- }
95
- \class_alias('WCML\\Twig\\TwigFilter', 'WCML\\Twig_SimpleFilter');
96
- // Ensure that the aliased name is loaded to keep BC for classes implementing the typehint with the old aliased name.
97
- \class_exists('WCML\\Twig\\Node\\Node');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/twig/src/TwigFunction.php DELETED
@@ -1,90 +0,0 @@
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
- namespace WCML\Twig;
12
-
13
- use WCML\Twig\Node\Node;
14
- /**
15
- * Represents a template function.
16
- *
17
- * @final
18
- *
19
- * @author Fabien Potencier <fabien@symfony.com>
20
- */
21
- class TwigFunction
22
- {
23
- protected $name;
24
- protected $callable;
25
- protected $options;
26
- protected $arguments = [];
27
- public function __construct($name, $callable, array $options = [])
28
- {
29
- $this->name = $name;
30
- $this->callable = $callable;
31
- $this->options = \array_merge(['needs_environment' => \false, 'needs_context' => \false, 'is_variadic' => \false, 'is_safe' => null, 'is_safe_callback' => null, 'node_class' => '\\WCML\\Twig\\Node\\Expression\\FunctionExpression', 'deprecated' => \false, 'alternative' => null], $options);
32
- }
33
- public function getName()
34
- {
35
- return $this->name;
36
- }
37
- public function getCallable()
38
- {
39
- return $this->callable;
40
- }
41
- public function getNodeClass()
42
- {
43
- return $this->options['node_class'];
44
- }
45
- public function setArguments($arguments)
46
- {
47
- $this->arguments = $arguments;
48
- }
49
- public function getArguments()
50
- {
51
- return $this->arguments;
52
- }
53
- public function needsEnvironment()
54
- {
55
- return $this->options['needs_environment'];
56
- }
57
- public function needsContext()
58
- {
59
- return $this->options['needs_context'];
60
- }
61
- public function getSafe(\WCML\Twig\Node\Node $functionArgs)
62
- {
63
- if (null !== $this->options['is_safe']) {
64
- return $this->options['is_safe'];
65
- }
66
- if (null !== $this->options['is_safe_callback']) {
67
- return \call_user_func($this->options['is_safe_callback'], $functionArgs);
68
- }
69
- return [];
70
- }
71
- public function isVariadic()
72
- {
73
- return $this->options['is_variadic'];
74
- }
75
- public function isDeprecated()
76
- {
77
- return (bool) $this->options['deprecated'];
78
- }
79
- public function getDeprecatedVersion()
80
- {
81
- return $this->options['deprecated'];
82
- }
83
- public function getAlternative()
84
- {
85
- return $this->options['alternative'];
86
- }
87
- }
88
- \class_alias('WCML\\Twig\\TwigFunction', 'WCML\\Twig_SimpleFunction');
89
- // Ensure that the aliased name is loaded to keep BC for classes implementing the typehint with the old aliased name.
90
- \class_exists('WCML\\Twig\\Node\\Node');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/twig/src/TwigTest.php DELETED
@@ -1,69 +0,0 @@
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
- namespace WCML\Twig;
12
-
13
- /**
14
- * Represents a template test.
15
- *
16
- * @final
17
- *
18
- * @author Fabien Potencier <fabien@symfony.com>
19
- */
20
- class TwigTest
21
- {
22
- protected $name;
23
- protected $callable;
24
- protected $options;
25
- private $arguments = [];
26
- public function __construct($name, $callable, array $options = [])
27
- {
28
- $this->name = $name;
29
- $this->callable = $callable;
30
- $this->options = \array_merge(['is_variadic' => \false, 'node_class' => '\\WCML\\Twig\\Node\\Expression\\TestExpression', 'deprecated' => \false, 'alternative' => null], $options);
31
- }
32
- public function getName()
33
- {
34
- return $this->name;
35
- }
36
- public function getCallable()
37
- {
38
- return $this->callable;
39
- }
40
- public function getNodeClass()
41
- {
42
- return $this->options['node_class'];
43
- }
44
- public function isVariadic()
45
- {
46
- return $this->options['is_variadic'];
47
- }
48
- public function isDeprecated()
49
- {
50
- return (bool) $this->options['deprecated'];
51
- }
52
- public function getDeprecatedVersion()
53
- {
54
- return $this->options['deprecated'];
55
- }
56
- public function getAlternative()
57
- {
58
- return $this->options['alternative'];
59
- }
60
- public function setArguments($arguments)
61
- {
62
- $this->arguments = $arguments;
63
- }
64
- public function getArguments()
65
- {
66
- return $this->arguments;
67
- }
68
- }
69
- \class_alias('WCML\\Twig\\TwigTest', 'WCML\\Twig_SimpleTest');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/twig/src/Util/DeprecationCollector.php DELETED
@@ -1,75 +0,0 @@
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
- namespace WCML\Twig\Util;
12
-
13
- use WCML\Twig\Environment;
14
- use WCML\Twig\Error\SyntaxError;
15
- use WCML\Twig\Source;
16
- /**
17
- * @author Fabien Potencier <fabien@symfony.com>
18
- *
19
- * @final
20
- */
21
- class DeprecationCollector
22
- {
23
- private $twig;
24
- private $deprecations;
25
- public function __construct(\WCML\Twig\Environment $twig)
26
- {
27
- $this->twig = $twig;
28
- }
29
- /**
30
- * Returns deprecations for templates contained in a directory.
31
- *
32
- * @param string $dir A directory where templates are stored
33
- * @param string $ext Limit the loaded templates by extension
34
- *
35
- * @return array An array of deprecations
36
- */
37
- public function collectDir($dir, $ext = '.twig')
38
- {
39
- $iterator = new \RegexIterator(new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($dir), \RecursiveIteratorIterator::LEAVES_ONLY), '{' . \preg_quote($ext) . '$}');
40
- return $this->collect(new \WCML\Twig\Util\TemplateDirIterator($iterator));
41
- }
42
- /**
43
- * Returns deprecations for passed templates.
44
- *
45
- * @param \Traversable $iterator An iterator of templates (where keys are template names and values the contents of the template)
46
- *
47
- * @return array An array of deprecations
48
- */
49
- public function collect(\Traversable $iterator)
50
- {
51
- $this->deprecations = [];
52
- \set_error_handler([$this, 'errorHandler']);
53
- foreach ($iterator as $name => $contents) {
54
- try {
55
- $this->twig->parse($this->twig->tokenize(new \WCML\Twig\Source($contents, $name)));
56
- } catch (\WCML\Twig\Error\SyntaxError $e) {
57
- // ignore templates containing syntax errors
58
- }
59
- }
60
- \restore_error_handler();
61
- $deprecations = $this->deprecations;
62
- $this->deprecations = [];
63
- return $deprecations;
64
- }
65
- /**
66
- * @internal
67
- */
68
- public function errorHandler($type, $msg)
69
- {
70
- if (\E_USER_DEPRECATED === $type) {
71
- $this->deprecations[] = $msg;
72
- }
73
- }
74
- }
75
- \class_alias('WCML\\Twig\\Util\\DeprecationCollector', 'WCML\\Twig_Util_DeprecationCollector');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/twig/src/Util/TemplateDirIterator.php DELETED
@@ -1,27 +0,0 @@
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
- namespace WCML\Twig\Util;
12
-
13
- /**
14
- * @author Fabien Potencier <fabien@symfony.com>
15
- */
16
- class TemplateDirIterator extends \IteratorIterator
17
- {
18
- public function current()
19
- {
20
- return \file_get_contents(parent::current());
21
- }
22
- public function key()
23
- {
24
- return (string) parent::key();
25
- }
26
- }
27
- \class_alias('WCML\\Twig\\Util\\TemplateDirIterator', 'WCML\\Twig_Util_TemplateDirIterator');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
locale/woocommerce-multilingual-ar.mo CHANGED
Binary file
locale/woocommerce-multilingual-de_DE.mo CHANGED
Binary file
locale/woocommerce-multilingual-el.mo CHANGED
Binary file
locale/woocommerce-multilingual-es_ES.mo CHANGED
Binary file
locale/woocommerce-multilingual-fr_FR.mo CHANGED
Binary file
locale/woocommerce-multilingual-he_IL.mo CHANGED
Binary file
locale/woocommerce-multilingual-it_IT.mo CHANGED
Binary file
locale/woocommerce-multilingual-ja.mo CHANGED
Binary file
locale/woocommerce-multilingual-ko_KR.mo CHANGED
Binary file
locale/woocommerce-multilingual-nl_NL.mo CHANGED
Binary file
locale/woocommerce-multilingual-pl_PL.mo CHANGED
Binary file
locale/woocommerce-multilingual-pt_BR.mo CHANGED
Binary file
locale/woocommerce-multilingual-pt_PT.mo CHANGED
Binary file
locale/woocommerce-multilingual-ru_RU.mo CHANGED
Binary file
locale/woocommerce-multilingual-sv_SE.mo CHANGED
Binary file
locale/woocommerce-multilingual-uk.mo CHANGED
Binary file
locale/woocommerce-multilingual-vi.mo CHANGED
Binary file
locale/woocommerce-multilingual-zh_CN.mo CHANGED
Binary file
locale/woocommerce-multilingual-zh_TW.mo CHANGED
Binary file
readme.txt CHANGED
@@ -4,8 +4,8 @@ Donate link: http://wpml.org/documentation/related-projects/woocommerce-multilin
4
  Tags: CMS, woocommerce, commerce, ecommerce, e-commerce, products, WPML, multilingual, e-shop, shop
5
  License: GPLv2
6
  Requires at least: 4.7
7
- Tested up to: 5.2.1
8
- Stable tag: 4.6.7
9
 
10
  Allows running fully multilingual e-commerce sites using WooCommerce and WPML.
11
 
@@ -52,13 +52,9 @@ You will also need [WPML](http://wpml.org), together with the String Translation
52
 
53
  = Minimum versions for WPML and modules =
54
 
55
- WooCommerce Multilingual checks that the following versions of WPML and their components are active:
56
 
57
- * WPML Multilingual CMS - 4.2.8
58
- * WPML String Translation - 2.10.6
59
- * WPML Translation Management - 2.8.7
60
-
61
- Without having all these running, WooCommerce Multilingual will not be able to run.
62
 
63
  == Installation ==
64
 
@@ -69,9 +65,9 @@ Without having all these running, WooCommerce Multilingual will not be able to r
69
  * MySQL version 5.6 or later
70
 
71
  * WooCommerce 3.3.0 or later
72
- * WPML Multilingual CMS 4.2.8 or later
73
- * WPML String Translation 2.10.6 or later
74
- * WPML Translation Management 2.8.7 or later
75
 
76
  = WordPress automatic installation =
77
  In your WordPress dashboard, go to the Plugins section and click 'Add new'.
@@ -140,469 +136,7 @@ WooCommerce Multilingual is compatible with all major WooCommerce extensions. We
140
 
141
  == Changelog ==
142
 
143
- = 4.6.7 =
144
- * Fix Shop Manager rights in editing translations.
145
- * Added admin notice when WooCommerce Dynamic Pricing & Discounts plugin by RightPress is installed to inform about compatibility issues
146
- * Add a "wcml_settings_ui_after_default" action to settings page to allow users add custom options
147
- * Add `wcml_get_woocommerce_currency` global function to get default WC currency value from DB
148
- * Fixed problem when Shop Manager was not able to edit translations.
149
- * Fixed compatibility issues where discounts weren't shown properly when using WooCommerce Dynamic Pricing and WooCommerce Brands together.
150
- * Fix 'IN' queries which can cause performance issues on big sites
151
- * Product variations not synchronized to second language
152
- * Shop page disappears on front-end in default language after updating shop page in secondary language
153
- * PayPal Payment Gateways settings make unsupported currency available to pay if supported one selected
154
- * Order again button on My Account view order pages not working for variable products
155
- * Not possible to disable api key for custom exchange rate service
156
- * Coupon was wrongly applied to product which doesn't have it
157
- * Skip WCML Wizard is not closing notice window needs refresh the page
158
- * Fixed PHP Notices when linking variable product translations
159
- * Fixed notice on Direct bank transfer settings page
160
- * Fixed the rate plugin message not being dismissible.
161
- * Show wizard notice on WP Dashboard and WCML Dashboard pages only
162
- * Linking variable product with original can cause error
163
- * Added default currency support for Direct Bank Transfer gateway settings
164
- * Variation sale price not set for translations if using bulk action
165
- * Price filtering widget does not work in WooCommerce >= 3.6.0 due to changes in how the widget works
166
- * Fix DB error on WooCommerce Reports page while filtering by product
167
- * Fixed `_stock_status` synchronization for variable products when "Enable stock management at product level'' is selected
168
- * Do not display the "Hide completed" switcher from the Translation Editor
169
- * Fix WooCommerce Subscriptions compatibility issue with Customer Renewal Invoice email has wrong language
170
- * WYSIWYG custom field is rendered as a text field in Translation Editor when using Types plugin
171
- * Wrong prices displayed on the front-end when the custom sale price is set in combination with a date range
172
-
173
- = 4.6.6 =
174
- * Fix error when using updated WPML String Translation without updating WPML
175
-
176
- = 4.6.5 =
177
- * The Events Calendar: convert currency for event_cost.
178
- * Wrong product price set after purchase in combination with custom prices for secondary currency and enabled stock
179
- * Translated attributes not saving if original one contains umlauts and original product language is German or Danish
180
- * Price not auto-calculated if you selected using custom prices and don't set a price
181
- * After quick edit variable product variations incremented their IDs
182
- * Added new wcml_translate_shipping_method_in_package filter
183
- * Products not filtered by current language while search Upsells/Cross-sells on product edit screen
184
- * Use default language if admin user not exists while sending "New Order" email to admins
185
- * Variation description not saved on installs with 300+ variations for product
186
-
187
- = 4.6.3 =
188
- * In some cases product translation can be converted to a simple product instead of correct type after saving
189
- * Fix not recalculated ratings after remove rating from admin
190
- * Fix no link to reviews in other languages if no reviews left in current one
191
- * Fix "set_product_language" REST API call not supported "PUT" method
192
- * Fix endpoints on My Account page when using a custom base permalink
193
- * Fixed performance issues while translating Product via WPML Translation Editor with a lot of variations
194
- * Fixed overridden discounted item price when manually creating/editing order from the admin
195
- * Fixed customer email language when changing order from "On Hold" to "Processing"
196
- * Fixed product gallery being synchronized even if WPML media duplication option is disabled
197
- * Fixed custom "Sing-up Fee" price for variation Subscription not saved
198
- * Fixed variation not available in second language in some cases when original language is German or Danish
199
- * Fix mixed endpoint contexts/domains and their translations/language
200
- * Fixed inability to add reviews after bought product
201
-
202
- = 4.6.2.1 =
203
- * Fix performance issues with WooCommerce 3.6.*
204
-
205
- = 4.6.2 =
206
- * Fix performance issue while saving product
207
- * Fix warning when _wc_rating_cout value is corrupted
208
- * Fix loop on original products without thumbnail set
209
-
210
- = 4.6.1 =
211
- * Fix product gallery images on default product with WC 3.6.0
212
- * Fix wrong Table Rate Shipping wrong rate prices calculation in secondary currency with WC 3.6.0
213
-
214
- = 4.6.0 =
215
- * Fix wrong currency code after removing item from manually created order
216
- * Replace *_woocommerce_term_meta functions on *_term_meta
217
- * Fix gallery images not showing up on translated product page
218
- * Fix double calculating order item price while manually adding it from admin to order with WooCommerce 3.6.0
219
- * Fix performance issues on checkout with manage stock products
220
- * Fix performance issue on shop page with WooCommerce 3.6
221
- * Fix loading scripts on admin pages
222
- * Fix coupon discount when editing order from admin
223
- * Fix wrong product price after adding another product to existing order from admin
224
- * Fix my-account page endpoints in secondary language with pages set to "Display as translated"
225
-
226
- = 4.5.0 =
227
- * Add "get_post_metadata" hook to filter Woocommerce product data
228
- * Added function in troubleshooting page to fix broken variations
229
- * Fixed DB error when saving a variation with specific steps
230
- * Fix refreshing of status icon when ATE Job of updated content is synced
231
- * Fix few notices when removing a Elementor widget and refresh page
232
- * Fetch ATE translations from WCML Product Translation Tab
233
- * Fix warning when adding comment to product
234
- * Fixed wrong price calculation when adding product to new order on backend
235
- * Fixed bookings counter on admin bookings listing page
236
- * Fixed stock quantity not synchronized to translation when creating it
237
- * Fixed notice when saving translation
238
- * Fixed translated attributes via ATE/Translation service not connected to translated product
239
- * Fix not translated "On Hold" email subject after returning order from "Processing"
240
- * Remove unneded $_SESSION variables on checkout page
241
- * Fix PHP notice `Notice: Only variables should be passed by reference`
242
- * Implemented dependency check for minimum compatible versions of required WPML plugins
243
- * Fixed default variation not pre-selected on front-end for translated product with non latin attribute in default language
244
- * Fix cannot change currency with "wcml_client_currency" filter
245
- * Fixed not valid API key when trying manually update exchange rates
246
- * WooCommerce Variation Swatches and Photos compatibility to translate attributes
247
- * Fix related product displays in all languages
248
- * Added compatibility with Yikes Custom Product Tabs
249
-
250
- = 4.4.2.1 =
251
- * Fix error while updating product
252
-
253
- = 4.4.2 =
254
- * Woocommerce Product addons fix notice with old global addons
255
- * Fix error with WPML Translation management < 2.8.0 in combination with updated WPML core to 3.2.0
256
- * Fix Composite products error on orders page
257
-
258
- = 4.4.1 =
259
- * Fixed catalog visibility not updating
260
- * Fix fatal error with Composite products
261
- * Fix fatal error with Woocommerce Product Addons
262
- * Removed options from WCML/Settings for handling Products translation since this can now be done with the post-switcher implemented in WPML 4.2.0
263
- * Fix fatal error when bundle product is false
264
- * Fix empty cart error with enabled option to clean cart when switching currency
265
- * Fixed issue with trailing comma in product gallery handling
266
-
267
- = 4.4.0 =
268
- * Added the ability to associate BACS accounts with currencies
269
- * Hide reviews in other languages link, if there are no reviews in product
270
- * Update WCML Logo
271
- * Removed Product Type Column from WCML backend and added compatibility with the WC Product Type Column plugin
272
- * Fix low_stock_amount not synchronized to translations
273
- * Fix custom attribute with number in name not appears to translation in Translation editor
274
- * Fix not applied price rule for WooCommerce Table Rate Shipping in second currency
275
- * Fix translated custom field wrongly saved to translation if contains array of strings
276
- * Endless loop when using troubleshooting action to duplicate terms
277
- * Fixed an issue with Elementor PRO products block showing all categories in the translated page.
278
- * Fixed Xliff doesn't contains variation descriptions for WooCommerce Subscriptions
279
- * Fixed compatibility issue with Flatsome theme
280
- * Fix issue with custom product attribute title when trying to upload translation with XLIFF file
281
- * Fixed cart validate for specific situations
282
- * Added filter for translated package rates
283
- * Added WPML switcher buttons library for Multi Currency in backend
284
- * Fix loading Jquery to any place in code and in header
285
- * Added fix for variation product "become" out-of-stock when translating using native screen
286
- * Removed backward compatibility filters for terms synchronization
287
- * Fixed attribute slug language always set to English
288
- * Wrong path in Bookings compatibility class
289
- * Fixed a fatal error occuring with older versions of WooCommerce (3.3.5)
290
- * Fixed confirming order as complete from the order edit screen, does not decrement the second language stock qty
291
- * Product category data always synchronizes on save of the translation and does not respect WPML option to sync taxonomies
292
- * Fixed call to undefined method WPML_URL_Filters::remove_global_hooks with WPML < 3.6.0
293
- * Fixed compatibility class name for wc product addons
294
- * Fixed manual order creation does not respect manual prices
295
- * Fix email language for the order as complete emails
296
- * Fixed Composite Products compatibility - Price not rounding to the nearest integer
297
- * Fixed missing custom attribute in XLIFF file / Pro Translation
298
- * Fix Endpoint error to prevent 404 in some cases
299
- * Fixed accepted arguments for terms_clause
300
- * Resolved an exception causing an error message in the cart in some setups
301
- * Fixed missed synchronization of 'outofstock' visibility term between product translations
302
- * Fix broken logic with Table Rate Shipping when product uses class with "break and abort" rule
303
- * Custom attributes terms not copied to diplicated translation after update values in original
304
- * Added support for wpml endpoints
305
- * WP Fastest Cache compatibility - fixed currency switcher problem
306
- * Added ability to set custom prices for secondary currencies in WC Product Add-Ons
307
- * Update minimum requirements
308
- * Added ability to add custom payment methods for each currency
309
-
310
- = 4.3.7 =
311
- * Fixed issue which was changing the current language of the site when saving an order
312
- * Better compatibility class for LiteSpeed Cache that doesn't require changing the URL
313
- * Fixed issue with serialized data in term meta table
314
- * Fix price with schedule sale dates in multicurrency
315
- * Add compatibility class for LiteSpeed Cache plugin
316
- * Fixed issue with problem in downloadable products in secondary language with different domain per language is enabled
317
-
318
- = 4.3.6 =
319
- * Removed wpml_referer_url as it is no longer used
320
- * Fixed Fatal error on updating original, after setting attachments to "do not translate"
321
- * Changed currency services rate rounding precision limit to 6 digits
322
- * Fixed 404 error for translated attribute archive page
323
- * Fixed prepending shop page before home page in breadcrumbs
324
-
325
- = 4.3.5 =
326
- * Fix rest translation in products creation
327
- * Fixed incorrect translation matched for Table Rate Shipping title
328
- * Price is not saved correctly via "Quick Edit" if secondary currency is selected on front
329
- * Fixed a performance issue when a product has a lot of variations.
330
- * Fixed variation image synchronization
331
- * Lower priority of 'woocommerce_cart_item_name' hook for "WooCommerce Product Subtitle" and others to work
332
- * Fixed performance issues on product listing page with big amount of attributes
333
- * Fixed fatal error with WPML older than 3.9
334
- * Fix redirection to wcml dashboard in a specific case if you skip wizard
335
- * Fixed stock status when purchasing the last product in the second language which does not update status for original
336
- * WooCommerce Product Bundle synchronizations problems when re-creating bundle product translation
337
- * Fixed Woo Variations Table Compatibility issue with overwritten product title in specific scenario
338
- * Fix cosmetic issue with mutli-currency message in product post screen
339
- * Fixed infinite loop with large product numbers and languages
340
-
341
- = 4.3.4 =
342
- * Fixed error: Cannot redeclare woocommerce_wp_text_input
343
- * Fixed error when creating booking from admin without creating order
344
- * Fixed Woocommerce Dynamic Price issue with Advanced category price in second language
345
- * Fixed attachments duplication when synchronizing gallery
346
- * Fix situation with filtering WC attributes calling by sku
347
- * Fix a problem that you cannot delete booking from trash
348
- * Fix prevent letters in multicurrency popup for number of decimals
349
- * Fix accept only symbols in decimal separator for multi currency
350
- * Resolved fatal error when a galler shortcode has a leading, trailing or extra comma
351
- * Fix issue in show comments in all languages functionality
352
- * Fixed displaying WYSIWYG fields from additional plugins as single line text
353
- * Fix small issue with order of breadcrumbs in second language
354
- * Fix default term value in product variation when using display as translated feature
355
- * Allow users to comment on product that they have bought, but in other languages
356
- * Fixed WooCommerce Dynamic Pricing compatibility -> filtering by role not applied for secondary currency
357
- * Added support for translating WooCommerce terms and conditions
358
- * Fixed totals in order if the product has custom price in second currency
359
- * Fix displaying email subject when you have 3rd party email notification plugin
360
- * Fixed product view price when secondary currency have different range of dates for sale price
361
- * Fix small issue with creations of WooCommerce Booking in backend
362
-
363
- = 4.3.3 =
364
- * Fixed small issue in WC Bookings where block cost in other currencies is not saved correctly
365
- * Fix an error due to a bug in upgrade logic
366
- * Fix compatibility issue with WC Product Addons and not displayed label in secondary language
367
- * Return back duplication logic for product image and gallery
368
- * Fix warning in secondary language if you don't have any wc pages
369
- * Fix wrong language for attribute in Product creation page
370
- * Fixed bug in Product Search Widget when wpml language set as a parameter
371
- * Fixed fatal error occurring in some cases when updating from older versions
372
- * Fixed cosmetic issue when hovering over currencies
373
-
374
- = 4.3.2.1 =
375
- * wcmlc argument always being added when switching currency
376
- * Missing images on the translated product page
377
-
378
- = 4.3.2 =
379
- * Fixed an error when adding a product to cart in specific situations
380
- * Error while adding product to cart wit WC < 3.4.0
381
- * Fixed issue with product images not showing in translations
382
- * SW Product bundles error while activating
383
-
384
- = 4.3.1 =
385
- * Error in WCML_Currency_Switcher_Templates while activating
386
- * Fix an issue where New order admin email subject and heading were overwrites with wrong data
387
- * Fixed the missing duplicated images when translating a product.
388
-
389
- = 4.3.0 =
390
- * Added ability to filtering comments by language
391
- * Use display-as-translated for product images and product galleries
392
- * Fixed issue when deleting a currency in Safari
393
- * Fixed issue causing fatal error when activating WCML and WPML String Translation
394
- * Changes in the Fixer.io API
395
- * Added a fix where in some situation the product slug URL is not translated correctly
396
- * Variable product removed from cart when switching language on the cart page
397
- * Multicurrency in defaults not calculated correctly when creating manual order
398
- * Product Bundles - search products returned wrong values
399
- * Translating custom product category base leads to products returning error 404 when both bases contains the same string
400
- * Table Rate Shipping - products with different classes produce no shipping method on cart page
401
- * New order admin email subject and heading were overwrites with wrong data
402
- * Fix small issue in product stock sync
403
- * Refund and restock - not working properly when refunding the variation in second language
404
- * WooCommerce Product Bundles -> original overwrites translation (visible when using title/description override)
405
-
406
- = 4.2.10 =
407
- * Fix compatibility issues with PHP 7.1
408
- * Fix issue with product slug when using language per domain in WPML
409
- * Removed notice when set domain per language in WPML
410
- * WooCommerce Bookings: Added support to translate booking emails
411
- * Removed warning from translation editor when set display as translated
412
- * Added compatibility for unsupported WooCommerce themes
413
- * Removed some custom WPML taxonomies from plugin's Dashboard
414
- * Fix an error with product variations which you cannot add them in cart if display as translated feature is used
415
- * WooCommerce Composite Products: Fix Default option sync when using component option category
416
- * WooCommerce Subscriptions: Fix Sign-up fee recalculation cost in some situations
417
- * Theme Storefront: Fix Cart widget currency symbol not switched after switching currency
418
- * Siteground Optimizer: Fix an issue with currency switcher
419
- * Wrong price when manually adding product to an order with multicurrency enabled
420
- * WooCommerce Bookings : Fix Block cost recalculation in second currency
421
- * Added filter for oder_item_quantity
422
- * Fix issue in endpoints when set My Account as homepage
423
- * WooCommerce Dynamic Pricing: Fix Order total rules by category
424
- * Relevanssi compatibility - add missing terms for translated product
425
-
426
- = 4.2.9 =
427
- * Fix wrong qty in cart page for same product and different language
428
- * Fix changes for WC 3.3 in order page for second language
429
- * Downloadable file paths always converted when "Different domain per language" chosen
430
- * Fix small error in automatic currency
431
- * Fix error in WC Reports in displaying sales by categories correctly for all languages
432
-
433
- = 4.2.8.1 =
434
- * Fix error with WPML < 3.9
435
-
436
- = 4.2.8 =
437
- * Visual Bakery Composer compatibility issue - some strings displays in default language instead on user admin language
438
- * Variable product with local attributes displays all variations values set to "any" with "use translation if available or fallback to default language" enabled for products
439
- * Product Customizer produce error messages
440
- * WooCommerce Subscriptions -> 'From....' price is not converted to current currency
441
- * Global add-on filtered by category - does not work in second language
442
- * [Fatal Error] WooCommerce Subscriptions -> Resubscribe with no multi-currency enabled
443
- * Variation downloadable files not synchronized with Products Download Files setting in the native editor
444
- * Incorrect category count in second languages
445
- * WooCommerce Subscription incorrect recurring totals in secondary currency
446
- * Manually set price (2nd currency) -> adding product to manually created order results in price of the first currency being used
447
-
448
- = 4.2.7.1 =
449
- * Fixed fatal error while updating to 4.2.7 with Woocommerce Bundles
450
-
451
- = 4.2.7 =
452
- * Translated attributes and "Display as translated" mode for products -> shows no variation in second language
453
- * Notices on front when Reset cart feature is enabled and WooCommerce version >= 2.3
454
- * Notice in edit order screen and empty comment added to the order (order note)
455
- * Woo Bundles product filtering for variable products does not work in second language
456
- * WooCommerce Subscriptions - > sign-up fee in the default currency does not work
457
- * Visiting customer-logout endpoint in the second language makes it re-register and sets the string as "Translation needs update"
458
- * Default attributes for variable products were not synchronized correctly for translated variable products.
459
- * Wrong "product" slug translation on product edit page
460
- * WooCommerce EU VAT - VAT set when exempt and doubled in second currency
461
- * WooCommerce widget for filtering by attribute when shop page is front/home page
462
- * Etheme Blanco compatibility - Inconsistency with minicart
463
- * Remove Yahoo service from available services because it was discontinued
464
- * Sync problems with Bundle product which contains one product two times in bundle items
465
- * Endpoints on my account page removed from the link URL
466
-
467
- = 4.2.6 =
468
- * WooCommerce Tab Manager categories aren't copied to translated tabs
469
- * Endpoint translation issue when submitting a job post on secondary languages [WP Job Manager]
470
- * After changing the payment method, the information is sent incorrectly in the email
471
- * WooCommerce Subscriptions plugin fatal error on the secondary language
472
- * Fix for Woocommerce Dynamic Pricing
473
- * WooCommerce subscriptions > Manually set sign-up fee is not respected
474
- * WoooCommerce Subscriptions -> changing currency and re-subscribing produces wrong price in the cart
475
- * Total sales not synced when not managing stocks
476
- * Adding to cart German product with custom attribute results in improper sanitized custom attribute name after the action is complete
477
- * WooCommerce Multilingual Translation editor -> Missing Custom Field label
478
- * WooCommerce Product Add-ons - Admin edit global addon screen shows previous value for name/descripton after update
479
- * Filtering by variation does not work for product bundle
480
- * Fix responsiveness of reset cart prompt
481
-
482
- = 4.2.5 =
483
- * Added 'wcml_hide_cart_alert_dialog' filter to support hide cart alert switching dialog
484
- * Cannot update Purchase note (any other custom field) once the job is completed
485
- * New order admin emails have un-translated heading and subject when admin language is different of default
486
- * Product in cart not adjusted to correct language when switching languages
487
- * WooCommerce Subscriptions -> Product with free trial has no payment method
488
- * Strings for subject and title are not translating for Refund emails
489
- * Page builder strings does not translate in a product when WCML is enabled
490
- * Fixed small glitch with no payment methods in free product with extra shipping cost
491
- * Fix an issue that caused fatal error in WooCommerce Store Exporter plugin
492
- * Fixed wrong output when using multiple categories in shortcodes
493
- * Fixed compatibility issue in WC Membership with wrong product url
494
- * Un-trashing product results of redirect to post listing in WCML
495
- * Fix a bug that the price calculation is not correct in combination with WC Bookings and WC Deposit plugin
496
- * MaxStore Pro theme compatibility for mini cart
497
- * Product price was doubled on cart in combination with Booking and Product Addons
498
-
499
- = 4.2.4 =
500
- * Allow translating categories used in shortcodes when the simple tax query is used
501
- * Switching language/currency reset cart feature redirect to random product page after reset cart
502
- * Fixed and incompatibility issue with the WooCommerce EU VAT Number extension
503
- * Wrong prices in secondary currency when applying coupons
504
- * Fixed a bug that was preventing adding multiple products to cart after changing the site language and resetting the cart
505
- * Fixed an incompatibility issue with WooCommerce Bookings: the layout of the conformation prompt from switching the cart was broken.
506
- * Serialized custom fields were translated incorrectly using the WooCommerce Multilingual Translation Editor
507
-
508
- = 4.2.3 =
509
- * A fatal error occurred when deactivating WPML with WooCommerce Multilingual being active
510
-
511
- = 4.2.2 =
512
- * My account Bookings list page displays bookings in all languages
513
- * Updating variable product does not refresh product visibility terms
514
- * Currency switcher doesn't reload the product page if # is present in the URL
515
- * Fixed a PHP fatal error that was occurring when using WooCommerce Multilingual together with Sensei
516
- * The 'featured' product field was not synchronized across product translations
517
- * When updating a translation, the product translation slug was overwritten if product contains page builders fields
518
- * The 'reset password' form in a secondary language pointed to a 404 error
519
- * "product/%product_cat%" product permalink doesn't work for products without category assigned in second language if "Uncategorized" string not translated in String Translation module
520
- * WC Subscriptions compatibility error
521
- * It was not possible to set the custom price value in secondary currencies as '0'
522
- * It was not possible to translate attribute slugs if the attributes base was not translated
523
- * Currency switcher styles were not loaded when using only a shortcode currency switcher
524
- * The customer order email was sent in default language when the 'Processing' button was clicked on the back-end
525
-
526
- = 4.2.1 =
527
- * Added the ability to set custom currencies for orders created via the REST API
528
- * Filter by translation status displays wrong results on WooCommerce Multilingual products list page
529
- * Prices were not synced when creating a product translation via REST API
530
- * Missing Woocommerce pages were created in default language
531
- * Fatal error while custom call not active currency switcher template
532
- * Duplicating from WooCommerce resulted in losing language data for the original product
533
- * Coupon with category restriction removed when switching language on cart page
534
- * PHP errors were shown on the admin dashboard when no orders existed and displaying errors was on
535
- * A fatal error (undefiend get_current_screen) was occurring in some conditions on the WP admin side
536
- * Cart widget shows wrong product names
537
- * Fixed a small but that defualt currency template didn't load correctly in new installation
538
- * Added compatibility for grouped products
539
- * Fixed an issue in lost password endpoint when editing it
540
- * The cart total in a secondary currencies could have been added a previously removed shipping tax
541
- * Post translation won't save when Product Bundles plugin is active
542
- * Fixed comp issue with dynamic price with translated variations don't work in secondary language
543
- * Cart reset button point to wrong language
544
- * Fix issue with not matched translated labels because of special characters
545
- * Fixed an issue when sold individually is enabled and different variations of the same product
546
- * Fix the ability to set custom download files in downloadable variable products with WCML product editor
547
- * Fixed small issue in separate file control in downloadable variation product
548
- * Fix a bug where Variations were made downloadable after their description was updated.
549
- * Checkout Field Editor compatibility fix
550
- * Fixed issue with displaying custom prices in Bundles Products
551
- * Add filter for 'woocommerce_subscriptions_product_price'
552
- * Fixed compatibi;ity issue with coupos not applied correctly in a subscription product
553
- * The `wcml_raw_price_amount` filter could not be used to convert to a different currency than the current user currency
554
-
555
- = 4.2.0 =
556
- * Added the ability to translate Sensei question custom post types
557
- * Added the ability to translate serialized custom fields with in the Translation Editor
558
- * Payment method title not displaying in emails Mollie Payment's payment processor compatibility
559
- * Show an admin notice for environments in which switching the language or currency on the front end, could corrupt the cart contents
560
- * Changing the order of the variations was disconnecting them from their translations
561
- * When selecting the currencylayer provider for automatic exchange rate, the API KEY filter was not visible
562
- * The multi-currency component made the admin dashboard page loading unnecessarily slow
563
- * Variations with custom attributes could not be duplicated as translations
564
- * A fatal error occurred when using old WordPress versions (before 4.4.0) - rest_get_url_prefix didn't exist
565
- * The admin orders page was loading slower than necessary
566
- * A PHP fatal error was occurring when using the Adventure Tours extension
567
- * A product addon was added to the cart more then once in combination with Bookings
568
- * For translated products, the product variation names were displayed in the old format (before WooCommerce 3.0)
569
- * The prices in the secondary currencies for products in secondary languages for products read via the REST API were incorrect
570
- * CSS for the currency switcher was loaded when the multi-currency was not enabled
571
- * Visual Composer field value not updated in WooCommerce Multilingual translation editor after update original
572
- * Wrong count of not translated products on WooCommerce Multilingual Status tab
573
- * Fixed a javascript error on the shop page
574
- * It was not possible to use the clear cart feature with enabled WPML Ajax cookies only
575
- * WooCommerce Product Bundles: Bundled items filtering by variation was not synced with translations
576
- * Bookings max availability value was changing after adding bookable product to cart few times
577
- * In some cases the the option to prompt for a confirmation about resetting the cart when switching the language was not working
578
- * The variation names were, sometimes, displayed in the wrong language in the orders, on the back-end
579
-
580
- = 4.1.4 =
581
- * Added possibility to filter available Currency Switcher templates paths via "wcml_cs_directories_to_scan" filter
582
- * The "Copy to a new draft" link was showing two times on the product edit page
583
- * For taxonomies having the term_id distinct from term_taxonomy_id, the translations could have been accidentally overwritten
584
- * In some conditions, a fatal error could come up when editing a product
585
- * In some circustances, disabling currency switcher on product page produced a fatal error
586
- * Custom attributes in the translations were reset after editing the original product
587
- * Sometimes, the translated product category pages were returning a 404 error
588
- * It was not possible to filter products by price on the shop page using the WooCommerce Price Filter widget
589
-
590
- = 4.1.2 =
591
- * Fixed `Fatal error: Call to undefined method WPML_WP_API::defined`
592
- * Fixed the currency switcher not being displayed correctly when using the Storefront theme
593
- * Fixed `Fatal error: Call to undefined function wc_format_decimal()`
594
- * Fixed a bug causing an error when upgrading WooCommerce Multilingual to version 4.1 with WooCommerce inactive.
595
- * ixed the currency switcher css being loaded when no currency switcher was displayed
596
-
597
- = 4.1.1 =
598
- * Fixed a pre PHP 5.4 compatibility issue
599
- * Fixed `Notice: Undefined index: switcher_id`
600
- * Fixed `Fatal error: Class ‘WPML_File’ not found` when using an old version of WPML
601
- * Fixed "Invalid or duplicated SKU" error when saving or updating a product with SKU
602
- * Fixed `Fatal error: Call to undefined function WC()` when disabling WooCommerce while WCML is running
603
-
604
- = 4.1.0 =
605
- * Fixed bookings issues
606
 
607
  = 4.1.0 =
608
  * Enhanced language switchers
4
  Tags: CMS, woocommerce, commerce, ecommerce, e-commerce, products, WPML, multilingual, e-shop, shop
5
  License: GPLv2
6
  Requires at least: 4.7
7
+ Tested up to: 5.2.4
8
+ Stable tag: 4.7.0
9
 
10
  Allows running fully multilingual e-commerce sites using WooCommerce and WPML.
11
 
52
 
53
  = Minimum versions for WPML and modules =
54
 
55
+ WooCommerce Multilingual checks that the required components are active and up to date.
56
 
57
+ If the checks fail, WooCommerce Multilingual will not be able to run.
 
 
 
 
58
 
59
  == Installation ==
60
 
65
  * MySQL version 5.6 or later
66
 
67
  * WooCommerce 3.3.0 or later
68
+ * WPML Multilingual CMS 4.3.0 or later
69
+ * WPML String Translation 3.0.0 or later
70
+ * WPML Translation Management 2.9.0 or later
71
 
72
  = WordPress automatic installation =
73
  In your WordPress dashboard, go to the Plugins section and click 'Add new'.
136
 
137
  == Changelog ==
138
 
139
+ For post 4.1.0 changelogs, see the `changelog` folder.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
140
 
141
  = 4.1.0 =
142
  * Enhanced language switchers
res/css/admin.css CHANGED
@@ -1 +1 @@
1
- .wcml-menu-warn{display:inline-block;color:#d54e21;line-height:15px;margin:1px 0 0 2px;z-index:26}a.wcml-external-link{padding-right:15px}a.wcml-external-link:after{content:"\f504";display:inline-block;width:15px;margin-right:-15px;font-size:14px;line-height:18px;font-family:dashicons;text-decoration:none;font-weight:normal;font-style:normal;vertical-align:top;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.wcml-pointer-inner .wcml-information-paragraph{padding-right:30px}.wcml-pointer-inner .wp-pointer-buttons{padding:0}.wcml-pointer-inner.wp-pointer-bottom .wp-pointer-arrow{left:auto;right:50px}.wcml-message-icon.wcml-table-cell,.wcml-message-content.wcml-table-cell{height:100px}.wcml-pointer-link{position:relative;text-decoration:none;padding:10px}.wcml-cart-dialog button{text-transform:capitalize}div[data-selector="woocommerce_table_rate_title"] a,div[data-selector="wpbody-content .woocommerce h2"] a{padding:10px 0 0 0}#shipping_rates .shipping_label .wcml-pointer-link{padding:0}.otgs-ico-ok:before{content:"\63"}
1
+ .wcml-menu-warn{display:inline-block;color:#d54e21;line-height:15px;margin:1px 0 0 2px;z-index:26}a.wcml-external-link{padding-right:15px}a.wcml-external-link:after{content:"\f504";display:inline-block;width:15px;margin-right:-15px;font-size:14px;line-height:18px;font-family:dashicons;text-decoration:none;font-weight:normal;font-style:normal;vertical-align:top;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.wcml-pointer-inner .wcml-information-paragraph{padding-right:30px}.wcml-pointer-inner .wp-pointer-buttons{padding:0}.wcml-pointer-inner.wp-pointer-bottom .wp-pointer-arrow{left:auto;right:50px}.wcml-message-icon.wcml-table-cell,.wcml-message-content.wcml-table-cell{height:100px}.wcml-pointer-link{position:relative;text-decoration:none;padding:10px}.wcml-cart-dialog button{text-transform:capitalize}div[data-selector="woocommerce_table_rate_title"] a,div[data-selector="wpbody-content .woocommerce h2"] a{padding:10px 0 0 0}#shipping_rates .shipping_label .wcml-pointer-link{padding:0}.otgs-ico-ok:before{content:"\63"}.wcml-wrap .mouse-hovered{display: none; width: auto; max-width: 350px; height:auto; max-height:250px; position: absolute; z-index:10; border:solid 4px #999; background: #fff;}
res/js/scripts.js CHANGED
@@ -134,6 +134,24 @@ jQuery(document).ready(function ($) {
134
  return false;
135
  });
136
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
137
 
138
  });
139
 
134
  return false;
135
  });
136
 
137
+ /**
138
+ * Function to display larger image on hover while you are in product list.
139
+ **/
140
+
141
+ $(document).ready(function() {
142
+ $('.original-image').mousemove(function(e) {
143
+ $img = $("#" + $(this).data('image-id'));
144
+ $img.show(200);
145
+ $img.offset({
146
+ top: e.pageY - 100,
147
+ left: e.pageX + 15
148
+ });
149
+ }).mouseleave(function() {
150
+ $img = $("#" + $(this).data('image-id'));
151
+ $img.hide(200);
152
+ });
153
+ });
154
+
155
 
156
  });
157
 
res/js/scripts.min.js CHANGED
@@ -1 +1 @@
1
- jQuery(document).ready(function($){var discard=false;window.onbeforeunload=function(e){if(discard){return $("#wcml_warn_message").val()}};$('.wcml-section input[type="submit"]').click(function(){discard=false});$(".wcml_search").click(function(){window.location=$(".wcml_products_admin_url").val()+"&cat="+$(".wcml_product_category").val()+"&trst="+$(".wcml_translation_status").val()+"&st="+$(".wcml_product_status").val()+"&slang="+$(".wcml_translation_status_lang").val()});$(".wcml_search_by_title").click(function(){window.location=$(".wcml_products_admin_url").val()+"&s="+$(".wcml_product_name").val()});$(".wcml_reset_search").click(function(){window.location=$(".wcml_products_admin_url").val()});var wcml_product_rows_data=new Array;var wcml_get_product_fields_string=function(row){var string="";row.find("input[type=text], textarea").each(function(){string+=$(this).val()});return string};$("#wcml_custom_exchange_rates").submit(function(){var thisf=$(this);thisf.find(":submit").parent().prepend(icl_ajxloaderimg+"&nbsp;");thisf.find(":submit").prop("disabled",true);$.ajax({type:"post",dataType:"json",url:ajaxurl,data:thisf.serialize(),success:function(){thisf.find(":submit").prev().remove();thisf.find(":submit").prop("disabled",false)}});return false});function wcml_remove_custom_rates(post_id){var thisa=$(this);$.ajax({type:"post",dataType:"json",url:ajaxurl,data:{action:"wcml_remove_custom_rates",post_id:post_id},success:function(){thisa.parent().parent().parent().fadeOut(function(){$(this).remove()})}});return false}$(document).on("click",".wcml_save_base",function(e){e.preventDefault();var elem=$(this);var dialog_saving_data=$(this).closest(".wcml-dialog-container");var link="#wcml-edit-base-slug-"+elem.attr("data-base")+"-"+elem.attr("data-language")+"-link";var dialog_container="#wcml-edit-base-slug-"+elem.attr("data-base")+"-"+elem.attr("data-language");$.ajax({type:"post",url:ajaxurl,dataType:"json",data:{action:"wcml_update_base_translation",base:elem.attr("data-base"),base_value:dialog_saving_data.find("#base-original").val(),base_translation:dialog_saving_data.find("#base-translation").val(),language:elem.attr("data-language"),wcml_nonce:$("#wcml_update_base_nonce").val()},success:function(response){$(dialog_container).remove();$(link).find("i").remove();$(link).append('<i class="otgs-ico-edit" >');$(link).parent().prepend(response)}})});$(document).on("click",".hide-rate-block",function(){var wrap=$(this).closest(".wcml-wrap");$(this).attr("disabled","disabled");var ajaxLoader=$('<span class="spinner" style="visibility: visible;">');var setting=jQuery(this).data("setting");$(this).parent().prepend(ajaxLoader);$(this).remove();$.ajax({type:"post",url:ajaxurl,dataType:"json",data:{action:"wcml_update_setting_ajx",setting:setting,value:0,nonce:$("#wcml_settings_nonce").val()},success:function(response){wrap.hide()}});return false})});
1
+ jQuery(document).ready(function($){var discard=false;window.onbeforeunload=function(e){if(discard){return $("#wcml_warn_message").val()}};$('.wcml-section input[type="submit"]').click(function(){discard=false});$(".wcml_search").click(function(){window.location=$(".wcml_products_admin_url").val()+"&cat="+$(".wcml_product_category").val()+"&trst="+$(".wcml_translation_status").val()+"&st="+$(".wcml_product_status").val()+"&slang="+$(".wcml_translation_status_lang").val()});$(".wcml_search_by_title").click(function(){window.location=$(".wcml_products_admin_url").val()+"&s="+$(".wcml_product_name").val()});$(".wcml_reset_search").click(function(){window.location=$(".wcml_products_admin_url").val()});var wcml_product_rows_data=new Array;var wcml_get_product_fields_string=function(row){var string="";row.find("input[type=text], textarea").each(function(){string+=$(this).val()});return string};$("#wcml_custom_exchange_rates").submit(function(){var thisf=$(this);thisf.find(":submit").parent().prepend(icl_ajxloaderimg+"&nbsp;");thisf.find(":submit").prop("disabled",true);$.ajax({type:"post",dataType:"json",url:ajaxurl,data:thisf.serialize(),success:function(){thisf.find(":submit").prev().remove();thisf.find(":submit").prop("disabled",false)}});return false});function wcml_remove_custom_rates(post_id){var thisa=$(this);$.ajax({type:"post",dataType:"json",url:ajaxurl,data:{action:"wcml_remove_custom_rates",post_id:post_id},success:function(){thisa.parent().parent().parent().fadeOut(function(){$(this).remove()})}});return false}$(document).on("click",".wcml_save_base",function(e){e.preventDefault();var elem=$(this);var dialog_saving_data=$(this).closest(".wcml-dialog-container");var link="#wcml-edit-base-slug-"+elem.attr("data-base")+"-"+elem.attr("data-language")+"-link";var dialog_container="#wcml-edit-base-slug-"+elem.attr("data-base")+"-"+elem.attr("data-language");$.ajax({type:"post",url:ajaxurl,dataType:"json",data:{action:"wcml_update_base_translation",base:elem.attr("data-base"),base_value:dialog_saving_data.find("#base-original").val(),base_translation:dialog_saving_data.find("#base-translation").val(),language:elem.attr("data-language"),wcml_nonce:$("#wcml_update_base_nonce").val()},success:function(response){$(dialog_container).remove();$(link).find("i").remove();$(link).append('<i class="otgs-ico-edit" >');$(link).parent().prepend(response)}})});$(document).on("click",".hide-rate-block",function(){var wrap=$(this).closest(".wcml-wrap");$(this).attr("disabled","disabled");var ajaxLoader=$('<span class="spinner" style="visibility: visible;">');var setting=jQuery(this).data("setting");$(this).parent().prepend(ajaxLoader);$(this).remove();$.ajax({type:"post",url:ajaxurl,dataType:"json",data:{action:"wcml_update_setting_ajx",setting:setting,value:0,nonce:$("#wcml_settings_nonce").val()},success:function(response){wrap.hide()}});return false});$(document).ready(function(){$(".original-image").mousemove(function(e){$img=$("#"+$(this).data("image-id"));$img.show(200);$img.offset({top:e.pageY-100,left:e.pageX+15})}).mouseleave(function(){$img=$("#"+$(this).data("image-id"));$img.hide(200)})})});
res/js/troubleshooting.js CHANGED
@@ -214,6 +214,33 @@ jQuery( function($) {
214
  });
215
  },
216
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
217
  fix_product_type_terms: function(){
218
  jQuery.ajax({
219
  type : "post",
@@ -248,6 +275,8 @@ jQuery( function($) {
248
  WCML_Troubleshooting.sync_stock();
249
  }else if(jQuery('#wcml_fix_relationships').is(':checked') && parseInt( jQuery('#count_relationships').val() ) !== 0 ){
250
  WCML_Troubleshooting.fix_translated_variations_relationships();
 
 
251
  }else{
252
  jQuery('#wcml_trbl').removeAttr('disabled');
253
  jQuery('.spinner').hide();
214
  });
215
  },
216
 
217
+ sync_deleted_meta: function(){
218
+ jQuery.ajax({
219
+ type : "post",
220
+ url : ajaxurl,
221
+ data : {
222
+ action: "sync_deleted_meta",
223
+ wcml_nonce: jQuery('#sync_deleted_meta_nonce').val()
224
+ },
225
+ dataType: 'json',
226
+ success: function(response) {
227
+
228
+ var count_input = jQuery('#count_meta'),
229
+ remaining = count_input.val();
230
+
231
+ if( remaining == 0 ){
232
+ WCML_Troubleshooting.run_next_troubleshooting_action();
233
+ jQuery('.deleted_meta_status').html(0);
234
+ }else{
235
+ remaining = Math.max( remaining - 5, 0 );
236
+ jQuery('.deleted_meta_status').html(remaining);
237
+ count_input.val(remaining);
238
+ WCML_Troubleshooting.sync_deleted_meta();
239
+ }
240
+ }
241
+ });
242
+ },
243
+
244
  fix_product_type_terms: function(){
245
  jQuery.ajax({
246
  type : "post",
275
  WCML_Troubleshooting.sync_stock();
276
  }else if(jQuery('#wcml_fix_relationships').is(':checked') && parseInt( jQuery('#count_relationships').val() ) !== 0 ){
277
  WCML_Troubleshooting.fix_translated_variations_relationships();
278
+ }else if(jQuery('#wcml_sync_deleted_meta').is(':checked') && parseInt( jQuery('#count_meta').val() ) !== 0 ){
279
+ WCML_Troubleshooting.sync_deleted_meta();
280
  }else{
281
  jQuery('#wcml_trbl').removeAttr('disabled');
282
  jQuery('.spinner').hide();
res/js/troubleshooting.min.js CHANGED
@@ -1 +1 @@
1
- jQuery(function($){WCML_Troubleshooting={init:function(){$(document).ready(function(){jQuery("#wcml_trbl").on("click",function(){var field=jQuery(this);field.attr("disabled","disabled");jQuery(".spinner").css("display","inline-block").css("visibility","visible");if(jQuery("#wcml_sync_update_product_count").is(":checked")){WCML_Troubleshooting.update_product_count()}else{WCML_Troubleshooting.run_next_troubleshooting_action()}});jQuery("#attr_to_duplicate").on("change",function(){jQuery(".attr_status").html(jQuery(this).find("option:selected").attr("rel"));jQuery("#count_terms").val(jQuery(this).find("option:selected").attr("rel"))});jQuery("#wcml_product_type_trbl").on("click",function(){var field=jQuery(this);field.attr("disabled","disabled");jQuery(".product_type_spinner").css("display","inline-block").css("visibility","visible");WCML_Troubleshooting.fix_product_type_terms()})})},update_product_count:function(){jQuery.ajax({type:"post",url:ajaxurl,data:{action:"trbl_update_count",wcml_nonce:jQuery("#trbl_update_count_nonce").val()},dataType:"json",success:function(response){jQuery(".var_status").each(function(){jQuery(this).html(response.data.count)});jQuery("#count_prod_variat").val(response.data.count);WCML_Troubleshooting.run_next_troubleshooting_action()}})},sync_variations:function(){jQuery.ajax({type:"post",url:ajaxurl,data:{action:"trbl_sync_variations",wcml_nonce:jQuery("#trbl_sync_variations_nonce").val()},dataType:"json",success:function(response){if(jQuery("#count_prod_variat").val()==0){jQuery(".var_status").each(function(){jQuery(this).html(0)});WCML_Troubleshooting.run_next_troubleshooting_action()}else{var left=jQuery("#count_prod_variat").val()-3;if(left<0){left=0}jQuery(".var_status").each(function(){jQuery(this).html(left)});jQuery("#count_prod_variat").val(left);WCML_Troubleshooting.sync_variations()}}})},sync_product_gallery:function(){jQuery.ajax({type:"post",url:ajaxurl,data:{action:"trbl_gallery_images",wcml_nonce:jQuery("#trbl_gallery_images_nonce").val(),page:jQuery("#sync_galerry_page").val()},dataType:"json",success:function(response){if(jQuery("#count_galleries").val()==0){WCML_Troubleshooting.run_next_troubleshooting_action();jQuery(".gallery_status").html(0)}else{var left=jQuery("#count_galleries").val()-5;if(left<0){left=0}else{jQuery("#sync_galerry_page").val(parseInt(jQuery("#sync_galerry_page").val())+1)}jQuery(".gallery_status").html(left);jQuery("#count_galleries").val(left);WCML_Troubleshooting.sync_product_gallery()}}})},sync_product_categories:function(){jQuery.ajax({type:"post",url:ajaxurl,data:{action:"trbl_sync_categories",wcml_nonce:jQuery("#trbl_sync_categories_nonce").val(),page:jQuery("#sync_category_page").val()},success:function(response){if(jQuery("#count_categories").val()==0){WCML_Troubleshooting.run_next_troubleshooting_action();jQuery(".cat_status").html(0)}else{var left=jQuery("#count_categories").val()-5;if(left<0){left=0}else{jQuery("#sync_category_page").val(parseInt(jQuery("#sync_category_page").val())+1)}jQuery(".cat_status").html(left);jQuery("#count_categories").val(left);WCML_Troubleshooting.sync_product_categories()}}})},duplicate_terms:function(){jQuery.ajax({type:"post",url:ajaxurl,data:{action:"trbl_duplicate_terms",wcml_nonce:jQuery("#trbl_duplicate_terms_nonce").val(),attr:jQuery("#attr_to_duplicate option:selected").val()},dataType:"json",success:function(response){if(jQuery("#count_terms").val()==0){WCML_Troubleshooting.run_next_troubleshooting_action();jQuery(".attr_status").html(0)}else{var left=jQuery("#count_terms").val()-5;if(left<0){left=0}jQuery(".attr_status").html(left);jQuery("#count_terms").val(left);WCML_Troubleshooting.duplicate_terms()}}})},sync_stock:function(){jQuery.ajax({type:"post",url:ajaxurl,data:{action:"trbl_sync_stock",wcml_nonce:jQuery("#trbl_sync_stock_nonce").val()},dataType:"json",success:function(response){jQuery("#count_stock").val(0);WCML_Troubleshooting.run_next_troubleshooting_action();jQuery(".stock_status").html(0)}})},fix_translated_variations_relationships:function(){jQuery.ajax({type:"post",url:ajaxurl,data:{action:"fix_translated_variations_relationships",wcml_nonce:jQuery("#fix_relationships_nonce").val()},dataType:"json",success:function(response){var count_input=jQuery("#count_relationships");if(count_input.val()==0){WCML_Troubleshooting.run_next_troubleshooting_action();jQuery(".relationships_status").html(0)}else{var left=count_input.val()-5;if(left<0){left=0}jQuery(".relationships_status").html(left);count_input.val(left);WCML_Troubleshooting.fix_translated_variations_relationships()}}})},fix_product_type_terms:function(){jQuery.ajax({type:"post",url:ajaxurl,data:{action:"trbl_fix_product_type_terms",wcml_nonce:jQuery("#trbl_product_type_terms_nonce").val()},dataType:"json",success:function(response){jQuery("#wcml_product_type_trbl").removeAttr("disabled");jQuery(".product_type_spinner").hide();jQuery(".product_type_fix_done").show();setTimeout(function(){jQuery(".product_type_fix_done").fadeOut(300)},2e3)}})},run_next_troubleshooting_action:function(){if(jQuery("#wcml_sync_product_variations").is(":checked")&&parseInt(jQuery("#count_prod_variat").val())!==0){WCML_Troubleshooting.sync_variations()}else if(jQuery("#wcml_sync_gallery_images").is(":checked")&&parseInt(jQuery("#count_galleries").val())!==0){WCML_Troubleshooting.sync_product_gallery()}else if(jQuery("#wcml_sync_categories").is(":checked")&&parseInt(jQuery("#count_categories").val())!==0){WCML_Troubleshooting.sync_product_categories()}else if(jQuery("#wcml_duplicate_terms").is(":checked")&&parseInt(jQuery("#count_terms").val())!==0){WCML_Troubleshooting.duplicate_terms()}else if(jQuery("#wcml_sync_stock").is(":checked")&&parseInt(jQuery("#count_stock").val())!==0){WCML_Troubleshooting.sync_stock()}else if(jQuery("#wcml_fix_relationships").is(":checked")&&parseInt(jQuery("#count_relationships").val())!==0){WCML_Troubleshooting.fix_translated_variations_relationships()}else{jQuery("#wcml_trbl").removeAttr("disabled");jQuery(".spinner").hide();jQuery("#wcml_trbl").next().fadeOut()}}};WCML_Troubleshooting.init()});
1
+ jQuery(function($){WCML_Troubleshooting={init:function(){$(document).ready(function(){jQuery("#wcml_trbl").on("click",function(){var field=jQuery(this);field.attr("disabled","disabled");jQuery(".spinner").css("display","inline-block").css("visibility","visible");if(jQuery("#wcml_sync_update_product_count").is(":checked")){WCML_Troubleshooting.update_product_count()}else{WCML_Troubleshooting.run_next_troubleshooting_action()}});jQuery("#attr_to_duplicate").on("change",function(){jQuery(".attr_status").html(jQuery(this).find("option:selected").attr("rel"));jQuery("#count_terms").val(jQuery(this).find("option:selected").attr("rel"))});jQuery("#wcml_product_type_trbl").on("click",function(){var field=jQuery(this);field.attr("disabled","disabled");jQuery(".product_type_spinner").css("display","inline-block").css("visibility","visible");WCML_Troubleshooting.fix_product_type_terms()})})},update_product_count:function(){jQuery.ajax({type:"post",url:ajaxurl,data:{action:"trbl_update_count",wcml_nonce:jQuery("#trbl_update_count_nonce").val()},dataType:"json",success:function(response){jQuery(".var_status").each(function(){jQuery(this).html(response.data.count)});jQuery("#count_prod_variat").val(response.data.count);WCML_Troubleshooting.run_next_troubleshooting_action()}})},sync_variations:function(){jQuery.ajax({type:"post",url:ajaxurl,data:{action:"trbl_sync_variations",wcml_nonce:jQuery("#trbl_sync_variations_nonce").val()},dataType:"json",success:function(response){if(jQuery("#count_prod_variat").val()==0){jQuery(".var_status").each(function(){jQuery(this).html(0)});WCML_Troubleshooting.run_next_troubleshooting_action()}else{var left=jQuery("#count_prod_variat").val()-3;if(left<0){left=0}jQuery(".var_status").each(function(){jQuery(this).html(left)});jQuery("#count_prod_variat").val(left);WCML_Troubleshooting.sync_variations()}}})},sync_product_gallery:function(){jQuery.ajax({type:"post",url:ajaxurl,data:{action:"trbl_gallery_images",wcml_nonce:jQuery("#trbl_gallery_images_nonce").val(),page:jQuery("#sync_galerry_page").val()},dataType:"json",success:function(response){if(jQuery("#count_galleries").val()==0){WCML_Troubleshooting.run_next_troubleshooting_action();jQuery(".gallery_status").html(0)}else{var left=jQuery("#count_galleries").val()-5;if(left<0){left=0}else{jQuery("#sync_galerry_page").val(parseInt(jQuery("#sync_galerry_page").val())+1)}jQuery(".gallery_status").html(left);jQuery("#count_galleries").val(left);WCML_Troubleshooting.sync_product_gallery()}}})},sync_product_categories:function(){jQuery.ajax({type:"post",url:ajaxurl,data:{action:"trbl_sync_categories",wcml_nonce:jQuery("#trbl_sync_categories_nonce").val(),page:jQuery("#sync_category_page").val()},success:function(response){if(jQuery("#count_categories").val()==0){WCML_Troubleshooting.run_next_troubleshooting_action();jQuery(".cat_status").html(0)}else{var left=jQuery("#count_categories").val()-5;if(left<0){left=0}else{jQuery("#sync_category_page").val(parseInt(jQuery("#sync_category_page").val())+1)}jQuery(".cat_status").html(left);jQuery("#count_categories").val(left);WCML_Troubleshooting.sync_product_categories()}}})},duplicate_terms:function(){jQuery.ajax({type:"post",url:ajaxurl,data:{action:"trbl_duplicate_terms",wcml_nonce:jQuery("#trbl_duplicate_terms_nonce").val(),attr:jQuery("#attr_to_duplicate option:selected").val()},dataType:"json",success:function(response){if(jQuery("#count_terms").val()==0){WCML_Troubleshooting.run_next_troubleshooting_action();jQuery(".attr_status").html(0)}else{var left=jQuery("#count_terms").val()-5;if(left<0){left=0}jQuery(".attr_status").html(left);jQuery("#count_terms").val(left);WCML_Troubleshooting.duplicate_terms()}}})},sync_stock:function(){jQuery.ajax({type:"post",url:ajaxurl,data:{action:"trbl_sync_stock",wcml_nonce:jQuery("#trbl_sync_stock_nonce").val()},dataType:"json",success:function(response){jQuery("#count_stock").val(0);WCML_Troubleshooting.run_next_troubleshooting_action();jQuery(".stock_status").html(0)}})},fix_translated_variations_relationships:function(){jQuery.ajax({type:"post",url:ajaxurl,data:{action:"fix_translated_variations_relationships",wcml_nonce:jQuery("#fix_relationships_nonce").val()},dataType:"json",success:function(response){var count_input=jQuery("#count_relationships");if(count_input.val()==0){WCML_Troubleshooting.run_next_troubleshooting_action();jQuery(".relationships_status").html(0)}else{var left=count_input.val()-5;if(left<0){left=0}jQuery(".relationships_status").html(left);count_input.val(left);WCML_Troubleshooting.fix_translated_variations_relationships()}}})},sync_deleted_meta:function(){jQuery.ajax({type:"post",url:ajaxurl,data:{action:"sync_deleted_meta",wcml_nonce:jQuery("#sync_deleted_meta_nonce").val()},dataType:"json",success:function(response){var count_input=jQuery("#count_meta"),remaining=count_input.val();if(remaining==0){WCML_Troubleshooting.run_next_troubleshooting_action();jQuery(".deleted_meta_status").html(0)}else{remaining=Math.max(remaining-5,0);jQuery(".deleted_meta_status").html(remaining);count_input.val(remaining);WCML_Troubleshooting.sync_deleted_meta()}}})},fix_product_type_terms:function(){jQuery.ajax({type:"post",url:ajaxurl,data:{action:"trbl_fix_product_type_terms",wcml_nonce:jQuery("#trbl_product_type_terms_nonce").val()},dataType:"json",success:function(response){jQuery("#wcml_product_type_trbl").removeAttr("disabled");jQuery(".product_type_spinner").hide();jQuery(".product_type_fix_done").show();setTimeout(function(){jQuery(".product_type_fix_done").fadeOut(300)},2e3)}})},run_next_troubleshooting_action:function(){if(jQuery("#wcml_sync_product_variations").is(":checked")&&parseInt(jQuery("#count_prod_variat").val())!==0){WCML_Troubleshooting.sync_variations()}else if(jQuery("#wcml_sync_gallery_images").is(":checked")&&parseInt(jQuery("#count_galleries").val())!==0){WCML_Troubleshooting.sync_product_gallery()}else if(jQuery("#wcml_sync_categories").is(":checked")&&parseInt(jQuery("#count_categories").val())!==0){WCML_Troubleshooting.sync_product_categories()}else if(jQuery("#wcml_duplicate_terms").is(":checked")&&parseInt(jQuery("#count_terms").val())!==0){WCML_Troubleshooting.duplicate_terms()}else if(jQuery("#wcml_sync_stock").is(":checked")&&parseInt(jQuery("#count_stock").val())!==0){WCML_Troubleshooting.sync_stock()}else if(jQuery("#wcml_fix_relationships").is(":checked")&&parseInt(jQuery("#count_relationships").val())!==0){WCML_Troubleshooting.fix_translated_variations_relationships()}else if(jQuery("#wcml_sync_deleted_meta").is(":checked")&&parseInt(jQuery("#count_meta").val())!==0){WCML_Troubleshooting.sync_deleted_meta()}else{jQuery("#wcml_trbl").removeAttr("disabled");jQuery(".spinner").hide();jQuery("#wcml_trbl").next().fadeOut()}}};WCML_Troubleshooting.init()});
templates/php/plugins-wrap.php ADDED
@@ -0,0 +1,127 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * @var $model \WPML\Templates\PHP\Model
4
+ *
5
+ * phpcs:disable WordPress.XSS.EscapeOutput.OutputNotEscaped
6
+ */
7
+ ?>
8
+ <div class="wrap">
9
+ <h1><?php echo wp_kses_post( $model->strings->title ); ?></h1>
10
+
11
+ <nav class="wcml-tabs wpml-tabs" style="display:table;margin-top:30px;">
12
+ <a class="nav-tab nav-tab-active wcml-required-plugins-tab" href="<?php echo esc_attr( $model->link_url ); ?>"><?php echo wp_kses_post( $model->strings->required ); ?></a>
13
+ </nav>
14
+
15
+ <div class="wcml-wrap wcml-required-plugins-wrap">
16
+ <div class="wcml-section">
17
+ <div class="wcml-section-header">
18
+ <h3>
19
+ <?php echo wp_kses_post( $model->strings->plugins ); ?>
20
+ <i class="otgs-ico-help wcml-tip" data-tip="<?php echo esc_attr( $model->strings->depends ); ?>"> </i>
21
+ </h3>
22
+ </div>
23
+ <div class="wcml-section-content wcml-section-content-wide">
24
+ <ul>
25
+ <?php
26
+ if ( true === $model->old_wpml ) {
27
+ ?>
28
+ <li>
29
+ <i class="otgs-ico-warning wpml-multilingual-cms otgs-old"></i>
30
+ <?php echo wp_kses_post( $model->strings->old_wpml_link ); ?>
31
+ <a href="<?php echo esc_attr( $model->tracking_link ); ?>"
32
+ target="_blank"><?php echo wp_kses_post( $model->strings->update_wpml ); ?></a>
33
+ </li>
34
+ <?php
35
+ } elseif ( true === $model->icl_version ) {
36
+ ?>
37
+ <li>
38
+ <i class="otgs-ico-ok wpml-multilingual-cms"></i>
39
+ <?php echo sprintf( $model->strings->inst_active, $model->strings->wpml ); ?>
40
+ </li>
41
+ <?php
42
+ if ( true === $model->icl_setup ) {
43
+ ?>
44
+ <li>
45
+ <i class="otgs-ico-ok wpml-multilingual-cms wpml-setup"></i>
46
+ <?php echo sprintf( $model->strings->is_setup, $model->strings->wpml ); ?>
47
+ </li>
48
+ <?php
49
+ } else {
50
+ ?>
51
+ <li>
52
+ <i class="otgs-ico-warning wpml-multilingual-cms otgs-no-setup"></i>
53
+ <?php echo sprintf( $model->strings->not_setup, $model->strings->wpml ); ?>
54
+ </li>
55
+ <?php
56
+ }
57
+ } else {
58
+ ?>
59
+ <li>
60
+ <i class="otgs-ico-warning wpml-multilingual-cms otgs-missing"></i>
61
+ <?php echo wp_kses_post( $model->strings->wpml_not_inst ); ?>
62
+ <a href="<?php echo esc_attr( $model->install_wpml_link ); ?>" target="_blank"><?php echo wp_kses_post( $model->strings->get_wpml ); ?></a>
63
+ </li>
64
+ <?php
65
+ }
66
+ if ( true === $model->tm_version ) {
67
+ ?>
68
+ <li>
69
+ <i class="otgs-ico-ok wpml-translation-management"></i>
70
+ <?php echo sprintf( $model->strings->inst_active, $model->strings->tm ); ?>
71
+ </li>
72
+ <?php
73
+ } else {
74
+ ?>
75
+ <li>
76
+ <i class="otgs-ico-warning wpml-translation-management otgs-missing"></i>
77
+ <?php echo sprintf( $model->strings->not_inst, $model->strings->tm ); ?>
78
+ <a href="<?php echo esc_attr( $model->install_wpml_link ); ?>" target="_blank"><?php echo wp_kses_post( $model->strings->get_wpml_tm ); ?></a>
79
+ </li>
80
+ <?php
81
+ }
82
+ if ( true === $model->st_version ) {
83
+ ?>
84
+ <li>
85
+ <i class="otgs-ico-ok wpml-string-translation"></i>
86
+ <?php echo sprintf( $model->strings->inst_active, $model->strings->st ); ?>
87
+ </li>
88
+ <?php
89
+ } else {
90
+ ?>
91
+ <li>
92
+ <i class="otgs-ico-warning wpml-string-translation otgs-missing"></i>
93
+ <?php echo sprintf( $model->strings->not_inst, $model->strings->st ); ?>
94
+ <a href="<?php echo esc_attr( $model->install_wpml_link ); ?>" target="_blank"><?php echo wp_kses_post( $model->strings->get_wpml_st ); ?></a>
95
+ </li>
96
+ <?php
97
+ }
98
+ if ( true === $model->old_wc ) {
99
+ ?>
100
+ <li>
101
+ <i class="otgs-ico-warning woocommerce otgs-old"></i>
102
+ <?php echo wp_kses_post( $model->strings->old_wc ); ?>
103
+ <a href="<?php echo esc_attr( $model->wc_link ); ?>" target="_blank"><?php echo wp_kses_post( $model->strings->download_wc ); ?></a>
104
+ </li>
105
+ <?php
106
+ } elseif ( true === $model->wc ) {
107
+ ?>
108
+ <li>
109
+ <i class="otgs-ico-ok woocommerce"></i>
110
+ <?php echo sprintf( $model->strings->inst_active, $model->strings->wc ); ?>
111
+ </li>
112
+ <?php
113
+ } else {
114
+ ?>
115
+ <li>
116
+ <i class="otgs-ico-warning woocommerce otgs-missing"></i>
117
+ <?php echo sprintf( $model->strings->not_inst, $model->strings->wc ); ?>
118
+ <a href="<?php echo esc_attr( $model->wc_link ); ?>" target="_blank"><?php echo wp_kses_post( $model->strings->download_wc ); ?></a>
119
+ </li>
120
+ <?php
121
+ }
122
+ ?>
123
+ </ul>
124
+ </div>
125
+ </div>
126
+ </div>
127
+ </div>
templates/plugins-wrap.twig DELETED
@@ -1,99 +0,0 @@
1
- <div class="wrap">
2
- <h1>{{ strings.title }}</h1>
3
-
4
- <nav class="wcml-tabs wpml-tabs" style="display:table;margin-top:30px;">
5
- <a class="nav-tab nav-tab-active wcml-required-plugins-tab" href="{{ link_url|e }}" >{{ strings.required }}</a>
6
- </nav>
7
-
8
- <div class="wcml-wrap wcml-required-plugins-wrap">
9
- <div class="wcml-section">
10
- <div class="wcml-section-header">
11
- <h3>
12
- {{ strings.plugins }}
13
- <i class="otgs-ico-help wcml-tip"
14
- data-tip="{{ strings.depends }}"></i>
15
- </h3>
16
- </div>
17
- <div class="wcml-section-content wcml-section-content-wide">
18
- <ul>
19
- {% if old_wpml %}
20
- <li>
21
- <i class="otgs-ico-warning wpml-multilingual-cms"></i>
22
- {{ strings.old_wpml_link|raw }}
23
- <a href="{{ tracking_link }}"
24
- target="_blank">{{ strings.update_wpml }}</a>
25
- </li>
26
- {% elseif icl_version %}
27
- <li>
28
- <i class="otgs-ico-ok wpml-multilingual-cms"></i>
29
- {{ strings.inst_active|format( strings.wpml )|raw }}
30
- </li>
31
- {% if icl_setup %}
32
- <li>
33
- <i class="otgs-ico-ok wpml-multilingual-cms wpml-setup"></i>
34
- {{ strings.is_setup|format( strings.wpml )|raw }}
35
- </li>
36
- {% else %}
37
- <li>
38
- <i class="otgs-ico-warning wpml-multilingual-cms wpml-setup"></i>
39
- {{ strings.not_setup|format( strings.wpml )|raw }}
40
- </li>
41
- {% endif %}
42
- {% else %}
43
- <li>
44
- <i class="otgs-ico-warning wpml-multilingual-cms"></i>
45
- {{ strings.wpml_not_inst|raw }}
46
- <a href="{{ install_wpml_link|e }}" target="_blank">{{ strings.get_wpml }}</a>
47
- </li>
48
- {% endif %}
49
-
50
- {% if tm_version %}
51
- <li>
52
- <i class="otgs-ico-ok wpml-translation-management"></i>
53
- {{ strings.inst_active|format( strings.tm )|raw }}
54
- </li>
55
- {% else %}
56
- <li>
57
- <i class="otgs-ico-warning wpml-translation-management"></i>
58
- {{ strings.not_inst|format( strings.tm )|raw }}
59
- <a href="{{ install_wpml_link|e }}" target="_blank">{{ strings.get_wpml_tm }}</a>
60
- </li>
61
- {% endif %}
62
-
63
- {% if st_version %}
64
- <li>
65
- <i class="otgs-ico-ok wpml-string-translation"></i>
66
- {{ strings.inst_active|format( strings.st )|raw }}
67
- </li>
68
- {% else %}
69
- <li>
70
- <i class="otgs-ico-warning wpml-string-translation"></i>
71
- {{ strings.not_inst|format( strings.st )|raw }}
72
- <a href="{{ install_wpml_link|e }}" target="_blank">{{ strings.get_wpml_st }}</a>
73
- </li>
74
- {% endif %}
75
-
76
- {% if old_wc %}
77
- <li>
78
- <i class="otgs-ico-warning woocommerce"></i>
79
- {{ strings.old_wc|raw }}
80
- <a href="{{ wc_link|e }}" target="_blank">{{ strings.download_wc }}</a>
81
- </li>
82
- {% elseif wc %}
83
- <li>
84
- <i class="otgs-ico-ok woocommerce"></i>
85
- {{ strings.inst_active|format( strings.wc )|raw }}
86
- </li>
87
- {% else %}
88
- <li>
89
- <i class="otgs-ico-warning woocommerce"></i>
90
- {{ strings.not_inst|format( strings.wc )|raw }}
91
- <a href="{{ wc_link|e }}" target="_blank">{{ strings.download_wc }}</a>
92
- </li>
93
- {% endif %}
94
- </ul>
95
- </div>
96
- </div>
97
- </div>
98
- </div>
99
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
templates/products-list/products.twig CHANGED
@@ -51,9 +51,15 @@
51
  <tr>
52
  <td class="thumb column-thumb">
53
  <a href="{{ product.edit_post_link|raw }}">
54
- <img width="150" height="150" src="{{ product.post_thumbnail }}" class="wp-post-image" >
55
  </a>
56
  </td>
 
 
 
 
 
 
57
  <td class="wpml-col-title wpml-col-title-flag">
58
  {% if product.post_parent != 0 %} &#8212; {% endif %}
59
  <strong>
51
  <tr>
52
  <td class="thumb column-thumb">
53
  <a href="{{ product.edit_post_link|raw }}">
54
+ <img width="150" height="150" src="{{ product.post_thumbnail }}" class="wp-post-image original-image" data-image-id="thumbnail-{{ product.ID }}" >
55
  </a>
56
  </td>
57
+
58
+ {# Conndition to check if we have thumbnail. If true the larger image appears #}
59
+ {% if product.has_image %}
60
+ <img id="thumbnail-{{ product.ID }}" src="{{ product.post_thumbnail }}" class="mouse-hovered">
61
+ {% endif %}
62
+
63
  <td class="wpml-col-title wpml-col-title-flag">
64
  {% if product.post_parent != 0 %} &#8212; {% endif %}
65
  <strong>
templates/troubleshooting.twig CHANGED
@@ -69,7 +69,7 @@
69
  <label>
70
  <input type="checkbox" id="wcml_sync_stock" />
71
  {{ strings.sync_stock }}
72
- <span class="stock_status">{{ sync_stock_count }}</span>
73
  <span>{{ strings.left }}</span>
74
  </label>
75
  </li>
@@ -81,6 +81,14 @@
81
  <span>{{ strings.left }}</span>
82
  </label>
83
  </li>
 
 
 
 
 
 
 
 
84
  <li>
85
  <button type="button" class="button-secondary" id="wcml_trbl">{{ strings.start }}</button>
86
  <input id="count_prod_variat" type="hidden" value="{{ prod_with_variations }}"/>
@@ -88,7 +96,8 @@
88
  <input id="count_galleries" type="hidden" value="{{ prod_count }}"/>
89
  <input id="count_categories" type="hidden" value="{{ prod_categories_count }}"/>
90
  <input id="count_terms" type="hidden" value="{{ terms_count }}"/>
91
- <input id="count_stock" type="hidden" value="{{ sync_stock_count }}"/>
 
92
  <input id="count_relationships" type="hidden" value="{{ fix_relationships_count }}"/>
93
  <input id="sync_galerry_page" type="hidden" value="0"/>
94
  <input id="sync_category_page" type="hidden" value="0"/>
@@ -100,6 +109,7 @@
100
  {{ nonces.trbl_duplicate_terms|raw }}
101
  {{ nonces.trbl_sync_stock|raw }}
102
  {{ nonces.fix_relationships|raw }}
 
103
  </li>
104
  </ul>
105
  {% if product_type_sync_needed %}
69
  <label>
70
  <input type="checkbox" id="wcml_sync_stock" />
71
  {{ strings.sync_stock }}
72
+ <span class="stock_status">{{ product_and_variations_count }}</span>
73
  <span>{{ strings.left }}</span>
74
  </label>
75
  </li>
81
  <span>{{ strings.left }}</span>
82
  </label>
83
  </li>
84
+ <li>
85
+ <label>
86
+ <input type="checkbox" id="wcml_sync_deleted_meta" />
87
+ {{ strings.sync_deleted_meta }}
88
+ <span class="deleted_meta_status">{{ product_and_variations_count }}</span>
89
+ <span>{{ strings.left }}</span>
90
+ </label>
91
+ </li>
92
  <li>
93
  <button type="button" class="button-secondary" id="wcml_trbl">{{ strings.start }}</button>
94
  <input id="count_prod_variat" type="hidden" value="{{ prod_with_variations }}"/>
96
  <input id="count_galleries" type="hidden" value="{{ prod_count }}"/>
97
  <input id="count_categories" type="hidden" value="{{ prod_categories_count }}"/>
98
  <input id="count_terms" type="hidden" value="{{ terms_count }}"/>
99
+ <input id="count_stock" type="hidden" value="{{ product_and_variations_count }}"/>
100
+ <input id="count_meta" type="hidden" value="{{ product_and_variations_count }}"/>
101
  <input id="count_relationships" type="hidden" value="{{ fix_relationships_count }}"/>
102
  <input id="sync_galerry_page" type="hidden" value="0"/>
103
  <input id="sync_category_page" type="hidden" value="0"/>
109
  {{ nonces.trbl_duplicate_terms|raw }}
110
  {{ nonces.trbl_sync_stock|raw }}
111
  {{ nonces.fix_relationships|raw }}
112
+ {{ nonces.sync_deleted_meta|raw }}
113
  </li>
114
  </ul>
115
  {% if product_type_sync_needed %}
vendor/autoload.php CHANGED
@@ -4,4 +4,4 @@
4
 
5
  require_once __DIR__ . '/composer/autoload_real.php';
6
 
7
- return ComposerAutoloaderInit45b9e3eb7ce593679d57b7aed79dfe16::getLoader();
4
 
5
  require_once __DIR__ . '/composer/autoload_real.php';
6
 
7
+ return ComposerAutoloaderInitff583bd185773a5093da3cb1ec65536c::getLoader();
vendor/autoload_52.php DELETED
@@ -1,7 +0,0 @@
1
- <?php
2
-
3
- // autoload_52.php generated by xrstf/composer-php52
4
-
5
- require_once dirname(__FILE__) . '/composer'.'/autoload_real_52.php';
6
-
7
- return ComposerAutoloaderInitf703a8bfc3adbe723a55b33eb074c1df::getLoader();
 
 
 
 
 
 
 
vendor/composer/ClassLoader52.php DELETED
@@ -1,271 +0,0 @@
1
- <?php
2
- /*
3
- * Copyright (c) 2013, Christoph Mewes, http://www.xrstf.de
4
- *
5
- * This file is released under the terms of the MIT license. You can find the
6
- * complete text in the attached LICENSE file or online at:
7
- *
8
- * http://www.opensource.org/licenses/mit-license.php
9
- *
10
- * --------------------------------------------------------------------------
11
- *
12
- * 99% of this is copied as-is from the original Composer source code and is
13
- * released under MIT license as well. Copyright goes to:
14
- *
15
- * - Fabien Potencier <fabien@symfony.com>
16
- * - Jordi Boggiano <j.boggiano@seld.be>
17
- */
18
-
19
- class xrstf_Composer52_ClassLoader {
20
- private $prefixes = array();
21
- private $fallbackDirs = array();
22
- private $useIncludePath = false;
23
- private $classMap = array();
24
- private $classMapAuthoratative = false;
25
- private $allowUnderscore = false;
26
-
27
- /**
28
- * @param boolean $flag true to allow class names with a leading underscore, false to disable
29
- */
30
- public function setAllowUnderscore($flag) {
31
- $this->allowUnderscore = (boolean) $flag;
32
- }
33
-
34
- /**
35
- * @return array
36
- */
37
- public function getPrefixes() {
38
- return $this->prefixes;
39
- }
40
-
41
- /**
42
- * Turns off searching the prefix and fallback directories for classes
43
- * that have not been registered with the class map.
44
- *
45
- * @param bool $classMapAuthoratative
46
- */
47
- public function setClassMapAuthoritative($classMapAuthoratative) {
48
- $this->classMapAuthoratative = $classMapAuthoratative;
49
- }
50
-
51
- /**
52
- * Should class lookup fail if not found in the current class map?
53
- *
54
- * @return bool
55
- */
56
- public function getClassMapAuthoratative() {
57
- return $this->classMapAuthoratative;
58
- }
59
-
60
- /**
61
- * @return array
62
- */
63
- public function getFallbackDirs() {
64
- return $this->fallbackDirs;
65
- }
66
-
67
- /**
68
- * @return array
69
- */
70
- public function getClassMap() {
71
- return $this->classMap;
72
- }
73
-
74
- /**
75
- * @param array $classMap class to filename map
76
- */
77
- public function addClassMap(array $classMap) {
78
- if ($this->classMap) {
79
- $this->classMap = array_merge($this->classMap, $classMap);
80
- }
81
- else {
82
- $this->classMap = $classMap;
83
- }
84
- }
85
-
86
- /**
87
- * Registers a set of classes, merging with any others previously set.
88
- *
89
- * @param string $prefix the classes prefix
90
- * @param array|string $paths the location(s) of the classes
91
- * @param bool $prepend prepend the location(s)
92
- */
93
- public function add($prefix, $paths, $prepend = false) {
94
- if (!$prefix) {
95
- if ($prepend) {
96
- $this->fallbackDirs = array_merge(
97
- (array) $paths,
98
- $this->fallbackDirs
99
- );
100
- }
101
- else {
102
- $this->fallbackDirs = array_merge(
103
- $this->fallbackDirs,
104
- (array) $paths
105
- );
106
- }
107
-
108
- return;
109
- }
110
-
111
- if (!isset($this->prefixes[$prefix])) {
112
- $this->prefixes[$prefix] = (array) $paths;
113
- return;
114
- }
115
-
116
- if ($prepend) {
117
- $this->prefixes[$prefix] = array_merge(
118
- (array) $paths,
119
- $this->prefixes[$prefix]
120
- );
121
- }
122
- else {
123
- $this->prefixes[$prefix] = array_merge(
124
- $this->prefixes[$prefix],
125
- (array) $paths
126
- );
127
- }
128
- }
129
-
130
- /**
131
- * Registers a set of classes, replacing any others previously set.
132
- *
133
- * @param string $prefix the classes prefix
134
- * @param array|string $paths the location(s) of the classes
135
- */
136
- public function set($prefix, $paths) {
137
- if (!$prefix) {
138
- $this->fallbackDirs = (array) $paths;
139
- return;
140
- }
141
-
142
- $this->prefixes[$prefix] = (array) $paths;
143
- }
144
-
145
- /**
146
- * Turns on searching the include path for class files.
147
- *
148
- * @param bool $useIncludePath
149
- */
150
- public function setUseIncludePath($useIncludePath) {
151
- $this->useIncludePath = $useIncludePath;
152
- }
153
-
154
- /**
155
- * Can be used to check if the autoloader uses the include path to check
156
- * for classes.
157
- *
158
- * @return bool
159
- */
160
- public function getUseIncludePath() {
161
- return $this->useIncludePath;
162
- }
163
-
164
- /**
165
- * Registers this instance as an autoloader.
166
- */
167
- public function register() {
168
- spl_autoload_register(array($this, 'loadClass'), true);
169
- }
170
-
171
- /**
172
- * Unregisters this instance as an autoloader.
173
- */
174
- public function unregister() {
175
- spl_autoload_unregister(array($this, 'loadClass'));
176
- }
177
-
178
- /**
179
- * Loads the given class or interface.
180
- *
181
- * @param string $class the name of the class
182
- * @return bool|null true, if loaded
183
- */
184
- public function loadClass($class) {
185
- if ($file = $this->findFile($class)) {
186
- include $file;
187
- return true;
188
- }
189
- }
190
-
191
- /**
192
- * Finds the path to the file where the class is defined.
193
- *
194
- * @param string $class the name of the class
195
- * @return string|null the path, if found
196
- */
197
- public function findFile($class) {
198
- if ('\\' === $class[0]) {
199
- $class = substr($class, 1);
200
- }
201
-
202
- if (isset($this->classMap[$class])) {
203
- return $this->classMap[$class];
204
- }
205
- elseif ($this->classMapAuthoratative) {
206
- return false;
207
- }
208
-
209
- $classPath = $this->getClassPath($class);
210
-
211
- foreach ($this->prefixes as $prefix => $dirs) {
212
- if (0 === strpos($class, $prefix)) {
213
- foreach ($dirs as $dir) {
214
- if (file_exists($dir.DIRECTORY_SEPARATOR.$classPath)) {
215
- return $dir.DIRECTORY_SEPARATOR.$classPath;
216
- }
217
- }
218
- }
219
- }
220
-
221
- foreach ($this->fallbackDirs as $dir) {
222
- if (file_exists($dir.DIRECTORY_SEPARATOR.$classPath)) {
223
- return $dir.DIRECTORY_SEPARATOR.$classPath;
224
- }
225
- }
226
-
227
- if ($this->useIncludePath && $file = self::resolveIncludePath($classPath)) {
228
- return $file;
229
- }
230
-
231
- return $this->classMap[$class] = false;
232
- }
233
-
234
- private function getClassPath($class) {
235
- if (false !== $pos = strrpos($class, '\\')) {
236
- // namespaced class name
237
- $classPath = str_replace('\\', DIRECTORY_SEPARATOR, substr($class, 0, $pos)).DIRECTORY_SEPARATOR;
238
- $className = substr($class, $pos + 1);
239
- }
240
- else {
241
- // PEAR-like class name
242
- $classPath = null;
243
- $className = $class;
244
- }
245
-
246
- $className = str_replace('_', DIRECTORY_SEPARATOR, $className);
247
-
248
- // restore the prefix
249
- if ($this->allowUnderscore && DIRECTORY_SEPARATOR === $className[0]) {
250
- $className[0] = '_';
251
- }
252
-
253
- $classPath .= $className.'.php';
254
-
255
- return $classPath;
256
- }
257
-
258
- public static function resolveIncludePath($classPath) {
259
- $paths = explode(PATH_SEPARATOR, get_include_path());
260
-
261
- foreach ($paths as $path) {
262
- $path = rtrim($path, '/\\');
263
-
264
- if ($file = file_exists($path.DIRECTORY_SEPARATOR.$file)) {
265
- return $file;
266
- }
267
- }
268
-
269
- return false;
270
- }
271
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/composer/autoload_classmap.php CHANGED
@@ -6,383 +6,11 @@ $vendorDir = dirname(dirname(__FILE__));
6
  $baseDir = dirname($vendorDir);
7
 
8
  return array(
9
- 'WCML\\Twig\\Cache\\CacheInterface' => $baseDir . '/lib/twig/src/Cache/CacheInterface.php',
10
- 'WCML\\Twig\\Cache\\FilesystemCache' => $baseDir . '/lib/twig/src/Cache/FilesystemCache.php',
11
- 'WCML\\Twig\\Cache\\NullCache' => $baseDir . '/lib/twig/src/Cache/NullCache.php',
12
- 'WCML\\Twig\\Compiler' => $baseDir . '/lib/twig/src/Compiler.php',
13
- 'WCML\\Twig\\Environment' => $baseDir . '/lib/twig/src/Environment.php',
14
- 'WCML\\Twig\\Error\\Error' => $baseDir . '/lib/twig/src/Error/Error.php',
15
- 'WCML\\Twig\\Error\\LoaderError' => $baseDir . '/lib/twig/src/Error/LoaderError.php',
16
- 'WCML\\Twig\\Error\\RuntimeError' => $baseDir . '/lib/twig/src/Error/RuntimeError.php',
17
- 'WCML\\Twig\\Error\\SyntaxError' => $baseDir . '/lib/twig/src/Error/SyntaxError.php',
18
- 'WCML\\Twig\\ExpressionParser' => $baseDir . '/lib/twig/src/ExpressionParser.php',
19
- 'WCML\\Twig\\Extension\\AbstractExtension' => $baseDir . '/lib/twig/src/Extension/AbstractExtension.php',
20
- 'WCML\\Twig\\Extension\\CoreExtension' => $baseDir . '/lib/twig/src/Extension/CoreExtension.php',
21
- 'WCML\\Twig\\Extension\\DebugExtension' => $baseDir . '/lib/twig/src/Extension/DebugExtension.php',
22
- 'WCML\\Twig\\Extension\\EscaperExtension' => $baseDir . '/lib/twig/src/Extension/EscaperExtension.php',
23
- 'WCML\\Twig\\Extension\\ExtensionInterface' => $baseDir . '/lib/twig/src/Extension/ExtensionInterface.php',
24
- 'WCML\\Twig\\Extension\\GlobalsInterface' => $baseDir . '/lib/twig/src/Extension/GlobalsInterface.php',
25
- 'WCML\\Twig\\Extension\\InitRuntimeInterface' => $baseDir . '/lib/twig/src/Extension/InitRuntimeInterface.php',
26
- 'WCML\\Twig\\Extension\\OptimizerExtension' => $baseDir . '/lib/twig/src/Extension/OptimizerExtension.php',
27
- 'WCML\\Twig\\Extension\\ProfilerExtension' => $baseDir . '/lib/twig/src/Extension/ProfilerExtension.php',
28
- 'WCML\\Twig\\Extension\\RuntimeExtensionInterface' => $baseDir . '/lib/twig/src/Extension/RuntimeExtensionInterface.php',
29
- 'WCML\\Twig\\Extension\\SandboxExtension' => $baseDir . '/lib/twig/src/Extension/SandboxExtension.php',
30
- 'WCML\\Twig\\Extension\\StagingExtension' => $baseDir . '/lib/twig/src/Extension/StagingExtension.php',
31
- 'WCML\\Twig\\Extension\\StringLoaderExtension' => $baseDir . '/lib/twig/src/Extension/StringLoaderExtension.php',
32
- 'WCML\\Twig\\FileExtensionEscapingStrategy' => $baseDir . '/lib/twig/src/FileExtensionEscapingStrategy.php',
33
- 'WCML\\Twig\\Lexer' => $baseDir . '/lib/twig/src/Lexer.php',
34
- 'WCML\\Twig\\Loader\\ArrayLoader' => $baseDir . '/lib/twig/src/Loader/ArrayLoader.php',
35
- 'WCML\\Twig\\Loader\\ChainLoader' => $baseDir . '/lib/twig/src/Loader/ChainLoader.php',
36
- 'WCML\\Twig\\Loader\\ExistsLoaderInterface' => $baseDir . '/lib/twig/src/Loader/ExistsLoaderInterface.php',
37
- 'WCML\\Twig\\Loader\\FilesystemLoader' => $baseDir . '/lib/twig/src/Loader/FilesystemLoader.php',
38
- 'WCML\\Twig\\Loader\\LoaderInterface' => $baseDir . '/lib/twig/src/Loader/LoaderInterface.php',
39
- 'WCML\\Twig\\Loader\\SourceContextLoaderInterface' => $baseDir . '/lib/twig/src/Loader/SourceContextLoaderInterface.php',
40
- 'WCML\\Twig\\Markup' => $baseDir . '/lib/twig/src/Markup.php',
41
- 'WCML\\Twig\\NodeTraverser' => $baseDir . '/lib/twig/src/NodeTraverser.php',
42
- 'WCML\\Twig\\NodeVisitor\\AbstractNodeVisitor' => $baseDir . '/lib/twig/src/NodeVisitor/AbstractNodeVisitor.php',
43
- 'WCML\\Twig\\NodeVisitor\\EscaperNodeVisitor' => $baseDir . '/lib/twig/src/NodeVisitor/EscaperNodeVisitor.php',
44
- 'WCML\\Twig\\NodeVisitor\\NodeVisitorInterface' => $baseDir . '/lib/twig/src/NodeVisitor/NodeVisitorInterface.php',
45
- 'WCML\\Twig\\NodeVisitor\\OptimizerNodeVisitor' => $baseDir . '/lib/twig/src/NodeVisitor/OptimizerNodeVisitor.php',
46
- 'WCML\\Twig\\NodeVisitor\\SafeAnalysisNodeVisitor' => $baseDir . '/lib/twig/src/NodeVisitor/SafeAnalysisNodeVisitor.php',
47
- 'WCML\\Twig\\NodeVisitor\\SandboxNodeVisitor' => $baseDir . '/lib/twig/src/NodeVisitor/SandboxNodeVisitor.php',
48
- 'WCML\\Twig\\Node\\AutoEscapeNode' => $baseDir . '/lib/twig/src/Node/AutoEscapeNode.php',
49
- 'WCML\\Twig\\Node\\BlockNode' => $baseDir . '/lib/twig/src/Node/BlockNode.php',
50
- 'WCML\\Twig\\Node\\BlockReferenceNode' => $baseDir . '/lib/twig/src/Node/BlockReferenceNode.php',
51
- 'WCML\\Twig\\Node\\BodyNode' => $baseDir . '/lib/twig/src/Node/BodyNode.php',
52
- 'WCML\\Twig\\Node\\CheckSecurityNode' => $baseDir . '/lib/twig/src/Node/CheckSecurityNode.php',
53
- 'WCML\\Twig\\Node\\CheckToStringNode' => $baseDir . '/lib/twig/src/Node/CheckToStringNode.php',
54
- 'WCML\\Twig\\Node\\DeprecatedNode' => $baseDir . '/lib/twig/src/Node/DeprecatedNode.php',
55
- 'WCML\\Twig\\Node\\DoNode' => $baseDir . '/lib/twig/src/Node/DoNode.php',
56
- 'WCML\\Twig\\Node\\EmbedNode' => $baseDir . '/lib/twig/src/Node/EmbedNode.php',
57
- 'WCML\\Twig\\Node\\Expression\\AbstractExpression' => $baseDir . '/lib/twig/src/Node/Expression/AbstractExpression.php',
58
- 'WCML\\Twig\\Node\\Expression\\ArrayExpression' => $baseDir . '/lib/twig/src/Node/Expression/ArrayExpression.php',
59
- 'WCML\\Twig\\Node\\Expression\\ArrowFunctionExpression' => $baseDir . '/lib/twig/src/Node/Expression/ArrowFunctionExpression.php',
60
- 'WCML\\Twig\\Node\\Expression\\AssignNameExpression' => $baseDir . '/lib/twig/src/Node/Expression/AssignNameExpression.php',
61
- 'WCML\\Twig\\Node\\Expression\\Binary\\AbstractBinary' => $baseDir . '/lib/twig/src/Node/Expression/Binary/AbstractBinary.php',
62
- 'WCML\\Twig\\Node\\Expression\\Binary\\AddBinary' => $baseDir . '/lib/twig/src/Node/Expression/Binary/AddBinary.php',
63
- 'WCML\\Twig\\Node\\Expression\\Binary\\AndBinary' => $baseDir . '/lib/twig/src/Node/Expression/Binary/AndBinary.php',
64
- 'WCML\\Twig\\Node\\Expression\\Binary\\BitwiseAndBinary' => $baseDir . '/lib/twig/src/Node/Expression/Binary/BitwiseAndBinary.php',
65
- 'WCML\\Twig\\Node\\Expression\\Binary\\BitwiseOrBinary' => $baseDir . '/lib/twig/src/Node/Expression/Binary/BitwiseOrBinary.php',
66
- 'WCML\\Twig\\Node\\Expression\\Binary\\BitwiseXorBinary' => $baseDir . '/lib/twig/src/Node/Expression/Binary/BitwiseXorBinary.php',
67
- 'WCML\\Twig\\Node\\Expression\\Binary\\ConcatBinary' => $baseDir . '/lib/twig/src/Node/Expression/Binary/ConcatBinary.php',
68
- 'WCML\\Twig\\Node\\Expression\\Binary\\DivBinary' => $baseDir . '/lib/twig/src/Node/Expression/Binary/DivBinary.php',
69
- 'WCML\\Twig\\Node\\Expression\\Binary\\EndsWithBinary' => $baseDir . '/lib/twig/src/Node/Expression/Binary/EndsWithBinary.php',
70
- 'WCML\\Twig\\Node\\Expression\\Binary\\EqualBinary' => $baseDir . '/lib/twig/src/Node/Expression/Binary/EqualBinary.php',
71
- 'WCML\\Twig\\Node\\Expression\\Binary\\FloorDivBinary' => $baseDir . '/lib/twig/src/Node/Expression/Binary/FloorDivBinary.php',
72
- 'WCML\\Twig\\Node\\Expression\\Binary\\GreaterBinary' => $baseDir . '/lib/twig/src/Node/Expression/Binary/GreaterBinary.php',
73
- 'WCML\\Twig\\Node\\Expression\\Binary\\GreaterEqualBinary' => $baseDir . '/lib/twig/src/Node/Expression/Binary/GreaterEqualBinary.php',
74
- 'WCML\\Twig\\Node\\Expression\\Binary\\InBinary' => $baseDir . '/lib/twig/src/Node/Expression/Binary/InBinary.php',
75
- 'WCML\\Twig\\Node\\Expression\\Binary\\LessBinary' => $baseDir . '/lib/twig/src/Node/Expression/Binary/LessBinary.php',
76
- 'WCML\\Twig\\Node\\Expression\\Binary\\LessEqualBinary' => $baseDir . '/lib/twig/src/Node/Expression/Binary/LessEqualBinary.php',
77
- 'WCML\\Twig\\Node\\Expression\\Binary\\MatchesBinary' => $baseDir . '/lib/twig/src/Node/Expression/Binary/MatchesBinary.php',
78
- 'WCML\\Twig\\Node\\Expression\\Binary\\ModBinary' => $baseDir . '/lib/twig/src/Node/Expression/Binary/ModBinary.php',
79
- 'WCML\\Twig\\Node\\Expression\\Binary\\MulBinary' => $baseDir . '/lib/twig/src/Node/Expression/Binary/MulBinary.php',
80
- 'WCML\\Twig\\Node\\Expression\\Binary\\NotEqualBinary' => $baseDir . '/lib/twig/src/Node/Expression/Binary/NotEqualBinary.php',
81
- 'WCML\\Twig\\Node\\Expression\\Binary\\NotInBinary' => $baseDir . '/lib/twig/src/Node/Expression/Binary/NotInBinary.php',
82
- 'WCML\\Twig\\Node\\Expression\\Binary\\OrBinary' => $baseDir . '/lib/twig/src/Node/Expression/Binary/OrBinary.php',
83
- 'WCML\\Twig\\Node\\Expression\\Binary\\PowerBinary' => $baseDir . '/lib/twig/src/Node/Expression/Binary/PowerBinary.php',
84
- 'WCML\\Twig\\Node\\Expression\\Binary\\RangeBinary' => $baseDir . '/lib/twig/src/Node/Expression/Binary/RangeBinary.php',
85
- 'WCML\\Twig\\Node\\Expression\\Binary\\StartsWithBinary' => $baseDir . '/lib/twig/src/Node/Expression/Binary/StartsWithBinary.php',
86
- 'WCML\\Twig\\Node\\Expression\\Binary\\SubBinary' => $baseDir . '/lib/twig/src/Node/Expression/Binary/SubBinary.php',
87
- 'WCML\\Twig\\Node\\Expression\\BlockReferenceExpression' => $baseDir . '/lib/twig/src/Node/Expression/BlockReferenceExpression.php',
88
- 'WCML\\Twig\\Node\\Expression\\CallExpression' => $baseDir . '/lib/twig/src/Node/Expression/CallExpression.php',
89
- 'WCML\\Twig\\Node\\Expression\\ConditionalExpression' => $baseDir . '/lib/twig/src/Node/Expression/ConditionalExpression.php',
90
- 'WCML\\Twig\\Node\\Expression\\ConstantExpression' => $baseDir . '/lib/twig/src/Node/Expression/ConstantExpression.php',
91
- 'WCML\\Twig\\Node\\Expression\\FilterExpression' => $baseDir . '/lib/twig/src/Node/Expression/FilterExpression.php',
92
- 'WCML\\Twig\\Node\\Expression\\Filter\\DefaultFilter' => $baseDir . '/lib/twig/src/Node/Expression/Filter/DefaultFilter.php',
93
- 'WCML\\Twig\\Node\\Expression\\FunctionExpression' => $baseDir . '/lib/twig/src/Node/Expression/FunctionExpression.php',
94
- 'WCML\\Twig\\Node\\Expression\\GetAttrExpression' => $baseDir . '/lib/twig/src/Node/Expression/GetAttrExpression.php',
95
- 'WCML\\Twig\\Node\\Expression\\InlinePrint' => $baseDir . '/lib/twig/src/Node/Expression/InlinePrint.php',
96
- 'WCML\\Twig\\Node\\Expression\\MethodCallExpression' => $baseDir . '/lib/twig/src/Node/Expression/MethodCallExpression.php',
97
- 'WCML\\Twig\\Node\\Expression\\NameExpression' => $baseDir . '/lib/twig/src/Node/Expression/NameExpression.php',
98
- 'WCML\\Twig\\Node\\Expression\\NullCoalesceExpression' => $baseDir . '/lib/twig/src/Node/Expression/NullCoalesceExpression.php',
99
- 'WCML\\Twig\\Node\\Expression\\ParentExpression' => $baseDir . '/lib/twig/src/Node/Expression/ParentExpression.php',
100
- 'WCML\\Twig\\Node\\Expression\\TempNameExpression' => $baseDir . '/lib/twig/src/Node/Expression/TempNameExpression.php',
101
- 'WCML\\Twig\\Node\\Expression\\TestExpression' => $baseDir . '/lib/twig/src/Node/Expression/TestExpression.php',
102
- 'WCML\\Twig\\Node\\Expression\\Test\\ConstantTest' => $baseDir . '/lib/twig/src/Node/Expression/Test/ConstantTest.php',
103
- 'WCML\\Twig\\Node\\Expression\\Test\\DefinedTest' => $baseDir . '/lib/twig/src/Node/Expression/Test/DefinedTest.php',
104
- 'WCML\\Twig\\Node\\Expression\\Test\\DivisiblebyTest' => $baseDir . '/lib/twig/src/Node/Expression/Test/DivisiblebyTest.php',
105
- 'WCML\\Twig\\Node\\Expression\\Test\\EvenTest' => $baseDir . '/lib/twig/src/Node/Expression/Test/EvenTest.php',
106
- 'WCML\\Twig\\Node\\Expression\\Test\\NullTest' => $baseDir . '/lib/twig/src/Node/Expression/Test/NullTest.php',
107
- 'WCML\\Twig\\Node\\Expression\\Test\\OddTest' => $baseDir . '/lib/twig/src/Node/Expression/Test/OddTest.php',
108
- 'WCML\\Twig\\Node\\Expression\\Test\\SameasTest' => $baseDir . '/lib/twig/src/Node/Expression/Test/SameasTest.php',
109
- 'WCML\\Twig\\Node\\Expression\\Unary\\AbstractUnary' => $baseDir . '/lib/twig/src/Node/Expression/Unary/AbstractUnary.php',
110
- 'WCML\\Twig\\Node\\Expression\\Unary\\NegUnary' => $baseDir . '/lib/twig/src/Node/Expression/Unary/NegUnary.php',
111
- 'WCML\\Twig\\Node\\Expression\\Unary\\NotUnary' => $baseDir . '/lib/twig/src/Node/Expression/Unary/NotUnary.php',
112
- 'WCML\\Twig\\Node\\Expression\\Unary\\PosUnary' => $baseDir . '/lib/twig/src/Node/Expression/Unary/PosUnary.php',
113
- 'WCML\\Twig\\Node\\FlushNode' => $baseDir . '/lib/twig/src/Node/FlushNode.php',
114
- 'WCML\\Twig\\Node\\ForLoopNode' => $baseDir . '/lib/twig/src/Node/ForLoopNode.php',
115
- 'WCML\\Twig\\Node\\ForNode' => $baseDir . '/lib/twig/src/Node/ForNode.php',
116
- 'WCML\\Twig\\Node\\IfNode' => $baseDir . '/lib/twig/src/Node/IfNode.php',
117
- 'WCML\\Twig\\Node\\ImportNode' => $baseDir . '/lib/twig/src/Node/ImportNode.php',
118
- 'WCML\\Twig\\Node\\IncludeNode' => $baseDir . '/lib/twig/src/Node/IncludeNode.php',
119
- 'WCML\\Twig\\Node\\MacroNode' => $baseDir . '/lib/twig/src/Node/MacroNode.php',
120
- 'WCML\\Twig\\Node\\ModuleNode' => $baseDir . '/lib/twig/src/Node/ModuleNode.php',
121
- 'WCML\\Twig\\Node\\Node' => $baseDir . '/lib/twig/src/Node/Node.php',
122
- 'WCML\\Twig\\Node\\NodeCaptureInterface' => $baseDir . '/lib/twig/src/Node/NodeCaptureInterface.php',
123
- 'WCML\\Twig\\Node\\NodeOutputInterface' => $baseDir . '/lib/twig/src/Node/NodeOutputInterface.php',
124
- 'WCML\\Twig\\Node\\PrintNode' => $baseDir . '/lib/twig/src/Node/PrintNode.php',
125
- 'WCML\\Twig\\Node\\SandboxNode' => $baseDir . '/lib/twig/src/Node/SandboxNode.php',
126
- 'WCML\\Twig\\Node\\SandboxedPrintNode' => $baseDir . '/lib/twig/src/Node/SandboxedPrintNode.php',
127
- 'WCML\\Twig\\Node\\SetNode' => $baseDir . '/lib/twig/src/Node/SetNode.php',
128
- 'WCML\\Twig\\Node\\SetTempNode' => $baseDir . '/lib/twig/src/Node/SetTempNode.php',
129
- 'WCML\\Twig\\Node\\SpacelessNode' => $baseDir . '/lib/twig/src/Node/SpacelessNode.php',
130
- 'WCML\\Twig\\Node\\TextNode' => $baseDir . '/lib/twig/src/Node/TextNode.php',
131
- 'WCML\\Twig\\Node\\WithNode' => $baseDir . '/lib/twig/src/Node/WithNode.php',
132
- 'WCML\\Twig\\Parser' => $baseDir . '/lib/twig/src/Parser.php',
133
- 'WCML\\Twig\\Profiler\\Dumper\\BaseDumper' => $baseDir . '/lib/twig/src/Profiler/Dumper/BaseDumper.php',
134
- 'WCML\\Twig\\Profiler\\Dumper\\BlackfireDumper' => $baseDir . '/lib/twig/src/Profiler/Dumper/BlackfireDumper.php',
135
- 'WCML\\Twig\\Profiler\\Dumper\\HtmlDumper' => $baseDir . '/lib/twig/src/Profiler/Dumper/HtmlDumper.php',
136
- 'WCML\\Twig\\Profiler\\Dumper\\TextDumper' => $baseDir . '/lib/twig/src/Profiler/Dumper/TextDumper.php',
137
- 'WCML\\Twig\\Profiler\\NodeVisitor\\ProfilerNodeVisitor' => $baseDir . '/lib/twig/src/Profiler/NodeVisitor/ProfilerNodeVisitor.php',
138
- 'WCML\\Twig\\Profiler\\Node\\EnterProfileNode' => $baseDir . '/lib/twig/src/Profiler/Node/EnterProfileNode.php',
139
- 'WCML\\Twig\\Profiler\\Node\\LeaveProfileNode' => $baseDir . '/lib/twig/src/Profiler/Node/LeaveProfileNode.php',
140
- 'WCML\\Twig\\Profiler\\Profile' => $baseDir . '/lib/twig/src/Profiler/Profile.php',
141
- 'WCML\\Twig\\RuntimeLoader\\ContainerRuntimeLoader' => $baseDir . '/lib/twig/src/RuntimeLoader/ContainerRuntimeLoader.php',
142
- 'WCML\\Twig\\RuntimeLoader\\FactoryRuntimeLoader' => $baseDir . '/lib/twig/src/RuntimeLoader/FactoryRuntimeLoader.php',
143
- 'WCML\\Twig\\RuntimeLoader\\RuntimeLoaderInterface' => $baseDir . '/lib/twig/src/RuntimeLoader/RuntimeLoaderInterface.php',
144
- 'WCML\\Twig\\Sandbox\\SecurityError' => $baseDir . '/lib/twig/src/Sandbox/SecurityError.php',
145
- 'WCML\\Twig\\Sandbox\\SecurityNotAllowedFilterError' => $baseDir . '/lib/twig/src/Sandbox/SecurityNotAllowedFilterError.php',
146
- 'WCML\\Twig\\Sandbox\\SecurityNotAllowedFunctionError' => $baseDir . '/lib/twig/src/Sandbox/SecurityNotAllowedFunctionError.php',
147
- 'WCML\\Twig\\Sandbox\\SecurityNotAllowedMethodError' => $baseDir . '/lib/twig/src/Sandbox/SecurityNotAllowedMethodError.php',
148
- 'WCML\\Twig\\Sandbox\\SecurityNotAllowedPropertyError' => $baseDir . '/lib/twig/src/Sandbox/SecurityNotAllowedPropertyError.php',
149
- 'WCML\\Twig\\Sandbox\\SecurityNotAllowedTagError' => $baseDir . '/lib/twig/src/Sandbox/SecurityNotAllowedTagError.php',
150
- 'WCML\\Twig\\Sandbox\\SecurityPolicy' => $baseDir . '/lib/twig/src/Sandbox/SecurityPolicy.php',
151
- 'WCML\\Twig\\Sandbox\\SecurityPolicyInterface' => $baseDir . '/lib/twig/src/Sandbox/SecurityPolicyInterface.php',
152
- 'WCML\\Twig\\Source' => $baseDir . '/lib/twig/src/Source.php',
153
- 'WCML\\Twig\\Template' => $baseDir . '/lib/twig/src/Template.php',
154
- 'WCML\\Twig\\TemplateWrapper' => $baseDir . '/lib/twig/src/TemplateWrapper.php',
155
- 'WCML\\Twig\\Test\\IntegrationTestCase' => $baseDir . '/lib/twig/src/Test/IntegrationTestCase.php',
156
- 'WCML\\Twig\\Test\\NodeTestCase' => $baseDir . '/lib/twig/src/Test/NodeTestCase.php',
157
- 'WCML\\Twig\\Token' => $baseDir . '/lib/twig/src/Token.php',
158
- 'WCML\\Twig\\TokenParser\\AbstractTokenParser' => $baseDir . '/lib/twig/src/TokenParser/AbstractTokenParser.php',
159
- 'WCML\\Twig\\TokenParser\\ApplyTokenParser' => $baseDir . '/lib/twig/src/TokenParser/ApplyTokenParser.php',
160
- 'WCML\\Twig\\TokenParser\\AutoEscapeTokenParser' => $baseDir . '/lib/twig/src/TokenParser/AutoEscapeTokenParser.php',
161
- 'WCML\\Twig\\TokenParser\\BlockTokenParser' => $baseDir . '/lib/twig/src/TokenParser/BlockTokenParser.php',
162
- 'WCML\\Twig\\TokenParser\\DeprecatedTokenParser' => $baseDir . '/lib/twig/src/TokenParser/DeprecatedTokenParser.php',
163
- 'WCML\\Twig\\TokenParser\\DoTokenParser' => $baseDir . '/lib/twig/src/TokenParser/DoTokenParser.php',
164
- 'WCML\\Twig\\TokenParser\\EmbedTokenParser' => $baseDir . '/lib/twig/src/TokenParser/EmbedTokenParser.php',
165
- 'WCML\\Twig\\TokenParser\\ExtendsTokenParser' => $baseDir . '/lib/twig/src/TokenParser/ExtendsTokenParser.php',
166
- 'WCML\\Twig\\TokenParser\\FilterTokenParser' => $baseDir . '/lib/twig/src/TokenParser/FilterTokenParser.php',
167
- 'WCML\\Twig\\TokenParser\\FlushTokenParser' => $baseDir . '/lib/twig/src/TokenParser/FlushTokenParser.php',
168
- 'WCML\\Twig\\TokenParser\\ForTokenParser' => $baseDir . '/lib/twig/src/TokenParser/ForTokenParser.php',
169
- 'WCML\\Twig\\TokenParser\\FromTokenParser' => $baseDir . '/lib/twig/src/TokenParser/FromTokenParser.php',
170
- 'WCML\\Twig\\TokenParser\\IfTokenParser' => $baseDir . '/lib/twig/src/TokenParser/IfTokenParser.php',
171
- 'WCML\\Twig\\TokenParser\\ImportTokenParser' => $baseDir . '/lib/twig/src/TokenParser/ImportTokenParser.php',
172
- 'WCML\\Twig\\TokenParser\\IncludeTokenParser' => $baseDir . '/lib/twig/src/TokenParser/IncludeTokenParser.php',
173
- 'WCML\\Twig\\TokenParser\\MacroTokenParser' => $baseDir . '/lib/twig/src/TokenParser/MacroTokenParser.php',
174
- 'WCML\\Twig\\TokenParser\\SandboxTokenParser' => $baseDir . '/lib/twig/src/TokenParser/SandboxTokenParser.php',
175
- 'WCML\\Twig\\TokenParser\\SetTokenParser' => $baseDir . '/lib/twig/src/TokenParser/SetTokenParser.php',
176
- 'WCML\\Twig\\TokenParser\\SpacelessTokenParser' => $baseDir . '/lib/twig/src/TokenParser/SpacelessTokenParser.php',
177
- 'WCML\\Twig\\TokenParser\\TokenParserInterface' => $baseDir . '/lib/twig/src/TokenParser/TokenParserInterface.php',
178
- 'WCML\\Twig\\TokenParser\\UseTokenParser' => $baseDir . '/lib/twig/src/TokenParser/UseTokenParser.php',
179
- 'WCML\\Twig\\TokenParser\\WithTokenParser' => $baseDir . '/lib/twig/src/TokenParser/WithTokenParser.php',
180
- 'WCML\\Twig\\TokenStream' => $baseDir . '/lib/twig/src/TokenStream.php',
181
- 'WCML\\Twig\\TwigFilter' => $baseDir . '/lib/twig/src/TwigFilter.php',
182
- 'WCML\\Twig\\TwigFunction' => $baseDir . '/lib/twig/src/TwigFunction.php',
183
- 'WCML\\Twig\\TwigTest' => $baseDir . '/lib/twig/src/TwigTest.php',
184
- 'WCML\\Twig\\Util\\DeprecationCollector' => $baseDir . '/lib/twig/src/Util/DeprecationCollector.php',
185
- 'WCML\\Twig\\Util\\TemplateDirIterator' => $baseDir . '/lib/twig/src/Util/TemplateDirIterator.php',
186
- 'WCML\\Twig_Autoloader' => $baseDir . '/lib/twig/lib/Twig/Autoloader.php',
187
- 'WCML\\Twig_BaseNodeVisitor' => $baseDir . '/lib/twig/lib/Twig/BaseNodeVisitor.php',
188
- 'WCML\\Twig_CacheInterface' => $baseDir . '/lib/twig/lib/Twig/CacheInterface.php',
189
- 'WCML\\Twig_Cache_Filesystem' => $baseDir . '/lib/twig/lib/Twig/Cache/Filesystem.php',
190
- 'WCML\\Twig_Cache_Null' => $baseDir . '/lib/twig/lib/Twig/Cache/Null.php',
191
- 'WCML\\Twig_Compiler' => $baseDir . '/lib/twig/lib/Twig/Compiler.php',
192
- 'WCML\\Twig_CompilerInterface' => $baseDir . '/lib/twig/lib/Twig/CompilerInterface.php',
193
- 'WCML\\Twig_ContainerRuntimeLoader' => $baseDir . '/lib/twig/lib/Twig/ContainerRuntimeLoader.php',
194
- 'WCML\\Twig_Environment' => $baseDir . '/lib/twig/lib/Twig/Environment.php',
195
- 'WCML\\Twig_Error' => $baseDir . '/lib/twig/lib/Twig/Error.php',
196
- 'WCML\\Twig_Error_Loader' => $baseDir . '/lib/twig/lib/Twig/Error/Loader.php',
197
- 'WCML\\Twig_Error_Runtime' => $baseDir . '/lib/twig/lib/Twig/Error/Runtime.php',
198
- 'WCML\\Twig_Error_Syntax' => $baseDir . '/lib/twig/lib/Twig/Error/Syntax.php',
199
- 'WCML\\Twig_ExistsLoaderInterface' => $baseDir . '/lib/twig/lib/Twig/ExistsLoaderInterface.php',
200
- 'WCML\\Twig_ExpressionParser' => $baseDir . '/lib/twig/lib/Twig/ExpressionParser.php',
201
- 'WCML\\Twig_Extension' => $baseDir . '/lib/twig/lib/Twig/Extension.php',
202
- 'WCML\\Twig_ExtensionInterface' => $baseDir . '/lib/twig/lib/Twig/ExtensionInterface.php',
203
- 'WCML\\Twig_Extension_Core' => $baseDir . '/lib/twig/lib/Twig/Extension/Core.php',
204
- 'WCML\\Twig_Extension_Debug' => $baseDir . '/lib/twig/lib/Twig/Extension/Debug.php',
205
- 'WCML\\Twig_Extension_Escaper' => $baseDir . '/lib/twig/lib/Twig/Extension/Escaper.php',
206
- 'WCML\\Twig_Extension_GlobalsInterface' => $baseDir . '/lib/twig/lib/Twig/Extension/GlobalsInterface.php',
207
- 'WCML\\Twig_Extension_InitRuntimeInterface' => $baseDir . '/lib/twig/lib/Twig/Extension/InitRuntimeInterface.php',
208
- 'WCML\\Twig_Extension_Optimizer' => $baseDir . '/lib/twig/lib/Twig/Extension/Optimizer.php',
209
- 'WCML\\Twig_Extension_Profiler' => $baseDir . '/lib/twig/lib/Twig/Extension/Profiler.php',
210
- 'WCML\\Twig_Extension_Sandbox' => $baseDir . '/lib/twig/lib/Twig/Extension/Sandbox.php',
211
- 'WCML\\Twig_Extension_Staging' => $baseDir . '/lib/twig/lib/Twig/Extension/Staging.php',
212
- 'WCML\\Twig_Extension_StringLoader' => $baseDir . '/lib/twig/lib/Twig/Extension/StringLoader.php',
213
- 'WCML\\Twig_FactoryRuntimeLoader' => $baseDir . '/lib/twig/lib/Twig/FactoryRuntimeLoader.php',
214
- 'WCML\\Twig_FileExtensionEscapingStrategy' => $baseDir . '/lib/twig/lib/Twig/FileExtensionEscapingStrategy.php',
215
- 'WCML\\Twig_Filter' => $baseDir . '/lib/twig/lib/Twig/Filter.php',
216
- 'WCML\\Twig_FilterCallableInterface' => $baseDir . '/lib/twig/lib/Twig/FilterCallableInterface.php',
217
- 'WCML\\Twig_FilterInterface' => $baseDir . '/lib/twig/lib/Twig/FilterInterface.php',
218
- 'WCML\\Twig_Filter_Function' => $baseDir . '/lib/twig/lib/Twig/Filter/Function.php',
219
- 'WCML\\Twig_Filter_Method' => $baseDir . '/lib/twig/lib/Twig/Filter/Method.php',
220
- 'WCML\\Twig_Filter_Node' => $baseDir . '/lib/twig/lib/Twig/Filter/Node.php',
221
- 'WCML\\Twig_Function' => $baseDir . '/lib/twig/lib/Twig/Function.php',
222
- 'WCML\\Twig_FunctionCallableInterface' => $baseDir . '/lib/twig/lib/Twig/FunctionCallableInterface.php',
223
- 'WCML\\Twig_FunctionInterface' => $baseDir . '/lib/twig/lib/Twig/FunctionInterface.php',
224
- 'WCML\\Twig_Function_Function' => $baseDir . '/lib/twig/lib/Twig/Function/Function.php',
225
- 'WCML\\Twig_Function_Method' => $baseDir . '/lib/twig/lib/Twig/Function/Method.php',
226
- 'WCML\\Twig_Function_Node' => $baseDir . '/lib/twig/lib/Twig/Function/Node.php',
227
- 'WCML\\Twig_Lexer' => $baseDir . '/lib/twig/lib/Twig/Lexer.php',
228
- 'WCML\\Twig_LexerInterface' => $baseDir . '/lib/twig/lib/Twig/LexerInterface.php',
229
- 'WCML\\Twig_LoaderInterface' => $baseDir . '/lib/twig/lib/Twig/LoaderInterface.php',
230
- 'WCML\\Twig_Loader_Array' => $baseDir . '/lib/twig/lib/Twig/Loader/Array.php',
231
- 'WCML\\Twig_Loader_Chain' => $baseDir . '/lib/twig/lib/Twig/Loader/Chain.php',
232
- 'WCML\\Twig_Loader_Filesystem' => $baseDir . '/lib/twig/lib/Twig/Loader/Filesystem.php',
233
- 'WCML\\Twig_Loader_String' => $baseDir . '/lib/twig/lib/Twig/Loader/String.php',
234
- 'WCML\\Twig_Markup' => $baseDir . '/lib/twig/lib/Twig/Markup.php',
235
- 'WCML\\Twig_Node' => $baseDir . '/lib/twig/lib/Twig/Node.php',
236
- 'WCML\\Twig_NodeCaptureInterface' => $baseDir . '/lib/twig/lib/Twig/NodeCaptureInterface.php',
237
- 'WCML\\Twig_NodeInterface' => $baseDir . '/lib/twig/lib/Twig/NodeInterface.php',
238
- 'WCML\\Twig_NodeOutputInterface' => $baseDir . '/lib/twig/lib/Twig/NodeOutputInterface.php',
239
- 'WCML\\Twig_NodeTraverser' => $baseDir . '/lib/twig/lib/Twig/NodeTraverser.php',
240
- 'WCML\\Twig_NodeVisitorInterface' => $baseDir . '/lib/twig/lib/Twig/NodeVisitorInterface.php',
241
- 'WCML\\Twig_NodeVisitor_Escaper' => $baseDir . '/lib/twig/lib/Twig/NodeVisitor/Escaper.php',
242
- 'WCML\\Twig_NodeVisitor_Optimizer' => $baseDir . '/lib/twig/lib/Twig/NodeVisitor/Optimizer.php',
243
- 'WCML\\Twig_NodeVisitor_SafeAnalysis' => $baseDir . '/lib/twig/lib/Twig/NodeVisitor/SafeAnalysis.php',
244
- 'WCML\\Twig_NodeVisitor_Sandbox' => $baseDir . '/lib/twig/lib/Twig/NodeVisitor/Sandbox.php',
245
- 'WCML\\Twig_Node_AutoEscape' => $baseDir . '/lib/twig/lib/Twig/Node/AutoEscape.php',
246
- 'WCML\\Twig_Node_Block' => $baseDir . '/lib/twig/lib/Twig/Node/Block.php',
247
- 'WCML\\Twig_Node_BlockReference' => $baseDir . '/lib/twig/lib/Twig/Node/BlockReference.php',
248
- 'WCML\\Twig_Node_Body' => $baseDir . '/lib/twig/lib/Twig/Node/Body.php',
249
- 'WCML\\Twig_Node_CheckSecurity' => $baseDir . '/lib/twig/lib/Twig/Node/CheckSecurity.php',
250
- 'WCML\\Twig_Node_Deprecated' => $baseDir . '/lib/twig/lib/Twig/Node/Deprecated.php',
251
- 'WCML\\Twig_Node_Do' => $baseDir . '/lib/twig/lib/Twig/Node/Do.php',
252
- 'WCML\\Twig_Node_Embed' => $baseDir . '/lib/twig/lib/Twig/Node/Embed.php',
253
- 'WCML\\Twig_Node_Expression' => $baseDir . '/lib/twig/lib/Twig/Node/Expression.php',
254
- 'WCML\\Twig_Node_Expression_Array' => $baseDir . '/lib/twig/lib/Twig/Node/Expression/Array.php',
255
- 'WCML\\Twig_Node_Expression_AssignName' => $baseDir . '/lib/twig/lib/Twig/Node/Expression/AssignName.php',
256
- 'WCML\\Twig_Node_Expression_Binary' => $baseDir . '/lib/twig/lib/Twig/Node/Expression/Binary.php',
257
- 'WCML\\Twig_Node_Expression_Binary_Add' => $baseDir . '/lib/twig/lib/Twig/Node/Expression/Binary/Add.php',
258
- 'WCML\\Twig_Node_Expression_Binary_And' => $baseDir . '/lib/twig/lib/Twig/Node/Expression/Binary/And.php',
259
- 'WCML\\Twig_Node_Expression_Binary_BitwiseAnd' => $baseDir . '/lib/twig/lib/Twig/Node/Expression/Binary/BitwiseAnd.php',
260
- 'WCML\\Twig_Node_Expression_Binary_BitwiseOr' => $baseDir . '/lib/twig/lib/Twig/Node/Expression/Binary/BitwiseOr.php',
261
- 'WCML\\Twig_Node_Expression_Binary_BitwiseXor' => $baseDir . '/lib/twig/lib/Twig/Node/Expression/Binary/BitwiseXor.php',
262
- 'WCML\\Twig_Node_Expression_Binary_Concat' => $baseDir . '/lib/twig/lib/Twig/Node/Expression/Binary/Concat.php',
263
- 'WCML\\Twig_Node_Expression_Binary_Div' => $baseDir . '/lib/twig/lib/Twig/Node/Expression/Binary/Div.php',
264
- 'WCML\\Twig_Node_Expression_Binary_EndsWith' => $baseDir . '/lib/twig/lib/Twig/Node/Expression/Binary/EndsWith.php',
265
- 'WCML\\Twig_Node_Expression_Binary_Equal' => $baseDir . '/lib/twig/lib/Twig/Node/Expression/Binary/Equal.php',
266
- 'WCML\\Twig_Node_Expression_Binary_FloorDiv' => $baseDir . '/lib/twig/lib/Twig/Node/Expression/Binary/FloorDiv.php',
267
- 'WCML\\Twig_Node_Expression_Binary_Greater' => $baseDir . '/lib/twig/lib/Twig/Node/Expression/Binary/Greater.php',
268
- 'WCML\\Twig_Node_Expression_Binary_GreaterEqual' => $baseDir . '/lib/twig/lib/Twig/Node/Expression/Binary/GreaterEqual.php',
269
- 'WCML\\Twig_Node_Expression_Binary_In' => $baseDir . '/lib/twig/lib/Twig/Node/Expression/Binary/In.php',
270
- 'WCML\\Twig_Node_Expression_Binary_Less' => $baseDir . '/lib/twig/lib/Twig/Node/Expression/Binary/Less.php',
271
- 'WCML\\Twig_Node_Expression_Binary_LessEqual' => $baseDir . '/lib/twig/lib/Twig/Node/Expression/Binary/LessEqual.php',
272
- 'WCML\\Twig_Node_Expression_Binary_Matches' => $baseDir . '/lib/twig/lib/Twig/Node/Expression/Binary/Matches.php',
273
- 'WCML\\Twig_Node_Expression_Binary_Mod' => $baseDir . '/lib/twig/lib/Twig/Node/Expression/Binary/Mod.php',
274
- 'WCML\\Twig_Node_Expression_Binary_Mul' => $baseDir . '/lib/twig/lib/Twig/Node/Expression/Binary/Mul.php',
275
- 'WCML\\Twig_Node_Expression_Binary_NotEqual' => $baseDir . '/lib/twig/lib/Twig/Node/Expression/Binary/NotEqual.php',
276
- 'WCML\\Twig_Node_Expression_Binary_NotIn' => $baseDir . '/lib/twig/lib/Twig/Node/Expression/Binary/NotIn.php',
277
- 'WCML\\Twig_Node_Expression_Binary_Or' => $baseDir . '/lib/twig/lib/Twig/Node/Expression/Binary/Or.php',
278
- 'WCML\\Twig_Node_Expression_Binary_Power' => $baseDir . '/lib/twig/lib/Twig/Node/Expression/Binary/Power.php',
279
- 'WCML\\Twig_Node_Expression_Binary_Range' => $baseDir . '/lib/twig/lib/Twig/Node/Expression/Binary/Range.php',
280
- 'WCML\\Twig_Node_Expression_Binary_StartsWith' => $baseDir . '/lib/twig/lib/Twig/Node/Expression/Binary/StartsWith.php',
281
- 'WCML\\Twig_Node_Expression_Binary_Sub' => $baseDir . '/lib/twig/lib/Twig/Node/Expression/Binary/Sub.php',
282
- 'WCML\\Twig_Node_Expression_BlockReference' => $baseDir . '/lib/twig/lib/Twig/Node/Expression/BlockReference.php',
283
- 'WCML\\Twig_Node_Expression_Call' => $baseDir . '/lib/twig/lib/Twig/Node/Expression/Call.php',
284
- 'WCML\\Twig_Node_Expression_Conditional' => $baseDir . '/lib/twig/lib/Twig/Node/Expression/Conditional.php',
285
- 'WCML\\Twig_Node_Expression_Constant' => $baseDir . '/lib/twig/lib/Twig/Node/Expression/Constant.php',
286
- 'WCML\\Twig_Node_Expression_ExtensionReference' => $baseDir . '/lib/twig/lib/Twig/Node/Expression/ExtensionReference.php',
287
- 'WCML\\Twig_Node_Expression_Filter' => $baseDir . '/lib/twig/lib/Twig/Node/Expression/Filter.php',
288
- 'WCML\\Twig_Node_Expression_Filter_Default' => $baseDir . '/lib/twig/lib/Twig/Node/Expression/Filter/Default.php',
289
- 'WCML\\Twig_Node_Expression_Function' => $baseDir . '/lib/twig/lib/Twig/Node/Expression/Function.php',
290
- 'WCML\\Twig_Node_Expression_GetAttr' => $baseDir . '/lib/twig/lib/Twig/Node/Expression/GetAttr.php',
291
- 'WCML\\Twig_Node_Expression_MethodCall' => $baseDir . '/lib/twig/lib/Twig/Node/Expression/MethodCall.php',
292
- 'WCML\\Twig_Node_Expression_Name' => $baseDir . '/lib/twig/lib/Twig/Node/Expression/Name.php',
293
- 'WCML\\Twig_Node_Expression_NullCoalesce' => $baseDir . '/lib/twig/lib/Twig/Node/Expression/NullCoalesce.php',
294
- 'WCML\\Twig_Node_Expression_Parent' => $baseDir . '/lib/twig/lib/Twig/Node/Expression/Parent.php',
295
- 'WCML\\Twig_Node_Expression_TempName' => $baseDir . '/lib/twig/lib/Twig/Node/Expression/TempName.php',
296
- 'WCML\\Twig_Node_Expression_Test' => $baseDir . '/lib/twig/lib/Twig/Node/Expression/Test.php',
297
- 'WCML\\Twig_Node_Expression_Test_Constant' => $baseDir . '/lib/twig/lib/Twig/Node/Expression/Test/Constant.php',
298
- 'WCML\\Twig_Node_Expression_Test_Defined' => $baseDir . '/lib/twig/lib/Twig/Node/Expression/Test/Defined.php',
299
- 'WCML\\Twig_Node_Expression_Test_Divisibleby' => $baseDir . '/lib/twig/lib/Twig/Node/Expression/Test/Divisibleby.php',
300
- 'WCML\\Twig_Node_Expression_Test_Even' => $baseDir . '/lib/twig/lib/Twig/Node/Expression/Test/Even.php',
301
- 'WCML\\Twig_Node_Expression_Test_Null' => $baseDir . '/lib/twig/lib/Twig/Node/Expression/Test/Null.php',
302
- 'WCML\\Twig_Node_Expression_Test_Odd' => $baseDir . '/lib/twig/lib/Twig/Node/Expression/Test/Odd.php',
303
- 'WCML\\Twig_Node_Expression_Test_Sameas' => $baseDir . '/lib/twig/lib/Twig/Node/Expression/Test/Sameas.php',
304
- 'WCML\\Twig_Node_Expression_Unary' => $baseDir . '/lib/twig/lib/Twig/Node/Expression/Unary.php',
305
- 'WCML\\Twig_Node_Expression_Unary_Neg' => $baseDir . '/lib/twig/lib/Twig/Node/Expression/Unary/Neg.php',
306
- 'WCML\\Twig_Node_Expression_Unary_Not' => $baseDir . '/lib/twig/lib/Twig/Node/Expression/Unary/Not.php',
307
- 'WCML\\Twig_Node_Expression_Unary_Pos' => $baseDir . '/lib/twig/lib/Twig/Node/Expression/Unary/Pos.php',
308
- 'WCML\\Twig_Node_Flush' => $baseDir . '/lib/twig/lib/Twig/Node/Flush.php',
309
- 'WCML\\Twig_Node_For' => $baseDir . '/lib/twig/lib/Twig/Node/For.php',
310
- 'WCML\\Twig_Node_ForLoop' => $baseDir . '/lib/twig/lib/Twig/Node/ForLoop.php',
311
- 'WCML\\Twig_Node_If' => $baseDir . '/lib/twig/lib/Twig/Node/If.php',
312
- 'WCML\\Twig_Node_Import' => $baseDir . '/lib/twig/lib/Twig/Node/Import.php',
313
- 'WCML\\Twig_Node_Include' => $baseDir . '/lib/twig/lib/Twig/Node/Include.php',
314
- 'WCML\\Twig_Node_Macro' => $baseDir . '/lib/twig/lib/Twig/Node/Macro.php',
315
- 'WCML\\Twig_Node_Module' => $baseDir . '/lib/twig/lib/Twig/Node/Module.php',
316
- 'WCML\\Twig_Node_Print' => $baseDir . '/lib/twig/lib/Twig/Node/Print.php',
317
- 'WCML\\Twig_Node_Sandbox' => $baseDir . '/lib/twig/lib/Twig/Node/Sandbox.php',
318
- 'WCML\\Twig_Node_SandboxedPrint' => $baseDir . '/lib/twig/lib/Twig/Node/SandboxedPrint.php',
319
- 'WCML\\Twig_Node_Set' => $baseDir . '/lib/twig/lib/Twig/Node/Set.php',
320
- 'WCML\\Twig_Node_SetTemp' => $baseDir . '/lib/twig/lib/Twig/Node/SetTemp.php',
321
- 'WCML\\Twig_Node_Spaceless' => $baseDir . '/lib/twig/lib/Twig/Node/Spaceless.php',
322
- 'WCML\\Twig_Node_Text' => $baseDir . '/lib/twig/lib/Twig/Node/Text.php',
323
- 'WCML\\Twig_Node_With' => $baseDir . '/lib/twig/lib/Twig/Node/With.php',
324
- 'WCML\\Twig_Parser' => $baseDir . '/lib/twig/lib/Twig/Parser.php',
325
- 'WCML\\Twig_ParserInterface' => $baseDir . '/lib/twig/lib/Twig/ParserInterface.php',
326
- 'WCML\\Twig_Profiler_Dumper_Base' => $baseDir . '/lib/twig/lib/Twig/Profiler/Dumper/Base.php',
327
- 'WCML\\Twig_Profiler_Dumper_Blackfire' => $baseDir . '/lib/twig/lib/Twig/Profiler/Dumper/Blackfire.php',
328
- 'WCML\\Twig_Profiler_Dumper_Html' => $baseDir . '/lib/twig/lib/Twig/Profiler/Dumper/Html.php',
329
- 'WCML\\Twig_Profiler_Dumper_Text' => $baseDir . '/lib/twig/lib/Twig/Profiler/Dumper/Text.php',
330
- 'WCML\\Twig_Profiler_NodeVisitor_Profiler' => $baseDir . '/lib/twig/lib/Twig/Profiler/NodeVisitor/Profiler.php',
331
- 'WCML\\Twig_Profiler_Node_EnterProfile' => $baseDir . '/lib/twig/lib/Twig/Profiler/Node/EnterProfile.php',
332
- 'WCML\\Twig_Profiler_Node_LeaveProfile' => $baseDir . '/lib/twig/lib/Twig/Profiler/Node/LeaveProfile.php',
333
- 'WCML\\Twig_Profiler_Profile' => $baseDir . '/lib/twig/lib/Twig/Profiler/Profile.php',
334
- 'WCML\\Twig_RuntimeLoaderInterface' => $baseDir . '/lib/twig/lib/Twig/RuntimeLoaderInterface.php',
335
- 'WCML\\Twig_Sandbox_SecurityError' => $baseDir . '/lib/twig/lib/Twig/Sandbox/SecurityError.php',
336
- 'WCML\\Twig_Sandbox_SecurityNotAllowedFilterError' => $baseDir . '/lib/twig/lib/Twig/Sandbox/SecurityNotAllowedFilterError.php',
337
- 'WCML\\Twig_Sandbox_SecurityNotAllowedFunctionError' => $baseDir . '/lib/twig/lib/Twig/Sandbox/SecurityNotAllowedFunctionError.php',
338
- 'WCML\\Twig_Sandbox_SecurityNotAllowedMethodError' => $baseDir . '/lib/twig/lib/Twig/Sandbox/SecurityNotAllowedMethodError.php',
339
- 'WCML\\Twig_Sandbox_SecurityNotAllowedPropertyError' => $baseDir . '/lib/twig/lib/Twig/Sandbox/SecurityNotAllowedPropertyError.php',
340
- 'WCML\\Twig_Sandbox_SecurityNotAllowedTagError' => $baseDir . '/lib/twig/lib/Twig/Sandbox/SecurityNotAllowedTagError.php',
341
- 'WCML\\Twig_Sandbox_SecurityPolicy' => $baseDir . '/lib/twig/lib/Twig/Sandbox/SecurityPolicy.php',
342
- 'WCML\\Twig_Sandbox_SecurityPolicyInterface' => $baseDir . '/lib/twig/lib/Twig/Sandbox/SecurityPolicyInterface.php',
343
- 'WCML\\Twig_SimpleFilter' => $baseDir . '/lib/twig/lib/Twig/SimpleFilter.php',
344
- 'WCML\\Twig_SimpleFunction' => $baseDir . '/lib/twig/lib/Twig/SimpleFunction.php',
345
- 'WCML\\Twig_SimpleTest' => $baseDir . '/lib/twig/lib/Twig/SimpleTest.php',
346
- 'WCML\\Twig_Source' => $baseDir . '/lib/twig/lib/Twig/Source.php',
347
- 'WCML\\Twig_SourceContextLoaderInterface' => $baseDir . '/lib/twig/lib/Twig/SourceContextLoaderInterface.php',
348
- 'WCML\\Twig_Template' => $baseDir . '/lib/twig/lib/Twig/Template.php',
349
- 'WCML\\Twig_TemplateInterface' => $baseDir . '/lib/twig/lib/Twig/TemplateInterface.php',
350
- 'WCML\\Twig_TemplateWrapper' => $baseDir . '/lib/twig/lib/Twig/TemplateWrapper.php',
351
- 'WCML\\Twig_Test' => $baseDir . '/lib/twig/lib/Twig/Test.php',
352
- 'WCML\\Twig_TestCallableInterface' => $baseDir . '/lib/twig/lib/Twig/TestCallableInterface.php',
353
- 'WCML\\Twig_TestInterface' => $baseDir . '/lib/twig/lib/Twig/TestInterface.php',
354
- 'WCML\\Twig_Test_Function' => $baseDir . '/lib/twig/lib/Twig/Test/Function.php',
355
- 'WCML\\Twig_Test_IntegrationTestCase' => $baseDir . '/lib/twig/lib/Twig/Test/IntegrationTestCase.php',
356
- 'WCML\\Twig_Test_Method' => $baseDir . '/lib/twig/lib/Twig/Test/Method.php',
357
- 'WCML\\Twig_Test_Node' => $baseDir . '/lib/twig/lib/Twig/Test/Node.php',
358
- 'WCML\\Twig_Test_NodeTestCase' => $baseDir . '/lib/twig/lib/Twig/Test/NodeTestCase.php',
359
- 'WCML\\Twig_Token' => $baseDir . '/lib/twig/lib/Twig/Token.php',
360
- 'WCML\\Twig_TokenParser' => $baseDir . '/lib/twig/lib/Twig/TokenParser.php',
361
- 'WCML\\Twig_TokenParserBroker' => $baseDir . '/lib/twig/lib/Twig/TokenParserBroker.php',
362
- 'WCML\\Twig_TokenParserBrokerInterface' => $baseDir . '/lib/twig/lib/Twig/TokenParserBrokerInterface.php',
363
- 'WCML\\Twig_TokenParserInterface' => $baseDir . '/lib/twig/lib/Twig/TokenParserInterface.php',
364
- 'WCML\\Twig_TokenParser_AutoEscape' => $baseDir . '/lib/twig/lib/Twig/TokenParser/AutoEscape.php',
365
- 'WCML\\Twig_TokenParser_Block' => $baseDir . '/lib/twig/lib/Twig/TokenParser/Block.php',
366
- 'WCML\\Twig_TokenParser_Deprecated' => $baseDir . '/lib/twig/lib/Twig/TokenParser/Deprecated.php',
367
- 'WCML\\Twig_TokenParser_Do' => $baseDir . '/lib/twig/lib/Twig/TokenParser/Do.php',
368
- 'WCML\\Twig_TokenParser_Embed' => $baseDir . '/lib/twig/lib/Twig/TokenParser/Embed.php',
369
- 'WCML\\Twig_TokenParser_Extends' => $baseDir . '/lib/twig/lib/Twig/TokenParser/Extends.php',
370
- 'WCML\\Twig_TokenParser_Filter' => $baseDir . '/lib/twig/lib/Twig/TokenParser/Filter.php',
371
- 'WCML\\Twig_TokenParser_Flush' => $baseDir . '/lib/twig/lib/Twig/TokenParser/Flush.php',
372
- 'WCML\\Twig_TokenParser_For' => $baseDir . '/lib/twig/lib/Twig/TokenParser/For.php',
373
- 'WCML\\Twig_TokenParser_From' => $baseDir . '/lib/twig/lib/Twig/TokenParser/From.php',
374
- 'WCML\\Twig_TokenParser_If' => $baseDir . '/lib/twig/lib/Twig/TokenParser/If.php',
375
- 'WCML\\Twig_TokenParser_Import' => $baseDir . '/lib/twig/lib/Twig/TokenParser/Import.php',
376
- 'WCML\\Twig_TokenParser_Include' => $baseDir . '/lib/twig/lib/Twig/TokenParser/Include.php',
377
- 'WCML\\Twig_TokenParser_Macro' => $baseDir . '/lib/twig/lib/Twig/TokenParser/Macro.php',
378
- 'WCML\\Twig_TokenParser_Sandbox' => $baseDir . '/lib/twig/lib/Twig/TokenParser/Sandbox.php',
379
- 'WCML\\Twig_TokenParser_Set' => $baseDir . '/lib/twig/lib/Twig/TokenParser/Set.php',
380
- 'WCML\\Twig_TokenParser_Spaceless' => $baseDir . '/lib/twig/lib/Twig/TokenParser/Spaceless.php',
381
- 'WCML\\Twig_TokenParser_Use' => $baseDir . '/lib/twig/lib/Twig/TokenParser/Use.php',
382
- 'WCML\\Twig_TokenParser_With' => $baseDir . '/lib/twig/lib/Twig/TokenParser/With.php',
383
- 'WCML\\Twig_TokenStream' => $baseDir . '/lib/twig/lib/Twig/TokenStream.php',
384
- 'WCML\\Twig_Util_DeprecationCollector' => $baseDir . '/lib/twig/lib/Twig/Util/DeprecationCollector.php',
385
- 'WCML\\Twig_Util_TemplateDirIterator' => $baseDir . '/lib/twig/lib/Twig/Util/TemplateDirIterator.php',
386
  'WCML_ATE_Activate_Synchronization' => $baseDir . '/classes/ate/class-wcml-ate-activate-synchronization.php',
387
  'WCML_Accommodation_Bookings' => $baseDir . '/compatibility/class-wcml-accommodation-bookings.php',
388
  'WCML_Admin_Cookie' => $baseDir . '/classes/class-wcml-admin-cookie.php',
@@ -451,7 +79,6 @@ return array(
451
  'WCML_LiteSpeed_Cache' => $baseDir . '/compatibility/class-wcml-litespeed-cache.php',
452
  'WCML_Locale' => $baseDir . '/inc/class-wcml-locale.php',
453
  'WCML_MaxStore' => $baseDir . '/compatibility/class-wcml-maxstore.php',
454
- 'WCML_Media' => $baseDir . '/inc/class-wcml-media.php',
455
  'WCML_Menus_Wrap' => $baseDir . '/inc/template-classes/class-wcml-menus-wrap.php',
456
  'WCML_Mix_and_Match_Products' => $baseDir . '/compatibility/class-wcml-mix-and-match-products.php',
457
  'WCML_Multi_Currency' => $baseDir . '/inc/currencies/class-wcml-multi-currency.php',
@@ -467,6 +94,7 @@ return array(
467
  'WCML_Multi_Currency_UI' => $baseDir . '/inc/template-classes/multi-currency/class-wcml-multi-currency-ui.php',
468
  'WCML_Not_Supported_Payment_Gateway' => $baseDir . '/classes/multi-currency/payment-gateways/class-wcml-not-supported-payment-gateway.php',
469
  'WCML_Not_Translatable_Attributes' => $baseDir . '/inc/template-classes/class-wcml-not-translatable-attributes.php',
 
470
  'WCML_Orders' => $baseDir . '/inc/class-wcml-orders.php',
471
  'WCML_Page_Builders' => $baseDir . '/inc/translation-editor/class-wcml-page-builders.php',
472
  'WCML_Payment_Gateway' => $baseDir . '/classes/multi-currency/payment-gateways/class-wcml-payment-gateway.php',
@@ -484,6 +112,7 @@ return array(
484
  'WCML_Privacy_Content_Factory' => $baseDir . '/classes/privacy/class-wcml-privacy-content-factory.php',
485
  'WCML_Product_Addons' => $baseDir . '/compatibility/class-wcml-product-addons.php',
486
  'WCML_Product_Bundles' => $baseDir . '/compatibility/class-wcml-product-bundles.php',
 
487
  'WCML_Product_Gallery_Filter' => $baseDir . '/classes/media/class-wcml-product-gallery-filter.php',
488
  'WCML_Product_Gallery_Filter_Factory' => $baseDir . '/classes/media/class-wcml-product-gallery-filter-factory.php',
489
  'WCML_Product_Image_Filter' => $baseDir . '/classes/media/class-wcml-product-image-filter.php',
@@ -569,6 +198,7 @@ return array(
569
  'WCML_WPSEO' => $baseDir . '/compatibility/class-wcml-wpseo.php',
570
  'WCML_Widgets' => $baseDir . '/inc/class-wcml-widgets.php',
571
  'WCML_Woo_Var_Table' => $baseDir . '/compatibility/class-wcml-woo-var-table.php',
 
572
  'WCML_WpFastest_Cache' => $baseDir . '/compatibility/class-wcml-wpfastest-cache.php',
573
  'WCML_Wpb_Vc' => $baseDir . '/compatibility/class-wcml-wpb-vc.php',
574
  'WCML_YIKES_Custom_Product_Tabs_Pro' => $baseDir . '/compatibility/class-wcml-yikes-custom-product-tabs-pro.php',
@@ -576,6 +206,7 @@ return array(
576
  'WCML_gravityforms' => $baseDir . '/compatibility/class-wcml-gravityforms.php',
577
  'WCML_wcExporter' => $baseDir . '/compatibility/class-wcml-wcexporter.php',
578
  'WCML_xDomain_Data' => $baseDir . '/classes/urls/class-wcml-xdomain-data.php',
 
579
  'WPML_Core_Version_Check' => $vendorDir . '/wpml-shared/wpml-lib-dependencies/src/dependencies/class-wpml-core-version-check.php',
580
  'WPML_Dependencies' => $vendorDir . '/wpml-shared/wpml-lib-dependencies/src/dependencies/class-wpml-dependencies.php',
581
  'WPML_PHP_Version_Check' => $vendorDir . '/wpml-shared/wpml-lib-dependencies/src/dependencies/class-wpml-php-version-check.php',
6
  $baseDir = dirname($vendorDir);
7
 
8
  return array(
9
+ 'WCML\\Media\\Wrapper\\Factory' => $baseDir . '/classes/media/Wrapper/Factory.php',
10
+ 'WCML\\Media\\Wrapper\\IMedia' => $baseDir . '/classes/media/Wrapper/IMedia.php',
11
+ 'WCML\\Media\\Wrapper\\NonTranslatable' => $baseDir . '/classes/media/Wrapper/NonTranslatable.php',
12
+ 'WCML\\Media\\Wrapper\\Translatable' => $baseDir . '/classes/media/Wrapper/Translatable.php',
13
+ 'WCML\\RewriteRules\\Hooks' => $baseDir . '/classes/RewriteRules/Hooks.php',
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
14
  'WCML_ATE_Activate_Synchronization' => $baseDir . '/classes/ate/class-wcml-ate-activate-synchronization.php',
15
  'WCML_Accommodation_Bookings' => $baseDir . '/compatibility/class-wcml-accommodation-bookings.php',
16
  'WCML_Admin_Cookie' => $baseDir . '/classes/class-wcml-admin-cookie.php',
79
  'WCML_LiteSpeed_Cache' => $baseDir . '/compatibility/class-wcml-litespeed-cache.php',
80
  'WCML_Locale' => $baseDir . '/inc/class-wcml-locale.php',
81
  'WCML_MaxStore' => $baseDir . '/compatibility/class-wcml-maxstore.php',
 
82
  'WCML_Menus_Wrap' => $baseDir . '/inc/template-classes/class-wcml-menus-wrap.php',
83
  'WCML_Mix_and_Match_Products' => $baseDir . '/compatibility/class-wcml-mix-and-match-products.php',
84
  'WCML_Multi_Currency' => $baseDir . '/inc/currencies/class-wcml-multi-currency.php',
94
  'WCML_Multi_Currency_UI' => $baseDir . '/inc/template-classes/multi-currency/class-wcml-multi-currency-ui.php',
95
  'WCML_Not_Supported_Payment_Gateway' => $baseDir . '/classes/multi-currency/payment-gateways/class-wcml-not-supported-payment-gateway.php',
96
  'WCML_Not_Translatable_Attributes' => $baseDir . '/inc/template-classes/class-wcml-not-translatable-attributes.php',
97
+ 'WCML_Order_Status_Manager' => $baseDir . '/compatibility/class-wcml-order-status-manager.php',
98
  'WCML_Orders' => $baseDir . '/inc/class-wcml-orders.php',
99
  'WCML_Page_Builders' => $baseDir . '/inc/translation-editor/class-wcml-page-builders.php',
100
  'WCML_Payment_Gateway' => $baseDir . '/classes/multi-currency/payment-gateways/class-wcml-payment-gateway.php',
112
  'WCML_Privacy_Content_Factory' => $baseDir . '/classes/privacy/class-wcml-privacy-content-factory.php',
113
  'WCML_Product_Addons' => $baseDir . '/compatibility/class-wcml-product-addons.php',
114
  'WCML_Product_Bundles' => $baseDir . '/compatibility/class-wcml-product-bundles.php',
115
+ 'WCML_Product_Data_Store_CPT' => $baseDir . '/classes/product/class-wcml-product-data-store-cpt.php',
116
  'WCML_Product_Gallery_Filter' => $baseDir . '/classes/media/class-wcml-product-gallery-filter.php',
117
  'WCML_Product_Gallery_Filter_Factory' => $baseDir . '/classes/media/class-wcml-product-gallery-filter-factory.php',
118
  'WCML_Product_Image_Filter' => $baseDir . '/classes/media/class-wcml-product-image-filter.php',
198
  'WCML_WPSEO' => $baseDir . '/compatibility/class-wcml-wpseo.php',
199
  'WCML_Widgets' => $baseDir . '/inc/class-wcml-widgets.php',
200
  'WCML_Woo_Var_Table' => $baseDir . '/compatibility/class-wcml-woo-var-table.php',
201
+ 'WCML_Woobe' => $baseDir . '/compatibility/class-wcml-woobe.php',
202
  'WCML_WpFastest_Cache' => $baseDir . '/compatibility/class-wcml-wpfastest-cache.php',
203
  'WCML_Wpb_Vc' => $baseDir . '/compatibility/class-wcml-wpb-vc.php',
204
  'WCML_YIKES_Custom_Product_Tabs_Pro' => $baseDir . '/compatibility/class-wcml-yikes-custom-product-tabs-pro.php',
206
  'WCML_gravityforms' => $baseDir . '/compatibility/class-wcml-gravityforms.php',
207
  'WCML_wcExporter' => $baseDir . '/compatibility/class-wcml-wcexporter.php',
208
  'WCML_xDomain_Data' => $baseDir . '/classes/urls/class-wcml-xdomain-data.php',
209
+ 'WPML\\Templates\\PHP\\Model' => $baseDir . '/classes/templates/php/model.php',
210
  'WPML_Core_Version_Check' => $vendorDir . '/wpml-shared/wpml-lib-dependencies/src/dependencies/class-wpml-core-version-check.php',
211
  'WPML_Dependencies' => $vendorDir . '/wpml-shared/wpml-lib-dependencies/src/dependencies/class-wpml-dependencies.php',
212
  'WPML_PHP_Version_Check' => $vendorDir . '/wpml-shared/wpml-lib-dependencies/src/dependencies/class-wpml-php-version-check.php',
vendor/composer/autoload_namespaces.php CHANGED
@@ -6,5 +6,4 @@ $vendorDir = dirname(dirname(__FILE__));
6
  $baseDir = dirname($vendorDir);
7
 
8
  return array(
9
- 'xrstf\\Composer52' => array($vendorDir . '/xrstf/composer-php52/lib'),
10
  );
6
  $baseDir = dirname($vendorDir);
7
 
8
  return array(
 
9
  );
vendor/composer/autoload_real.php CHANGED
@@ -2,7 +2,7 @@
2
 
3
  // autoload_real.php @generated by Composer
4
 
5
- class ComposerAutoloaderInit45b9e3eb7ce593679d57b7aed79dfe16
6
  {
7
  private static $loader;
8
 
@@ -19,15 +19,15 @@ class ComposerAutoloaderInit45b9e3eb7ce593679d57b7aed79dfe16
19
  return self::$loader;
20
  }
21
 
22
- spl_autoload_register(array('ComposerAutoloaderInit45b9e3eb7ce593679d57b7aed79dfe16', 'loadClassLoader'), true, true);
23
  self::$loader = $loader = new \Composer\Autoload\ClassLoader();
24
- spl_autoload_unregister(array('ComposerAutoloaderInit45b9e3eb7ce593679d57b7aed79dfe16', '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\ComposerStaticInit45b9e3eb7ce593679d57b7aed79dfe16::getInitializer($loader));
31
  } else {
32
  $map = require __DIR__ . '/autoload_namespaces.php';
33
  foreach ($map as $namespace => $path) {
@@ -48,19 +48,19 @@ class ComposerAutoloaderInit45b9e3eb7ce593679d57b7aed79dfe16
48
  $loader->register(true);
49
 
50
  if ($useStaticLoader) {
51
- $includeFiles = Composer\Autoload\ComposerStaticInit45b9e3eb7ce593679d57b7aed79dfe16::$files;
52
  } else {
53
  $includeFiles = require __DIR__ . '/autoload_files.php';
54
  }
55
  foreach ($includeFiles as $fileIdentifier => $file) {
56
- composerRequire45b9e3eb7ce593679d57b7aed79dfe16($fileIdentifier, $file);
57
  }
58
 
59
  return $loader;
60
  }
61
  }
62
 
63
- function composerRequire45b9e3eb7ce593679d57b7aed79dfe16($fileIdentifier, $file)
64
  {
65
  if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) {
66
  require $file;
2
 
3
  // autoload_real.php @generated by Composer
4
 
5
+ class ComposerAutoloaderInitff583bd185773a5093da3cb1ec65536c
6
  {
7
  private static $loader;
8
 
19
  return self::$loader;
20
  }
21
 
22
+ spl_autoload_register(array('ComposerAutoloaderInitff583bd185773a5093da3cb1ec65536c', 'loadClassLoader'), true, true);
23
  self::$loader = $loader = new \Composer\Autoload\ClassLoader();
24
+ spl_autoload_unregister(array('ComposerAutoloaderInitff583bd185773a5093da3cb1ec65536c', '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\ComposerStaticInitff583bd185773a5093da3cb1ec65536c::getInitializer($loader));
31
  } else {
32
  $map = require __DIR__ . '/autoload_namespaces.php';
33
  foreach ($map as $namespace => $path) {
48
  $loader->register(true);
49
 
50
  if ($useStaticLoader) {
51
+ $includeFiles = Composer\Autoload\ComposerStaticInitff583bd185773a5093da3cb1ec65536c::$files;
52
  } else {
53
  $includeFiles = require __DIR__ . '/autoload_files.php';
54
  }
55
  foreach ($includeFiles as $fileIdentifier => $file) {
56
+ composerRequireff583bd185773a5093da3cb1ec65536c($fileIdentifier, $file);
57
  }
58
 
59
  return $loader;
60
  }
61
  }
62
 
63
+ function composerRequireff583bd185773a5093da3cb1ec65536c($fileIdentifier, $file)
64
  {
65
  if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) {
66
  require $file;
vendor/composer/autoload_real_52.php DELETED
@@ -1,46 +0,0 @@
1
- <?php
2
-
3
- // autoload_real_52.php generated by xrstf/composer-php52
4
-
5
- class ComposerAutoloaderInitf703a8bfc3adbe723a55b33eb074c1df {
6
- private static $loader;
7
-
8
- public static function loadClassLoader($class) {
9
- if ('xrstf_Composer52_ClassLoader' === $class) {
10
- require dirname(__FILE__).'/ClassLoader52.php';
11
- }
12
- }
13
-
14
- /**
15
- * @return xrstf_Composer52_ClassLoader
16
- */
17
- public static function getLoader() {
18
- if (null !== self::$loader) {
19
- return self::$loader;
20
- }
21
-
22
- spl_autoload_register(array('ComposerAutoloaderInitf703a8bfc3adbe723a55b33eb074c1df', 'loadClassLoader'), true /*, true */);
23
- self::$loader = $loader = new xrstf_Composer52_ClassLoader();
24
- spl_autoload_unregister(array('ComposerAutoloaderInitf703a8bfc3adbe723a55b33eb074c1df', 'loadClassLoader'));
25
-
26
- $vendorDir = dirname(dirname(__FILE__));
27
- $baseDir = dirname($vendorDir);
28
- $dir = dirname(__FILE__);
29
-
30
- $map = require $dir.'/autoload_namespaces.php';
31
- foreach ($map as $namespace => $path) {
32
- $loader->add($namespace, $path);
33
- }
34
-
35
- $classMap = require $dir.'/autoload_classmap.php';
36
- if ($classMap) {
37
- $loader->addClassMap($classMap);
38
- }
39
-
40
- $loader->register(true);
41
-
42
- require $vendorDir . '/jakeasmith/http_build_url/src/http_build_url.php';
43
-
44
- return $loader;
45
- }
46
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/composer/autoload_static.php CHANGED
@@ -4,7 +4,7 @@
4
 
5
  namespace Composer\Autoload;
6
 
7
- class ComposerStaticInit45b9e3eb7ce593679d57b7aed79dfe16
8
  {
9
  public static $files = array (
10
  'b45b351e6b6f7487d819961fef2fda77' => __DIR__ . '/..' . '/jakeasmith/http_build_url/src/http_build_url.php',
@@ -24,394 +24,12 @@ class ComposerStaticInit45b9e3eb7ce593679d57b7aed79dfe16
24
  ),
25
  );
26
 
27
- public static $prefixesPsr0 = array (
28
- 'x' =>
29
- array (
30
- 'xrstf\\Composer52' =>
31
- array (
32
- 0 => __DIR__ . '/..' . '/xrstf/composer-php52/lib',
33
- ),
34
- ),
35
- );
36
-
37
  public static $classMap = array (
38
- 'WCML\\Twig\\Cache\\CacheInterface' => __DIR__ . '/../..' . '/lib/twig/src/Cache/CacheInterface.php',
39
- 'WCML\\Twig\\Cache\\FilesystemCache' => __DIR__ . '/../..' . '/lib/twig/src/Cache/FilesystemCache.php',
40
- 'WCML\\Twig\\Cache\\NullCache' => __DIR__ . '/../..' . '/lib/twig/src/Cache/NullCache.php',
41
- 'WCML\\Twig\\Compiler' => __DIR__ . '/../..' . '/lib/twig/src/Compiler.php',
42
- 'WCML\\Twig\\Environment' => __DIR__ . '/../..' . '/lib/twig/src/Environment.php',
43
- 'WCML\\Twig\\Error\\Error' => __DIR__ . '/../..' . '/lib/twig/src/Error/Error.php',
44
- 'WCML\\Twig\\Error\\LoaderError' => __DIR__ . '/../..' . '/lib/twig/src/Error/LoaderError.php',
45
- 'WCML\\Twig\\Error\\RuntimeError' => __DIR__ . '/../..' . '/lib/twig/src/Error/RuntimeError.php',
46
- 'WCML\\Twig\\Error\\SyntaxError' => __DIR__ . '/../..' . '/lib/twig/src/Error/SyntaxError.php',
47
- 'WCML\\Twig\\ExpressionParser' => __DIR__ . '/../..' . '/lib/twig/src/ExpressionParser.php',
48
- 'WCML\\Twig\\Extension\\AbstractExtension' => __DIR__ . '/../..' . '/lib/twig/src/Extension/AbstractExtension.php',
49
- 'WCML\\Twig\\Extension\\CoreExtension' => __DIR__ . '/../..' . '/lib/twig/src/Extension/CoreExtension.php',
50
- 'WCML\\Twig\\Extension\\DebugExtension' => __DIR__ . '/../..' . '/lib/twig/src/Extension/DebugExtension.php',
51
- 'WCML\\Twig\\Extension\\EscaperExtension' => __DIR__ . '/../..' . '/lib/twig/src/Extension/EscaperExtension.php',
52
- 'WCML\\Twig\\Extension\\ExtensionInterface' => __DIR__ . '/../..' . '/lib/twig/src/Extension/ExtensionInterface.php',
53
- 'WCML\\Twig\\Extension\\GlobalsInterface' => __DIR__ . '/../..' . '/lib/twig/src/Extension/GlobalsInterface.php',
54
- 'WCML\\Twig\\Extension\\InitRuntimeInterface' => __DIR__ . '/../..' . '/lib/twig/src/Extension/InitRuntimeInterface.php',
55
- 'WCML\\Twig\\Extension\\OptimizerExtension' => __DIR__ . '/../..' . '/lib/twig/src/Extension/OptimizerExtension.php',
56
- 'WCML\\Twig\\Extension\\ProfilerExtension' => __DIR__ . '/../..' . '/lib/twig/src/Extension/ProfilerExtension.php',
57
- 'WCML\\Twig\\Extension\\RuntimeExtensionInterface' => __DIR__ . '/../..' . '/lib/twig/src/Extension/RuntimeExtensionInterface.php',
58
- 'WCML\\Twig\\Extension\\SandboxExtension' => __DIR__ . '/../..' . '/lib/twig/src/Extension/SandboxExtension.php',
59
- 'WCML\\Twig\\Extension\\StagingExtension' => __DIR__ . '/../..' . '/lib/twig/src/Extension/StagingExtension.php',
60
- 'WCML\\Twig\\Extension\\StringLoaderExtension' => __DIR__ . '/../..' . '/lib/twig/src/Extension/StringLoaderExtension.php',
61
- 'WCML\\Twig\\FileExtensionEscapingStrategy' => __DIR__ . '/../..' . '/lib/twig/src/FileExtensionEscapingStrategy.php',
62
- 'WCML\\Twig\\Lexer' => __DIR__ . '/../..' . '/lib/twig/src/Lexer.php',
63
- 'WCML\\Twig\\Loader\\ArrayLoader' => __DIR__ . '/../..' . '/lib/twig/src/Loader/ArrayLoader.php',
64
- 'WCML\\Twig\\Loader\\ChainLoader' => __DIR__ . '/../..' . '/lib/twig/src/Loader/ChainLoader.php',
65
- 'WCML\\Twig\\Loader\\ExistsLoaderInterface' => __DIR__ . '/../..' . '/lib/twig/src/Loader/ExistsLoaderInterface.php',
66
- 'WCML\\Twig\\Loader\\FilesystemLoader' => __DIR__ . '/../..' . '/lib/twig/src/Loader/FilesystemLoader.php',
67
- 'WCML\\Twig\\Loader\\LoaderInterface' => __DIR__ . '/../..' . '/lib/twig/src/Loader/LoaderInterface.php',
68
- 'WCML\\Twig\\Loader\\SourceContextLoaderInterface' => __DIR__ . '/../..' . '/lib/twig/src/Loader/SourceContextLoaderInterface.php',
69
- 'WCML\\Twig\\Markup' => __DIR__ . '/../..' . '/lib/twig/src/Markup.php',
70
- 'WCML\\Twig\\NodeTraverser' => __DIR__ . '/../..' . '/lib/twig/src/NodeTraverser.php',
71
- 'WCML\\Twig\\NodeVisitor\\AbstractNodeVisitor' => __DIR__ . '/../..' . '/lib/twig/src/NodeVisitor/AbstractNodeVisitor.php',
72
- 'WCML\\Twig\\NodeVisitor\\EscaperNodeVisitor' => __DIR__ . '/../..' . '/lib/twig/src/NodeVisitor/EscaperNodeVisitor.php',
73
- 'WCML\\Twig\\NodeVisitor\\NodeVisitorInterface' => __DIR__ . '/../..' . '/lib/twig/src/NodeVisitor/NodeVisitorInterface.php',
74
- 'WCML\\Twig\\NodeVisitor\\OptimizerNodeVisitor' => __DIR__ . '/../..' . '/lib/twig/src/NodeVisitor/OptimizerNodeVisitor.php',
75
- 'WCML\\Twig\\NodeVisitor\\SafeAnalysisNodeVisitor' => __DIR__ . '/../..' . '/lib/twig/src/NodeVisitor/SafeAnalysisNodeVisitor.php',
76
- 'WCML\\Twig\\NodeVisitor\\SandboxNodeVisitor' => __DIR__ . '/../..' . '/lib/twig/src/NodeVisitor/SandboxNodeVisitor.php',
77
- 'WCML\\Twig\\Node\\AutoEscapeNode' => __DIR__ . '/../..' . '/lib/twig/src/Node/AutoEscapeNode.php',
78
- 'WCML\\Twig\\Node\\BlockNode' => __DIR__ . '/../..' . '/lib/twig/src/Node/BlockNode.php',
79
- 'WCML\\Twig\\Node\\BlockReferenceNode' => __DIR__ . '/../..' . '/lib/twig/src/Node/BlockReferenceNode.php',
80
- 'WCML\\Twig\\Node\\BodyNode' => __DIR__ . '/../..' . '/lib/twig/src/Node/BodyNode.php',
81
- 'WCML\\Twig\\Node\\CheckSecurityNode' => __DIR__ . '/../..' . '/lib/twig/src/Node/CheckSecurityNode.php',
82
- 'WCML\\Twig\\Node\\CheckToStringNode' => __DIR__ . '/../..' . '/lib/twig/src/Node/CheckToStringNode.php',
83
- 'WCML\\Twig\\Node\\DeprecatedNode' => __DIR__ . '/../..' . '/lib/twig/src/Node/DeprecatedNode.php',
84
- 'WCML\\Twig\\Node\\DoNode' => __DIR__ . '/../..' . '/lib/twig/src/Node/DoNode.php',
85
- 'WCML\\Twig\\Node\\EmbedNode' => __DIR__ . '/../..' . '/lib/twig/src/Node/EmbedNode.php',
86
- 'WCML\\Twig\\Node\\Expression\\AbstractExpression' => __DIR__ . '/../..' . '/lib/twig/src/Node/Expression/AbstractExpression.php',
87
- 'WCML\\Twig\\Node\\Expression\\ArrayExpression' => __DIR__ . '/../..' . '/lib/twig/src/Node/Expression/ArrayExpression.php',
88
- 'WCML\\Twig\\Node\\Expression\\ArrowFunctionExpression' => __DIR__ . '/../..' . '/lib/twig/src/Node/Expression/ArrowFunctionExpression.php',
89
- 'WCML\\Twig\\Node\\Expression\\AssignNameExpression' => __DIR__ . '/../..' . '/lib/twig/src/Node/Expression/AssignNameExpression.php',
90
- 'WCML\\Twig\\Node\\Expression\\Binary\\AbstractBinary' => __DIR__ . '/../..' . '/lib/twig/src/Node/Expression/Binary/AbstractBinary.php',
91
- 'WCML\\Twig\\Node\\Expression\\Binary\\AddBinary' => __DIR__ . '/../..' . '/lib/twig/src/Node/Expression/Binary/AddBinary.php',
92
- 'WCML\\Twig\\Node\\Expression\\Binary\\AndBinary' => __DIR__ . '/../..' . '/lib/twig/src/Node/Expression/Binary/AndBinary.php',
93
- 'WCML\\Twig\\Node\\Expression\\Binary\\BitwiseAndBinary' => __DIR__ . '/../..' . '/lib/twig/src/Node/Expression/Binary/BitwiseAndBinary.php',
94
- 'WCML\\Twig\\Node\\Expression\\Binary\\BitwiseOrBinary' => __DIR__ . '/../..' . '/lib/twig/src/Node/Expression/Binary/BitwiseOrBinary.php',
95
- 'WCML\\Twig\\Node\\Expression\\Binary\\BitwiseXorBinary' => __DIR__ . '/../..' . '/lib/twig/src/Node/Expression/Binary/BitwiseXorBinary.php',
96
- 'WCML\\Twig\\Node\\Expression\\Binary\\ConcatBinary' => __DIR__ . '/../..' . '/lib/twig/src/Node/Expression/Binary/ConcatBinary.php',
97
- 'WCML\\Twig\\Node\\Expression\\Binary\\DivBinary' => __DIR__ . '/../..' . '/lib/twig/src/Node/Expression/Binary/DivBinary.php',
98
- 'WCML\\Twig\\Node\\Expression\\Binary\\EndsWithBinary' => __DIR__ . '/../..' . '/lib/
4
 
5
  namespace Composer\Autoload;
6
 
7
+ class ComposerStaticInitff583bd185773a5093da3cb1ec65536c
8
  {
9
  public static $files = array (
10
  'b45b351e6b6f7487d819961fef2fda77' => __DIR__ . '/..' . '/jakeasmith/http_build_url/src/http_build_url.php',
24
  ),
25
  );
26
 
 
 
 
 
 
 
 
 
 
 
27
  public static $classMap = array (